void CThermosmart::SetSetpoint(const int idx, const float temp) { if (m_bDoLogin) { if (!Login()) return; } char szTemp[20]; sprintf(szTemp, "%.1f", temp); std::string sTemp = szTemp; std::string szPostdata = "target_temperature=" + sTemp; std::vector<std::string> ExtraHeaders; std::string sResult; std::string sURL = THERMOSMART_SETPOINT_PATH; stdreplace(sURL, "[TID]", m_ThermostatID); stdreplace(sURL, "[access_token]", m_AccessToken); if (!HTTPClient::PUT(sURL, szPostdata, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "Thermosmart: Error setting thermostat data!"); m_bDoLogin = true; return; } SendSetPointSensor(1, temp, "target temperature"); }
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 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 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); } } }
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 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 CNest::GetMeterDetails() { std::string sResult; #ifdef DEBUG_NextThermostatR sResult = ReadFile("E:\\nest.json"); #else if (m_UserName.size()==0) return; if (m_Password.size()==0) return; if (m_bDoLogin) { if (!Login()) return; } std::vector<std::string> ExtraHeaders; ExtraHeaders.push_back("user-agent:Nest/1.1.0.10 CFNetwork/548.0.4"); ExtraHeaders.push_back("Authorization:Basic " + m_AccessToken); ExtraHeaders.push_back("X-nl-user-id:" + m_UserID); ExtraHeaders.push_back("X-nl-protocol-version:1"); //Get Data std::string sURL = m_TransportURL + NEST_GET_STATUS + m_UserID; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "Nest: Error getting current state!"); m_bDoLogin = true; return; } #endif #ifdef DEBUG_NextThermostatW SaveString2Disk(sResult, "E:\\nest.json"); #endif Json::Value root; Json::Reader jReader; if (!jReader.parse(sResult, root)) { _log.Log(LOG_ERROR, "Nest: Invalid data received!"); m_bDoLogin = true; return; } bool bHaveShared = !root["shared"].empty(); bool bHaveTopaz = !root["topaz"].empty(); if ((!bHaveShared) && (!bHaveTopaz)) { _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } //Protect if (bHaveTopaz) { if (root["topaz"].size() < 1) { _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } Json::Value::Members members = root["topaz"].getMemberNames(); if (members.size() < 1) { _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } int SwitchIndex = 1; for (Json::Value::iterator itDevice = root["topaz"].begin(); itDevice != root["topaz"].end(); ++itDevice) { Json::Value device = *itDevice; std::string devstring = itDevice.key().asString(); if (device["where_id"].empty()) continue; std::string whereid = device["where_id"].asString(); //lookup name std::string devName = devstring; if (!root["where"].empty()) { for (Json::Value::iterator itWhere = root["where"].begin(); itWhere != root["where"].end(); ++itWhere) { Json::Value iwhere = *itWhere; if (!iwhere["wheres"].empty()) { for (Json::Value::iterator itWhereNest = iwhere["wheres"].begin(); itWhereNest != iwhere["wheres"].end(); ++itWhereNest) { Json::Value iwhereItt = *itWhereNest; if (!iwhereItt["where_id"].empty()) { std::string tmpWhereid = iwhereItt["where_id"].asString(); if (tmpWhereid == whereid) { devName = iwhereItt["name"].asString(); break; } } } } } } bool bIAlarm = false; bool bBool; if (!device["component_speaker_test_passed"].empty()) { bBool = device["component_speaker_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_smoke_test_passed"].empty()) { bBool = device["component_smoke_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_heat_test_passed"].empty()) { bBool = device["component_heat_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_buzzer_test_passed"].empty()) { bBool = device["component_buzzer_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_us_test_passed"].empty()) { bBool = device["component_us_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_temp_test_passed"].empty()) { bBool = device["component_temp_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_wifi_test_passed"].empty()) { bBool = device["component_wifi_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_als_test_passed"].empty()) { bBool = device["component_als_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_co_test_passed"].empty()) { bBool = device["component_co_test_passed"].asBool(); if (!bBool) bIAlarm = true; } if (!device["component_hum_test_passed"].empty()) { bBool = device["component_hum_test_passed"].asBool(); if (!bBool) bIAlarm = true; } UpdateSmokeSensor(SwitchIndex, bIAlarm, devName); SwitchIndex++; } } //Thermostat if (!bHaveShared) return; if (root["shared"].size()<1) { if (bHaveTopaz) return; _log.Log(LOG_ERROR, "Nest: request not successful, restarting..!"); m_bDoLogin = true; return; } size_t iThermostat = 0; for (Json::Value::iterator ittStructure = root["structure"].begin(); ittStructure != root["structure"].end(); ++ittStructure) { Json::Value nstructure = *ittStructure; if (!nstructure.isObject()) continue; std::string StructureID = ittStructure.key().asString(); std::string StructureName = nstructure["name"].asString(); for (Json::Value::iterator ittDevice = nstructure["devices"].begin(); ittDevice != nstructure["devices"].end(); ++ittDevice) { std::string devID = (*ittDevice).asString(); if (devID.find("device.")==std::string::npos) continue; std::string Serial = devID.substr(7); if (root["device"].empty()) continue; if (root["device"][Serial].empty()) continue; //not found !? if (root["shared"][Serial].empty()) continue; //Nothing shared? Json::Value ndevice = root["device"][Serial]; if (!ndevice.isObject()) continue; std::string Name = "Thermostat"; if (!ndevice["where_id"].empty()) { //Lookup our 'where' (for the Name of the thermostat) std::string where_id = ndevice["where_id"].asString(); if (!root["where"].empty()) { if (!root["where"][StructureID].empty()) { for (Json::Value::iterator ittWheres = root["where"][StructureID]["wheres"].begin(); ittWheres != root["where"][StructureID]["wheres"].end(); ++ittWheres) { Json::Value nwheres = *ittWheres; if (nwheres["where_id"] == where_id) { Name = StructureName + " " + nwheres["name"].asString(); break; } } } } } _tNestThemostat ntherm; ntherm.Serial = Serial; ntherm.StructureID = StructureID; ntherm.Name = Name; m_thermostats[iThermostat] = ntherm; Json::Value nshared = root["shared"][Serial]; //Setpoint if (!nshared["target_temperature"].empty()) { float currentSetpoint = nshared["target_temperature"].asFloat(); SendSetPointSensor((const unsigned char)(iThermostat * 3) + 1, currentSetpoint, Name + " Setpoint"); } //Room Temperature/Humidity if (!nshared["current_temperature"].empty()) { float currentTemp = nshared["current_temperature"].asFloat(); int Humidity = root["device"][Serial]["current_humidity"].asInt(); SendTempHumSensor((iThermostat * 3) + 2, 255, currentTemp, Humidity, Name + " TempHum"); } // Check if thermostat is currently Heating if (nshared["can_heat"].asBool() && !nshared["hvac_heater_state"].empty()) { bool bIsHeating = nshared["hvac_heater_state"].asBool(); UpdateSwitch((unsigned char)(113 + (iThermostat * 3)), bIsHeating, Name + " HeatingOn"); } // Check if thermostat is currently Cooling if (nshared["can_cool"].asBool() && !nshared["hvac_ac_state"].empty()) { bool bIsCooling = nshared["hvac_ac_state"].asBool(); UpdateSwitch((unsigned char)(114 + (iThermostat * 3)), bIsCooling, Name + " CoolingOn"); } //Away if (!nstructure["away"].empty()) { bool bIsAway = nstructure["away"].asBool(); SendSwitch((iThermostat * 3) + 3, 1, 255, bIsAway, 0, Name + " Away"); } iThermostat++; } } }
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()); } }
void CNestThermostat::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; ExtraHeaders.push_back("user-agent:Nest/1.1.0.10 CFNetwork/548.0.4"); ExtraHeaders.push_back("Authorization:Basic " + m_AccessToken); ExtraHeaders.push_back("X-nl-user-id:" + m_UserID); ExtraHeaders.push_back("X-nl-protocol-version:1"); //Get Data std::string sURL = m_TransportURL + NEST_GET_STATUS + m_UserID; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "NestThermostat: Error getting current state!"); m_bDoLogin = true; return; } Json::Value root; Json::Reader jReader; if (!jReader.parse(sResult, root)) { _log.Log(LOG_ERROR, "NestThermostat: Invalid data received!"); m_bDoLogin = true; return; } if (root["shared"].empty() == true) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } if (root["shared"].size()<1) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } Json::Value::Members members = root["shared"].getMemberNames(); if (members.size() < 1) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } //Get Serial m_Serial = *members.begin(); //Get Structure members = root["structure"].getMemberNames(); if (members.size() < 1) { _log.Log(LOG_ERROR, "NestThermostat: request not successful, restarting..!"); m_bDoLogin = true; return; } m_StructureID = *members.begin(); Json::Value vShared = *root["shared"].begin(); //Setpoint if (!vShared["target_temperature"].empty()) { float currentSetpoint = vShared["target_temperature"].asFloat(); SendSetPointSensor(1, currentSetpoint, "Room Setpoint"); } //Room Temperature/Humidity if (!vShared["current_temperature"].empty()) { float currentTemp = vShared["current_temperature"].asFloat(); int Humidity = root["device"][m_Serial]["current_humidity"].asInt(); SendTempHumSensor(2, 255, currentTemp, Humidity, "Room TempHum"); } //Away Json::Value vStructure = *root["structure"].begin(); if (!vStructure["away"].empty()) { bool bIsAway = vStructure["away"].asBool(); SendSwitch(3, 1, 255, bIsAway, 0, "Away"); } }
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 CToonThermostat::SetSetpoint(const int idx, const float temp) { if (m_UserName.size() == 0) return; if (m_Password.size() == 0) return; if (m_bDoLogin == true) { if (!Login()) return; } std::string sResult; std::vector<std::string> ExtraHeaders; if (idx==1) { //Room Set Point char szTemp[20]; sprintf(szTemp,"%d",int(temp*100.0f)); std::string sTemp = szTemp; std::stringstream sstr2; sstr2 << "?clientId=" << m_ClientID << "&clientIdChecksum=" << m_ClientIDChecksum << "&value=" << sTemp << "&random=" << GetRandom(); std::string szPostdata = sstr2.str(); std::string sURL = TOON_HOST + TOON_TEMPSET_PATH + szPostdata; if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "ToonThermostat: Error setting setpoint!"); m_bDoLogin = true; return; } 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: setPoint request not successful, restarting..!"); m_bDoLogin = true; return; } if (root["success"] == false) { _log.Log(LOG_ERROR, "ToonThermostat: setPoint request not successful, restarting..!"); m_bDoLogin = true; return; } SendSetPointSensor(idx, temp, "Room Setpoint"); m_retry_counter = 0; m_poll_counter = TOON_POLL_INTERVAL_SHORT; } }
void CDaikin::GetControlInfo() { std::string sResult; #ifdef DEBUG_DaikinR sResult = ReadFile("E:\\Daikin_get_control_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_control_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_control_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() < 8) { _log.Log(LOG_ERROR, "Daikin: Invalid data received"); return; } 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] == "mode") { //0-1-7 auto //2 dehum //3 cooling //4 heating //6 fan } else if (results2[0] == "stemp") { //Target Temperature SendSetPointSensor(1, 1, 1, static_cast<float>(atof(results2[1].c_str())), "Target Temperature"); } } //UpdateSwitch(1, Idx, (lValue == 1) ? true : false, 100, sstr.str()); }