changeset 536:014b6d036d9a

last minute patches
author Louis Opter <kalessin@kalessin.fr>
date Sat, 04 Feb 2017 00:09:54 +0100
parents 94a103071afe
children 13ca3b5e1563
files dont_check_that_lightsd_is_running.patch fix_display_bulb_id_label_display.patch series update_changelog.patch update_jsmn.patch update_lightsc_example.patch
diffstat 6 files changed, 352 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dont_check_that_lightsd_is_running.patch	Sat Feb 04 00:09:54 2017 +0100
@@ -0,0 +1,17 @@
+# HG changeset patch
+# Parent  e34e830efd2159da8bb0436e79c2ed5d7872db62
+Don't check that lightsd is running in the demo script
+
+I'll try to have it running on the WiFi access point directly.
+
+diff --git a/slides/fosdem_2017/monolight-demo.sh b/slides/fosdem_2017/monolight-demo.sh
+--- a/slides/fosdem_2017/monolight-demo.sh
++++ b/slides/fosdem_2017/monolight-demo.sh
+@@ -17,7 +17,6 @@
+ check_venv monolight
+ 
+ check_process serialoscd
+-check_process lightsd
+ 
+ cat <<EOF
+ ### monolight demo ###
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fix_display_bulb_id_label_display.patch	Sat Feb 04 00:09:54 2017 +0100
@@ -0,0 +1,71 @@
+# HG changeset patch
+# Parent  1ccc537e56b330c85712a64764593c84d83d938a
+Display a valid target as the label when a bulb has no label
+
+When a bulb has no label lightsd displays its id (MAC address) instead.
+This changeset keeps this behavior but removes the ":" from the MAC
+address so it's a valid target. This yields to a slightly better user
+experience when on-boarding new bulbs which might not have a label.
+
+diff --git a/core/proto.c b/core/proto.c
+--- a/core/proto.c
++++ b/core/proto.c
+@@ -320,7 +320,7 @@
+         (src), (start), (stop), (dst), sizeof((dst))    \
+     )
+ 
+-        char h[16], s[16], b[16];
++        char h[16], s[16], b[16], bulb_id[16];
+         PRINT_COMPONENT(bulb->state.hue, h, 0, 360);
+         PRINT_COMPONENT(bulb->state.saturation, s, 0, 1);
+         PRINT_COMPONENT(bulb->state.brightness, b, 0, 1);
+@@ -331,8 +331,14 @@
+             label = bulb->state.label;
+             label_size = (int)sizeof(bulb->state.label);
+         } else {
+-            label = bulb_addr;
+-            label_size = (int)sizeof(bulb_addr);
++            label = bulb_id;
++            label_size = LGTD_ARRAY_SIZE(bulb_id);
++            snprintf(
++                bulb_id, label_size,
++                "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
++                bulb->addr[0], bulb->addr[1], bulb->addr[2],
++                bulb->addr[3], bulb->addr[4], bulb->addr[5]
++            );
+         }
+ 
+         LGTD_SNPRINTF_APPEND(
+diff --git a/tests/core/proto/test_proto_get_light_state.c b/tests/core/proto/test_proto_get_light_state.c
+--- a/tests/core/proto/test_proto_get_light_state.c
++++ b/tests/core/proto/test_proto_get_light_state.c
+@@ -156,7 +156,7 @@
+             "\"_vendor\":\"martine\","
+             "\"hsbk\":[0,0,1,4000],"
+             "\"power\":false,"
+-            "\"label\":\"05:04:03:02:01:00\","
++            "\"label\":\"050403020100\","
+             "\"tags\":[\"vapor\",\"d^-^b\"]"
+         "},{"
+             "\"_lifx\":{"
+@@ -243,7 +243,7 @@
+             "\"_vendor\":\"martine\","
+             "\"hsbk\":[0,0,1,4000],"
+             "\"power\":false,"
+-            "\"label\":\"05:04:03:02:01:00\","
++            "\"label\":\"050403020100\","
+             "\"tags\":[\"vapor\",\"d^-^b\"]"
+         "},"
+         "{"
+diff --git a/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c b/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c
+--- a/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c
++++ b/tests/core/proto/test_proto_get_light_state_unknown_tag_id.c
+@@ -112,7 +112,7 @@
+             "\"_vendor\":null,"
+             "\"hsbk\":[0,0,1,4000],"
+             "\"power\":false,"
+-            "\"label\":\"05:04:03:02:01:00\","
++            "\"label\":\"050403020100\","
+             "\"tags\":[\"vapor\",\"d^-^b\"]"
+         "},"
+         "{"
--- a/series	Fri Feb 03 00:23:11 2017 +0100
+++ b/series	Sat Feb 04 00:09:54 2017 +0100
@@ -1,3 +1,8 @@
+update_jsmn.patch
+fix_display_bulb_id_label_display.patch
+dont_check_that_lightsd_is_running.patch
+update_lightsc_example.patch
+update_changelog.patch
 add_power_transition.patch #+future
 open_gateway_on_any_bulb_response.patch #+future
 make_gateway_write_callbacks_low_priority.patch #+future
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/update_changelog.patch	Sat Feb 04 00:09:54 2017 +0100
@@ -0,0 +1,63 @@
+# HG changeset patch
+# Parent  d3fbb5e04ac58767972206ac6e4fbbbfb619bd45
+Update the changelog for 1.2.0
+
+diff --git a/docs/changelog.rst b/docs/changelog.rst
+--- a/docs/changelog.rst
++++ b/docs/changelog.rst
+@@ -11,15 +11,25 @@
+   are added in a backwards-compatible manner;
+ - PATCH version gets incremented for backwards-compatible bug fixes.
+ 
+-1.2.0 (unreleased)
++1.2.0 (2017-02-04)
+ ------------------
+ 
+-This release doesn't have any new user-facing feature but packs a bunch of fixes
+-and improvements, both in the code but also the documentation and examples.
++This release doesn't have any new user-facing feature for lightsd but packs a
++bunch of fixes and improvements, both in the code but also the documentation and
++examples.
++
++However, this release sees the start of a Python client library for lightsd
++which you'll find in the ``clients`` directory of the lightsd repository. This
++library is currently used to build another child project of lightsd: monolight,
++an user-interface for the `Monome grid`_. Both project should end up on PyPi_
++soon.
+ 
+ Also worth noting, is the full continuous integration pipeline that has been
+ setup behind the scenes. Most of the work for this release went into it. It will
+-hopefully make it a lot easier to work on the project.
++hopefully make it a lot easier to work on lightsd.
++
++.. _Monome grid: http://www.monome.org/grid/
++.. _PyPi: https://pypi.python.org/pypi
+ 
+ Fixes
+ ~~~~~
+@@ -29,7 +39,9 @@
+ - Correctly support optional arguments in the JSON-RPC API;
+ - A couple of crash/security fixes, one being in the jsmn_ JSON parser which has
+   been upgraded to its latest version;
+-- FreeBSD build (more BSD fixes to come though, see :gh:`16`).
++- FreeBSD build (more BSD fixes to come though, see :gh:`16`);
++- ``get_light_state`` now returns a valid target for the bulb's label (the bulb
++  id) when it doesn't have a label set.
+ 
+ .. _jsmn: https://github.com/zserge/jsmn
+ 
+@@ -41,10 +53,14 @@
+ - `Sylvain Laurent`_ for his original work on fixing discovery;
+ - `Xavier Deguillard`_ for his contributions; additional automated tests will be
+   setup to make crashes and security issues much harder to creep in;
++- `Guillaume Gomez`_ & `Michael Zapata`_ for their help with the landing page on
++  https://www.lightsd.io/;
+ - All the people who have been trying the project and reporting issues!
+ 
+ .. _Sylvain Laurent: https://github.com/Magicking/
+ .. _Xavier Deguillard: https://github.com/Rip-Rip
++.. _Guillaume Gomez: https://github.com/GuillaumeGomez
++.. _Michael Zapata: https://github.com/michael-zapata
+ 
+ 1.1.2 (2015-11-30)
+ ------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/update_jsmn.patch	Sat Feb 04 00:09:54 2017 +0100
@@ -0,0 +1,89 @@
+# HG changeset patch
+# Parent  f5f57598dc1dcd815946a0e37c847a784792e8f1
+Update jsmn to its latest version
+
+diff --git a/core/jsmn.c b/core/jsmn.c
+--- a/core/jsmn.c
++++ b/core/jsmn.c
+@@ -1,24 +1,6 @@
+-/*
+- * Copyright (c) 2010 Serge A. Zaitsev
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining a copy
+- * of this software and associated documentation files (the "Software"), to deal
+- * in the Software without restriction, including without limitation the rights
+- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+- * copies of the Software, and to permit persons to whom the Software is
+- * furnished to do so, subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice shall be included in
+- * all copies or substantial portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+- * THE SOFTWARE.
+- */
++// This file is from jsmn under the MIT license:
++//
++// http://zserge.com/jsmn.html
+ 
+ #include "jsmn.h"
+ 
+@@ -220,6 +202,9 @@
+ 						break;
+ 					}
+ 					if (token->parent == -1) {
++						if(token->type != type || parser->toksuper == -1) {
++							return JSMN_ERROR_INVAL;
++						}
+ 						break;
+ 					}
+ 					token = &tokens[token->parent];
+diff --git a/core/jsmn.h b/core/jsmn.h
+--- a/core/jsmn.h
++++ b/core/jsmn.h
+@@ -1,24 +1,6 @@
+-/*
+- * Copyright (c) 2010 Serge A. Zaitsev
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining a copy
+- * of this software and associated documentation files (the "Software"), to deal
+- * in the Software without restriction, including without limitation the rights
+- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+- * copies of the Software, and to permit persons to whom the Software is
+- * furnished to do so, subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice shall be included in
+- * all copies or substantial portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+- * THE SOFTWARE.
+- */
++// This file is from jsmn under the MIT license:
++//
++// http://zserge.com/jsmn.html
+ 
+ #ifndef __JSMN_H_
+ #define __JSMN_H_
+@@ -55,9 +37,9 @@
+ 
+ /**
+  * JSON token description.
+- * @param		type	type (object, array, string etc.)
+- * @param		start	start position in JSON data string
+- * @param		end		end position in JSON data string
++ * type		type (object, array, string etc.)
++ * start	start position in JSON data string
++ * end		end position in JSON data string
+  */
+ typedef struct {
+ 	jsmntype_t type;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/update_lightsc_example.patch	Sat Feb 04 00:09:54 2017 +0100
@@ -0,0 +1,107 @@
+# HG changeset patch
+# Parent  f5f57598dc1dcd815946a0e37c847a784792e8f1
+Update the example for the Python client
+
+The API changed a little bit since it was written.
+
+diff --git a/clients/python/lightsc/README.rst b/clients/python/lightsc/README.rst
+--- a/clients/python/lightsc/README.rst
++++ b/clients/python/lightsc/README.rst
+@@ -4,14 +4,14 @@
+ lightsd_ is a daemon (background service) to control your LIFX_ WiFi "smart"
+ bulbs. This package allows you to make RPC calls to lightsd to control your
+ light bulbs from Python. It is built on top of the ``asyncio`` module and
+-requires Python ≥ 3.5:
++requires Python ≥ 3.5, here is a complete example:
+ 
+ .. code-block:: python
+ 
+    import asyncio
+    import click
+ 
+-   from lightsc import LightsView, create_async_lightsd_connection
++   from lightsc import create_async_lightsd_connection
+    from lightsc.requests import (
+        GetLightState,
+        PowerOff,
+@@ -19,13 +19,16 @@
+        SetLightFromHSBK,
+     )
+ 
++
+    async def example(url, targets):
+-       async with create_async_lightsd_connection(url) as client:
++       client = await create_async_lightsd_connection(url)
++       try:
+            click.echo("Connected to lightsd running at {}".format(client.url))
+ 
+-           view = LightsView()
+-           view.update(await client.apply(GetLightState(targets))
+-           click.echo("Discovered bulbs: {}".format(view))
++           lights_state = await client.apply(GetLightState(targets))
++           click.echo("Discovered {} bulbs: {}".format(
++               len(lights_state.bulbs), lights_state.bulbs
++           ))
+ 
+            transition_ms = 600
+            red_hsbk = (0., 1., 1., 3500)
+@@ -34,29 +37,42 @@
+                batch.append(PowerOn(targets))
+                batch.append(SetLightFromHSBK(targets, *red_hsbk, transition_ms=transition_ms))
+ 
++           await asyncio.sleep(transition_ms / 1000)
++           click.echo("{}ms transition done".format(transition_ms))
++
+            click.echo("Restoring original state")
+            async with client.batch() as batch:
+-               for b in view.bulbs:
++               for b in lights_state.bulbs:
+                    PowerState = PowerOn if b.power else PowerOff
+                    hsbk = (b.h, b.s, b.b, b.k)
+ 
+                    batch.append(PowerState([b.label]))
+                    batch.append(SetLightFromHSBK([b.label], *hsbk, transition_ms=transition_ms))
++       finally:
++           await client.close()
++
+ 
+    @click.command()
+    @click.option("--lightsd-url", help="supported schemes: tcp+jsonrpc://, unix+jsonrpc://")
+    @click.argument("bulb_targets", nargs=-1, required=True)
+-   def main(lightsd_url, bulb_targets)
+-       """This example will turn all your bulbs to red before restoring their
++   def main(lightsd_url, bulb_targets):
++       """This example will turn the targeted bulbs to red before restoring their
+        original state.
+ 
+-       If an URL is not provided this script will attempt to connect to
+-       lightsd's UNIX socket.
++       Read the `protocol docs`_ to learn how to format targets.
++
++       If an URL is not provided this script will attempt to connect to lightsd's
++       UNIX socket.
++
++       .. _protocol docs: protocol.html#targeting-bulbs
+        """
+ 
+        evl = asyncio.get_event_loop()
+        evl.run_until_complete(evl.create_task(example(lightsd_url, bulb_targets)))
+ 
++   if __name__ == "__main__":
++       main()
++
+ .. _lightsd: https://www.lightsd.io/
+ .. _LIFX: http://lifx.co/
+ 
+diff --git a/clients/python/lightsc/lightsc/client.py b/clients/python/lightsc/lightsc/client.py
+--- a/clients/python/lightsc/lightsc/client.py
++++ b/clients/python/lightsc/lightsc/client.py
+@@ -33,7 +33,7 @@
+ import locale
+ import logging
+ import os
+-import urllib
++import urllib.parse
+ import uuid
+ 
+ from typing import (