@@ -159,30 +159,77 @@ void NanoleafController::UpdateLEDs(std::vector<RGBColor>& colors)
159159
160160 if (model == NANOLEAF_LIGHT_PANELS_MODEL)
161161 {
162+ /* ---------------------------------------------------------*\
163+ | Protocol V1 - https://forum.nanoleaf.me/docs |
164+ | |
165+ | Size Description |
166+ | --------------------------------------------------------- |
167+ | 1 nPanels Number of panels |
168+ | |
169+ | 1 panelId ID of panel |
170+ | 1 nFrames Number of frames (always 1) |
171+ | 1 R Red channel |
172+ | 1 G Green channel |
173+ | 1 B Blue channel |
174+ | 1 W White channel (ignored) |
175+ | 1 transitionTime Transition time (x 100ms) |
176+ \*---------------------------------------------------------*/
162177 uint8_t size = panel_ids.size ();
163178
164- uint8_t * message = (uint8_t *)malloc (size* 7 + 6 + 1 );
179+ uint8_t * message = (uint8_t *)malloc (( size * 7 ) + 1 );
165180
166- message[0 ] = (uint8_t )size;
181+ message[0 ] = (uint8_t )size; /* nPanels */
167182
168183 for (int i = 0 ; i < size; i++)
169184 {
170- message[( 7 * i) + 0 + 1 ] = (uint8_t )panel_ids[i];
171- message[( 7 * i) + 1 + 1 ] = (uint8_t )1 ;
172- message[( 7 * i) + 2 + 1 ] = (uint8_t )RGBGetRValue (colors[i]);
173- message[( 7 * i) + 3 + 1 ] = (uint8_t )RGBGetGValue (colors[i]);
174- message[( 7 * i) + 4 + 1 ] = (uint8_t )RGBGetBValue (colors[i]);
175- message[( 7 * i) + 5 + 1 ] = (uint8_t )0 ;
176- message[( 7 * i) + 6 + 1 ] = (uint8_t )0 ;
185+ message[(7 * i) + 0 + 1 ] = (uint8_t )panel_ids[i]; /* panelId */
186+ message[(7 * i) + 1 + 1 ] = (uint8_t )1 ; /* nFrames */
187+ message[(7 * i) + 2 + 1 ] = (uint8_t )RGBGetRValue (colors[i]); /* R */
188+ message[(7 * i) + 3 + 1 ] = (uint8_t )RGBGetGValue (colors[i]); /* G */
189+ message[(7 * i) + 4 + 1 ] = (uint8_t )RGBGetBValue (colors[i]); /* B */
190+ message[(7 * i) + 5 + 1 ] = (uint8_t )0 ; /* W */
191+ message[(7 * i) + 6 + 1 ] = (uint8_t )0 ; /* transitionTime */
177192 }
178193
179- external_control_socket.udp_write (reinterpret_cast < char *>(message), size* 7 + 6 + 1 );
194+ external_control_socket.udp_write (( char *)message, ( size * 7 ) + 1 );
180195 }
181- else if (model == NANOLEAF_CANVAS_MODEL)
196+ else if ((model == NANOLEAF_CANVAS_MODEL)
197+ || (model == NANOLEAF_SHAPES_MODEL))
182198 {
183199 /* ---------------------------------------------------------*\
184- | Insert V2 protocol implementation here. |
200+ | Protocol V2 - https://forum.nanoleaf.me/docs |
201+ | |
202+ | Size Description |
203+ | --------------------------------------------------------- |
204+ | 2 nPanels Number of panels |
205+ | |
206+ | 2 panelId ID of panel |
207+ | 1 R Red channel |
208+ | 1 G Green channel |
209+ | 1 B Blue channel |
210+ | 1 W White channel (ignored) |
211+ | 2 transitionTime Transition time (x 100ms) |
185212 \*---------------------------------------------------------*/
213+ uint8_t size = panel_ids.size ();
214+
215+ uint8_t * message = (uint8_t *)malloc ((size * 8 ) + 2 );
216+
217+ message[0 ] = (uint8_t )(size >> 8 ); /* nPanels H */
218+ message[1 ] = (uint8_t )(size & 0xFF ); /* nPanels L */
219+
220+ for (int i = 0 ; i < size; i++)
221+ {
222+ message[(8 * i) + 0 + 2 ] = (uint8_t )(panel_ids[i] >> 8 ); /* panelId H */
223+ message[(8 * i) + 1 + 2 ] = (uint8_t )(panel_ids[i] & 0xFF ); /* panelId L */
224+ message[(8 * i) + 2 + 2 ] = (uint8_t )RGBGetRValue (colors[i]); /* R */
225+ message[(8 * i) + 3 + 2 ] = (uint8_t )RGBGetGValue (colors[i]); /* G */
226+ message[(8 * i) + 4 + 2 ] = (uint8_t )RGBGetBValue (colors[i]); /* B */
227+ message[(8 * i) + 5 + 2 ] = (uint8_t )0 ; /* W */
228+ message[(8 * i) + 6 + 2 ] = (uint8_t )0 ; /* transitionTime H */
229+ message[(8 * i) + 7 + 2 ] = (uint8_t )0 ; /* transitionTime L */
230+ }
231+
232+ external_control_socket.udp_write ((char *)message, (size * 8 ) + 2 );
186233 }
187234}
188235
@@ -192,21 +239,40 @@ void NanoleafController::StartExternalControl()
192239 request[" write" ][" command" ] = " display" ;
193240 request[" write" ][" animType" ] = " extControl" ;
194241
242+ /* -------------------------------------------------------------*\
243+ | Determine whether to use v1 or v2 extControl protocol based |
244+ | on model string |
245+ \*-------------------------------------------------------------*/
195246 if (model == NANOLEAF_LIGHT_PANELS_MODEL)
196247 {
248+ /* ---------------------------------------------------------*\
249+ | Protocol v1 returns IP and port for UDP communication |
250+ \*---------------------------------------------------------*/
197251 request[" write" ][" extControlVersion" ] = " v1" ;
252+
253+ json response;
254+ if ((APIRequest (" PUT" , location, " /api/v1/" +auth_token+" /effects" , &request, &response) / 100 ) == 2 )
255+ {
256+ external_control_socket.udp_client (response[" streamControlIpAddr" ].get <std::string>().c_str (), std::to_string (response[" streamControlPort" ].get <int >()).c_str ());
257+
258+ selectedEffect = NANOLEAF_DIRECT_MODE_EFFECT_NAME;
259+ }
198260 }
199- else if (model == NANOLEAF_CANVAS_MODEL)
261+ else if ((model == NANOLEAF_CANVAS_MODEL)
262+ || (model == NANOLEAF_SHAPES_MODEL))
200263 {
264+ /* ---------------------------------------------------------*\
265+ | Protocol v2 does not return anything, use device IP and |
266+ | port 60222 |
267+ \*---------------------------------------------------------*/
201268 request[" write" ][" extControlVersion" ] = " v2" ;
202- }
203269
204- json response;
205- if ((APIRequest (" PUT" , location, " /api/v1/" +auth_token+" /effects" , &request, &response) / 100 ) == 2 )
206- {
207- external_control_socket.udp_client (response[" streamControlIpAddr" ].get <std::string>().c_str (), std::to_string (response[" streamControlPort" ].get <int >()).c_str ());
270+ if ((APIRequest (" PUT" , location, " /api/v1/" +auth_token+" /effects" , &request) / 100 ) == 2 )
271+ {
272+ external_control_socket.udp_client (address.c_str (), " 60222" );
208273
209- selectedEffect = NANOLEAF_DIRECT_MODE_EFFECT_NAME;
274+ selectedEffect = NANOLEAF_DIRECT_MODE_EFFECT_NAME;
275+ }
210276 }
211277}
212278
@@ -280,4 +346,4 @@ std::string NanoleafController::GetSelectedEffect()
280346int NanoleafController::GetBrightness ()
281347{
282348 return brightness;
283- };
349+ };
0 commit comments