|
| 1 | +#include "Bridge.h" |
| 2 | +#include "HueDeviceTypes.h" |
| 3 | + |
| 4 | +#ifdef _WIN32 |
| 5 | +#include "WinHttpHandler.h" |
| 6 | +#else |
| 7 | +#include "LinHttpHandler.h" |
| 8 | +#endif |
| 9 | + |
| 10 | +#include "Detector.h" |
| 11 | +#include "LogManager.h" |
| 12 | +#include "PhilipsHueController.h" |
| 13 | +#include "PhilipsHueEntertainmentController.h" |
| 14 | +#include "RGBController_PhilipsHue.h" |
| 15 | +#include "RGBController_PhilipsHueEntertainment.h" |
| 16 | +#include "SettingsManager.h" |
| 17 | + |
| 18 | +/******************************************************************************************\ |
| 19 | +* * |
| 20 | +* DetectPhilipsHueControllers * |
| 21 | +* * |
| 22 | +* Detect Philips Hue lighting devices with RGB control * |
| 23 | +* * |
| 24 | +\******************************************************************************************/ |
| 25 | + |
| 26 | +void DetectPhilipsHueControllers(std::vector<RGBController*>& rgb_controllers) |
| 27 | +{ |
| 28 | + json hue_settings; |
| 29 | + |
| 30 | + /*-------------------------------------------------*\ |
| 31 | + | Create an HTTP handler | |
| 32 | + \*-------------------------------------------------*/ |
| 33 | +#ifdef _WIN32 |
| 34 | + using SystemHttpHandler = hueplusplus::WinHttpHandler; |
| 35 | +#else |
| 36 | + using SystemHttpHandler = hueplusplus::LinHttpHandler; |
| 37 | +#endif |
| 38 | + |
| 39 | + /*-------------------------------------------------*\ |
| 40 | + | Get Philips Hue settings from settings manager | |
| 41 | + \*-------------------------------------------------*/ |
| 42 | + hue_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("PhilipsHueDevices"); |
| 43 | + |
| 44 | + /*-------------------------------------------------*\ |
| 45 | + | Create a finder and find bridges | |
| 46 | + \*-------------------------------------------------*/ |
| 47 | + static hueplusplus::BridgeFinder finder(std::make_shared<SystemHttpHandler>()); |
| 48 | + std::vector<hueplusplus::BridgeFinder::BridgeIdentification> bridges;// = finder.findBridges(); |
| 49 | + |
| 50 | + /*-------------------------------------------------*\ |
| 51 | + | If no bridges were detected, manually add bridge | |
| 52 | + | IP and MAC (need to get these from file) | |
| 53 | + \*-------------------------------------------------*/ |
| 54 | + if(bridges.empty()) |
| 55 | + { |
| 56 | + if(hue_settings.contains("bridges")) |
| 57 | + { |
| 58 | + hueplusplus::BridgeFinder::BridgeIdentification ident; |
| 59 | + |
| 60 | + if(hue_settings["bridges"][0].contains("ip")) |
| 61 | + { |
| 62 | + ident.ip = hue_settings["bridges"][0]["ip"]; |
| 63 | + } |
| 64 | + |
| 65 | + if(hue_settings["bridges"][0].contains("mac")) |
| 66 | + { |
| 67 | + ident.mac = hue_settings["bridges"][0]["mac"]; |
| 68 | + } |
| 69 | + |
| 70 | + bridges.push_back(ident); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + /*-------------------------------------------------*\ |
| 75 | + | If no bridges were found, return, otherwise | |
| 76 | + | connect to the first bridge | |
| 77 | + \*-------------------------------------------------*/ |
| 78 | + if(bridges.empty()) |
| 79 | + { |
| 80 | + return; |
| 81 | + } |
| 82 | + else |
| 83 | + { |
| 84 | + /*-------------------------------------------------*\ |
| 85 | + | Check if a saved username exists | |
| 86 | + \*-------------------------------------------------*/ |
| 87 | + if(hue_settings.contains("bridges")) |
| 88 | + { |
| 89 | + /*-------------------------------------------------*\ |
| 90 | + | Add the username if it exists | |
| 91 | + \*-------------------------------------------------*/ |
| 92 | + if(hue_settings["bridges"][0].contains("username")) |
| 93 | + { |
| 94 | + finder.addUsername(bridges[0].mac, hue_settings["bridges"][0]["username"]); |
| 95 | + } |
| 96 | + |
| 97 | + /*-------------------------------------------------*\ |
| 98 | + | Add the client key if it exists | |
| 99 | + \*-------------------------------------------------*/ |
| 100 | + if(hue_settings["bridges"][0].contains("clientkey")) |
| 101 | + { |
| 102 | + finder.addClientKey(bridges[0].mac, hue_settings["bridges"][0]["clientkey"]); |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + /*-------------------------------------------------*\ |
| 107 | + | If username was added, this should connect right | |
| 108 | + | away. If not, the user will have to push the | |
| 109 | + | connect button on the bridge. | |
| 110 | + \*-------------------------------------------------*/ |
| 111 | + try |
| 112 | + { |
| 113 | + static hueplusplus::Bridge bridge = finder.getBridge(bridges[0]); |
| 114 | + |
| 115 | + bridge.refresh(); |
| 116 | + |
| 117 | + /*-------------------------------------------------*\ |
| 118 | + | Check to see if we need to save the settings | |
| 119 | + | Settings need to be saved if either username or | |
| 120 | + | client key either do not exist or have changed | |
| 121 | + \*-------------------------------------------------*/ |
| 122 | + bool save_settings = false; |
| 123 | + bool use_entertainment = false; |
| 124 | + |
| 125 | + if(hue_settings.contains("bridges")) |
| 126 | + { |
| 127 | + if(hue_settings["bridges"][0].contains("username")) |
| 128 | + { |
| 129 | + if(hue_settings["bridges"][0]["username"] != bridge.getUsername()) |
| 130 | + { |
| 131 | + save_settings = true; |
| 132 | + } |
| 133 | + } |
| 134 | + else |
| 135 | + { |
| 136 | + save_settings = true; |
| 137 | + } |
| 138 | + |
| 139 | + if(hue_settings["bridges"][0].contains("clientkey")) |
| 140 | + { |
| 141 | + if(hue_settings["bridges"][0]["clientkey"] != bridge.getClientKey()) |
| 142 | + { |
| 143 | + use_entertainment = true; |
| 144 | + save_settings = true; |
| 145 | + } |
| 146 | + } |
| 147 | + else |
| 148 | + { |
| 149 | + save_settings = true; |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + /*-------------------------------------------------*\ |
| 154 | + | Save the settings if needed | |
| 155 | + \*-------------------------------------------------*/ |
| 156 | + if(save_settings) |
| 157 | + { |
| 158 | + hue_settings["bridges"][0]["username"] = bridge.getUsername(); |
| 159 | + hue_settings["bridges"][0]["clientkey"] = bridge.getClientKey(); |
| 160 | + hue_settings["bridges"][0]["entertainment"] = use_entertainment; |
| 161 | + |
| 162 | + ResourceManager::get()->GetSettingsManager()->SetSettings("PhilipsHueDevices", hue_settings); |
| 163 | + |
| 164 | + ResourceManager::get()->GetSettingsManager()->SaveSettings(); |
| 165 | + } |
| 166 | + |
| 167 | + /*-------------------------------------------------*\ |
| 168 | + | Get all groups from the bridge | |
| 169 | + \*-------------------------------------------------*/ |
| 170 | + if(hue_settings["bridges"][0].contains("entertainment")) |
| 171 | + { |
| 172 | + use_entertainment = hue_settings["bridges"][0]["entertainment"]; |
| 173 | + } |
| 174 | + |
| 175 | + /*-------------------------------------------------*\ |
| 176 | + | Get all groups from the bridge | |
| 177 | + \*-------------------------------------------------*/ |
| 178 | + if(use_entertainment) |
| 179 | + { |
| 180 | + std::vector<hueplusplus::Group> groups = bridge.groups().getAll(); |
| 181 | + |
| 182 | + if(groups.size() > 0) |
| 183 | + { |
| 184 | + /*-------------------------------------------------*\ |
| 185 | + | Loop through all available groups and check to | |
| 186 | + | see if any are Entertainment groups | |
| 187 | + \*-------------------------------------------------*/ |
| 188 | + for(unsigned int group_idx = 0; group_idx < groups.size(); group_idx++) |
| 189 | + { |
| 190 | + if(groups[group_idx].getType() == "Entertainment") |
| 191 | + { |
| 192 | + PhilipsHueEntertainmentController* new_controller = new PhilipsHueEntertainmentController(bridge, groups[group_idx]); |
| 193 | + RGBController_PhilipsHueEntertainment* new_rgbcontroller = new RGBController_PhilipsHueEntertainment(new_controller); |
| 194 | + rgb_controllers.push_back(new_rgbcontroller); |
| 195 | + } |
| 196 | + } |
| 197 | + } |
| 198 | + } |
| 199 | + |
| 200 | + /*-------------------------------------------------*\ |
| 201 | + | Get all lights from the bridge | |
| 202 | + \*-------------------------------------------------*/ |
| 203 | + else |
| 204 | + { |
| 205 | + std::vector<hueplusplus::Light> lights = bridge.lights().getAll(); |
| 206 | + |
| 207 | + if(lights.size() > 0) |
| 208 | + { |
| 209 | + /*-------------------------------------------------*\ |
| 210 | + | Loop through all available lights and add those | |
| 211 | + | that have color (RGB) control capability | |
| 212 | + \*-------------------------------------------------*/ |
| 213 | + for(unsigned int light_idx = 0; light_idx < lights.size(); light_idx++) |
| 214 | + { |
| 215 | + if(lights[light_idx].hasColorControl()) |
| 216 | + { |
| 217 | + PhilipsHueController* new_controller = new PhilipsHueController(lights[light_idx], bridge.getBridgeIP()); |
| 218 | + RGBController_PhilipsHue* new_rgbcontroller = new RGBController_PhilipsHue(new_controller); |
| 219 | + rgb_controllers.push_back(new_rgbcontroller); |
| 220 | + } |
| 221 | + } |
| 222 | + } |
| 223 | + } |
| 224 | + } |
| 225 | + catch(std::exception &e) |
| 226 | + { |
| 227 | + LOG_NOTICE("Exception occurred in Philips Hue detection"); |
| 228 | + } |
| 229 | + } |
| 230 | +} /* DetectPhilipsHueControllers() */ |
| 231 | + |
| 232 | +REGISTER_DETECTOR("Philips Hue", DetectPhilipsHueControllers); |
0 commit comments