bool CToonThermostat::ParseThermostatData(const Json::Value &root) { //thermostatInfo if (root["thermostatInfo"].empty()) return false; float currentTemp = root["thermostatInfo"]["currentTemp"].asFloat() / 100.0f; float currentSetpoint = root["thermostatInfo"]["currentSetpoint"].asFloat() / 100.0f; SendSetPointSensor(1, currentSetpoint, "Room Setpoint"); SendTempSensor(1, 255, currentTemp, "Room Temperature"); //int programState = root["thermostatInfo"]["programState"].asInt(); //int activeState = root["thermostatInfo"]["activeState"].asInt(); if (root["thermostatInfo"]["burnerInfo"].empty() == false) { //burnerinfo //0=off //1=heating //2=hot water //3=pre-heating int burnerInfo = 0; if (root["thermostatInfo"]["burnerInfo"].isString()) { burnerInfo = atoi(root["thermostatInfo"]["burnerInfo"].asString().c_str()); } else if (root["thermostatInfo"]["burnerInfo"].isInt()) { burnerInfo = root["thermostatInfo"]["burnerInfo"].asInt(); } if (burnerInfo == 1) { UpdateSwitch(113, true, "HeatingOn"); UpdateSwitch(114, false, "TapwaterOn"); UpdateSwitch(115, false, "PreheatOn"); } else if (burnerInfo == 2) { UpdateSwitch(113, false, "HeatingOn"); UpdateSwitch(114, true, "TapwaterOn"); UpdateSwitch(115, false, "PreheatOn"); } else if (burnerInfo == 3) { UpdateSwitch(113, false, "HeatingOn"); UpdateSwitch(114, false, "TapwaterOn"); UpdateSwitch(115, true, "PreheatOn"); } else { UpdateSwitch(113, false, "HeatingOn"); UpdateSwitch(114, false, "TapwaterOn"); UpdateSwitch(115, false, "PreheatOn"); } } return true; }
void CICYThermostat::GetMeterDetails() { if (m_UserName.size()==0) return; if (m_Password.size()==0) return; if (!GetSerialAndToken()) return; std::string sResult; //Get Data std::vector<std::string> ExtraHeaders; ExtraHeaders.push_back("Session-token:"+m_Token); std::string sURL = ""; if (m_companymode == CMODE_PORTAL) sURL = ICY_DATA_URL; else if (m_companymode == CMODE_ENI) sURL = ENI_DATA_URL; else sURL = SEC_DATA_URL; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR,"ICYThermostat: Error getting data!"); return; } Json::Value root; Json::Reader jReader; bool ret = jReader.parse(sResult, root); if (!ret) { _log.Log(LOG_ERROR, "ICYThermostat: Invalid data received!"); return; } if (root["temperature1"].empty() == true) { _log.Log(LOG_ERROR, "ICYThermostat: Invalid data received!"); return; } SendSetPointSensor(1, root["temperature1"].asFloat(), "Room Setpoint"); if (root["temperature2"].empty() == true) { _log.Log(LOG_ERROR, "ICYThermostat: Invalid data received!"); return; } SendTempSensor(1, 255, root["temperature2"].asFloat(), "Room Temperature"); }
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, temp, devName); } else if (qType == "Load") { doffset = 1100; float perc = static_cast<float>(atof(devValue.c_str())); SendPercentage(doffset + dindex, 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())); SendVoltage(doffset + dindex, volt, devName); } else if (qType == "Current") { doffset = 1400; float curr = static_cast<float>(atof(devValue.c_str())); SendCurrent(doffset + dindex, curr, devName); } return; }
void CHardwareMonitor::GetInternalTemperature() { std::vector<std::string> ret = ExecuteCommandAndReturn(szInternalTemperatureCommand); if (ret.empty()) return; std::string tmpline = ret[0]; if (tmpline.find("temp=") == std::string::npos) return; tmpline = tmpline.substr(5); size_t pos = tmpline.find("'"); if (pos != std::string::npos) { tmpline = tmpline.substr(0, pos); } float temperature = static_cast<float>(atof(tmpline.c_str())); if (temperature == 0) return; //hardly possible for a on board temp sensor, if it is, it is probably not working if ((temperature != 85) && (temperature > -273)) { SendTempSensor(1, temperature, "Internal Temperature"); } }
void CAccuWeather::GetMeterDetails() { std::string sResult; #ifdef DEBUG_AccuWeatherR sResult=ReadFile("E:\\AccuWeather.json"); #else std::stringstream sURL; std::string szLoc = CURLEncode::URLEncode(m_LocationKey); sURL << "https://dataservice.accuweather.com/currentconditions/v1/" << szLoc << "?apikey=" << m_APIKey << "&details=true"; try { bool bret; std::string szURL = sURL.str(); bret = HTTPClient::GET(szURL, sResult); if (!bret) { _log.Log(LOG_ERROR, "AccuWeather: Error getting http data!"); return; } } catch (...) { _log.Log(LOG_ERROR, "AccuWeather: Error getting http data!"); return; } #endif #ifdef DEBUG_AccuWeatherW SaveString2Disk(sResult, "E:\\AccuWeather.json"); #endif try { Json::Value root; Json::Reader jReader; bool ret = jReader.parse(sResult, root); if (!ret) { _log.Log(LOG_ERROR, "AccuWeather: Invalid data received!"); return; } if (root.size() < 1) { _log.Log(LOG_ERROR, "AccuWeather: Invalid data received!"); return; } root = root[0]; if (root["LocalObservationDateTime"].empty()) { _log.Log(LOG_ERROR, "AccuWeather: Invalid data received, or unknown location!"); return; } float temp = 0; int humidity = 0; int barometric = 0; int barometric_forcast = baroForecastNoInfo; if (!root["Temperature"].empty()) { temp = root["Temperature"]["Metric"]["Value"].asFloat(); } if (!root["RelativeHumidity"].empty()) { humidity = root["RelativeHumidity"].asInt(); } if (!root["Pressure"].empty()) { barometric = atoi(root["Pressure"]["Metric"]["Value"].asString().c_str()); if (barometric < 1000) barometric_forcast = baroForecastRain; else if (barometric < 1020) barometric_forcast = baroForecastCloudy; else if (barometric < 1030) barometric_forcast = baroForecastPartlyCloudy; else barometric_forcast = baroForecastSunny; if (!root["WeatherIcon"].empty()) { int forcasticon = atoi(root["WeatherIcon"].asString().c_str()); switch (forcasticon) { case 1: case 2: case 3: barometric_forcast = baroForecastSunny; break; case 4: case 5: case 6: barometric_forcast = baroForecastCloudy; break; case 7: case 8: case 9: case 10: case 11: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 39: case 40: case 41: case 42: case 43: case 44: barometric_forcast = baroForecastRain; break; case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: barometric_forcast = baroForecastCloudy; break; } } } if (barometric != 0) { //Add temp+hum+baro device SendTempHumBaroSensor(1, 255, temp, humidity, static_cast<float>(barometric), barometric_forcast, "THB"); } else if (humidity != 0) { //add temp+hum device SendTempHumSensor(1, 255, temp, humidity, "TempHum"); } else { //add temp device SendTempSensor(1, 255, temp, "Temperature"); } //Wind if (!root["Wind"].empty()) { int wind_degrees = -1; float windspeed_ms = 0; float windgust_ms = 0; float wind_temp = temp; float wind_chill = temp; if (!root["Wind"]["Direction"].empty()) { wind_degrees = root["Wind"]["Direction"]["Degrees"].asInt(); } if (!root["Wind"]["Speed"].empty()) { windspeed_ms = root["Wind"]["Speed"]["Metric"]["Value"].asFloat() / 3.6f; //km/h to m/s } if (!root["WindGust"].empty()) { if (!root["WindGust"]["Speed"].empty()) { windgust_ms = root["WindGust"]["Speed"]["Metric"]["Value"].asFloat() / 3.6f; //km/h to m/s } } if (!root["RealFeelTemperature"].empty()) { wind_chill = root["RealFeelTemperature"]["Metric"]["Value"].asFloat(); } if (wind_degrees != -1) { SendWind(1, 255, wind_degrees, windspeed_ms, windgust_ms, temp, wind_chill, true, "Wind"); } } //UV if (!root["UVIndex"].empty()) { float UV = static_cast<float>(atof(root["UVIndex"].asString().c_str())); if ((UV < 16) && (UV >= 0)) { SendUVSensor(0, 1, 255, UV, "UV"); } } //Rain if (!root["PrecipitationSummary"].empty()) { if (!root["PrecipitationSummary"]["Precipitation"].empty()) { float RainCount = static_cast<float>(atof(root["PrecipitationSummary"]["Precipitation"]["Metric"]["Value"].asString().c_str())); if ((RainCount != -9999.00f) && (RainCount >= 0.00f)) { RBUF tsen; memset(&tsen, 0, sizeof(RBUF)); tsen.RAIN.packetlength = sizeof(tsen.RAIN) - 1; tsen.RAIN.packettype = pTypeRAIN; tsen.RAIN.subtype = sTypeRAINWU; tsen.RAIN.battery_level = 9; tsen.RAIN.rssi = 12; tsen.RAIN.id1 = 0; tsen.RAIN.id2 = 1; tsen.RAIN.rainrateh = 0; tsen.RAIN.rainratel = 0; if (!root["PrecipitationSummary"]["PastHour"].empty()) { float rainrateph = static_cast<float>(atof(root["PrecipitationSummary"]["PastHour"]["Metric"]["Value"].asString().c_str())); if (rainrateph != -9999.00f) { int at10 = round(std::abs(rainrateph*10.0f)); tsen.RAIN.rainrateh = (BYTE)(at10 / 256); at10 -= (tsen.RAIN.rainrateh * 256); tsen.RAIN.rainratel = (BYTE)(at10); } } int tr10 = int((float(RainCount)*10.0f)); tsen.RAIN.raintotal1 = 0; tsen.RAIN.raintotal2 = (BYTE)(tr10 / 256); tr10 -= (tsen.RAIN.raintotal2 * 256); tsen.RAIN.raintotal3 = (BYTE)(tr10); sDecodeRXMessage(this, (const unsigned char *)&tsen.RAIN, NULL, 255); } } } //Visibility if (!root["Visibility"].empty()) { if (!root["Visibility"]["Metric"].empty()) { float visibility = root["Visibility"]["Metric"]["Value"].asFloat(); if (visibility >= 0) { _tGeneralDevice gdevice; gdevice.subtype = sTypeVisibility; gdevice.floatval1 = visibility; sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } } } //Forecast URL if (!root["Link"].empty()) { m_ForecastURL = root["Link"].asString(); } } catch (...) { _log.Log(LOG_ERROR, "AccuWeather: Error parsing JSon data!"); } }
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, 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 float rcounter=GetRainSensorCounter(ID); m_ActRainCounter[ID%MAX_IDS] = rcounter; } m_ActRainCounter[ID%MAX_IDS] += Rainmm; SendRainSensor(ID, 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, 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())); SendPercentage(ID, Percentage, "power of solar panel"); } break; default: _log.Log(LOG_STATUS, "Unknown Type: %c", rCode); break; } }
void CToonThermostat::GetMeterDetails() { if (m_UserName.size()==0) return; if (m_Password.size()==0) return; std::string sResult; if (m_bDoLogin) { if (!Login()) return; } std::vector<std::string> ExtraHeaders; std::stringstream sstr2; sstr2 << "?clientId=" << m_ClientID << "&clientIdChecksum=" << m_ClientIDChecksum << "&random=" << GetRandom(); std::string szPostdata = sstr2.str(); //Get Data std::string sURL = TOON_HOST + TOON_UPDATE_PATH + szPostdata; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "ToonThermostat: Error getting current state!"); m_bDoLogin = true; return; } time_t atime = mytime(NULL); #ifdef DEBUG_ToonThermostat char szFileName[MAX_PATH]; static int sNum = 1; sprintf_s(szFileName, "E:\\toonresult_%03d.txt", sNum++); SaveString2Disk(sResult, szFileName); #endif Json::Value root; Json::Reader jReader; if (!jReader.parse(sResult, root)) { _log.Log(LOG_ERROR, "ToonThermostat: Invalid data received!"); m_bDoLogin = true; return; } if (root["success"].empty() == true) { _log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!"); m_bDoLogin = true; return; } if (root["success"] == false) { _log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!"); m_bDoLogin = true; return; } //ZWave Devices if (root["deviceStatusInfo"].empty() == false) { if (root["deviceStatusInfo"]["device"].empty() == false) { int totDevices = root["deviceStatusInfo"]["device"].size(); for (int ii = 0; ii < totDevices; ii++) { std::string deviceName = root["deviceStatusInfo"]["device"][ii]["name"].asString(); std::string uuid = root["deviceStatusInfo"]["device"][ii]["devUUID"].asString(); int state = root["deviceStatusInfo"]["device"][ii]["currentState"].asInt(); int Idx; if (!GetUUIDIdx(uuid, Idx)) { if (!AddUUID(uuid, Idx)) { _log.Log(LOG_ERROR, "ToonThermostat: Error adding UUID to database?! Uuid=%s", uuid.c_str()); return; } } UpdateSwitch(Idx, state != 0, deviceName); } } } //thermostatInfo if (root["thermostatInfo"].empty() == false) { float currentTemp = root["thermostatInfo"]["currentTemp"].asFloat() / 100.0f; float currentSetpoint = root["thermostatInfo"]["currentSetpoint"].asFloat() / 100.0f; SendSetPointSensor(1, currentSetpoint, "Room Setpoint"); SendTempSensor(1, currentTemp, "Room Temperature"); //int programState = root["thermostatInfo"]["programState"].asInt(); //int activeState = root["thermostatInfo"]["activeState"].asInt(); if (root["thermostatInfo"]["burnerInfo"].empty() == false) { //burnerinfo //0=off //1=heating //2=hot water //3=pre-heating int burnerInfo = 0; if (root["thermostatInfo"]["burnerInfo"].isString()) { burnerInfo = atoi(root["thermostatInfo"]["burnerInfo"].asString().c_str()); } else if (root["thermostatInfo"]["burnerInfo"].isInt()) { burnerInfo = root["thermostatInfo"]["burnerInfo"].asInt(); } if (burnerInfo == 1) { UpdateSwitch(113, true, "HeatingOn"); UpdateSwitch(114, false, "TapwaterOn"); UpdateSwitch(115, false, "PreheatOn"); } else if (burnerInfo == 2) { UpdateSwitch(113, false, "HeatingOn"); UpdateSwitch(114, true, "TapwaterOn"); UpdateSwitch(115, false, "PreheatOn"); } else if (burnerInfo == 3) { UpdateSwitch(113, false, "HeatingOn"); UpdateSwitch(114, false, "TapwaterOn"); UpdateSwitch(115, true, "PreheatOn"); } else { UpdateSwitch(113, false, "HeatingOn"); UpdateSwitch(114, false, "TapwaterOn"); UpdateSwitch(115, false, "PreheatOn"); } } } if (root["gasUsage"].empty() == false) { m_p1gas.gasusage = (unsigned long)(root["gasUsage"]["meterReading"].asFloat()); } if (root["powerUsage"].empty() == false) { m_p1power.powerusage1 = (unsigned long)(root["powerUsage"]["meterReadingLow"].asFloat()); m_p1power.powerusage2 = (unsigned long)(root["powerUsage"]["meterReading"].asFloat()); if (root["powerUsage"]["meterReadingProdu"].empty() == false) { m_p1power.powerdeliv1 = (unsigned long)(root["powerUsage"]["meterReadingLowProdu"].asFloat()); m_p1power.powerdeliv2 = (unsigned long)(root["powerUsage"]["meterReadingProdu"].asFloat()); } m_p1power.usagecurrent = (unsigned long)(root["powerUsage"]["value"].asFloat()); //Watt } //Send Electra if value changed, or at least every 5 minutes if ( (m_p1power.usagecurrent != m_lastelectrausage) || (atime - m_lastSharedSendElectra >= 300) ) { if ((m_p1power.powerusage1 != 0) || (m_p1power.powerusage2 != 0) || (m_p1power.powerdeliv1 != 0) || (m_p1power.powerdeliv2 != 0)) { m_lastSharedSendElectra = atime; m_lastelectrausage = m_p1power.usagecurrent; sDecodeRXMessage(this, (const unsigned char *)&m_p1power); } } //Send GAS if the value changed, or at least every 5 minutes if ( (m_p1gas.gasusage != m_lastgasusage) || (atime - m_lastSharedSendGas >= 300) ) { if (m_p1gas.gasusage != 0) { m_lastSharedSendGas = atime; m_lastgasusage = m_p1gas.gasusage; sDecodeRXMessage(this, (const unsigned char *)&m_p1gas); } } }
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,temp,"SolarMain"); SendPercentage(SE_FREQ,freq,"Hz"); SendVoltage(SE_VOLT_AC,voltageAC,"AC"); SendVoltage(SE_VOLT_DC,voltageDC,"DC"); } b+=restbytes; dlen-=restbytes; continue; } return (b-pData); }
void CThermosmart::GetMeterDetails() { if (m_UserName.empty() || m_Password.empty() ) return; std::string sResult; #ifdef DEBUG_ThermosmartThermostat_read sResult = ReadFile("E:\\thermosmart_getdata.txt"); #else if (m_bDoLogin) { if (!Login()) return; } std::string sURL = THERMOSMART_ACCESS_PATH; stdreplace(sURL, "[TID]", m_ThermostatID); stdreplace(sURL, "[access_token]", m_AccessToken); if (!HTTPClient::GET(sURL, sResult)) { _log.Log(LOG_ERROR, "Thermosmart: Error getting thermostat data!"); m_bDoLogin = true; return; } #ifdef DEBUG_ThermosmartThermostat SaveString2Disk(sResult, "E:\\thermosmart_getdata.txt"); #endif #endif Json::Value root; Json::Reader jReader; bool ret = jReader.parse(sResult, root); if (!ret) { _log.Log(LOG_ERROR, "Thermosmart: Invalid/no data received..."); m_bDoLogin = true; return; } if (root["target_temperature"].empty() || root["room_temperature"].empty()) { _log.Log(LOG_ERROR, "Thermosmart: Invalid/no data received..."); m_bDoLogin = true; return; } float temperature; temperature = (float)root["target_temperature"].asFloat(); SendSetPointSensor(1, temperature, "target temperature"); temperature = (float)root["room_temperature"].asFloat(); SendTempSensor(2, 255, temperature, "room temperature"); if (!root["outside_temperature"].empty()) { temperature = (float)root["outside_temperature"].asFloat(); SendTempSensor(3, 255, temperature, "outside temperature"); } if (!root["source"].empty()) { std::string actSource = root["source"].asString(); bool bPauzeOn = (actSource == "pause"); SendSwitch(1, 1, 255, bPauzeOn, 0, "Thermostat Pause"); } }
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"); } }
JaMessage CJabloDongle::ParseMessage(std::string msgstring) { JaMessage msg; std::stringstream msgstream(msgstring); std::string msgtok; int tokNum; bool singlePlaceTemp = false; if(msgstring == "\nOK\n") { msg.mtype = JMTYPE_OK; } else if(msgstring == "\nERROR\n") { msg.mtype = JMTYPE_ERR; } else if(!msgstring.compare(0, 16, "\nTURRIS DONGLE V") && (msgstring.length() > 17)) { msg.mtype = JMTYPE_VERSION; msg.version = std::string(msgstring.c_str() + 16); msg.version.erase(msg.version.size() - 1); } else if(!msgstring.compare(0, 6, "\nSLOT:")) { if(sscanf(msgstring.c_str(), "\nSLOT:%u [%u]\n", &msg.slot_num, &msg.slot_val) == 2) { msg.mtype = JMTYPE_SLOT; } else if(sscanf(msgstring.c_str(), "\nSLOT:%u [--------]\n", &msg.slot_num) == 1) { msg.mtype = JMTYPE_SLOT; msg.slot_val = 0; } } else { tokNum = 0; while(msgstream >> msgtok) { if(tokNum == 0) { if(sscanf(msgtok.c_str(), "[%u]", &msg.did) != 1) break; } #ifdef OLDFW else if(tokNum == 1) { if(sscanf(msgtok.c_str(), "ID:%u", &msg.mid) != 1) { msg.mid = -1; if(msgtok.compare("ID:---") != 0) break; } } #endif #ifdef OLDFW else if(tokNum == 2) { #else else if(tokNum == 1) { #endif msg.devmodel = msgtok; } #ifdef OLDFW else if(tokNum == 3) { #else else if(tokNum == 2) { #endif if(msgtok == "SENSOR") { msg.mtype = JMTYPE_SENSOR; } else if(msgtok == "TAMPER") { msg.mtype = JMTYPE_TAMPER; } else if(msgtok == "BEACON") { msg.mtype = JMTYPE_BEACON; } else if(msgtok == "BUTTON") { msg.mtype = JMTYPE_BUTTON; } else if(msgtok == "ARM:1") { msg.mtype = JMTYPE_ARM; } else if(msgtok == "ARM:0") { msg.mtype = JMTYPE_DISARM; } else if(sscanf(msgtok.c_str(), "SET:%f", &msg.temp) == 1) { msg.mtype = JMTYPE_SET; } else if(sscanf(msgtok.c_str(), "INT:%f", &msg.temp) == 1) { msg.mtype = JMTYPE_INT; } else if(msgtok == "SET:") { msg.mtype = JMTYPE_SET; singlePlaceTemp = true; } else if(msgtok == "INT:") { msg.mtype = JMTYPE_INT; singlePlaceTemp = true; } else { msg.mtype = JMTYPE_UNDEF; } } #ifdef OLDFW else if((tokNum == 4) && (singlePlaceTemp == true)) { #else else if((tokNum == 3) && (singlePlaceTemp == true)) { #endif if(sscanf(msgtok.c_str(), "%f", &msg.temp) != 1) { msg.temp = 0; msg.mtype = JMTYPE_UNDEF; } singlePlaceTemp = false; } else { if(sscanf(msgtok.c_str(), "LB:%d", &msg.lb) != 1) if(sscanf(msgtok.c_str(), "ACT:%d", &msg.act) != 1) sscanf(msgtok.c_str(), "BLACKOUT:%d", &msg.blackout); } tokNum++; } } return msg; } void CJabloDongle::ProcessMessage(JaMessage jmsg) { Ja_device *jdev; if((jmsg.mtype != JMTYPE_SLOT) && (jmsg.mtype != JMTYPE_VERSION) && (jmsg.mtype != JMTYPE_OK) && (jmsg.mtype != JMTYPE_ERR)) { _log.Log(LOG_STATUS, "Received message of type %s from device %d (%s)", jmsg.MtypeAsString().c_str(), jmsg.did, jmsg.devmodel.c_str()); } switch(jmsg.mtype) { case JMTYPE_SLOT: { SlotReadCallback(jmsg.slot_num, jmsg.slot_val); readSlotsCond.notify_one(); break; } case JMTYPE_VERSION: { ProbeCallback(jmsg.version); probeCond.notify_one(); break; } case JMTYPE_SENSOR: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_SENSOR"; SendSwitch(jmsg.did, SUBSWITCH_SENSOR, (jmsg.lb == 1) ? 0 : 100, (jmsg.act == -1) ? 1 : jmsg.act, 0, dev_desc.str()); break; } case JMTYPE_TAMPER: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_TAMPER"; SendSwitch(jmsg.did, SUBSWITCH_TAMPER, (jmsg.lb == 1) ? 0 : 100, (jmsg.act == -1) ? 1 : jmsg.act, 0, dev_desc.str()); break; } case JMTYPE_BUTTON: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_BUTTON"; SendSwitch(jmsg.did, SUBSWITCH_BUTTON, (jmsg.lb == 1) ? 0 : 100, (jmsg.act == -1) ? 1 : jmsg.act, 0, dev_desc.str()); break; } case JMTYPE_ARM: case JMTYPE_DISARM: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_ARM"; SendSwitch(jmsg.did, SUBSWITCH_ARM, (jmsg.lb == 1) ? 0 : 100, (jmsg.mtype == JMTYPE_ARM) ? 1 : 0, 0, dev_desc.str()); break; } case JMTYPE_SET: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_SET"; SendSetPointSensor(jmsg.did, (jmsg.lb == 1) ? 0 : 100, jmsg.temp, dev_desc.str()); break; } case JMTYPE_INT: { std::stringstream dev_desc; dev_desc << jmsg.devmodel << "_" << std::setfill('0') << jmsg.did << "_INT"; SendTempSensor(jmsg.did, (jmsg.lb == 1) ? 0 : 100, jmsg.temp, dev_desc.str()); break; } } } void CJabloDongle::ReadCallback(const char *data, size_t len) { unsigned char *mf, *ml; unsigned char *bufptr; unsigned char msgline[128]; JaMessage jmsg; bool messagesInBuffer; boost::lock_guard<boost::mutex> l(readQueueMutex); if (!m_bIsStarted) return; if (!m_bEnableReceive) return; //receive data to buffer if((m_bufferpos + len) < sizeof(m_buffer)) { memcpy(m_buffer + m_bufferpos, data, len); m_bufferpos += len; } else { _log.Log(LOG_STATUS, "JabloDongle: Buffer Full"); } //m_buffer[m_bufferpos] = '\0'; //_log.Log(LOG_STATUS, "Pokus received: %s", m_buffer); do { messagesInBuffer = false; //find sync sequence \n[ bufptr = m_buffer; while((mf = (unsigned char*)strchr((const char*)bufptr, '\n')) != NULL) { //check if character after newline is printable character if((mf[1] > 32 && (mf[1] < 127))) break; bufptr = mf + 1; } //is there at least 1 whole msg in buffer? if((mf != NULL) && (strlen((char*)mf) > 2)) { ml = (unsigned char*)strchr((char*)mf + 2, '\n'); if(ml != NULL) messagesInBuffer = true; } if(messagesInBuffer) { //copy single message into separate buffer memcpy(msgline, mf, ml - mf + 1); msgline[ml - mf + 1] = '\0'; //shift message buffer and adjust end pointer memmove(m_buffer, ml + 1, m_bufferpos); m_bufferpos -= (ml - m_buffer) + 1; //process message //_log.Log(LOG_STATUS, "Received line %s", msgline); jmsg = ParseMessage(std::string((char*)msgline)); #ifdef OLDFW //quick and dirty hack for msg deduplication, will be removed in final version if((jmsg.mid == -1) && ((jmsg.mtype != last_mtype) || ((jmsg.mtype != JMTYPE_SET) && (jmsg.mtype != JMTYPE_INT)))) { ProcessMessage(jmsg); last_mtype = jmsg.mtype; } else if(jmsg.mid != last_mid) { ProcessMessage(jmsg); last_mid = jmsg.mid; } #else ProcessMessage(jmsg); #endif } }while(messagesInBuffer); } void CJabloDongle::SendTempSensor(int NodeID, const int BatteryLevel, const float temperature, const std::string &defaultname) { bool bDeviceExits = true; std::stringstream szQuery; std::vector<std::vector<std::string> > result; NodeID &= 0xFFFF; //TEMP packet has only 2 bytes for ID. char szTmp[30]; sprintf(szTmp, "%d", (unsigned int)NodeID); szQuery << "SELECT Name FROM DeviceStatus WHERE (HardwareID==" << m_HwdID << ") AND (DeviceID=='" << szTmp << "') AND (Type==" << int(pTypeTEMP) << ") AND (Subtype==" << int(sTypeTemperature) << ")"; result = m_sql.query(szQuery.str()); if (result.size() < 1) { bDeviceExits = false; } RBUF tsen; memset(&tsen, 0, sizeof(RBUF)); tsen.TEMP.packetlength = sizeof(tsen.TEMP) - 1; tsen.TEMP.packettype = pTypeTEMP; tsen.TEMP.subtype = sTypeTemperature; tsen.TEMP.battery_level = BatteryLevel; tsen.TEMP.rssi = 12; tsen.TEMP.id1 = (NodeID & 0xFF00) >> 8; tsen.TEMP.id2 = NodeID & 0xFF; tsen.TEMP.tempsign = (temperature >= 0) ? 0 : 1; int at10 = round(temperature*10.0f); tsen.TEMP.temperatureh = (BYTE)(at10 / 256); at10 -= (tsen.TEMP.temperatureh * 256); tsen.TEMP.temperaturel = (BYTE)(at10); sDecodeRXMessage(this, (const unsigned char *)&tsen.TEMP); if (!bDeviceExits) { //Assign default name for device szQuery.clear(); szQuery.str(""); szQuery << "UPDATE DeviceStatus SET Name='" << defaultname << "' WHERE (HardwareID==" << m_HwdID << ") AND (DeviceID=='" << szTmp << "') AND (Type==" << int(pTypeTEMP) << ") AND (Subtype==" << int(sTypeTemperature) << ")"; m_sql.query(szQuery.str()); } }
bool CRFLink::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) { _log.Log(LOG_STATUS, "RFLink: Controller Initialized!..."); //Enable DEBUG //write("10;RFDEBUG=ON;\n"); //Enable Undecoded DEBUG //write("10;RFUDEBUG=ON;\n"); return true; } if (Name_ID.find("OK") != std::string::npos) { //_log.Log(LOG_STATUS, "RFLink: OK received!..."); m_bTXokay = true; // variable to indicate an OK was received return true; } } if (results.size() < 4) return true; if (results[3].find("ID=") == std::string::npos) return false; //?? 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; int 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 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; raincounter = RFLinkGetHexStringValue(results[ii]); } 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); } 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]); windspeed = float(iTemp) * 0.0277778f; //convert to m/s } else if (results[ii].find("WINGS") != std::string::npos) { bHaveWindGust = true; iTemp = RFLinkGetHexStringValue(results[ii]); 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) / 10.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("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]); } } if (bHaveTemp&&bHaveHum&&bHaveBaro) { SendTempHumBaroSensor(ID, BatteryLevel, temp, humidity, baro, baroforecast); } else if (bHaveTemp&&bHaveHum) { SendTempHumSensor(ID, BatteryLevel, temp, humidity, "TempHum"); } else if (bHaveTemp) { SendTempSensor(ID, BatteryLevel, temp,"Temp"); } else if (bHaveHum) { SendHumiditySensor(ID, BatteryLevel, humidity); } else if (bHaveBaro) { SendBaroSensor(Node_ID, Child_ID, BatteryLevel, baro, baroforecast); } if (bHaveLux) { SendLuxSensor(Node_ID, Child_ID, BatteryLevel, lux, "Lux"); } if (bHaveUV) { SendUVSensor(Node_ID, Child_ID, BatteryLevel, uv); } if (bHaveRain) { SendRainSensor(ID, BatteryLevel, float(raincounter), "Rain"); } if (bHaveWindDir && bHaveWindSpeed && bHaveWindGust && bHaveWindChill) { SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, "Wind"); } else if (bHaveWindDir && bHaveWindGust) { SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, "Wind"); } else if (bHaveWindSpeed) { SendWind(ID, BatteryLevel, float(windir), windspeed, windgust, windtemp, windchill, bHaveWindTemp, "Wind"); } if (bHaveCO2) { SendAirQualitySensor((ID & 0xFF00) >> 8, ID & 0xFF, BatteryLevel, co2, "CO2"); } if (bHaveSound) { SendSoundSensor(ID, BatteryLevel, sound, "Sound"); } if (bHaveRGB) { //RRGGBB SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgb, false, "RGB Light"); } if (bHaveRGBW) { //RRGGBBWW SendRGBWSwitch(Node_ID, Child_ID, BatteryLevel, rgbw, true, "RGBW Light"); } if (bHaveBlind) { SendBlindSensor(Node_ID, Child_ID, BatteryLevel, blind, "Blinds/Window"); } if (bHaveKWatt) { SendKwhMeter(Node_ID, Child_ID, BatteryLevel, kwatt / 1000.0f, kwatt, "Meter"); } if (bHaveWatt) { SendKwhMeter(Node_ID, Child_ID, BatteryLevel, 0, watt, "Meter"); } if (bHaveDistance) { SendDistanceSensor(Node_ID, Child_ID, BatteryLevel, distance); } if (bHaveMeter) { SendMeterSensor(Node_ID, Child_ID, BatteryLevel, meter); } if (bHaveVoltage) { SendVoltageSensor(Node_ID, Child_ID, BatteryLevel, voltage, "Voltage"); } if (bHaveCurrent) { SendCurrentSensor(ID, BatteryLevel, current, 0, 0, "Current"); } if (bHaveSwitch && bHaveSwitchCmd) { std::string switchType = results[2]; SendSwitchInt(ID, switchunit, BatteryLevel, switchType, switchcmd, switchlevel); } return true; }
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())); SendTempSensor(idx - 1, 255, _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, ((m_OverrideTemperature!=0.0f) ? m_OverrideTemperature : _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())); if (_status.CH_water_pressure != 0) { SendPressureSensor(0, idx - 1, 255, _status.CH_water_pressure, "CH Water Pressure"); } _status.Room_temperature = static_cast<float>(atof(results[idx++].c_str())); SendTempSensor(idx - 1, 255, _status.Room_temperature, "Room Temperature"); _status.Boiler_water_temperature = static_cast<float>(atof(results[idx++].c_str())); SendTempSensor(idx - 1, 255, _status.Boiler_water_temperature, "Boiler Water Temperature"); _status.DHW_temperature = static_cast<float>(atof(results[idx++].c_str())); SendTempSensor(idx - 1, 255, _status.DHW_temperature, "DHW Temperature"); _status.Outside_temperature = static_cast<float>(atof(results[idx++].c_str())); SendTempSensor(idx - 1, 255, _status.Outside_temperature, "Outside Temperature"); _status.Return_water_temperature = static_cast<float>(atof(results[idx++].c_str())); SendTempSensor(idx - 1, 255, _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("PR: I")!=std::string::npos) { _tOTGWGPIO _GPIO; _GPIO.A=static_cast<int>(sLine[6]- '0'); UpdateSwitch(98,(_GPIO.A==1),"GPIOAStatusIsHigh"); _GPIO.B=static_cast<int>(sLine[7]- '0'); UpdateSwitch(99,(_GPIO.B==1),"GPIOBStatusIsHigh"); } else if (sLine.find("PR: O")!=std::string::npos) { // Check if setpoint is overriden m_OverrideTemperature=0.0f; char status=sLine[6]; if (status == 'c' || status == 't') { // Get override setpoint value m_OverrideTemperature=static_cast<float>(atof(sLine.substr(7).c_str())); } } else if (sLine.find("PR: A") != std::string::npos) { //Gateway Version std::string tmpstr = sLine.substr(6); size_t tpos = tmpstr.find(' '); if (tpos != std::string::npos) { m_Version = tmpstr.substr(tpos + 9); } } 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()); } } } }
void CAnnaThermostat::GetMeterDetails() { if (m_UserName.size() == 0) return; if (m_Password.size() == 0) return; std::string sResult; #ifdef DEBUG_AnnaThermostat sResult = ReadFile("E:\\appliances.xml"); #else //Get Data std::stringstream szURL; if (m_Password.empty()) { szURL << "http://" << m_IPAddress << ":" << m_IPPort; } else { szURL << "http://" << m_UserName << ":" << m_Password << "@" << m_IPAddress << ":" << m_IPPort; } szURL << ANNA_GET_STATUS; if (!HTTPClient::GET(szURL.str(), sResult)) { _log.Log(LOG_ERROR, "AnnaThermostat: Error getting current state!"); return; } #endif if (sResult.empty()) { _log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!"); return; } stdreplace(sResult, "\r\n", ""); TiXmlDocument doc; if (doc.Parse(sResult.c_str())) { _log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!"); return; } TiXmlElement *pRoot; TiXmlElement *pAppliance, *pElem; TiXmlAttribute *pAttribute; std::string sname, tmpstr; pRoot = doc.FirstChildElement("appliances"); if (!pRoot) { _log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!"); return; } pAppliance = pRoot->FirstChildElement("appliance"); while (pAppliance) { TiXmlHandle hAppliance = TiXmlHandle(pAppliance); pElem = pAppliance->FirstChildElement("name"); if (pElem == NULL) { _log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!"); return; } std::string ApplianceName=pElem->GetText(); if ((m_ThermostatID.empty()) && (ApplianceName == "Anna")) { pAttribute = pAppliance->FirstAttribute(); if (pAttribute != NULL) { std::string aName = pAttribute->Name(); if (aName == "id") { m_ThermostatID = pAttribute->Value(); } } } //Handle point_log pElem = hAppliance.FirstChild("logs").FirstChild().Element(); if (!pElem) { _log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!"); return; } TiXmlHandle hLogs = TiXmlHandle(pElem); pElem = hAppliance.FirstChild("logs").Child("point_log", 0).ToElement(); if (!pElem) { _log.Log(LOG_ERROR, "AnnaThermostat: Invalid data received!"); return; } for (pElem; pElem; pElem = pElem->NextSiblingElement()) { sname = GetElementChildValue(pElem, "type"); if (sname == "temperature") { tmpstr = GetPeriodMeasurement(pElem); if (!tmpstr.empty()) { float temperature = (float)atof(tmpstr.c_str()); SendTempSensor(1, 255, temperature, sname); } } else if (sname == "illuminance") { tmpstr = GetPeriodMeasurement(pElem); if (!tmpstr.empty()) { float illuminance = (float)atof(tmpstr.c_str()); SendLuxSensor(2, 1, 255, illuminance, sname); } } else if (sname == "thermostat") { tmpstr = GetPeriodMeasurement(pElem); if (!tmpstr.empty()) { float temperature = (float)atof(tmpstr.c_str()); SendSetPointSensor(3, temperature, sname); } } /* else if (sname == "intended_boiler_temperature") { tmpstr = GetPeriodMeasurement(pElem); if (!tmpstr.empty()) { float temperature = (float)atof(tmpstr.c_str()); SendTempSensor(4, 255, temperature, sname); } } */ else if (sname == "return_water_temperature") { tmpstr = GetPeriodMeasurement(pElem); if (!tmpstr.empty()) { float temperature = (float)atof(tmpstr.c_str()); SendTempSensor(5, 255, temperature, sname); } } else if (sname == "boiler_temperature") { tmpstr = GetPeriodMeasurement(pElem); if (!tmpstr.empty()) { float temperature = (float)atof(tmpstr.c_str()); SendTempSensor(6, 255, temperature, sname); } } else if (sname == "maximum_boiler_temperature") { tmpstr = GetPeriodMeasurement(pElem); if (!tmpstr.empty()) { float temperature = (float)atof(tmpstr.c_str()); SendTempSensor(7, 255, temperature, sname); } } } pAppliance = pAppliance->NextSiblingElement("appliance"); } return; }
void CDarkSky::GetMeterDetails() { std::string sResult; #ifdef DEBUG_DarkSkyR sResult=ReadFile("E:\\DarkSky.json"); #else std::stringstream sURL; std::string szLoc = m_Location; std::string szExclude = "minutely,hourly,daily,alerts,flags"; sURL << "https://api.darksky.net/forecast/" << m_APIKey << "/" << szLoc << "?exclude=" << szExclude; try { bool bret; std::string szURL = sURL.str(); bret = HTTPClient::GET(szURL, sResult); if (!bret) { _log.Log(LOG_ERROR, "DarkSky: Error getting http data!."); return; } } catch (...) { _log.Log(LOG_ERROR, "DarkSky: Error getting http data!"); return; } #ifdef DEBUG_DarkSkyW SaveString2Disk(sResult, "E:\\DarkSky.json"); #endif #endif Json::Value root; Json::Reader jReader; bool ret=jReader.parse(sResult,root); if ((!ret) || (!root.isObject())) { _log.Log(LOG_ERROR,"DarkSky: Invalid data received! Check Location, use a City or GPS Coordinates (xx.yyyy,xx.yyyyy)"); return; } if (root["currently"].empty()==true) { _log.Log(LOG_ERROR,"DarkSky: Invalid data received, or unknown location!"); return; } /* std::string tmpstr2 = root.toStyledString(); FILE *fOut = fopen("E:\\DarkSky.json", "wb+"); fwrite(tmpstr2.c_str(), 1, tmpstr2.size(), fOut); fclose(fOut); */ float temp; int humidity=0; int barometric=0; int barometric_forcast=baroForecastNoInfo; temp=root["currently"]["temperature"].asFloat(); //Convert to celcius temp=float((temp-32)*(5.0/9.0)); if (root["currently"]["humidity"].empty()==false) { humidity=round(root["currently"]["humidity"].asFloat()*100.0f); } if (root["currently"]["pressure"].empty()==false) { barometric=atoi(root["currently"]["pressure"].asString().c_str()); if (barometric<1000) barometric_forcast=baroForecastRain; else if (barometric<1020) barometric_forcast=baroForecastCloudy; else if (barometric<1030) barometric_forcast=baroForecastPartlyCloudy; else barometric_forcast=baroForecastSunny; if (root["currently"]["icon"].empty()==false) { std::string forcasticon=root["currently"]["icon"].asString(); if ((forcasticon=="partly-cloudy-day")||(forcasticon=="partly-cloudy-night")) { barometric_forcast=baroForecastPartlyCloudy; } else if (forcasticon=="cloudy") { barometric_forcast=baroForecastCloudy; } else if ((forcasticon=="clear-day")||(forcasticon=="clear-night")) { barometric_forcast=baroForecastSunny; } else if ((forcasticon=="rain")||(forcasticon=="snow")) { barometric_forcast=baroForecastRain; } } } if (barometric!=0) { //Add temp+hum+baro device SendTempHumBaroSensor(1, 255, temp, humidity, static_cast<float>(barometric), barometric_forcast, "THB"); } else if (humidity!=0) { //add temp+hum device SendTempHumSensor(1, 255, temp, humidity, "TempHum"); } else { //add temp device SendTempSensor(1, 255, temp, "Temperature"); } //Wind int wind_degrees=-1; float windspeed_ms=0; float windgust_ms=0; float wind_temp=temp; float wind_chill=temp; int windgust=1; float windchill=-1; if (root["currently"]["windBearing"].empty()==false) { wind_degrees=atoi(root["currently"]["windBearing"].asString().c_str()); } if (root["currently"]["windSpeed"].empty()==false) { if ((root["currently"]["windSpeed"] != "N/A") && (root["currently"]["windSpeed"] != "--")) { float temp_wind_mph = static_cast<float>(atof(root["currently"]["windSpeed"].asString().c_str())); if (temp_wind_mph!=-9999.00f) { //convert to m/s windspeed_ms=temp_wind_mph*0.44704f; } } } if (root["currently"]["windGust"].empty()==false) { if ((root["currently"]["windGust"] != "N/A") && (root["currently"]["windGust"] != "--")) { float temp_wind_gust_mph = static_cast<float>(atof(root["currently"]["windGust"].asString().c_str())); if (temp_wind_gust_mph!=-9999.00f) { //convert to m/s windgust_ms=temp_wind_gust_mph*0.44704f; } } } if (root["currently"]["apparentTemperature"].empty()==false) { if ((root["currently"]["apparentTemperature"] != "N/A") && (root["currently"]["apparentTemperature"] != "--")) { wind_chill = static_cast<float>(atof(root["currently"]["apparentTemperature"].asString().c_str())); //Convert to celcius wind_chill=float((wind_chill-32)*(5.0/9.0)); } } if (wind_degrees!=-1) { RBUF tsen; memset(&tsen,0,sizeof(RBUF)); tsen.WIND.packetlength=sizeof(tsen.WIND)-1; tsen.WIND.packettype=pTypeWIND; tsen.WIND.subtype=sTypeWIND4; tsen.WIND.battery_level=9; tsen.WIND.rssi=12; tsen.WIND.id1=0; tsen.WIND.id2=1; float winddir=float(wind_degrees); int aw=round(winddir); tsen.WIND.directionh=(BYTE)(aw/256); aw-=(tsen.WIND.directionh*256); tsen.WIND.directionl=(BYTE)(aw); tsen.WIND.av_speedh=0; tsen.WIND.av_speedl=0; int sw=round(windspeed_ms*10.0f); tsen.WIND.av_speedh=(BYTE)(sw/256); sw-=(tsen.WIND.av_speedh*256); tsen.WIND.av_speedl=(BYTE)(sw); tsen.WIND.gusth=0; tsen.WIND.gustl=0; int gw=round(windgust_ms*10.0f); tsen.WIND.gusth=(BYTE)(gw/256); gw-=(tsen.WIND.gusth*256); tsen.WIND.gustl=(BYTE)(gw); //this is not correct, why no wind temperature? and only chill? tsen.WIND.chillh=0; tsen.WIND.chilll=0; tsen.WIND.temperatureh=0; tsen.WIND.temperaturel=0; tsen.WIND.tempsign=(wind_temp>=0)?0:1; int at10=round(std::abs(wind_temp*10.0f)); tsen.WIND.temperatureh=(BYTE)(at10/256); at10-=(tsen.WIND.temperatureh*256); tsen.WIND.temperaturel=(BYTE)(at10); tsen.WIND.chillsign=(wind_temp>=0)?0:1; at10=round(std::abs(wind_chill*10.0f)); tsen.WIND.chillh=(BYTE)(at10/256); at10-=(tsen.WIND.chillh*256); tsen.WIND.chilll=(BYTE)(at10); sDecodeRXMessage(this, (const unsigned char *)&tsen.WIND, NULL, 255); } //UV if (root["currently"]["uvIndex"].empty() == false) { if ((root["currently"]["uvIndex"] != "N/A") && (root["currently"]["uvIndex"] != "--")) { float UV = root["currently"]["uvIndex"].asFloat(); if ((UV < 16) && (UV >= 0)) { SendUVSensor(0, 1, 255, UV, "UV Index"); } } } //Rain if (root["currently"]["precipIntensity"].empty()==false) { if ((root["currently"]["precipIntensity"] != "N/A") && (root["currently"]["precipIntensity"] != "--")) { float RainCount = static_cast<float>(atof(root["currently"]["precipIntensity"].asString().c_str()))*25.4f; //inches to mm if ((RainCount!=-9999.00f)&&(RainCount>=0.00f)) { RBUF tsen; memset(&tsen,0,sizeof(RBUF)); tsen.RAIN.packetlength=sizeof(tsen.RAIN)-1; tsen.RAIN.packettype=pTypeRAIN; tsen.RAIN.subtype=sTypeRAINWU; tsen.RAIN.battery_level=9; tsen.RAIN.rssi=12; tsen.RAIN.id1=0; tsen.RAIN.id2=1; tsen.RAIN.rainrateh=0; tsen.RAIN.rainratel=0; int tr10=int((float(RainCount)*10.0f)); tsen.RAIN.raintotal1=0; tsen.RAIN.raintotal2=(BYTE)(tr10/256); tr10-=(tsen.RAIN.raintotal2*256); tsen.RAIN.raintotal3=(BYTE)(tr10); sDecodeRXMessage(this, (const unsigned char *)&tsen.RAIN, NULL, 255); } } } //Visibility if (root["currently"]["visibility"].empty()==false) { if ((root["currently"]["visibility"] != "N/A") && (root["currently"]["visibility"] != "--")) { float visibility = static_cast<float>(atof(root["currently"]["visibility"].asString().c_str()))*1.60934f; //miles to km if (visibility>=0) { _tGeneralDevice gdevice; gdevice.subtype=sTypeVisibility; gdevice.floatval1=visibility; sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } } } //Solar Radiation if (root["currently"]["ozone"].empty()==false) { if ((root["currently"]["ozone"] != "N/A") && (root["currently"]["ozone"] != "--")) { float radiation = static_cast<float>(atof(root["currently"]["ozone"].asString().c_str())); if (radiation>=0.0f) { SendCustomSensor(1, 0, 255, radiation, "Ozone Sensor", "DU"); //(dobson units) } } } }
bool CDavisLoggerSerial::HandleLoopData(const unsigned char *data, size_t len) { const uint8_t *pData=data+1; #ifndef DEBUG_DAVIS if (len!=100) return false; if ( (data[1]!='L')|| (data[2]!='O')|| (data[3]!='O')|| (data[96]!=0x0a)|| (data[97]!=0x0d) ) return false; //bool bIsRevA = (data[4]=='P'); #else // FILE *fOut=fopen("davisrob.bin","wb+"); // fwrite(data,1,len,fOut); // fclose(fOut); unsigned char szBuffer[200]; FILE *fIn=fopen("E:\\davis2.bin","rb+"); //FILE *fIn=fopen("davisrob.bin","rb+"); fread(&szBuffer,1,100,fIn); fclose(fIn); pData=szBuffer+1; bool bIsRevA(szBuffer[4]=='P'); #endif RBUF tsen; memset(&tsen,0,sizeof(RBUF)); unsigned char tempIdx=1; bool bBaroValid=false; float BaroMeter=0; bool bInsideTemperatureValid=false; float InsideTemperature=0; bool bInsideHumidityValid=false; int InsideHumidity=0; bool bOutsideTemperatureValid=false; float OutsideTemperature=0; bool bOutsideHumidityValid=false; int OutsideHumidity=0; bool bWindDirectionValid=false; int WindDirection=0; bool bWindSpeedValid=false; float WindSpeed=0; bool bWindSpeedAVR10Valid=false; float WindSpeedAVR10=0; bool bUVValid=false; float UV=0; //Barometer if ((pData[7]!=0xFF)&&(pData[8]!=0xFF)) { bBaroValid=true; BaroMeter=((unsigned int)((pData[8] << 8) | pData[7])) / 29.53f; //in hPa } //Inside Temperature if ((pData[9]!=0xFF)||(pData[10]!=0x7F)) { bInsideTemperatureValid=true; InsideTemperature=((unsigned int)((pData[10] << 8) | pData[9])) / 10.f; InsideTemperature = (InsideTemperature - 32.0f) * 5.0f / 9.0f; } //Inside Humidity if (pData[11]!=0xFF) { InsideHumidity=pData[11]; if (InsideHumidity<101) bInsideHumidityValid=true; } if (bBaroValid&&bInsideTemperatureValid&&bInsideHumidityValid) { uint8_t forecastitem = pData[89]; int forecast = 0; if ((forecastitem & 0x01) == 0x01) forecast = wsbaroforcast_rain; else if ((forecastitem & 0x02) == 0x02) forecast = wsbaroforcast_cloudy; else if ((forecastitem & 0x04) == 0x04) forecast = wsbaroforcast_some_clouds; else if ((forecastitem & 0x08) == 0x08) forecast = wsbaroforcast_sunny; else if ((forecastitem & 0x10) == 0x10) forecast = wsbaroforcast_snow; SendTempHumBaroSensorFloat(tempIdx++, 255, InsideTemperature, InsideHumidity, BaroMeter, forecast, "THB"); } //Outside Temperature if ((pData[12]!=0xFF)||(pData[13]!=0x7F)) { bOutsideTemperatureValid=true; OutsideTemperature=((unsigned int)((pData[13] << 8) | pData[12])) / 10.f; OutsideTemperature = (OutsideTemperature - 32.0f) * 5.0f / 9.0f; } //Outside Humidity if (pData[33]!=0xFF) { OutsideHumidity=pData[33]; if (OutsideHumidity<101) bOutsideHumidityValid=true; } if (bOutsideTemperatureValid||bOutsideHumidityValid) { if ((bOutsideTemperatureValid)&&(bOutsideHumidityValid)) { //Temp+hum SendTempHumSensor(tempIdx++, 255, OutsideTemperature, OutsideHumidity,"Outside TempHum"); } else if (bOutsideTemperatureValid) { //Temp SendTempSensor(tempIdx++, 255, OutsideTemperature, "Outside Temp"); } else if (bOutsideHumidityValid) { //hum SendHumiditySensor(tempIdx++, 255, OutsideHumidity, "Outside Humidity"); } } tempIdx=10; //Add Extra Temp/Hum Sensors int iTmp; for (int iTmp=0; iTmp<7; iTmp++) { bool bTempValid=false; bool bHumValid=false; float temp=0; uint8_t hum=0; if (pData[18+iTmp]!=0xFF) { bTempValid=true; temp=pData[18+iTmp]-90.0f; temp = (temp - 32.0f) * 5.0f / 9.0f; } if (pData[34+iTmp]!=0xFF) { bHumValid=true; hum=pData[34+iTmp]; } if ((bTempValid)&&(bHumValid)) { //Temp+hum SendTempHumSensor(tempIdx++, 255, temp, hum, "Extra TempHum"); } else if (bTempValid) { //Temp SendTempSensor(tempIdx++, 255, temp, "Extra Temp"); } else if (bHumValid) { //hum SendHumiditySensor(tempIdx++, 255, hum, "Extra Humidity"); } } tempIdx=20; //Add Extra Soil Temp Sensors for (iTmp=0; iTmp<4; iTmp++) { bool bTempValid=false; float temp=0; if (pData[25+iTmp]!=0xFF) { bTempValid=true; temp=pData[25+iTmp]-90.0f; temp = (temp - 32.0f) * 5.0f / 9.0f; } if (bTempValid) { SendTempSensor(tempIdx++, 255, temp, "Soil Temp"); } } tempIdx=30; //Add Extra Leaf Temp Sensors for (iTmp=0; iTmp<4; iTmp++) { bool bTempValid=false; float temp=0; if (pData[29+iTmp]!=0xFF) { bTempValid=true; temp=pData[29+iTmp]-90.0f; temp = (temp - 32.0f) * 5.0f / 9.0f; } if (bTempValid) { SendTempSensor(tempIdx++, 255, temp, "Leaf Temp"); } } //Wind Speed if (pData[14]!=0xFF) { bWindSpeedValid=true; WindSpeed=(pData[14])*(4.0f/9.0f); } //Wind Speed AVR 10 minutes if (pData[15]!=0xFF) { bWindSpeedAVR10Valid=true; WindSpeedAVR10=(pData[15])*(4.0f/9.0f); } //Wind Direction if ((pData[16]!=0xFF)&&(pData[17]!=0x7F)) { bWindDirectionValid=true; WindDirection=((unsigned int)((pData[17] << 8) | pData[16])); } if ((bWindSpeedValid)&&(bWindDirectionValid)) { memset(&tsen,0,sizeof(RBUF)); tsen.WIND.packetlength=sizeof(tsen.WIND)-1; tsen.WIND.packettype=pTypeWIND; tsen.WIND.subtype=sTypeWINDNoTemp; tsen.WIND.battery_level=9; tsen.WIND.rssi=12; tsen.WIND.id1=0; tsen.WIND.id2=1; int aw=round(WindDirection); tsen.WIND.directionh=(BYTE)(aw/256); aw-=(tsen.WIND.directionh*256); tsen.WIND.directionl=(BYTE)(aw); tsen.WIND.av_speedh=0; tsen.WIND.av_speedl=0; int sw=round(WindSpeed*10.0f); tsen.WIND.av_speedh=(BYTE)(sw/256); sw-=(tsen.WIND.av_speedh*256); tsen.WIND.av_speedl=(BYTE)(sw); tsen.WIND.gusth=0; tsen.WIND.gustl=0; //this is not correct, why no wind temperature? and only chill? tsen.WIND.chillh=0; tsen.WIND.chilll=0; tsen.WIND.temperatureh=0; tsen.WIND.temperaturel=0; if (bOutsideTemperatureValid) { tsen.WIND.tempsign=(OutsideTemperature>=0)?0:1; tsen.WIND.chillsign=(OutsideTemperature>=0)?0:1; int at10=round(abs(OutsideTemperature*10.0f)); tsen.WIND.temperatureh=(BYTE)(at10/256); tsen.WIND.chillh=(BYTE)(at10/256); at10-=(tsen.WIND.chillh*256); tsen.WIND.temperaturel=(BYTE)(at10); tsen.WIND.chilll=(BYTE)(at10); } sDecodeRXMessage(this, (const unsigned char *)&tsen.WIND, NULL, 255); } //UV if (pData[43]!=0xFF) { UV=(pData[43])/10.0f; if (UV<100) bUVValid=true; } if (bUVValid) { RBUF tsen; memset(&tsen,0,sizeof(RBUF)); tsen.UV.packetlength=sizeof(tsen.UV)-1; tsen.UV.packettype=pTypeUV; tsen.UV.subtype=sTypeUV1; tsen.UV.battery_level=9; tsen.UV.rssi=12; tsen.UV.id1=0; tsen.UV.id2=1; tsen.UV.uv=(BYTE)round(UV*10); sDecodeRXMessage(this, (const unsigned char *)&tsen.UV, NULL, 255); } //Rain Rate if ((pData[41]!=0xFF)&&(pData[42]!=0xFF)) { float rainRate=((unsigned int)((pData[42] << 8) | pData[41])) / 100.0f; //inches rainRate*=25.4f; //mm } //Rain Day if ((pData[50]!=0xFF)&&(pData[51]!=0xFF)) { float rainDay=((unsigned int)((pData[51] << 8) | pData[50])) / 100.0f; //inches rainDay*=25.4f; //mm } //Rain Year if ((pData[54]!=0xFF)&&(pData[55]!=0xFF)) { float rainYear=((unsigned int)((pData[55] << 8) | pData[54])) / 100.0f; //inches rainYear*=25.4f; //mm SendRainSensor(1, 255, rainYear, "Rain"); } //Solar Radiation if ((pData[44]!=0xFF)&&(pData[45]!=0x7F)) { unsigned int solarRadiation=((unsigned int)((pData[45] << 8) | pData[44]));//Watt/M2 _tGeneralDevice gdevice; gdevice.subtype=sTypeSolarRadiation; gdevice.floatval1=float(solarRadiation); sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } //Soil Moistures for (int iMoister=0; iMoister<4; iMoister++) { if (pData[62+iMoister]!=0xFF) { int moister=pData[62+iMoister]; SendMoistureSensor(1 + iMoister, 255, moister, "Moisture"); } } //Leaf Wetness for (int iLeaf=0; iLeaf<4; iLeaf++) { if (pData[66+iLeaf]!=0xFF) { int leaf_wetness=pData[66+iLeaf]; _tGeneralDevice gdevice; gdevice.subtype=sTypeLeafWetness; gdevice.intval1=leaf_wetness; gdevice.id=1+iLeaf; sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } } return true; }
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 CWunderground::GetMeterDetails() { std::string sResult; #ifdef DEBUG_WUNDERGROUND sResult= ReadFile("E:\\wu.json"); #else std::stringstream sURL; std::string szLoc = CURLEncode::URLEncode(m_Location); sURL << "http://api.wunderground.com/api/" << m_APIKey << "/conditions/q/" << szLoc << ".json"; bool bret; std::string szURL=sURL.str(); bret=HTTPClient::GET(szURL,sResult); if (!bret) { _log.Log(LOG_ERROR,"Wunderground: Error getting http data!"); return; } #ifdef DEBUG_WUNDERGROUND2 SaveString2Disk(sResult, "E:\\wu.json"); #endif #endif Json::Value root; Json::Reader jReader; bool ret=jReader.parse(sResult,root); if (!ret) { _log.Log(LOG_ERROR,"WUnderground: Invalid data received!"); return; } bool bValid = true; if (root["response"].empty() == true) { bValid = false; } else if (!root["response"]["error"].empty()) { bValid = false; if (!root["response"]["error"]["description"].empty()) { _log.Log(LOG_ERROR, "WUnderground: Error: %s", root["response"]["error"]["description"].asString().c_str()); return; } } else if (root["current_observation"].empty()==true) { bValid = false; return; } else if (root["current_observation"]["temp_c"].empty() == true) { bValid = false; } if (!bValid) { _log.Log(LOG_ERROR, "WUnderground: Invalid data received, or no data returned!"); return; } /* std::string tmpstr2 = root.toStyledString(); FILE *fOut = fopen("E:\\underground.json", "wb+"); fwrite(tmpstr2.c_str(), 1, tmpstr2.size(), fOut); fclose(fOut); */ std::string tmpstr; float temp; int humidity=0; int barometric=0; int barometric_forcast=baroForecastNoInfo; temp=root["current_observation"]["temp_c"].asFloat(); if (root["current_observation"]["relative_humidity"].empty()==false) { tmpstr=root["current_observation"]["relative_humidity"].asString(); size_t pos=tmpstr.find("%"); if (pos==std::string::npos) { _log.Log(LOG_ERROR,"WUnderground: Invalid data received!"); return; } humidity=atoi(tmpstr.substr(0,pos).c_str()); } if (root["current_observation"]["pressure_mb"].empty()==false) { barometric=atoi(root["current_observation"]["pressure_mb"].asString().c_str()); if (barometric<1000) barometric_forcast=baroForecastRain; else if (barometric<1020) barometric_forcast=baroForecastCloudy; else if (barometric<1030) barometric_forcast=baroForecastPartlyCloudy; else barometric_forcast=baroForecastSunny; if (root["current_observation"]["icon"].empty()==false) { std::string forcasticon=root["current_observation"]["icon"].asString(); if (forcasticon=="partlycloudy") { barometric_forcast=baroForecastPartlyCloudy; } else if (forcasticon=="cloudy") { barometric_forcast=baroForecastCloudy; } else if (forcasticon=="sunny") { barometric_forcast=baroForecastSunny; } else if (forcasticon=="rain") { barometric_forcast=baroForecastRain; } } } if (barometric!=0) { //Add temp+hum+baro device SendTempHumBaroSensor(1, 255, temp, humidity, static_cast<float>(barometric), barometric_forcast, "THB"); } else if (humidity!=0) { //add temp+hum device SendTempHumSensor(1, 255, temp, humidity, "TempHum"); } else { //add temp device SendTempSensor(1, 255, temp, "Temperature"); } //Wind int wind_degrees=-1; float wind_mph=-1; float wind_gust_mph=-1; float windspeed_ms=0; float windgust_ms=0; float wind_temp=temp; float wind_chill=temp; int windgust=1; float windchill=-1; if (root["current_observation"]["wind_degrees"].empty()==false) { wind_degrees=atoi(root["current_observation"]["wind_degrees"].asString().c_str()); } if (root["current_observation"]["wind_mph"].empty()==false) { if ((root["current_observation"]["wind_mph"] != "N/A") && (root["current_observation"]["wind_mph"] != "--")) { float temp_wind_mph = static_cast<float>(atof(root["current_observation"]["wind_mph"].asString().c_str())); if (temp_wind_mph!=-9999.00f) { wind_mph=temp_wind_mph; //convert to m/s windspeed_ms=wind_mph*0.44704f; } } } if (root["current_observation"]["wind_gust_mph"].empty()==false) { if ((root["current_observation"]["wind_gust_mph"] != "N/A") && (root["current_observation"]["wind_gust_mph"] != "--")) { float temp_wind_gust_mph = static_cast<float>(atof(root["current_observation"]["wind_gust_mph"].asString().c_str())); if (temp_wind_gust_mph!=-9999.00f) { wind_gust_mph=temp_wind_gust_mph; //convert to m/s windgust_ms=wind_gust_mph*0.44704f; } } } if (root["current_observation"]["feelslike_c"].empty()==false) { if ((root["current_observation"]["feelslike_c"] != "N/A") && (root["current_observation"]["feelslike_c"] != "--")) { wind_chill = static_cast<float>(atof(root["current_observation"]["feelslike_c"].asString().c_str())); } } if (wind_degrees!=-1) { RBUF tsen; memset(&tsen,0,sizeof(RBUF)); tsen.WIND.packetlength=sizeof(tsen.WIND)-1; tsen.WIND.packettype=pTypeWIND; tsen.WIND.subtype=sTypeWIND4; tsen.WIND.battery_level=9; tsen.WIND.rssi=12; tsen.WIND.id1=0; tsen.WIND.id2=1; float winddir=float(wind_degrees); int aw=round(winddir); tsen.WIND.directionh=(BYTE)(aw/256); aw-=(tsen.WIND.directionh*256); tsen.WIND.directionl=(BYTE)(aw); tsen.WIND.av_speedh=0; tsen.WIND.av_speedl=0; int sw=round(windspeed_ms*10.0f); tsen.WIND.av_speedh=(BYTE)(sw/256); sw-=(tsen.WIND.av_speedh*256); tsen.WIND.av_speedl=(BYTE)(sw); tsen.WIND.gusth=0; tsen.WIND.gustl=0; int gw=round(windgust_ms*10.0f); tsen.WIND.gusth=(BYTE)(gw/256); gw-=(tsen.WIND.gusth*256); tsen.WIND.gustl=(BYTE)(gw); //this is not correct, why no wind temperature? and only chill? tsen.WIND.chillh=0; tsen.WIND.chilll=0; tsen.WIND.temperatureh=0; tsen.WIND.temperaturel=0; tsen.WIND.tempsign=(wind_temp>=0)?0:1; int at10=round(std::abs(wind_temp*10.0f)); tsen.WIND.temperatureh=(BYTE)(at10/256); at10-=(tsen.WIND.temperatureh*256); tsen.WIND.temperaturel=(BYTE)(at10); tsen.WIND.chillsign=(wind_temp>=0)?0:1; at10=round(std::abs(wind_chill*10.0f)); tsen.WIND.chillh=(BYTE)(at10/256); at10-=(tsen.WIND.chillh*256); tsen.WIND.chilll=(BYTE)(at10); sDecodeRXMessage(this, (const unsigned char *)&tsen.WIND, NULL, 255); } //UV if (root["current_observation"].empty() == false) { if (root["current_observation"]["UV"].empty() == false) { if ((root["current_observation"]["UV"] != "N/A") && (root["current_observation"]["UV"] != "--")) { float UV = static_cast<float>(atof(root["current_observation"]["UV"].asString().c_str())); if ((UV < 16) && (UV >= 0)) { SendUVSensor(0, 1, 255, UV, "UV"); } } } } //Rain if (root["current_observation"]["precip_today_metric"].empty() == false) { if ((root["current_observation"]["precip_today_metric"] != "N/A") && (root["current_observation"]["precip_today_metric"] != "--")) { float RainCount = static_cast<float>(atof(root["current_observation"]["precip_today_metric"].asString().c_str())); if ((RainCount != -9999.00f) && (RainCount >= 0.00f)) { RBUF tsen; memset(&tsen, 0, sizeof(RBUF)); tsen.RAIN.packetlength = sizeof(tsen.RAIN) - 1; tsen.RAIN.packettype = pTypeRAIN; tsen.RAIN.subtype = sTypeRAINWU; tsen.RAIN.battery_level = 9; tsen.RAIN.rssi = 12; tsen.RAIN.id1 = 0; tsen.RAIN.id2 = 1; tsen.RAIN.rainrateh = 0; tsen.RAIN.rainratel = 0; if (root["current_observation"]["precip_1hr_metric"].empty() == false) { if ((root["current_observation"]["precip_1hr_metric"] != "N/A") && (root["current_observation"]["precip_1hr_metric"] != "--")) { float rainrateph = static_cast<float>(atof(root["current_observation"]["precip_1hr_metric"].asString().c_str())); if (rainrateph != -9999.00f) { int at10 = round(std::abs(rainrateph*10.0f)); tsen.RAIN.rainrateh = (BYTE)(at10 / 256); at10 -= (tsen.RAIN.rainrateh * 256); tsen.RAIN.rainratel = (BYTE)(at10); } } } int tr10 = int((float(RainCount)*10.0f)); tsen.RAIN.raintotal1 = 0; tsen.RAIN.raintotal2 = (BYTE)(tr10 / 256); tr10 -= (tsen.RAIN.raintotal2 * 256); tsen.RAIN.raintotal3 = (BYTE)(tr10); sDecodeRXMessage(this, (const unsigned char *)&tsen.RAIN, NULL, 255); } } } //Visibility if (root["current_observation"]["visibility_km"].empty() == false) { if ((root["current_observation"]["visibility_km"] != "N/A") && (root["current_observation"]["visibility_km"] != "--")) { float visibility = static_cast<float>(atof(root["current_observation"]["visibility_km"].asString().c_str())); if (visibility >= 0) { _tGeneralDevice gdevice; gdevice.subtype = sTypeVisibility; gdevice.floatval1 = visibility; sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } } } //Solar Radiation if (root["current_observation"]["solarradiation"].empty() == false) { if ((root["current_observation"]["solarradiation"] != "N/A") && (root["current_observation"]["solarradiation"] != "--")) { float radiation = static_cast<float>(atof(root["current_observation"]["solarradiation"].asString().c_str())); if (radiation >= 0.0f) { _tGeneralDevice gdevice; gdevice.subtype = sTypeSolarRadiation; gdevice.floatval1 = radiation; sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } } } }
void CPVOutputInput::GetMeterDetails() { if (m_SID.size()==0) return; if (m_KEY.size()==0) return; std::string sResult; std::stringstream sstr; sstr << "http://pvoutput.org/service/r2/getstatus.jsp?sid=" << m_SID << "&key=" << m_KEY; if (!HTTPClient::GET(sstr.str(),sResult)) { _log.Log(LOG_ERROR,"PVOutput (Input): Error login!"); return; } std::vector<std::string> splitresult; StringSplit(sResult,",",splitresult); if (splitresult.size()<9) { _log.Log(LOG_ERROR,"PVOutput (Input): Invalid Data received!"); return; } double Usage=atof(splitresult[3].c_str()); if (Usage < 0) Usage = 0; bool bHaveConsumption=false; double Consumption=0; if (splitresult[5]!="NaN") { Consumption=atof(splitresult[5].c_str()); if (Consumption < 0) Consumption = 0; bHaveConsumption=true; } if (splitresult[6]!="NaN") { double Efficiency=atof(splitresult[6].c_str())*100.0; if (Efficiency>100.0) Efficiency=100.0; SendPercentage(1,float(Efficiency),"Efficiency"); } if (splitresult[7]!="NaN") { double Temperature=atof(splitresult[7].c_str()); SendTempSensor(1,float(Temperature),"Temperature"); } if (splitresult[8]!="NaN") { double Voltage=atof(splitresult[8].c_str()); if (Voltage>=0) SendVoltage(1,float(Voltage),"Voltage"); } sstr.clear(); sstr.str(""); sstr << "http://pvoutput.org/service/r2/getstatistic.jsp?sid=" << m_SID << "&key=" << m_KEY << "&c=1"; if (!HTTPClient::GET(sstr.str(),sResult)) { _log.Log(LOG_ERROR,"PVOutput (Input): Error login!"); return; } StringSplit(sResult,",",splitresult); if (splitresult.size()<11) { _log.Log(LOG_ERROR,"PVOutput (Input): Invalid Data received!"); return; } double kWhCounterUsage=atof(splitresult[0].c_str()); SendMeter(0, 1, Usage / 1000.0, kWhCounterUsage / 1000.0, "SolarMain"); if (bHaveConsumption) { if (splitresult.size() > 11) { double kWhCounterConsumed = atof(splitresult[11].c_str()); if (kWhCounterConsumed != 0) { SendMeter(0, 2, Consumption / 1000.0, kWhCounterConsumed / 1000.0, "SolarConsumed"); } } } }
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 CSterbox::GetMeterDetails() { std::string sResult; std::stringstream szURL; //if(m_Password.empty()) //{ szURL << "http://" << m_szIPAddress << ":" << m_usIPPort; //} //else //{ // szURL << "http://" << m_Username << ":" << m_Password << "@" << m_szIPAddress << ":" << m_usIPPort; //} szURL << "/x.cgi"; if (!HTTPClient::GET(szURL.str(),sResult)) { _log.Log(LOG_ERROR,"Sterbox: Error connecting to: %s", m_szIPAddress.c_str()); return; } std::vector<std::string> results; std::vector<std::string> outputs; std::vector<std::string> inputs; std::vector<std::string> analog; StringSplit(sResult, "<br>", results); if (results.size()<8) { _log.Log(LOG_ERROR,"Sterbox: Result 8 Error connecting to: %s", m_szIPAddress.c_str()); return; } //if (results[0] != "<body>") std::string tmpstr; std::string tmpstr2; std::string tmpinp; tmpstr = results[0]; if (tmpstr.find("<title>SterBox_State</title>") != std::string::npos) { _log.Log(LOG_ERROR, "Sterbox: Error getting status"); return; } size_t ii; size_t jj; int pos1; int Idx = 0; if (m_Username.empty()) { StringSplit("o,o,o,o,i,i,i,i", ",", inputs); } else { StringSplit(m_Username, ",", inputs); //_log.Log(LOG_ERROR,"Sterbox: Username : %s , IP: %s", m_Username.c_str(), m_szIPAddress.c_str()); } for (ii = 1; ii < results.size(); ii++) { tmpstr = results[ii]; if (tmpstr.find("OU") != std::string::npos) { tmpstr = tmpstr.substr(strlen("OU")); pos1 = tmpstr.find("="); if (pos1 != std::string::npos) { tmpstr = tmpstr.substr(pos1+1); //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr.c_str()); StringSplit(tmpstr, ",", outputs); for (jj = 0; jj < inputs.size(); jj++) { tmpinp = inputs[jj]; //if (( jj < 4 || jj > 7 )) pos1 = tmpinp.find("o"); if (pos1 != std::string::npos) { int lValue = 0; //tmpstr = tmpstr.substr(pos1+1); tmpstr2 = outputs[jj]; //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str()); pos1 = tmpstr2.find("s"); if (pos1 != std::string::npos) { lValue = 1; } else { lValue = 0; } std::stringstream sstr; sstr << "Relay " << jj; UpdateSwitch(1, jj, (lValue == 1) ? true : false, 100, sstr.str()); } } } } else if (tmpstr.find("IN") != std::string::npos) { tmpstr = tmpstr.substr(strlen("IN")); pos1 = tmpstr.find("="); if (pos1 != std::string::npos) { tmpstr = tmpstr.substr(pos1+1); //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr.c_str()); StringSplit(tmpstr, ",", outputs); for (jj = 0; jj < inputs.size(); jj++) { tmpinp = inputs[jj]; //if (( jj > 3 && jj < 8 )) pos1 = tmpinp.find("i"); if (pos1 != std::string::npos) { int lValue = 0; //tmpstr = tmpstr.substr(pos1+1); tmpstr2 = outputs[jj]; //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str()); pos1 = tmpstr2.find("S"); if (pos1 != std::string::npos) { lValue = 1; } else { lValue = 0; } std::stringstream sstr; sstr << "Relay " << jj; UpdateSwitch(1, jj, (lValue == 1) ? true : false, 100, sstr.str()); } } } } else if (tmpstr.find("AN") != std::string::npos) { tmpstr = tmpstr.substr(strlen("AN")); pos1 = tmpstr.find("="); if (pos1 != std::string::npos) { tmpstr = tmpstr.substr(pos1+1); StringSplit(tmpstr, ",", outputs); if (m_Password.empty()) { StringSplit("t,t,t", ",", analog); } else { //StringSplit("t,t,t", ",", inputs); StringSplit(m_Password, ",", analog); //_log.Log(LOG_ERROR,"Sterbox: Pass : %s", m_Password.c_str()); } for (jj = 0; jj < 3; jj++) { tmpstr2 = outputs[jj]; tmpinp = analog[jj]; tmpstr2 = tmpstr2.substr(1, 10); float lValue = (float)atof(tmpstr2.c_str()); std::stringstream sstr; sstr << "Analog " << jj; pos1 = tmpinp.find("t"); if (pos1 != std::string::npos) { SendTempSensor(jj,255,lValue, sstr.str()); } pos1 = tmpinp.find("v"); if (pos1 != std::string::npos) { SendVoltageSensor(0, jj, 255, lValue, sstr.str()); } pos1 = tmpinp.find("l"); if (pos1 != std::string::npos) { SendLuxSensor(0, jj, 255,lValue, sstr.str()); } pos1 = tmpinp.find("h"); if (pos1 != std::string::npos) { SendHumiditySensor(jj,255,int(lValue), sstr.str()); } //SendTempSensor(jj,255,lValue, sstr.str()); //_log.Log(LOG_ERROR,"Sterbox: OU Status: %s", tmpstr2.c_str()); } //Idx = atoi(tmpstr.substr(0, pos1).c_str()); //tmpstr = tmpstr.substr(pos1 + 1); //pos1 = tmpstr.find("<"); //if (pos1 != std::string::npos) //{ // int lValue = atoi(tmpstr.substr(0, pos1).c_str()); // float voltage = (float)(5.0f / 1023.0f)*lValue; // if (voltage > 5.0f) // voltage = 5.0f; // std::stringstream sstr; // sstr << "Voltage " << Idx; // SendVoltageSensor(0, Idx, 255, voltage, sstr.str()); //} } } } }
void CToonThermostat::GetMeterDetails() { if (m_UserName.size()==0) return; if (m_Password.size()==0) return; if (m_bDoLogin) { if (!Login()) return; } std::string sResult; std::vector<std::string> ExtraHeaders; std::stringstream sstr2; sstr2 << "?clientId=" << m_ClientID << "&clientIdChecksum=" << m_ClientIDChecksum << "&random=" << GetRandom(); std::string szPostdata = sstr2.str(); //Get Data std::string sURL = TOON_HOST + TOON_UPDATE_PATH + szPostdata; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "ToonThermostat: Error getting current state!"); m_bDoLogin = true; return; } time_t atime = mytime(NULL); Json::Value root; Json::Reader jReader; if (!jReader.parse(sResult, root)) { _log.Log(LOG_ERROR, "ToonThermostat: Invalid data received!"); m_bDoLogin = true; return; } if (root["success"].empty() == true) { _log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!"); m_bDoLogin = true; return; } if (root["success"] == false) { _log.Log(LOG_ERROR, "ToonThermostat: ToonState request not successful, restarting..!"); m_bDoLogin = true; return; } //thermostatInfo if (root["thermostatInfo"].empty() == false) { float currentTemp = root["thermostatInfo"]["currentTemp"].asFloat() / 100.0f; float currentSetpoint = root["thermostatInfo"]["currentSetpoint"].asFloat() / 100.0f; SendSetPointSensor(1, currentSetpoint, "Room Setpoint"); SendTempSensor(1, currentTemp, "Room Temperature"); //int programState = root["thermostatInfo"]["programState"].asInt(); //int activeState = root["thermostatInfo"]["activeState"].asInt(); if (root["thermostatInfo"]["burnerInfo"].empty() == false) { //burnerinfo //0=off //1=heating //2=hot water //3=pre-heating if (root["thermostatInfo"]["burnerInfo"].isString()) { std::string sBurnerInfo = root["thermostatInfo"]["burnerInfo"].asString(); int burnerInfo = atoi(sBurnerInfo.c_str()); UpdateSwitch(113, burnerInfo != 0, "FlameOn"); } else if (root["thermostatInfo"]["burnerInfo"].isInt()) { int burnerInfo = root["thermostatInfo"]["burnerInfo"].asInt(); UpdateSwitch(113, burnerInfo != 0, "FlameOn"); } } } if (root["gasUsage"].empty() == false) { m_p1gas.gasusage = (unsigned long)(root["gasUsage"]["meterReading"].asFloat()); } if (root["powerUsage"].empty() == false) { m_p1power.powerusage1 = (unsigned long)(root["powerUsage"]["meterReading"].asFloat()); m_p1power.powerusage2 = (unsigned long)(root["powerUsage"]["meterReadingLow"].asFloat()); if (root["powerUsage"]["meterReadingProdu"].empty() == false) { m_p1power.powerdeliv1 = (unsigned long)(root["powerUsage"]["meterReadingProdu"].asFloat()); m_p1power.powerdeliv2 = (unsigned long)(root["powerUsage"]["meterReadingLowProdu"].asFloat()); } m_p1power.usagecurrent = (unsigned long)(root["powerUsage"]["value"].asFloat()); //Watt } //Send Electra if value changed, or at least every 5 minutes if ( (m_p1power.usagecurrent != m_lastelectrausage) || (atime - m_lastSharedSendElectra >= 300) ) { if ((m_p1power.powerusage1 != 0) || (m_p1power.powerusage2 != 0) || (m_p1power.powerdeliv1 != 0) || (m_p1power.powerdeliv2 != 0)) { m_lastSharedSendElectra = atime; m_lastelectrausage = m_p1power.usagecurrent; sDecodeRXMessage(this, (const unsigned char *)&m_p1power); } } //Send GAS if the value changed, or at least every 5 minutes if ( (m_p1gas.gasusage != m_lastgasusage) || (atime - m_lastSharedSendGas >= 300) ) { if (m_p1gas.gasusage != 0) { m_lastSharedSendGas = atime; m_lastgasusage = m_p1gas.gasusage; sDecodeRXMessage(this, (const unsigned char *)&m_p1gas); } } }
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 CDaikin::GetSensorInfo() { std::string sResult; #ifdef DEBUG_DaikinR sResult = ReadFile("E:\\Daikin_get_sensor_info.txt"); #else std::stringstream szURL; if (m_Password.empty()) { szURL << "http://" << m_szIPAddress << ":" << m_usIPPort; } else { szURL << "http://" << m_Username << ":" << m_Password << "@" << m_szIPAddress << ":" << m_usIPPort; } szURL << "/aircon/get_sensor_info"; if (!HTTPClient::GET(szURL.str(), sResult)) { _log.Log(LOG_ERROR, "Daikin: Error connecting to: %s", m_szIPAddress.c_str()); return; } #ifdef DEBUG_DaikinW SaveString2Disk(sResult, "E:\\Daikin_get_sensor_info.txt"); #endif #endif if (sResult.find("ret=OK") == std::string::npos) { _log.Log(LOG_ERROR, "Daikin: Error getting data (check IP/Port)"); return; } std::vector<std::string> results; StringSplit(sResult, ",", results); if (results.size() < 6) { _log.Log(LOG_ERROR, "Daikin: Invalid data received"); return; } float htemp = -1; int hhum = -1; std::vector<std::string>::const_iterator itt; for (itt = results.begin(); itt != results.end(); ++itt) { std::string sVar = *itt; std::vector<std::string> results2; StringSplit(sVar, "=", results2); if (results2.size() != 2) continue; if (results2[0] == "htemp") { htemp = static_cast<float>(atof(results2[1].c_str())); } else if (results2[0] == "hhum") { if (results2[1]!="-") hhum = static_cast<int>(atoi(results2[1].c_str())); } else if (results2[0] == "otemp") { SendTempSensor(11, -1, static_cast<float>(atof(results2[1].c_str())), "Outside Temperature"); } if (htemp != -1) { if (hhum != -1) SendTempHumSensor(10, -1, htemp, hhum, "Home Temp+Hum"); else SendTempSensor(10, -1, htemp, "Home Temperature"); } } }