diff --git a/Controllers/NanoleafController/NanoleafController.cpp b/Controllers/NanoleafController/NanoleafController.cpp index 86a810a2..b14bd755 100644 --- a/Controllers/NanoleafController/NanoleafController.cpp +++ b/Controllers/NanoleafController/NanoleafController.cpp @@ -23,46 +23,60 @@ long APIRequest(std::string method, std::string location, std::string URI, json* CURL* curl = curl_easy_init(); - // Set remote URL. + /*-------------------------------------------------------------*\ + | Set remote URL. | + \*-------------------------------------------------------------*/ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method.c_str()); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - // Don't bother trying IPv6, which would increase DNS resolution time. + /*-------------------------------------------------------------*\ + | Don't bother trying IPv6, which would increase DNS resolution | + | time. | + \*-------------------------------------------------------------*/ curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); - // Don't wait forever, time out after 10 seconds. + /*-------------------------------------------------------------*\ + | Don't wait forever, time out after 10 seconds. | + \*-------------------------------------------------------------*/ curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10); - // Follow HTTP redirects if necessary. + /*-------------------------------------------------------------*\ + | Follow HTTP redirects if necessary. | + \*-------------------------------------------------------------*/ curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); if(request_data) { - // LOG_DEBUG("[Nanoleaf] Sending data: %s", request_data->dump().c_str()); curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, request_data->dump().c_str()); } - // Response information. - long httpCode(0); - std::unique_ptr httpData(new std::string()); + /*-------------------------------------------------------------*\ + | Response information. | + \*-------------------------------------------------------------*/ + long httpCode(0); + std::unique_ptr httpData(new std::string()); - // Hook up data handling function. + /*-------------------------------------------------------------*\ + | Hook up data handling function. | + \*-------------------------------------------------------------*/ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); - /*---------------------------------------------------------*\ - | Hook up data container (will be passed as the last | - | parameter to the callback handling function). Can be any | - | pointer type, since it will internally be passed as a | - | void pointer. | - \*---------------------------------------------------------*/ + /*-------------------------------------------------------------*\ + | Hook up data container (will be passed as the last parameter | + | to the callback handling function). Can be any pointer type, | + | since it will internally be passed as a void pointer. | + \*-------------------------------------------------------------*/ curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get()); - // Run our HTTP GET command, capture the HTTP response code, and clean up. + /*-------------------------------------------------------------*\ + | Run our HTTP GET command, capture the HTTP response code, and | + | clean up. | + \*-------------------------------------------------------------*/ curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); curl_easy_cleanup(curl); - if (httpCode/100 == 2) + if((httpCode / 100) == 2) { if(response_data) { @@ -79,22 +93,22 @@ long APIRequest(std::string method, std::string location, std::string URI, json* NanoleafController::NanoleafController(std::string a_address, int a_port, std::string a_auth_token) { - address = a_address; - port = a_port; - auth_token = a_auth_token; - location = address+":"+std::to_string(port); + address = a_address; + port = a_port; + auth_token = a_auth_token; + location = address + ":" + std::to_string(port); json data; if(APIRequest("GET", location, "/api/v1/"+auth_token, nullptr, &data) == 200) { - name = data["name"]; - serial = data["serialNo"]; - manufacturer = data["manufacturer"]; - firmware_version = data["firmwareVersion"]; - model = data["model"]; + name = data["name"]; + serial = data["serialNo"]; + manufacturer = data["manufacturer"]; + firmware_version = data["firmwareVersion"]; + model = data["model"]; - brightness = data["state"]["brightness"]["value"]; - selectedEffect = data["effects"]["select"]; + brightness = data["state"]["brightness"]["value"]; + selectedEffect = data["effects"]["select"]; for(json::const_iterator it = data["effects"]["effectsList"].begin(); it != data["effects"]["effectsList"].end(); ++it) { @@ -131,46 +145,52 @@ void NanoleafController::Unpair(std::string address, int port, std::string auth_ { const std::string location = address+":"+std::to_string(port); - // We really don't care if this fails. + /*-------------------------------------------------------------*\ + | We really don't care if this fails. | + \*-------------------------------------------------------------*/ APIRequest("DELETE", location, "/api/v1/"+auth_token, nullptr, nullptr); } void NanoleafController::UpdateLEDs(std::vector& colors) { - // Requires StartExternalControl() to have been called prior. + /*-------------------------------------------------------------*\ + | Requires StartExternalControl() to have been called prior. | + \*-------------------------------------------------------------*/ if(model == NANOLEAF_LIGHT_PANELS_MODEL) { - uint8_t size = panel_ids.size(); + uint8_t size = panel_ids.size(); - uint8_t* message = (uint8_t*)malloc(size*7+6+1); + uint8_t* message = (uint8_t*)malloc(size*7+6+1); - message[0] = (uint8_t)size; + message[0] = (uint8_t)size; - for (int i = 0; i < size; i++) + for(int i = 0; i < size; i++) { - message[7*i+0+1] = (uint8_t)panel_ids[i]; - message[7*i+1+1] = (uint8_t)1; - message[7*i+2+1] = (uint8_t)RGBGetRValue(colors[i]); - message[7*i+3+1] = (uint8_t)RGBGetGValue(colors[i]); - message[7*i+4+1] = (uint8_t)RGBGetBValue(colors[i]); - message[7*i+5+1] = (uint8_t)0; - message[7*i+6+1] = (uint8_t)0; + message[( 7 * i) + 0 + 1] = (uint8_t)panel_ids[i]; + message[( 7 * i) + 1 + 1] = (uint8_t)1; + message[( 7 * i) + 2 + 1] = (uint8_t)RGBGetRValue(colors[i]); + message[( 7 * i) + 3 + 1] = (uint8_t)RGBGetGValue(colors[i]); + message[( 7 * i) + 4 + 1] = (uint8_t)RGBGetBValue(colors[i]); + message[( 7 * i) + 5 + 1] = (uint8_t)0; + message[( 7 * i) + 6 + 1] = (uint8_t)0; } external_control_socket.udp_write(reinterpret_cast(message), size*7+6+1); } else if(model == NANOLEAF_CANVAS_MODEL) { - // Insert V2 protocol implementation here. + /*---------------------------------------------------------*\ + | Insert V2 protocol implementation here. | + \*---------------------------------------------------------*/ } } void NanoleafController::StartExternalControl() { json request; - request["write"]["command"] = "display"; - request["write"]["animType"] = "extControl"; + request["write"]["command"] = "display"; + request["write"]["animType"] = "extControl"; if(model == NANOLEAF_LIGHT_PANELS_MODEL) { @@ -182,7 +202,7 @@ void NanoleafController::StartExternalControl() } json response; - if(APIRequest("PUT", location, "/api/v1/"+auth_token+"/effects", &request, &response)/100 == 2) + if((APIRequest("PUT", location, "/api/v1/"+auth_token+"/effects", &request, &response) / 100) == 2) { external_control_socket.udp_client(response["streamControlIpAddr"].get().c_str(), std::to_string(response["streamControlPort"].get()).c_str()); @@ -194,7 +214,8 @@ void NanoleafController::SelectEffect(std::string effect_name) { json request; request["select"] = effect_name; - if(APIRequest("PUT", location, "/api/v1/"+auth_token+"/effects", &request)/100 == 2) + + if((APIRequest("PUT", location, "/api/v1/"+auth_token+"/effects", &request) / 100) == 2) { selectedEffect = effect_name; } @@ -204,8 +225,59 @@ void NanoleafController::SetBrightness(int a_brightness) { json request; request["brightness"]["value"] = a_brightness; - if(APIRequest("PUT", location, "/api/v1/"+auth_token+"/state", &request)/100 == 2) + + if((APIRequest("PUT", location, "/api/v1/"+auth_token+"/state", &request) / 100) == 2) { brightness = a_brightness; } } + +std::string NanoleafController::GetAuthToken() +{ + return auth_token; +}; + +std::string NanoleafController::GetName() +{ + return name; +}; + +std::string NanoleafController::GetSerial() +{ + return serial; +}; + +std::string NanoleafController::GetManufacturer() +{ + return manufacturer; +}; + +std::string NanoleafController::GetFirmwareVersion() +{ + return firmware_version; +}; + +std::string NanoleafController::GetModel() +{ + return model; +}; + +std::vector& NanoleafController::GetEffects() +{ + return effects; +}; + +std::vector& NanoleafController::GetPanelIds() +{ + return panel_ids; +}; + +std::string NanoleafController::GetSelectedEffect() +{ + return selectedEffect; +}; + +int NanoleafController::GetBrightness() +{ + return brightness; +}; \ No newline at end of file diff --git a/Controllers/NanoleafController/NanoleafController.h b/Controllers/NanoleafController/NanoleafController.h index 37bcaabc..35f6372c 100644 --- a/Controllers/NanoleafController/NanoleafController.h +++ b/Controllers/NanoleafController/NanoleafController.h @@ -7,56 +7,55 @@ \*-----------------------------------------*/ #pragma once + #include "RGBController.h" #include "net_port.h" -#define NANOLEAF_DIRECT_MODE_EFFECT_NAME "*Dynamic*" - -#define NANOLEAF_LIGHT_PANELS_MODEL "NL22" -#define NANOLEAF_CANVAS_MODEL "NL29" +#define NANOLEAF_DIRECT_MODE_EFFECT_NAME "*Dynamic*" +#define NANOLEAF_LIGHT_PANELS_MODEL "NL22" +#define NANOLEAF_CANVAS_MODEL "NL29" class NanoleafController { public: - static std::string Pair(std::string address, int port); - static void Unpair(std::string address, int port, std::string auth_token); - NanoleafController(std::string a_address, int a_port, std::string a_auth_token); - void SelectEffect(std::string effect_name); - void StartExternalControl(); - void SetBrightness(int a_brightness); - // Requires External Control to have been started. - void UpdateLEDs(std::vector& colors); + static std::string Pair(std::string address, int port); + static void Unpair(std::string address, int port, std::string auth_token); - std::string GetAuthToken() { return auth_token; }; - std::string GetName() { return name; }; - std::string GetSerial() { return serial; }; - std::string GetManufacturer() { return manufacturer; }; - std::string GetFirmwareVersion() { return firmware_version; }; - std::string GetModel() { return model; }; - std::vector& GetEffects() { return effects; }; - std::vector& GetPanelIds() { return panel_ids; }; - std::string GetSelectedEffect() { return selectedEffect; }; - int GetBrightness() { return brightness; }; + void SelectEffect(std::string effect_name); + void StartExternalControl(); + void SetBrightness(int a_brightness); + void UpdateLEDs(std::vector& colors); + + std::string GetAuthToken(); + std::string GetName(); + std::string GetSerial(); + std::string GetManufacturer(); + std::string GetFirmwareVersion(); + std::string GetModel(); + std::vector& GetEffects(); + std::vector& GetPanelIds(); + std::string GetSelectedEffect(); + int GetBrightness(); private: - net_port external_control_socket; + net_port external_control_socket; - std::string address; - int port; - std::string location; - std::string auth_token; + std::string address; + int port; + std::string location; + std::string auth_token; - std::string name; - std::string serial; - std::string manufacturer; - std::string firmware_version; - std::string model; + std::string name; + std::string serial; + std::string manufacturer; + std::string firmware_version; + std::string model; - std::vector effects; - std::vector panel_ids; + std::vector effects; + std::vector panel_ids; - std::string selectedEffect; - int brightness; + std::string selectedEffect; + int brightness; }; diff --git a/Controllers/NanoleafController/RGBController_Nanoleaf.cpp b/Controllers/NanoleafController/RGBController_Nanoleaf.cpp index 2bf8b1a5..1e16ce03 100644 --- a/Controllers/NanoleafController/RGBController_Nanoleaf.cpp +++ b/Controllers/NanoleafController/RGBController_Nanoleaf.cpp @@ -14,18 +14,20 @@ using json = nlohmann::json; RGBController_Nanoleaf::RGBController_Nanoleaf(std::string a_address, int a_port, std::string a_auth_token) : - nanoleaf(a_address, a_port, a_auth_token) + controller(a_address, a_port, a_auth_token) { - location = a_address+":"+std::to_string(a_port); - name = nanoleaf.GetName(); - serial = nanoleaf.GetSerial(); - vendor = nanoleaf.GetManufacturer(); - version = nanoleaf.GetFirmwareVersion(); - description = nanoleaf.GetModel(); - type = DEVICE_TYPE_LIGHT; + location = a_address+":"+std::to_string(a_port); + name = controller.GetName(); + serial = controller.GetSerial(); + vendor = controller.GetManufacturer(); + version = controller.GetFirmwareVersion(); + description = controller.GetModel(); + type = DEVICE_TYPE_LIGHT; - // Direct mode currently only supported for Nanoleaf Panels. - if(nanoleaf.GetModel() == NANOLEAF_LIGHT_PANELS_MODEL) + /*-------------------------------------------------------------*\ + | Direct mode currently only supported for Nanoleaf Panels. | + \*-------------------------------------------------------------*/ + if(controller.GetModel() == NANOLEAF_LIGHT_PANELS_MODEL) { mode Direct; Direct.name = "Direct"; @@ -33,31 +35,41 @@ RGBController_Nanoleaf::RGBController_Nanoleaf(std::string a_address, int a_port Direct.color_mode = MODE_COLORS_PER_LED; modes.push_back(Direct); - // Set this effect as current if the name is selected. - if(nanoleaf.GetSelectedEffect() == NANOLEAF_DIRECT_MODE_EFFECT_NAME) + /*---------------------------------------------------------*\ + | Set this effect as current if the name is selected. | + \*---------------------------------------------------------*/ + if(controller.GetSelectedEffect() == NANOLEAF_DIRECT_MODE_EFFECT_NAME) { - // If the direct mode is active, we need to call this method to open the socket. - nanoleaf.StartExternalControl(); + /*-----------------------------------------------------*\ + | If the direct mode is active, we need to call this | + | method to open the socket. | + \*-----------------------------------------------------*/ + controller.StartExternalControl(); active_mode = 0; } } - for(std::vector::const_iterator it = nanoleaf.GetEffects().begin(); it != nanoleaf.GetEffects().end(); ++it) + /*-------------------------------------------------------------*\ + | Create additional modes from device effects list | + \*-------------------------------------------------------------*/ + for(std::vector::const_iterator it = controller.GetEffects().begin(); it != controller.GetEffects().end(); ++it) { mode effect; - effect.name = *it; - effect.flags = MODE_FLAG_HAS_BRIGHTNESS; - effect.color_mode = MODE_COLORS_NONE; - effect.brightness_max = 100; - effect.brightness_min = 0; - effect.brightness = 100; + effect.name = *it; + effect.flags = MODE_FLAG_HAS_BRIGHTNESS; + effect.color_mode = MODE_COLORS_NONE; + effect.brightness_max = 100; + effect.brightness_min = 0; + effect.brightness = 100; modes.push_back(effect); - // Set this effect as current if the name is selected. - if(nanoleaf.GetSelectedEffect() == effect.name) + /*---------------------------------------------------------*\ + | Set this effect as current if the name is selected. | + \*---------------------------------------------------------*/ + if(controller.GetSelectedEffect() == effect.name) { - active_mode = modes.size() - 1; + active_mode = modes.size() - 1; } } @@ -69,12 +81,12 @@ void RGBController_Nanoleaf::SetupZones() zone led_zone; led_zone.name = "Nanoleaf Layout"; led_zone.type = ZONE_TYPE_LINEAR; - led_zone.leds_count = nanoleaf.GetPanelIds().size(); + led_zone.leds_count = controller.GetPanelIds().size(); led_zone.leds_min = led_zone.leds_count; led_zone.leds_max = led_zone.leds_count; led_zone.matrix_map = NULL; - for(std::vector::const_iterator it = nanoleaf.GetPanelIds().begin(); it != nanoleaf.GetPanelIds().end(); ++it) + for(std::vector::const_iterator it = controller.GetPanelIds().begin(); it != controller.GetPanelIds().end(); ++it) { led new_led; new_led.name = std::to_string(*it); @@ -95,9 +107,9 @@ void RGBController_Nanoleaf::ResizeZone(int /*zone*/, int /*new_size*/) void RGBController_Nanoleaf::DeviceUpdateLEDs() { - if(nanoleaf.GetModel() == NANOLEAF_LIGHT_PANELS_MODEL) + if(controller.GetModel() == NANOLEAF_LIGHT_PANELS_MODEL) { - nanoleaf.UpdateLEDs(colors); + controller.UpdateLEDs(colors); } } @@ -113,27 +125,24 @@ void RGBController_Nanoleaf::UpdateSingleLED(int /*led*/) void RGBController_Nanoleaf::SetCustomMode() { - if(nanoleaf.GetModel() == NANOLEAF_LIGHT_PANELS_MODEL) - { - // Put the Nanoleaf into direct mode. - nanoleaf.StartExternalControl(); - } + active_mode = 0; } void RGBController_Nanoleaf::DeviceUpdateMode() { - // 0 mode is reserved for Direct mode - if(active_mode == 0 && nanoleaf.GetModel() == NANOLEAF_LIGHT_PANELS_MODEL) + /*---------------------------------------------------------*\ + | Mode 0 is reserved for Direct mode | + \*---------------------------------------------------------*/ + if(active_mode == 0 && controller.GetModel() == NANOLEAF_LIGHT_PANELS_MODEL) { - nanoleaf.StartExternalControl(); + controller.StartExternalControl(); } - // Update normal effects. + /*---------------------------------------------------------*\ + | Update normal effects. | + \*---------------------------------------------------------*/ else { - // Select effect. - nanoleaf.SelectEffect(modes[active_mode].name); - - // Update brightness. - nanoleaf.SetBrightness(modes[active_mode].brightness); + controller.SelectEffect(modes[active_mode].name); + controller.SetBrightness(modes[active_mode].brightness); } } diff --git a/Controllers/NanoleafController/RGBController_Nanoleaf.h b/Controllers/NanoleafController/RGBController_Nanoleaf.h index 368898fe..11e4f236 100644 --- a/Controllers/NanoleafController/RGBController_Nanoleaf.h +++ b/Controllers/NanoleafController/RGBController_Nanoleaf.h @@ -28,5 +28,5 @@ public: void DeviceUpdateMode(); private: - NanoleafController nanoleaf; + NanoleafController controller; };