//"12345679","0052","D7FF","00747","id","*FDFF","*FFFF","0282","324.29999","224.89999","317.89999","1.60000","224.20000","-0.00300","50.01000","0.01180","1.00550","2.01350","9292" int SolarEdgeBase::ParsePacket0x0282(const unsigned char *pData, int dlen) { const unsigned char *b=pData; //10 Floats int totfloats=dlen/4; if (totfloats!=10) return 0; //DC1 Voltage float voltageDC1=GetFloat(b); b+=4; //AC2 Voltage float voltageAC1=GetFloat(b); b+=4; //DC2 Voltage float voltageDC2=GetFloat(b); b+=4; //Iets1 float Iets1=GetFloat(b); b+=4; //AC2 Voltage float voltageAC2=GetFloat(b); b+=4; //Iets2 float Iets2=GetFloat(b); b+=4; //Frequency float freq=GetFloat(b); SendPercentageSensor(SE_FREQ, 0, 255, freq, "Hz"); b+=4; //skip the rest return dlen-2; }
//"12345679","0056","D3FF","00749","id","*FDFF","*FFFF","0280","325.60001","225.50000","1.60000","224.79999","50.00000","5.56000","15.39000","0.01220","0.01000","1254.00000","0.00000","B794" int SolarEdgeBase::ParsePacket0x0280(const unsigned char *pData, int dlen) { const unsigned char *b=pData; //11 Float values int totfloats=dlen/4; if (totfloats!=11) return 0; //DC Voltage float voltageDC=GetFloat(b); b+=4; dlen-=4; //AC Voltage1 float voltageAC1=GetFloat(b); b+=4; dlen-=4; //Iets1 float Iets1=GetFloat(b); b+=4; dlen-=4; //AC Voltage2 float voltageAC2=GetFloat(b); b+=4; dlen-=4; //Frequency float freq=GetFloat(b); SendPercentageSensor(SE_FREQ, 0, 255, freq, "Hz"); b+=4; dlen-=4; //Ampere float ampere=GetFloat(b); b+=4; dlen-=4; //Temp float temp=GetFloat(b); b+=4; dlen-=4; //Iets2 float Iets2=GetFloat(b); b+=4; dlen-=4; //Iets3 float Iets3=GetFloat(b); b+=4; dlen-=4; //Watt P-Out float Watt=GetFloat(b); b+=4; dlen-=4; //Iets4 (unsigned long) unsigned long *pUL=(unsigned long*)b; b+=4; dlen-=4; return (b-pData); }
void CHardwareMonitor::UpdateSystemSensor(const std::string& qType, const int dindex, const std::string& devName, const std::string& devValue) { if (!m_HwdID) { #ifdef _DEBUG _log.Log(LOG_NORM,"Hardware Monitor: Id not found!"); #endif return; } int doffset = 0; if (qType == "Temperature") { doffset = 1000; float temp = static_cast<float>(atof(devValue.c_str())); SendTempSensor(doffset + dindex, 255, temp, devName); } else if (qType == "Load") { doffset = 1100; float perc = static_cast<float>(atof(devValue.c_str())); SendPercentageSensor(doffset + dindex, 0, 255, perc, devName); } else if (qType == "Fan") { doffset = 1200; int fanspeed = atoi(devValue.c_str()); SendFanSensor(doffset + dindex, fanspeed, devName); } else if (qType == "Voltage") { doffset = 1300; float volt = static_cast<float>(atof(devValue.c_str())); SendVoltageSensor(0, doffset + dindex, 255, volt, devName); } else if (qType == "Current") { doffset = 1400; float curr = static_cast<float>(atof(devValue.c_str())); SendCurrent(doffset + dindex, curr, devName); } return; }
bool CRFLinkBase::ParseLine(const std::string &sLine) { m_LastReceivedTime = mytime(NULL); std::vector<std::string> results; StringSplit(sLine, ";", results); if (results.size() < 2) return false; //not needed bool bHideDebugLog = ( (sLine.find("PONG") != std::string::npos)|| (sLine.find("PING") != std::string::npos) ); int RFLink_ID = atoi(results[0].c_str()); if (RFLink_ID != 20) { return false; //only accept RFLink->Master messages } #ifdef ENABLE_LOGGING if (!bHideDebugLog) _log.Log(LOG_NORM, "RFLink: %s", sLine.c_str()); #endif //std::string Sensor_ID = results[1]; if (results.size() >2) { //Status reply std::string Name_ID = results[2]; if ((Name_ID.find("Nodo RadioFrequencyLink") != std::string::npos) || (Name_ID.find("RFLink Gateway") != std::string::npos)) { _log.Log(LOG_STATUS, "RFLink: Controller Initialized!..."); WriteInt("10;VERSION;\n"); // 20;3C;VER=1.1;REV=37;BUILD=01; //Enable DEBUG //write("10;RFDEBUG=ON;\n"); //Enable Undecoded DEBUG //write("10;RFUDEBUG=ON;\n"); return true; } if (Name_ID.find("VER") != std::string::npos) { //_log.Log(LOG_STATUS, "RFLink: %s", sLine.c_str()); int versionlo = 0; int versionhi = 0; int revision = 0; int build = 0; if (results[2].find("VER") != std::string::npos) { versionhi = RFLinkGetIntStringValue(results[2]); versionlo = RFLinkGetIntDecStringValue(results[2]); } if (results[3].find("REV") != std::string::npos){ revision = RFLinkGetIntStringValue(results[3]); } if (results[4].find("BUILD") != std::string::npos) { build = RFLinkGetIntStringValue(results[4]); } _log.Log(LOG_STATUS, "RFLink Detected, Version: %d.%d Revision: %d Build: %d", versionhi, versionlo, revision, build); std::stringstream sstr; sstr << revision << "." << build; m_Version = sstr.str(); mytime(&m_LastHeartbeatReceive); // keep heartbeat happy mytime(&m_LastHeartbeat); // keep heartbeat happy m_LastReceivedTime = m_LastHeartbeat; m_bTXokay = true; // variable to indicate an OK was received return true; } if (Name_ID.find("PONG") != std::string::npos) { //_log.Log(LOG_STATUS, "RFLink: PONG received!..."); mytime(&m_LastHeartbeatReceive); // keep heartbeat happy mytime(&m_LastHeartbeat); // keep heartbeat happy m_LastReceivedTime = m_LastHeartbeat; m_bTXokay = true; // variable to indicate an OK was received return true; } if (Name_ID.find("OK") != std::string::npos) { //_log.Log(LOG_STATUS, "RFLink: OK received!..."); mytime(&m_LastHeartbeatReceive); // keep heartbeat happy mytime(&m_LastHeartbeat); // keep heartbeat happy m_LastReceivedTime = m_LastHeartbeat; m_bTXokay = true; // variable to indicate an OK was received return true; } else if (Name_ID.find("CMD UNKNOWN") != std::string::npos) { _log.Log(LOG_ERROR, "RFLink: Error/Unknown command received!..."); m_bTXokay = true; // variable to indicate an ERROR was received return true; } } if (results.size() < 4) return true; if (results[3].find("ID=") == std::string::npos) return false; //?? mytime(&m_LastHeartbeatReceive); // keep heartbeat happy mytime(&m_LastHeartbeat); // keep heartbeat happy //_log.Log(LOG_STATUS, "RFLink: t1=%d t2=%d", m_LastHeartbeat, m_LastHeartbeatReceive); m_LastReceivedTime = m_LastHeartbeat; std::stringstream ss; unsigned int ID; ss << std::hex << results[3].substr(3); ss >> ID; int Node_ID = (ID & 0xFF00) >> 8; int Child_ID = ID & 0xFF; bool bHaveTemp = false; float temp = 0; bool bHaveHum = false; int humidity = 0; bool bHaveHumStatus = false; int humstatus = 0; bool bHaveBaro = false; float baro = 0; int baroforecast = 0; bool bHaveRain = false; float raincounter = 0; bool bHaveLux = false; float lux = 0; bool bHaveUV = false; float uv = 0; bool bHaveWindDir = false; int windir = 0; bool bHaveWindSpeed = false; float windspeed = 0; bool bHaveWindGust = false; float windgust = 0; bool bHaveWindTemp = false; float windtemp = 0; bool bHaveWindChill = false; float windchill = 0; bool bHaveRGB = false; int rgb = 0; bool bHaveRGBW = false; int rgbw = 0; bool bHaveSound = false; int sound = 0; bool bHaveCO2 = false; int co2 = 0; bool bHaveBlind = false; int blind = 0; bool bHaveKWatt = false; float kwatt = 0; bool bHaveWatt = false; float watt = 0; bool bHaveDistance = false; float distance = 0; bool bHaveMeter = false; float meter = 0; bool bHaveVoltage = false; float voltage = 0; bool bHaveCurrent = false; float current = 0; bool bHaveCurrent2 = false; float current2 = 0; bool bHaveCurrent3 = false; float current3 = 0; bool bHaveImpedance = false; float impedance = 0; bool bHaveSwitch = false; int switchunit = 0; bool bHaveSwitchCmd = false; std::string switchcmd = ""; int switchlevel = 0; int BatteryLevel = 255; std::string tmpstr; int iTemp; for (size_t ii = 4; ii < results.size(); ii++) { if (results[ii].find("TEMP") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveTemp = true; if ((iTemp & 0x8000) == 0x8000) { //negative temp iTemp = -(iTemp & 0xFFF); } temp = float(iTemp) / 10.0f; } else if (results[ii].find("HUM") != std::string::npos) { bHaveHum = true; humidity = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("HSTATUS") != std::string::npos) { bHaveHumStatus = true; humstatus = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("BARO") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveBaro = true; baro = float(iTemp); } else if (results[ii].find("BFORECAST") != std::string::npos) { baroforecast = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("RAIN") != std::string::npos) { bHaveRain = true; iTemp = RFLinkGetHexStringValue(results[ii]); raincounter = float(iTemp) / 10.0f; } else if (results[ii].find("LUX") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveLux = true; lux = float(iTemp); } else if (results[ii].find("UV") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveUV = true; uv = float(iTemp) /10.0f; } else if (results[ii].find("BAT") != std::string::npos) { tmpstr = RFLinkGetStringValue(results[ii]); BatteryLevel = (tmpstr == "OK") ? 100 : 0; } else if (results[ii].find("WINDIR") != std::string::npos) { bHaveWindDir = true; windir = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("WINSP") != std::string::npos) { bHaveWindSpeed = true; iTemp = RFLinkGetHexStringValue(results[ii]); // received value is km/u windspeed = (float(iTemp) * 0.0277778f); //convert to m/s } else if (results[ii].find("WINGS") != std::string::npos) { bHaveWindGust = true; iTemp = RFLinkGetHexStringValue(results[ii]); // received value is km/u windgust = (float(iTemp) * 0.0277778f); //convert to m/s } else if (results[ii].find("WINTMP") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveWindTemp = true; if ((iTemp & 0x8000) == 0x8000) { //negative temp iTemp = -(iTemp & 0xFFF); } windtemp = float(iTemp) / 10.0f; } else if (results[ii].find("WINCHL") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveWindChill = true; if ((iTemp & 0x8000) == 0x8000) { //negative temp iTemp = -(iTemp & 0xFFF); } windchill = float(iTemp) / 10.0f; } else if (results[ii].find("SOUND") != std::string::npos) { bHaveSound = true; sound = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("CO2") != std::string::npos) { bHaveCO2 = true; co2 = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("RGBW") != std::string::npos) { bHaveRGBW = true; rgbw = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("RGB") != std::string::npos) { bHaveRGB = true; rgb = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("BLIND") != std::string::npos) { bHaveBlind = true; blind = RFLinkGetIntStringValue(results[ii]); } else if (results[ii].find("KWATT") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveKWatt = true; kwatt = float(iTemp) / 1000.0f; } else if (results[ii].find("WATT") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveWatt = true; watt = float(iTemp) / 10.0f; } else if (results[ii].find("DIST") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveDistance = true; distance = float(iTemp) / 10.0f; } else if (results[ii].find("METER") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveMeter = true; meter = float(iTemp) / 10.0f; } else if (results[ii].find("VOLT") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveVoltage = true; voltage = float(iTemp) / 10.0f; } else if (results[ii].find("CURRENT") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveCurrent = true; current = float(iTemp) / 10.0f; } else if (results[ii].find("CURRENT2") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveCurrent2 = true; current2 = float(iTemp) / 10.0f; } else if (results[ii].find("CURRENT3") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveCurrent3 = true; current3 = float(iTemp) / 10.0f; } else if (results[ii].find("IMPEDANCE") != std::string::npos) { iTemp = RFLinkGetHexStringValue(results[ii]); bHaveCurrent = true; current = float(iTemp) / 10.0f; } else if (results[ii].find("SWITCH") != std::string::npos) { bHaveSwitch = true; switchunit = RFLinkGetHexStringValue(results[ii]); } else if (results[ii].find("CMD") != std::string::npos) { bHaveSwitchCmd = true; switchcmd = RFLinkGetStringValue(results[ii]); } else if (results[ii].find("SMOKEALERT") != std::string::npos) { bHaveSwitch = true; switchunit = 1; bHaveSwitchCmd = true; switchcmd = RFLinkGetStringValue(results[ii]); } else if (results[ii].find("CHIME") != std::string::npos) { bHaveSwitch = true; switchunit = 2; bHaveSwitchCmd = true; switchcmd = "ON"; } } std::string tmp_Name = results[2]; if (bHaveTemp&&bHaveHum&&bHaveBaro) { SendTempHumBaroSensor(ID, BatteryLevel, temp, humidity, baro, baroforecast, tmp_Name); } else if (bHaveTemp&&bHaveHum) { SendTempHumSensor(ID, BatteryLevel, temp, humidity, tmp_Name); } else if (bHaveTemp) { SendTempSensor(ID, BatteryLevel, temp, tmp_Name); } else if (bHaveHum) { SendHumiditySensor(ID, BatteryLevel, humidity, tmp_Name); } else if (bHaveBaro) { SendBaroSensor(Node_ID, Child_ID, BatteryLevel, baro, baroforecast, tmp_Name); } if (bHaveLux) { SendLuxSensor(Node_ID, Child_ID, BatteryLevel, lux, tmp_Name); } if (bHaveUV) { SendUVSensor(Node_ID, Child_ID, BatteryLevel, uv, tmp_Name); } if (bHaveRain) { SendRainSensor(ID, BatteryLevel, float(raincounter), tmp_Name); } if (bHaveWindDir && bHaveWindSpeed && bHaveWindGust && bHaveWindChill) { SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, tmp_Name); } else if (bHaveWindDir && bHaveWindGust) { SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, tmp_Name); } else if (bHaveWindSpeed) { SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, tmp_Name); } if (bHaveCO2) { SendAirQualitySensor((ID & 0xFF00) >> 8, ID & 0xFF, BatteryLevel, co2, tmp_Name); } if (bHaveSound) { SendSoundSensor(ID, BatteryLevel, sound, tmp_Name); } if (bHaveRGB) { //RRGGBB SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgb, false, tmp_Name); } if (bHaveRGBW) { //RRGGBBWW SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgbw, true, tmp_Name); } if (bHaveBlind) { SendBlindSensor(Node_ID, Child_ID, BatteryLevel, blind, tmp_Name); } if (bHaveKWatt&bHaveWatt) { SendKwhMeterOldWay(Node_ID, Child_ID, BatteryLevel, watt / 100.0f, kwatt, tmp_Name); } else if (bHaveKWatt) { SendKwhMeterOldWay(Node_ID, Child_ID, BatteryLevel, watt / 100.0f, kwatt, tmp_Name); } else if (bHaveWatt) { SendKwhMeterOldWay(Node_ID, Child_ID, BatteryLevel, watt / 100.0f, kwatt, tmp_Name); } if (bHaveDistance) { SendDistanceSensor(Node_ID, Child_ID, BatteryLevel, distance, tmp_Name); } if (bHaveMeter) { SendMeterSensor(Node_ID, Child_ID, BatteryLevel, meter, tmp_Name); } if (bHaveVoltage) { SendVoltageSensor(Node_ID, Child_ID, BatteryLevel, voltage, tmp_Name); } if (bHaveCurrent && bHaveCurrent2 && bHaveCurrent3) { SendCurrentSensor(ID, BatteryLevel, current, current2, current3, tmp_Name); } else if (bHaveCurrent) { SendCurrentSensor(ID, BatteryLevel, current, 0, 0, tmp_Name); } if (bHaveImpedance) { SendPercentageSensor(Node_ID, Child_ID, BatteryLevel, impedance, tmp_Name); } if (bHaveSwitch && bHaveSwitchCmd) { std::string switchType = results[2]; SendSwitchInt(ID, switchunit, BatteryLevel, switchType, switchcmd, switchlevel); } return true; }
void Meteostick::ParseLine() { if (m_bufferpos < 1) return; std::string sLine((char*)&m_buffer); std::vector<std::string> results; StringSplit(sLine, " ", results); if (results.size() < 1) return; //invalid data switch (m_state) { case MSTATE_INIT: if (sLine.find("# MeteoStick Version") == 0) { _log.Log(LOG_STATUS, sLine.c_str()); return; } if (results[0] == "?") { //Turn off filters write("f0\n"); m_state = MSTATE_FILTERS; } return; case MSTATE_FILTERS: //Set output to 'computer values' write("o1\n"); m_state = MSTATE_VALUES; return; case MSTATE_VALUES: #ifdef USE_868_Mhz //Set listen frequency to 868Mhz write("m1\n"); #else //Set listen frequency to 915Mhz write("m0\n"); #endif m_state = MSTATE_DATA; return; } if (m_state != MSTATE_DATA) return; if (results.size() < 3) return; unsigned char rCode = results[0][0]; if (rCode == '#') return; //#ifdef _DEBUG _log.Log(LOG_NORM, sLine.c_str()); //#endif switch (rCode) { case 'B': //temperature in Celsius, pressure in hPa if (results.size() >= 3) { float temp = static_cast<float>(atof(results[1].c_str())); float baro = static_cast<float>(atof(results[2].c_str())); SendTempBaroSensor(0, temp, baro, "Meteostick Temp+Baro"); } break; case 'W': //current wind speed in m / s, wind direction in degrees if (results.size() >= 5) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); if (m_LastOutsideTemp[ID%MAX_IDS] != 12345) { float speed = static_cast<float>(atof(results[2].c_str())); int direction = static_cast<int>(atoi(results[3].c_str())); SendWindSensor(ID, m_LastOutsideTemp[ID%MAX_IDS], speed, direction, "Wind"); } } break; case 'T': //temperature in degree Celsius, humidity in percent if (results.size() >= 5) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); float temp = static_cast<float>(atof(results[2].c_str())); int hum = static_cast<int>(atoi(results[3].c_str())); SendTempHumSensor(ID, 255, temp, hum, "Outside Temp+Hum"); m_LastOutsideTemp[ID%MAX_IDS] = temp; m_LastOutsideHum[ID%MAX_IDS] = hum; } break; case 'R': //Rain //counter value (value 0 - 255), ticks, 1 tick = 0.2mm or 0.01in //it only has a small counter, so we should make the total counter ourselfses if (results.size() >= 4) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); int raincntr = atoi(results[2].c_str()); float Rainmm = 0; if (m_LastRainValue[ID%MAX_IDS] != -1) { int cntr_diff = (raincntr - m_LastRainValue[ID%MAX_IDS])&255; Rainmm = float(cntr_diff); #ifdef RAIN_IN_MM //one tick is one mm Rainmm*=0.2f; //convert to mm; #else //one tick is 0.01 inch, we need to convert this also to mm //Rainmm *= 0.01f; //convert to inch //Rainmm *= 25.4f; //convert to mm //or directly Rainmm *= 0.254; #endif } m_LastRainValue[ID%MAX_IDS] = raincntr; if (m_ActRainCounter[ID%MAX_IDS] == -1) { //Get Last stored Rain counter bool bExists = false; float rcounter= GetRainSensorValue(ID,bExists); m_ActRainCounter[ID%MAX_IDS] = rcounter; } m_ActRainCounter[ID%MAX_IDS] += Rainmm; SendRainSensor(ID, 255, m_ActRainCounter[ID%MAX_IDS], "Rain"); } break; case 'S': //solar radiation, solar radiation in W / qm if (results.size() >= 4) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); float Radiation = static_cast<float>(atof(results[2].c_str())); SendSolarRadiationSensor(ID, Radiation, "Solar Radiation"); } break; case 'U': //UV index if (results.size() >= 4) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); float UV = static_cast<float>(atof(results[2].c_str())); SendUVSensor(ID, UV, "UV"); } break; case 'L': //wetness data of a leaf station //channel number (1 - 4), leaf wetness (0-15) if (results.size() >= 5) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); unsigned char Channel = (unsigned char)atoi(results[2].c_str()); unsigned char Wetness = (unsigned char)atoi(results[3].c_str()); SendLeafWetnessRainSensor(ID, Channel, Wetness, "Leaf Wetness"); } break; case 'M': //soil moisture of a soil station //channel number (1 - 4), Soil moisture in cbar(0 - 200) if (results.size() >= 5) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); unsigned char Channel = (unsigned char)atoi(results[2].c_str()); unsigned char Moisture = (unsigned char)atoi(results[3].c_str()); SendSoilMoistureSensor(ID, Channel, Moisture, "Soil Moisture"); } break; case 'O': //soil / leaf temperature of a soil / leaf station //channel number (1 - 4), soil / leaf temperature in degrees Celsius if (results.size() >= 5) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); unsigned char Channel = (unsigned char)atoi(results[2].c_str()); float temp = static_cast<float>(atof(results[3].c_str())); unsigned char finalID = (ID * 10) + Channel; SendTempSensor(finalID, 255, temp, "Soil/Leaf Temp"); } break; case 'P': //solar panel power in(0 - 100) if (results.size() >= 4) { unsigned char ID = (unsigned char)atoi(results[1].c_str()); float Percentage = static_cast<float>(atof(results[2].c_str())); SendPercentageSensor(ID, 0, 255, Percentage, "power of solar panel"); } break; default: _log.Log(LOG_STATUS, "Unknown Type: %c", rCode); break; } }
void CSBFSpot::GetMeterDetails() { if (m_SBFDataPath.size() == 0) { _log.Log(LOG_ERROR, "SBFSpot: Data path empty!"); return; } if (m_SBFPlantName.size() == 0) { _log.Log(LOG_ERROR, "SBFSpot: Plant name empty!"); return; } time_t atime = time(NULL); struct tm ltime; localtime_r(&atime, <ime); int ActHourMin = (ltime.tm_hour * 60) + ltime.tm_min; int sunRise = getSunRiseSunSetMinutes(true); int sunSet = getSunRiseSunSetMinutes(false); //We only poll one hour before sunrise till one hour after sunset if (ActHourMin + 120 < sunRise) return; if (ActHourMin - 120 > sunSet) return; char szLogFile[256]; char szDateStr[50]; strcpy(szDateStr, strftime_t("%Y%m%d", atime)); sprintf(szLogFile, "%s%s-Spot-%s.csv", strftime_t(m_SBFDataPath.c_str(), atime), m_SBFPlantName.c_str(), szDateStr); std::string szSeperator = ";"; bool bHaveVersion = false; std::string tmpString; std::ifstream infile; std::string szLastDate = ""; std::vector<std::string> szLastLines; std::vector<std::string> results; std::string sLine; infile.open(szLogFile); if (!infile.is_open()) { if ((ActHourMin > sunRise) && (ActHourMin < sunSet)) { _log.Log(LOG_ERROR, "SBFSpot: Could not open spot file: %s", szLogFile); } return; } while (!infile.eof()) { getline(infile, sLine); sLine.erase(std::remove(sLine.begin(), sLine.end(), '\r'), sLine.end()); if (sLine.size() != 0) { if (sLine.find("sep=") == 0) { tmpString = sLine.substr(strlen("sep=")); if (tmpString != "") { szSeperator = tmpString; } } else if (sLine.find("Version CSV1") == 0) { bHaveVersion = true; } else if (bHaveVersion) { if ( (sLine.find(";DeviceName") == std::string::npos) && (sLine.find(";Watt") == std::string::npos) ) { StringSplit(sLine, szSeperator, results); if (results.size() >= 30) { if (m_SBFInverter.empty() || (m_SBFInverter == results[3])) { if (szLastDate.empty() || (szLastDate != results[0])) { szLastDate = results[0]; szLastLines.clear(); } if (szLastDate == results[0]) { szLastLines.push_back(sLine); } } } } } } } infile.close(); if (szLastLines.empty()) { _log.Log(LOG_ERROR, "SBFSpot: No data record found in spot file!"); return; } if (szLastDate == m_LastDateTime) { return; } m_LastDateTime = szLastDate; double kWhCounter = 0; double Pac = 0; int InvIdx = 0; std::vector<std::string>::const_iterator itt; for (itt = szLastLines.begin(); itt != szLastLines.end(); ++itt) { StringSplit(*itt, szSeperator, results); if (results[1].size() < 1) { _log.Log(LOG_ERROR, "SBFSpot: No data record found in spot file!"); return; } if ((results[28] != "OK") && (results[28] != "Ok")) { _log.Log(LOG_ERROR, "SBFSpot: Invalid field [28] should be OK!"); return; } std::string szKwhCounter = results[23]; stdreplace(szKwhCounter, ",", "."); kWhCounter += atof(szKwhCounter.c_str()); std::string szPacActual = results[20]; stdreplace(szPacActual, ",", "."); Pac += atof(szPacActual.c_str()); float voltage; tmpString = results[16]; stdreplace(tmpString, ",", "."); voltage = static_cast<float>(atof(tmpString.c_str())); SendVoltageSensor(0, (InvIdx * 10) + 1, 255, voltage, "Volt uac1"); tmpString = results[17]; stdreplace(tmpString, ",", "."); voltage = static_cast<float>(atof(tmpString.c_str())); if (voltage != 0) { SendVoltageSensor(0, (InvIdx * 10) + 2, 255, voltage, "Volt uac2"); } tmpString = results[18]; stdreplace(tmpString, ",", "."); voltage = static_cast<float>(atof(tmpString.c_str())); if (voltage != 0) { SendVoltageSensor(0, (InvIdx * 10) + 3, 255, voltage, "Volt uac3"); } float percentage; tmpString = results[21]; stdreplace(tmpString, ",", "."); percentage = static_cast<float>(atof(tmpString.c_str())); SendPercentageSensor((InvIdx * 10) + 1, 0, 255, percentage, "Efficiency"); tmpString = results[24]; stdreplace(tmpString, ",", "."); percentage = static_cast<float>(atof(tmpString.c_str())); SendPercentageSensor((InvIdx * 10) + 2, 0, 255, percentage, "Hz"); tmpString = results[27]; stdreplace(tmpString, ",", "."); percentage = static_cast<float>(atof(tmpString.c_str())); SendPercentageSensor((InvIdx * 10) + 3, 0, 255, percentage, "BT_Signal"); if (results.size() >= 31) { tmpString = results[30]; stdreplace(tmpString, ",", "."); float temperature = static_cast<float>(atof(tmpString.c_str())); SendTempSensor((InvIdx * 10) + 1, 255, temperature, "Temperature"); } InvIdx++; } //Send combined counter/pac if (kWhCounter != 0) { double LastUsage = 0; double LastTotal = 0; if (GetMeter(0, 1, LastUsage, LastTotal)) { if (kWhCounter < (int)(LastTotal * 100) / 100) { _log.Log(LOG_ERROR, "SBFSpot: Actual KwH counter (%f) less then last Counter (%f)!", kWhCounter, LastTotal); return; } } SendMeter(0, 1, Pac / 1000.0, kWhCounter, "SolarMain"); } }
void MySensorsBase::SendSensor2Domoticz(_tMySensorNode *pNode, _tMySensorChild *pChild, const _eSetType vType) { m_iLastSendNodeBatteryValue = 255; if (pChild->hasBattery) { m_iLastSendNodeBatteryValue = pChild->batValue; } int cNode = (pChild->nodeID << 8) | pChild->childID; int intValue; float floatValue; std::string stringValue; switch (vType) { case V_TEMP: { float Temp = 0; pChild->GetValue(V_TEMP, Temp); _tMySensorChild *pChildHum = FindChildWithValueType(pChild->nodeID, V_HUM); _tMySensorChild *pChildBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE); if (pChildHum && pChildBaro) { int Humidity; float Baro; bool bHaveHumidity = pChildHum->GetValue(V_HUM, Humidity); bool bHaveBaro = pChildBaro->GetValue(V_PRESSURE, Baro); if (bHaveHumidity && bHaveBaro) { int forecast = bmpbaroforecast_unknown; _tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST); if (pSensorForecast) { pSensorForecast->GetValue(V_FORECAST, forecast); } if (forecast == bmpbaroforecast_cloudy) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } //We are using the TempHumBaro Float type now, convert the forecast int nforecast = wsbaroforcast_some_clouds; if (Baro <= 980) nforecast = wsbaroforcast_heavy_rain; else if (Baro <= 995) { if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } else if (Baro >= 1029) nforecast = wsbaroforcast_sunny; switch (forecast) { case bmpbaroforecast_sunny: nforecast = wsbaroforcast_sunny; break; case bmpbaroforecast_cloudy: nforecast = wsbaroforcast_cloudy; break; case bmpbaroforecast_thunderstorm: nforecast = wsbaroforcast_heavy_rain; break; case bmpbaroforecast_rain: if (Temp>1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } SendTempHumBaroSensorFloat(cNode, pChild->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro"); } } else if (pChildHum) { int Humidity; bool bHaveHumidity = pChildHum->GetValue(V_HUM, Humidity); if (bHaveHumidity) { SendTempHumSensor(cNode, pChild->batValue, Temp, Humidity, (!pChild->childName.empty()) ? pChild->childName : "TempHum"); } } else { SendTempSensor(cNode, pChild->batValue, Temp, (!pChild->childName.empty()) ? pChild->childName : "Temp"); } } break; case V_HUM: { _tMySensorChild *pChildTemp = FindChildWithValueType(pChild->nodeID, V_TEMP); _tMySensorChild *pChildBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE); int forecast = bmpbaroforecast_unknown; _tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST); if (pSensorForecast) { pSensorForecast->GetValue(V_FORECAST, forecast); } if (forecast == bmpbaroforecast_cloudy) { if (pChildBaro) { float Baro; if (pChildBaro->GetValue(V_PRESSURE, Baro)) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } } } float Temp; float Baro; int Humidity; pChild->GetValue(V_HUM, Humidity); if (pChildTemp && pChildBaro) { bool bHaveTemp = pChildTemp->GetValue(V_TEMP, Temp); bool bHaveBaro = pChildBaro->GetValue(V_PRESSURE, Baro); if (bHaveTemp && bHaveBaro) { cNode = (pChildTemp->nodeID << 8) | pChildTemp->childID; //We are using the TempHumBaro Float type now, convert the forecast int nforecast = wsbaroforcast_some_clouds; if (Baro <= 980) nforecast = wsbaroforcast_heavy_rain; else if (Baro <= 995) { if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } else if (Baro >= 1029) nforecast = wsbaroforcast_sunny; switch (forecast) { case bmpbaroforecast_sunny: nforecast = wsbaroforcast_sunny; break; case bmpbaroforecast_cloudy: nforecast = wsbaroforcast_cloudy; break; case bmpbaroforecast_thunderstorm: nforecast = wsbaroforcast_heavy_rain; break; case bmpbaroforecast_rain: if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } SendTempHumBaroSensorFloat(cNode, pChildTemp->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro"); } } else if (pChildTemp) { bool bHaveTemp = pChildTemp->GetValue(V_TEMP, Temp); if (bHaveTemp) { cNode = (pChildTemp->nodeID << 8) | pChildTemp->childID; SendTempHumSensor(cNode, pChildTemp->batValue, Temp, Humidity, (!pChild->childName.empty()) ? pChild->childName : "TempHum"); } } else { SendHumiditySensor(cNode, pChild->batValue, Humidity); } } break; case V_PRESSURE: { float Baro; pChild->GetValue(V_PRESSURE, Baro); _tMySensorChild *pSensorTemp = FindChildWithValueType(pChild->nodeID, V_TEMP); _tMySensorChild *pSensorHum = FindChildWithValueType(pChild->nodeID, V_HUM); int forecast = bmpbaroforecast_unknown; _tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST); if (pSensorForecast) { pSensorForecast->GetValue(V_FORECAST, forecast); } if (forecast == bmpbaroforecast_cloudy) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } if (pSensorTemp && pSensorHum) { float Temp; int Humidity; bool bHaveTemp = pSensorTemp->GetValue(V_TEMP, Temp); bool bHaveHumidity = pSensorHum->GetValue(V_HUM, Humidity); if (bHaveTemp && bHaveHumidity) { cNode = (pSensorTemp->nodeID << 8) | pSensorTemp->childID; //We are using the TempHumBaro Float type now, convert the forecast int nforecast = wsbaroforcast_some_clouds; if (Baro <= 980) nforecast = wsbaroforcast_heavy_rain; else if (Baro <= 995) { if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } else if (Baro >= 1029) nforecast = wsbaroforcast_sunny; switch (forecast) { case bmpbaroforecast_sunny: nforecast = wsbaroforcast_sunny; break; case bmpbaroforecast_cloudy: nforecast = wsbaroforcast_cloudy; break; case bmpbaroforecast_thunderstorm: nforecast = wsbaroforcast_heavy_rain; break; case bmpbaroforecast_rain: if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } SendTempHumBaroSensorFloat(cNode, pSensorTemp->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro"); } } else SendBaroSensor(pChild->nodeID, pChild->childID, pChild->batValue, Baro, forecast); } break; case V_TRIPPED: // Tripped status of a security sensor. 1 = Tripped, 0 = Untripped if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, "Security Sensor"); break; case V_ARMED: //Armed status of a security sensor. 1 = Armed, 0 = Bypassed if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, "Security Sensor"); break; case V_LOCK_STATUS: //Lock status. 1 = Locked, 0 = Unlocked if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, "Lock Sensor"); break; case V_STATUS: // Light status. 0 = off 1 = on if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue != 0), 100, "Light"); break; case V_SCENE_ON: if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID + intValue, true, 100, "Scene"); break; case V_SCENE_OFF: if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID + intValue, false, 100, "Scene"); break; case V_PERCENTAGE: // Dimmer value. 0 - 100 % if (pChild->GetValue(vType, intValue)) { int level = intValue; UpdateSwitch(pChild->nodeID, pChild->childID, (level != 0), level, "Light"); } break; case V_RGB: //RRGGBB if (pChild->GetValue(vType, intValue)) SendRGBWSwitch(pChild->nodeID, pChild->childID, pChild->batValue, intValue, false, (!pChild->childName.empty()) ? pChild->childName : "RGB Light"); break; case V_RGBW: //RRGGBBWW if (pChild->GetValue(vType, intValue)) SendRGBWSwitch(pChild->nodeID, pChild->childID, pChild->batValue, intValue, true, (!pChild->childName.empty()) ? pChild->childName : "RGBW Light"); break; case V_UP: case V_DOWN: case V_STOP: if (pChild->GetValue(vType, intValue)) SendBlindSensor(pChild->nodeID, pChild->childID, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Blinds/Window"); break; case V_LIGHT_LEVEL: if (pChild->GetValue(vType, floatValue)) { _tLightMeter lmeter; lmeter.id1 = 0; lmeter.id2 = 0; lmeter.id3 = 0; lmeter.id4 = pChild->nodeID; lmeter.dunit = pChild->childID; lmeter.fLux = floatValue; lmeter.battery_level = pChild->batValue; if (pChild->hasBattery) lmeter.battery_level = pChild->batValue; sDecodeRXMessage(this, (const unsigned char *)&lmeter); } break; case V_LEVEL: if ((pChild->presType == S_DUST)|| (pChild->presType == S_AIR_QUALITY)) { if (pChild->GetValue(vType, intValue)) { _tAirQualityMeter meter; meter.len = sizeof(_tAirQualityMeter) - 1; meter.type = pTypeAirQuality; meter.subtype = sTypeVoltcraft; meter.airquality = intValue; meter.id1 = pChild->nodeID; meter.id2 = pChild->childID; sDecodeRXMessage(this, (const unsigned char *)&meter); } } else if (pChild->presType == S_LIGHT_LEVEL) { if (pChild->GetValue(vType, intValue)) { _tLightMeter lmeter; lmeter.id1 = 0; lmeter.id2 = 0; lmeter.id3 = 0; lmeter.id4 = pChild->nodeID; lmeter.dunit = pChild->childID; lmeter.fLux = (float)intValue; lmeter.battery_level = pChild->batValue; if (pChild->hasBattery) lmeter.battery_level = pChild->batValue; sDecodeRXMessage(this, (const unsigned char *)&lmeter); } } else if (pChild->presType == S_SOUND) { if (pChild->GetValue(vType, intValue)) SendSoundSensor(cNode, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Sound Level"); } else if (pChild->presType == S_MOISTURE) { if (pChild->GetValue(vType, intValue)) { _tGeneralDevice gdevice; gdevice.subtype = sTypeSoilMoisture; gdevice.intval1 = intValue; gdevice.id = pChild->nodeID; sDecodeRXMessage(this, (const unsigned char *)&gdevice); } } break; case V_RAIN: if (pChild->GetValue(vType, floatValue)) SendRainSensor(cNode, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Rain"); break; case V_WATT: { if (pChild->GetValue(vType, floatValue)) { _tMySensorChild *pSensorKwh = pNode->FindChildWithValueType(pChild->childID, V_KWH);// FindChildWithValueType(pChild->nodeID, V_KWH); if (pSensorKwh) { float Kwh; if (pSensorKwh->GetValue(V_KWH, Kwh)) SendKwhMeter(pSensorKwh->nodeID, pSensorKwh->childID, pSensorKwh->batValue, floatValue / 1000.0f, Kwh, (!pChild->childName.empty()) ? pChild->childName : "Meter"); } else { SendWattMeter(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Usage"); } } } break; case V_KWH: if (pChild->GetValue(vType, floatValue)) { _tMySensorChild *pSensorWatt = pNode->FindChildWithValueType(pChild->childID, V_WATT);// FindChildWithValueType(pChild->nodeID, V_WATT); if (pSensorWatt) { float Watt; if (pSensorWatt->GetValue(V_WATT, Watt)) SendKwhMeter(pChild->nodeID, pChild->childID, pChild->batValue, Watt / 1000.0f, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Meter"); } else { SendKwhMeter(pChild->nodeID, pChild->childID, pChild->batValue, 0, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Meter"); } } break; case V_DISTANCE: if (pChild->GetValue(vType, floatValue)) SendDistanceSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue); break; case V_FLOW: //Flow of water in meter (for now send as a percentage sensor) if (pChild->GetValue(vType, floatValue)) SendPercentageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Water Flow"); break; case V_VOLUME: //Water Volume if (pChild->GetValue(vType, floatValue)) SendMeterSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Water"); break; case V_VOLTAGE: if (pChild->GetValue(vType, floatValue)) SendVoltageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Voltage"); break; case V_UV: if (pChild->GetValue(vType, floatValue)) SendUVSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue); break; case V_IMPEDANCE: if (pChild->GetValue(vType, floatValue)) SendPercentageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Impedance"); break; case V_WEIGHT: if (pChild->GetValue(vType, floatValue)) { while (1 == 0); } break; case V_CURRENT: if (pChild->GetValue(vType, floatValue)) SendCurrentSensor(cNode, pChild->batValue, floatValue, 0, 0, (!pChild->childName.empty()) ? pChild->childName : "Current"); break; case V_FORECAST: if (pChild->GetValue(vType, intValue)) { _tMySensorChild *pSensorBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE); if (pSensorBaro) { float Baro; if (pSensorBaro->GetValue(V_PRESSURE, Baro)) { int forecast = intValue; if (forecast == bmpbaroforecast_cloudy) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } SendBaroSensor(pSensorBaro->nodeID, pSensorBaro->childID, pSensorBaro->batValue, Baro, forecast); } } else { if (pChild->GetValue(V_FORECAST, stringValue)) { std::stringstream sstr; sstr << pChild->nodeID; std::string devname = (!pChild->childName.empty()) ? pChild->childName : "Forecast"; m_sql.UpdateValue(m_HwdID, sstr.str().c_str(), pChild->childID, pTypeGeneral, sTypeTextStatus, 12, pChild->batValue, 0, stringValue.c_str(), devname); } } } break; case V_WIND: case V_GUST: case V_DIRECTION: MakeAndSendWindSensor(pChild->nodeID, (!pChild->childName.empty()) ? pChild->childName : "Wind"); break; case V_HVAC_SETPOINT_HEAT: if (pChild->GetValue(vType, floatValue)) { SendSetPointSensor(pNode->nodeID, pChild->childID, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Heater Setpoint"); } break; } }
void SolarMaxTCP::ParseLine() { std::string InputStr = std::string((const char*)&m_buffer); size_t npos = InputStr.find("|"); if (npos == std::string::npos) { _log.Log(LOG_ERROR, "SolarMax: Invalid data received!"); return; } InputStr = InputStr.substr(npos + 4); npos = InputStr.find("|"); if (npos == std::string::npos) { _log.Log(LOG_ERROR, "SolarMax: Invalid data received!"); return; } InputStr = InputStr.substr(0,npos); std::vector<std::string> results; StringSplit(InputStr, ";", results); if (results.size() < 2) return; //invalid data std::vector<std::string>::const_iterator itt; double kwhCounter = 0; double ActUsage = 0; for (itt = results.begin(); itt != results.end(); ++itt) { std::vector<std::string> varresults; StringSplit(*itt, "=", varresults); if (varresults.size() !=2) continue; std::string sLabel = varresults[0]; std::string sVal = varresults[1]; if (sLabel == "KT0") { //Energy total kwhCounter = SolarMaxGetHexStringValue(sVal);// / 10.0f; } else if (sLabel == "KDY") { //Energy Today } else if (sLabel == "PAC") { //AC power ActUsage = SolarMaxGetHexStringValue(sVal)/2.0f; } else if (sLabel == "UDC") { //DC voltage [mV] float voltage = float(SolarMaxGetHexStringValue(sVal)) / 10.0f; SendVoltageSensor(1, 2, 255, voltage, "DC voltage"); } else if (sLabel == "UL1") { //AC voltage [mV] float voltage = float(SolarMaxGetHexStringValue(sVal)) / 10.0f; SendVoltageSensor(1, 3, 255, voltage, "AC voltage"); } else if (sLabel == "IDC") { //DC current [mA] float amps = float(SolarMaxGetHexStringValue(sVal)) / 100.0f; SendCurrentSensor(4, 255, amps, 0, 0, "DC current"); } else if (sLabel == "IL1") { //AC current [mA] float amps = float(SolarMaxGetHexStringValue(sVal)) / 100.0f; SendCurrentSensor(5, 255, amps, 0, 0, "AC current"); } else if (sLabel == "PIN") { //Power installed [mW] (PIN) //float power_installed = (float)SolarMaxGetHexStringValue(sVal); } else if (sLabel == "PRL") { //AC power [%] float percentage = (float)SolarMaxGetHexStringValue(sVal); SendPercentageSensor(6, 6, 255, percentage, "AC power Percentage"); } else if (sLabel == "TNF") { //AC Frequency (Hz) float freq = (float)SolarMaxGetHexStringValue(sVal)/100; SendPercentageSensor(7, 7, 255, freq, "Hz"); } else if (sLabel == "TKK") { //Temperature Heat Sink float temp = (float)SolarMaxGetHexStringValue(sVal);// / 10.0f; SendTempSensor(8, 255, temp,"Temperature Heat Sink"); } } if (kwhCounter != 0) { SendKwhMeterOldWay(1, 1, 255, ActUsage/1000.0f, kwhCounter, "kWh Meter"); } }
int SolarEdgeBase::ParsePacket0x0500(const unsigned char *pData, int dlen) { const unsigned char *b=pData; short *pShort; int orgdlen=dlen; //Meter and Panel report while (dlen>20) { bool bIsPanel=false; bool bIsMain=false; bool bIs0300=false; //0000 for Panel, 0010 for Main? pShort=(short*)b; int ReportType=*pShort; b+=2; dlen-=2; if (ReportType==0x000) { bIsPanel=true; bIsMain=false; bIs0300=false; } else if (ReportType==0x0010) { bIsPanel=false; bIsMain=true; bIs0300=false; } else if (ReportType==0x0300) { bIsPanel=false; bIsMain=false; bIs0300=true; } else { //don't know you! return orgdlen-2; } //PanelID/Main unsigned long ID2=*(unsigned long*)b; //sprintf_s(szTmp,"\"%08X\"",ID2); b+=4; dlen-=4; //rest bytes pShort=(short*)b; int restbytes=*pShort; //sprintf_s(szTmp,"\"%04d\"",restbytes); b+=2; dlen-=2; const unsigned char *b2=(const BYTE*)b; int len2=restbytes; //Something //sprintf_s(szTmp,"\"%02X%02X\"",b2[0],b2[1]); b2+=2; len2-=2; //F052 (F352 for 0300) b2+=2; len2-=2; //2 times ID b2+=4; len2-=4; //uL=*(unsigned long*)b2; b2+=4; len2-=4; if (bIsMain) { //Temp float temp=GetFloat(b2); b2+=4; //Watt P-Out float Watt=GetFloat(b2); b2+=4; float Pac=GetFloat(b2); b2+=4; //AC Voltage float voltageAC=GetFloat(b2); b2+=4; //Iets2 float Iets2=GetFloat(b2); b2+=4; //Frequency float freq=GetFloat(b2); b2+=4; //Iets3 float Iets3=GetFloat(b2); b2+=4; //Iets4 float Iets4=GetFloat(b2); b2+=4; //DC Voltage float voltageDC=GetFloat(b2); b2+=4; //Iets5 float Iets5=GetFloat(b2); b2+=4; //Counter float counter=GetFloat(b2); b2+=4; SendMeter(0,1, Pac/100.0f, counter/1000.0f, "SolarMain"); SendTempSensor(1, 255, temp, "SolarMain"); SendPercentageSensor(SE_FREQ, 0, 255, freq, "Hz"); SendVoltageSensor(0, SE_VOLT_AC, 255, voltageAC, "AC"); SendVoltageSensor(0, SE_VOLT_DC, 255, voltageDC, "DC"); } b+=restbytes; dlen-=restbytes; continue; } return (b-pData); }
void OTGWBase::ParseLine() { if (m_bufferpos<2) return; std::string sLine((char*)&m_buffer); std::vector<std::string> results; StringSplit(sLine,",",results); if (results.size()==25) { //status report //0 Status (MsgID=0) - Printed as two 8-bit bitfields //1 Control setpoint (MsgID=1) - Printed as a floating point value //2 Remote parameter flags (MsgID= 6) - Printed as two 8-bit bitfields //3 Maximum relative modulation level (MsgID=14) - Printed as a floating point value //4 Boiler capacity and modulation limits (MsgID=15) - Printed as two bytes //5 Room Setpoint (MsgID=16) - Printed as a floating point value //6 Relative modulation level (MsgID=17) - Printed as a floating point value //7 CH water pressure (MsgID=18) - Printed as a floating point value //8 Room temperature (MsgID=24) - Printed as a floating point value //9 Boiler water temperature (MsgID=25) - Printed as a floating point value //10 DHW temperature (MsgID=26) - Printed as a floating point value //11 Outside temperature (MsgID=27) - Printed as a floating point value //12 Return water temperature (MsgID=28) - Printed as a floating point value //13 DHW setpoint boundaries (MsgID=48) - Printed as two bytes //14 Max CH setpoint boundaries (MsgID=49) - Printed as two bytes //15 DHW setpoint (MsgID=56) - Printed as a floating point value //16 Max CH water setpoint (MsgID=57) - Printed as a floating point value //17 Burner starts (MsgID=116) - Printed as a decimal value //18 CH pump starts (MsgID=117) - Printed as a decimal value //19 DHW pump/valve starts (MsgID=118) - Printed as a decimal value //20 DHW burner starts (MsgID=119) - Printed as a decimal value //21 Burner operation hours (MsgID=120) - Printed as a decimal value //22 CH pump operation hours (MsgID=121) - Printed as a decimal value //23 DHW pump/valve operation hours (MsgID=122) - Printed as a decimal value //24 DHW burner operation hours (MsgID=123) - Printed as a decimal value _tOTGWStatus _status; int idx=0; _status.MsgID=results[idx++]; if (_status.MsgID.size()==17) { bool bCH_enabled=(_status.MsgID[7]=='1'); UpdateSwitch(101,bCH_enabled,"CH_enabled"); bool bDHW_enabled=(_status.MsgID[6]=='1'); UpdateSwitch(102,bDHW_enabled,"DHW_enabled"); bool bCooling_enable=(_status.MsgID[5]=='1'); UpdateSwitch(103,bCooling_enable,"Cooling_enable"); bool bOTC_active=(_status.MsgID[4]=='1'); UpdateSwitch(104,bOTC_active,"OTC_active"); bool bCH2_enabled=(_status.MsgID[3]=='1'); UpdateSwitch(105,bCH2_enabled,"CH2_enabled"); bool bFault_indication=(_status.MsgID[9+7]=='1'); UpdateSwitch(110,bFault_indication,"Fault_indication"); bool bCH_active=(_status.MsgID[9+6]=='1'); UpdateSwitch(111,bCH_active,"CH_active"); bool bDHW_active=(_status.MsgID[9+5]=='1'); UpdateSwitch(112,bDHW_active,"DHW_active"); bool bFlameOn=(_status.MsgID[9+4]=='1'); UpdateSwitch(113,bFlameOn,"FlameOn"); bool bCooling_Mode_Active=(_status.MsgID[9+3]=='1'); UpdateSwitch(114,bCooling_Mode_Active,"Cooling_Mode_Active"); bool bCH2_Active=(_status.MsgID[9+2]=='1'); UpdateSwitch(115,bCH2_Active,"CH2_Active"); bool bDiagnosticEvent=(_status.MsgID[9+1]=='1'); UpdateSwitch(116,bDiagnosticEvent,"DiagnosticEvent"); } _status.Control_setpoint=static_cast<float>(atof(results[idx++].c_str())); UpdateTempSensor(idx-1,_status.Control_setpoint,"Control Setpoint"); _status.Remote_parameter_flags=results[idx++]; _status.Maximum_relative_modulation_level = static_cast<float>(atof(results[idx++].c_str())); bool bExists = CheckPercentageSensorExists(idx - 1, 1); if ((_status.Maximum_relative_modulation_level != 0) || (bExists)) { SendPercentageSensor(idx - 1, 1, 255, _status.Maximum_relative_modulation_level, "Maximum Relative Modulation Level"); } _status.Boiler_capacity_and_modulation_limits=results[idx++]; _status.Room_Setpoint = static_cast<float>(atof(results[idx++].c_str())); UpdateSetPointSensor(idx - 1, _status.Room_Setpoint, "Room Setpoint"); _status.Relative_modulation_level = static_cast<float>(atof(results[idx++].c_str())); bExists = CheckPercentageSensorExists(idx - 1, 1); if ((_status.Relative_modulation_level != 0) || (bExists)) { SendPercentageSensor(idx - 1, 1, 255, _status.Relative_modulation_level, "Relative modulation level"); } _status.CH_water_pressure = static_cast<float>(atof(results[idx++].c_str())); bExists = CheckPercentageSensorExists(idx - 1, 1); if (_status.CH_water_pressure != 0) { UpdatePressureSensor(idx-1,_status.CH_water_pressure,"CH Water Pressure"); } _status.Room_temperature = static_cast<float>(atof(results[idx++].c_str())); UpdateTempSensor(idx - 1, _status.Room_temperature, "Room Temperature"); _status.Boiler_water_temperature = static_cast<float>(atof(results[idx++].c_str())); UpdateTempSensor(idx - 1, _status.Boiler_water_temperature, "Boiler Water Temperature"); _status.DHW_temperature = static_cast<float>(atof(results[idx++].c_str())); UpdateTempSensor(idx - 1, _status.DHW_temperature, "DHW Temperature"); _status.Outside_temperature = static_cast<float>(atof(results[idx++].c_str())); UpdateTempSensor(idx - 1, _status.Outside_temperature, "Outside Temperature"); _status.Return_water_temperature = static_cast<float>(atof(results[idx++].c_str())); UpdateTempSensor(idx - 1, _status.Return_water_temperature, "Return Water Temperature"); _status.DHW_setpoint_boundaries=results[idx++]; _status.Max_CH_setpoint_boundaries=results[idx++]; _status.DHW_setpoint = static_cast<float>(atof(results[idx++].c_str())); UpdateSetPointSensor(idx - 1, _status.DHW_setpoint, "DHW Setpoint"); _status.Max_CH_water_setpoint = static_cast<float>(atof(results[idx++].c_str())); UpdateSetPointSensor(idx - 1, _status.Max_CH_water_setpoint, "Max_CH Water Setpoint"); _status.Burner_starts=atol(results[idx++].c_str()); _status.CH_pump_starts=atol(results[idx++].c_str()); _status.DHW_pump_valve_starts=atol(results[idx++].c_str()); _status.DHW_burner_starts=atol(results[idx++].c_str()); _status.Burner_operation_hours=atol(results[idx++].c_str()); _status.CH_pump_operation_hours=atol(results[idx++].c_str()); _status.DHW_pump_valve_operation_hours=atol(results[idx++].c_str()); _status.DHW_burner_operation_hours=atol(results[idx++].c_str()); return; } else { if (sLine=="SE") { _log.Log(LOG_ERROR,"OTGW: Error received!"); } else if (sLine.find("PR: G")!=std::string::npos) { _tOTGWGPIO _GPIO; _GPIO.A=static_cast<int>(sLine[6]- '0'); if (_GPIO.A==0 || _GPIO.A==1) { UpdateSwitch(96,(_GPIO.A==1),"GPIOAPulledToGround"); } else { // Remove device (how?) } _GPIO.B=static_cast<int>(sLine[7]- '0'); if (_GPIO.B==0 || _GPIO.B==1) { UpdateSwitch(97,(_GPIO.B==1),"GPIOBPulledToGround"); } else { // Remove device (how?) } } else { if ( (sLine.find("OT")==std::string::npos)&& (sLine.find("PS") == std::string::npos)&& (sLine.find("SC") == std::string::npos) ) { //Dont report OT/PS/SC feedback _log.Log(LOG_STATUS,"OTGW: %s",sLine.c_str()); } } } }