bool CPhilipsHue::GetLights(const Json::Value &root) { if (root["lights"].empty()) return false; for (Json::Value::const_iterator iLight = root["lights"].begin(); iLight != root["lights"].end(); ++iLight) { Json::Value light = *iLight; if (light.isObject()) { std::string szLID = iLight.key().asString(); int lID = atoi(szLID.c_str()); _tHueLight tlight; tlight.level = 0; tlight.sat = 0; // Philips 0- 254, should be corrected to 0 - 255 ? tlight.hue = 0; // Philips 0 - 65535, should be converted to 0 - 255 ? tlight.on = light["state"]["on"].asBool(); bool bDoSend = true; _eHueLightType LType = HLTYPE_NORMAL; if (!light["state"]["bri"].empty()) { //Lamp with brightness control LType = HLTYPE_DIM; int tbri = light["state"]["bri"].asInt(); if ((tbri != 0) && (tbri != 255)) tbri += 1; //hue reports 255 as 254 tlight.level = int((100.0f / 255.0f)*float(tbri)); } if ((!light["state"]["sat"].empty()) && (!light["state"]["hue"].empty())) { //Lamp with hue/sat control LType = HLTYPE_RGBW; tlight.sat = light["state"]["sat"].asInt(); tlight.hue = light["state"]["hue"].asInt(); } if (m_lights.find(lID) != m_lights.end()) { _tHueLight alight = m_lights[lID]; if ( (alight.on == tlight.on) && (alight.level == tlight.level) && (alight.sat == tlight.sat) && (alight.hue == tlight.hue) ) { bDoSend = false; } } m_lights[lID] = tlight; if (bDoSend) { //_log.Log(LOG_STATUS, "HueBridge state change: tbri = %d, level = %d", tbri, tlight.level); InsertUpdateSwitch(lID, LType, tlight.on, tlight.level, tlight.sat, tlight.hue, light["name"].asString(), ""); } } } return true; }
bool CPhilipsHue::GetScenes(const Json::Value &root) { if (root["scenes"].empty()) return false; int ii=0; for (Json::Value::iterator iScene = root["scenes"].begin(); iScene != root["scenes"].end(); ++iScene) { Json::Value scene = *iScene; if (scene.isObject()) { _tHueScene hscene; hscene.id = iScene.key().asString();; hscene.name = scene["name"].asString(); hscene.lastupdated = scene["lastupdated"].asString(); //Strip some info size_t tpos = hscene.name.find(" from "); if (tpos != std::string::npos) { hscene.name = hscene.name.substr(0, tpos); } int sID = ii + 1; bool bDoSend = true; if (m_scenes.find(hscene.id) != m_scenes.end()) { _tHueScene ascene = m_scenes[hscene.id]; if (ascene.lastupdated == hscene.lastupdated) { bDoSend = false; } } m_scenes[hscene.id] = hscene; if (bDoSend) { std::string Name = "Scene " + hscene.name; InsertUpdateSwitch(2000 + sID, HLTYPE_SCENE, false, 1000, 0, 0, Name, hscene.id); } } ii++; } return true; }
bool CPhilipsHue::GetGroups(const Json::Value &root) { //Groups (0=All) if (root["groups"].empty()) return false; for (Json::Value::iterator iGroup = root["groups"].begin(); iGroup != root["groups"].end(); ++iGroup) { Json::Value group = *iGroup; if (group.isObject()) { std::string szGID = iGroup.key().asString(); int gID = atoi(szGID.c_str()); bool bIsOn = false; int tbri = 255; int tsat = 255; int thue = 255; if (!group["action"]["on"].empty()) bIsOn = group["action"]["on"].asBool(); if (!group["action"]["bri"].empty()) tbri = group["action"]["bri"].asInt(); if (!group["action"]["sat"].empty()) tsat = group["action"]["sat"].asInt(); if (!group["action"]["hue"].empty()) thue = group["action"]["hue"].asInt(); if ((tbri != 0) && (tbri != 255)) tbri += 1; //hue reports 255 as 254 int BrightnessLevel = int((100.0f / 255.0f)*float(tbri)); _tHueLight tstate; if (bIsOn) { tstate.cmd = (BrightnessLevel != 0) ? Limitless_SetBrightnessLevel : Limitless_LedOn; } else tstate.cmd = Limitless_LedOff; tstate.level = BrightnessLevel; tstate.sat = tsat; tstate.hue = thue; bool bDoSend = true; if (m_groups.find(gID) != m_groups.end()) { _tHueGroup agroup = m_groups[gID]; if ( (agroup.gstate.cmd == tstate.cmd) && (agroup.gstate.level == tstate.level) && (agroup.gstate.sat == tstate.sat) && (agroup.gstate.hue == tstate.hue) ) { bDoSend = false; } } m_groups[gID].gstate = tstate; if (bDoSend) { std::string Name = "Group " + group["name"].asString(); InsertUpdateSwitch(1000 + gID, HLTYPE_RGBW, bIsOn, BrightnessLevel, tsat, thue, Name, ""); } } } //Special Request for Group0 (All Lights) std::stringstream sstr2; sstr2 << "http://" << m_IPAddress << ":" << m_Port << "/api/" << m_UserName << "/groups/0"; std::string sResult; std::vector<std::string> ExtraHeaders; if (!HTTPClient::GET(sstr2.str(), ExtraHeaders, sResult)) { //No group all(0) return true; } Json::Reader jReader; Json::Value root2; bool ret = jReader.parse(sResult, root2); ret = jReader.parse(sResult, root2); if (!ret) { _log.Log(LOG_ERROR, "Philips Hue: Invalid data received, or invalid IPAddress/Username!"); return false; } if (sResult.find("\"error\":") != std::string::npos) { //We had an error _log.Log(LOG_ERROR, "Philips Hue: Error received: %s", root2[0]["error"]["description"].asString().c_str()); return false; } if (sResult.find("lights") == std::string::npos) { return false; } bool bIsOn = false; int tbri = 255; int tsat = 255; int thue = 255; if (!root2["action"]["on"].empty()) bIsOn = root2["action"]["on"].asBool(); if (!root2["action"]["bri"].empty()) tbri = root2["action"]["bri"].asInt(); if (!root2["action"]["sat"].empty()) tsat = root2["action"]["sat"].asInt(); if (!root2["action"]["hue"].empty()) thue = root2["action"]["hue"].asInt(); if ((tbri != 0) && (tbri != 255)) tbri += 1; //hue reports 255 as 254 int BrightnessLevel = int((100.0f / 255.0f)*float(tbri)); _tHueLight tstate; if (bIsOn) { tstate.cmd = (BrightnessLevel != 0) ? Limitless_SetBrightnessLevel : Limitless_LedOn; } else tstate.cmd = Limitless_LedOff; tstate.level = BrightnessLevel; tstate.sat = tsat; tstate.hue = thue; bool bDoSend = true; int gID = 0; if (m_groups.find(gID) != m_groups.end()) { _tHueGroup agroup = m_groups[gID]; if ( (agroup.gstate.cmd == tstate.cmd) && (agroup.gstate.level == tstate.level) && (agroup.gstate.sat == tstate.sat) && (agroup.gstate.hue == tstate.hue) ) { bDoSend = false; } } m_groups[gID].gstate = tstate; if (bDoSend) { std::string Name = "Group All Lights"; InsertUpdateSwitch(1000 + gID, HLTYPE_RGBW, bIsOn, BrightnessLevel, tsat, thue, Name,""); } return true; }
bool CPhilipsHue::GetLights(const Json::Value &root) { if (root["lights"].empty()) return false; for (Json::Value::iterator iLight = root["lights"].begin(); iLight != root["lights"].end(); ++iLight) { Json::Value light = *iLight; if (light.isObject()) { std::string szLID = iLight.key().asString(); int lID = atoi(szLID.c_str()); _tHueLight tlight; int BrightnessLevel = 0; tlight.level = 0; tlight.sat = 0; tlight.hue = 0; int tbri = 0; bool bIsOn = light["state"]["on"].asBool(); bool bDoSend = true; _eHueLightType LType = HLTYPE_NORMAL; if (bIsOn) { tlight.cmd = light2_sOn; } else tlight.cmd = light2_sOff; if (!light["state"]["bri"].empty()) { //Lamp with brightness control LType = HLTYPE_DIM; tbri = light["state"]["bri"].asInt(); if ((tbri != 0) && (tbri != 255)) tbri += 1; //hue reports 255 as 254 tlight.level = tbri; BrightnessLevel = int((100.0f / 255.0f)*float(tbri)); if (bIsOn) { tlight.cmd = (BrightnessLevel != 0) ? light2_sSetLevel : light2_sOn; } else tlight.cmd = light2_sOff; } if ((!light["state"]["sat"].empty()) && (!light["state"]["hue"].empty())) { //Lamp with hue/sat control LType = HLTYPE_RGBW; tlight.sat = light["state"]["sat"].asInt(); tlight.hue = light["state"]["hue"].asInt(); if (bIsOn) { tlight.cmd = (BrightnessLevel != 0) ? Limitless_SetBrightnessLevel : Limitless_LedOn; } else tlight.cmd = Limitless_LedOff; } if (m_lights.find(lID) != m_lights.end()) { _tHueLight alight = m_lights[lID]; if ( (alight.cmd == tlight.cmd) && (alight.level == tlight.level) && (alight.sat == tlight.sat) && (alight.hue == tlight.hue) ) { bDoSend = false; } } m_lights[lID] = tlight; if (bDoSend) { InsertUpdateSwitch(lID, LType, bIsOn, BrightnessLevel, tlight.sat, tlight.hue, light["name"].asString(), ""); } } } return true; }
bool CPhilipsHue::GetScenes(const Json::Value &root) { if (root["scenes"].empty()) return false; for (Json::Value::const_iterator iScene = root["scenes"].begin(); iScene != root["scenes"].end(); ++iScene) { Json::Value scene = *iScene; if (scene.isObject()) { _tHueScene hscene; hscene.id = iScene.key().asString();; hscene.name = scene["name"].asString(); hscene.lastupdated = scene["lastupdated"].asString(); if (hscene.lastupdated.empty()) continue; //old scene/legacy scene //Strip some info size_t tpos = hscene.name.find(" from "); if (tpos != std::string::npos) { hscene.name = hscene.name.substr(0, tpos); } bool bDoSend = true; if (m_scenes.find(hscene.id) != m_scenes.end()) { _tHueScene ascene = m_scenes[hscene.id]; if (ascene.lastupdated == hscene.lastupdated) { bDoSend = false; } } m_scenes[hscene.id] = hscene; if (bDoSend) { int sID = -1; std::vector<std::vector<std::string> > result; result = m_sql.safe_query("SELECT ID FROM WOLNodes WHERE (HardwareID==%d) AND (MacAddress=='%q')", m_HwdID, hscene.id.c_str()); if (!result.empty()) { //existing scene sID = atoi(result[0][0].c_str()); } else { //New scene m_sql.safe_query("INSERT INTO WOLNodes (HardwareID, Name, MacAddress) VALUES (%d, '%q', '%q')", m_HwdID, hscene.name.c_str(), hscene.id.c_str()); result = m_sql.safe_query("SELECT ID FROM WOLNodes WHERE (HardwareID==%d) AND (MacAddress=='%q')", m_HwdID, hscene.id.c_str()); if (result.empty()) { _log.Log(LOG_ERROR, "Philips Hue: Problem adding new Scene!!"); return false; } sID = atoi(result[0][0].c_str()); } std::string Name = "Scene " + hscene.name; InsertUpdateSwitch(2000 + sID, HLTYPE_SCENE, false, 100, 0, 0, Name, hscene.id); } } } return true; }
bool CPhilipsHue::GetLights(const Json::Value &root) { if (root["lights"].empty()) return false; for (Json::Value::iterator iLight = root["lights"].begin(); iLight != root["lights"].end(); ++iLight) { Json::Value light = *iLight; if (light.isObject()) { std::string szLID = iLight.key().asString(); int lID = atoi(szLID.c_str()); std::string ltype = light["type"].asString(); if ( (ltype == "Dimmable plug-in unit") || (ltype == "Dimmable light") || (ltype == "Color temperature light") ) { //Normal light (with dim option) bool bIsOn = light["state"]["on"].asBool(); int tbri = light["state"]["bri"].asInt(); if ((tbri != 0) && (tbri != 255)) tbri += 1; //hue reports 255 as 254 int BrightnessLevel = int((100.0f / 255.0f)*float(tbri)); _tHueLight tlight; if (bIsOn) { tlight.cmd = (BrightnessLevel != 0) ? light2_sSetLevel : light2_sOn; } else tlight.cmd = light2_sOff; tlight.level = BrightnessLevel; tlight.sat = 0; tlight.hue = 0; bool bDoSend = true; if (m_lights.find(lID) != m_lights.end()) { _tHueLight alight = m_lights[lID]; if ( (alight.cmd == tlight.cmd) && (alight.level == tlight.level) ) { bDoSend = false; } } m_lights[lID] = tlight; if (bDoSend) InsertUpdateSwitch(lID, HLTYPE_DIM, bIsOn, BrightnessLevel, 0, 0, light["name"].asString(), ""); } else if ( (ltype == "Extended color light") || (ltype == "Color light") ) { //RGBW type bool bIsOn = light["state"]["on"].asBool(); int tbri = light["state"]["bri"].asInt(); int tsat = light["state"]["sat"].asInt(); int thue = light["state"]["hue"].asInt(); if ((tbri != 0) && (tbri != 255)) tbri += 1; //hue reports 255 as 254 int BrightnessLevel = int((100.0f / 255.0f)*float(tbri)); _tHueLight tlight; if (bIsOn) { tlight.cmd = (BrightnessLevel != 0) ? Limitless_SetBrightnessLevel : Limitless_LedOn; } else tlight.cmd = Limitless_LedOff; tlight.level = BrightnessLevel; tlight.sat = tsat; tlight.hue = thue; bool bDoSend = true; if (m_lights.find(lID) != m_lights.end()) { _tHueLight alight = m_lights[lID]; if ( (alight.cmd == tlight.cmd) && (alight.level == tlight.level) && (alight.sat == tlight.sat) && (alight.hue == tlight.hue) ) { bDoSend = false; } } m_lights[lID] = tlight; if (bDoSend) { InsertUpdateSwitch(lID, HLTYPE_RGBW, bIsOn, BrightnessLevel, tsat, thue, light["name"].asString(), ""); } } } } return true; }
bool CPhilipsHue::GetLightStates() { std::vector<std::string> ExtraHeaders; std::string sResult; #ifdef DEBUG_PhilipsHue sResult= ReadFile("E:\\philipshue.jon"); #else std::stringstream sstr2; sstr2 << "http://" << m_IPAddress << ":" << m_Port << "/api/" << m_UserName; //Get Data std::string sURL = sstr2.str(); if (!HTTPClient::GET(sURL, ExtraHeaders, sResult)) { _log.Log(LOG_ERROR, "Philips Hue: Error getting Light States, (Check IPAddress/Username)"); return false; } #endif #ifdef DEBUG_PhilipsHue2 SaveString2Disk(sResult, "E:\\philipshue.jon"); #endif Json::Value root; Json::Reader jReader; bool ret = jReader.parse(sResult, root); if (!ret) { _log.Log(LOG_ERROR, "Philips Hue: Invalid data received, or invalid IPAddress/Username!"); return false; } if (sResult.find("error") != std::string::npos) { //We had an error _log.Log(LOG_ERROR, "Philips Hue: Error received: %s", root[0]["error"]["description"].asString().c_str()); return false; } if (sResult.find("lights") == std::string::npos) { return false; } int totLights = root["lights"].size(); char szNode[10]; for (int ii = 0; ii < 255; ii++) { sprintf(szNode, "%d", ii + 1); if (root["lights"][szNode].empty()) continue; std::string ltype = root["lights"][szNode]["type"].asString(); if ( (ltype == "Dimmable plug-in unit") || (ltype == "Dimmable light") ) { //Normal light (with dim option) bool bIsOn = root["lights"][szNode]["state"]["on"].asBool(); int tbri = root["lights"][szNode]["state"]["bri"].asInt(); int BrightnessLevel = int((100.0f / 255.0f)*float(tbri)); _tHueLight tlight; if (bIsOn) { tlight.cmd = (BrightnessLevel != 0) ? light2_sSetLevel: light2_sOn; } else tlight.cmd = light2_sOff; tlight.level = BrightnessLevel; tlight.sat = 0; tlight.hue = 0; bool bDoSend = true; if (m_lights.find(ii + 1) != m_lights.end()) { _tHueLight alight = m_lights[ii + 1]; if ( (alight.cmd == tlight.cmd) && (alight.level == tlight.level) ) { bDoSend = false; } } m_lights[ii + 1] = tlight; if (bDoSend) InsertUpdateSwitch(ii + 1, HLTYPE_DIM, bIsOn, BrightnessLevel, 0, 0, root["lights"][szNode]["name"].asString()); } else if ( (ltype == "Extended color light") || (ltype == "Color light") ) { //RGBW type bool bIsOn = root["lights"][szNode]["state"]["on"].asBool(); int tbri = root["lights"][szNode]["state"]["bri"].asInt(); int tsat = root["lights"][szNode]["state"]["sat"].asInt(); int thue = root["lights"][szNode]["state"]["hue"].asInt(); int BrightnessLevel = int((100.0f / 255.0f)*float(tbri)); _tHueLight tlight; if (bIsOn) { tlight.cmd = (BrightnessLevel != 0) ? Limitless_SetBrightnessLevel : Limitless_LedOn; } else tlight.cmd = Limitless_LedOff; tlight.level = BrightnessLevel; tlight.sat = tsat; tlight.hue = thue; bool bDoSend = true; if (m_lights.find(ii + 1) != m_lights.end()) { _tHueLight alight = m_lights[ii + 1]; if ( (alight.cmd == tlight.cmd) && (alight.level == tlight.level)&& (alight.sat == tlight.sat)&& (alight.hue == tlight.hue) ) { bDoSend = false; } } m_lights[ii + 1] = tlight; if (bDoSend) InsertUpdateSwitch(ii + 1, HLTYPE_RGBW, bIsOn, BrightnessLevel, tsat, thue, root["lights"][szNode]["name"].asString()); } } return true; }