lopter / lightsd Goto Github PK
View Code? Open in Web Editor NEWA daemon with a JSON-RPC API to control your light bulbs
License: GNU General Public License v3.0
A daemon with a JSON-RPC API to control your light bulbs
License: GNU General Public License v3.0
lightsd version 1.1.2
CMake version 3.5.0
libevent2 version 2.0.22
The problem is that it isn't finding endian.h and running "cmake -DCMAKE_BUILD_TYPE=RELEASE .." fails due to that.
"Could not find Endian (missing: ENDIAN_H_PATH)"
From what I can gather by a little research is that Linux and other systems use #include endian.h while it seems FreeBSD and possibly other BSD's use #include sys/endian.h
Creating a directory lightsd/compat/FreeBSD and putting endian.h from FreeBSD's system in there is a workaround that seems to work. However, running make to build lightsd fails with multiple errors. I don't know if that is because of my tinkering with endian.h or if it would fail anyway with a proper fix to that issue.
kqueue(2)
file descriptors aren't inherited by child processes therefore we need to fork before we call event_base_new
from libevent.
This is pretty annoying because it means we need to rework lightsd's initialization process.
A quick hack/workaround by replacing fork
with rfork(RFPROC)
, also seems to indicate that signal handling isn't working once in the background.
Thanks @kraduk for reporting this issue.
I might be mistaken, but according to the official documentation, the value temperature in the response StateWifiInfo and StateHostInfo is an signed 16-bit integer. In your code it is an unsigned type (lgtd_lifx_packet_ip_state).
I tried running lightsd with stderr redirected to a log file which works fine in the foreground but not in the background (-d) as it seems to close the stdio file descriptors. Would it be possible to add support via the command line to specify a log file location?
Thanks & great work!
Is anybody working on an alternative Home Assistant component for Lifx lights which interfaces with lightsd instead of whatever 10 minute detecting horror show is being used currently?
Hi,
I've found lightsd due to my contempt for how poorly all the other solutions (such as the integrated LIFX support in Home Assistant) perform. It seemed to me like this project was trying to solve all the problems that plagued those implementations.
However, when I try to start lightsd (whether directly or through the startup scripts) I get the error:
[ERR] lightsd: can't setup lightsd: Address already in use
Any ideas as to what might cause this? It's not complaining about the port (of which I have tried many), but the address.. I've tried 0.0.0.0, 127.0.0.1 and my wlan0 ip (as well as not specifying at all as is the default with the startup script).
FWIW I'm running Raspbian Jessie on a Raspberry Pi 3.
Regards,
Michal
I run lightsd with -l to allow connections from network based clients. I recently updated my OS to ubuntu 16.04 and lightsd to 1.2.1 and noticed it was no longer paying attention to my DAEMON_OPTS= line in /etc/default/lightsd. This is due to using systemd now, which is fine, but might be worth mentioning that /etc/default/lightsd isn't used on systemd systems and changes to options should be done in the service file.
Just a suggestion.
bulbs(found=0, on=0)
Full log:
root@raspberrypi:/home/pi# systemctl status lightsd
â— lightsd.service - LIFX WiFi smart bulbs control service
Loaded: loaded (/usr/lib/systemd/system/lightsd.service; enabled)
Active: active (running) since Tue 2016-12-13 21:53:33 UTC; 13min ago
Main PID: 22127 (lightsd)
CGroup: /system.slice/lightsd.service
└─22127 lightsd: listening_on(/run/lightsd/socket); command_pipes(/run/lightsd/pipe); bulbs(found=0, on=0); clients(connected=0)
Dec 13 21:58:12 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x196 from [::ffff:192.168.2.42]:56700
Dec 13 22:00:26 raspberrypi systemd[1]: Started LIFX WiFi smart bulbs control service.
Dec 13 22:01:05 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x40 from [::ffff:192.168.2.149]:56700
Dec 13 22:01:07 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x196 from [::ffff:192.168.2.149]:56700
Dec 13 22:03:16 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x40 from [::ffff:192.168.2.43]:56700
Dec 13 22:03:18 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x196 from [::ffff:192.168.2.43]:56700
Dec 13 22:05:37 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x40 from [::ffff:192.168.2.76]:56700
Dec 13 22:05:39 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x196 from [::ffff:192.168.2.76]:56700
Dec 13 22:06:59 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x40 from [::ffff:192.168.2.85]:56700
Dec 13 22:07:01 raspberrypi lightsd[22127]: [WARN] lightsd: received unknown packet 0x196 from [::ffff:192.168.2.85]:56700
LIFX have released new firmware updates that includes changes which breaks lightsd, at least parts of lightsd. The A19 bulbs that I have updated to 2.14 are now crashing if I try to change their tag with lightsd. It may affect other messages, but I haven't tried them all. Setting the label works, and changing their colors works as well.
LIFX are saying lightsd is using deprecated messages, and this seems to be a problem with (all?) third-party software for the LIFX bulbs with the new firmware. I would appreciate it if lightsd could be updated to resolve this.
Thank you very much.
Been using lighted for a while now! Recently switched to google wifi and only 22 of 30 lights found, but 0 connected...
Hello Lopter,
Can you, please, add new LIFX product_id in lightsd/lifx/bulb.c from
https://lan.developer.lifx.com/docs/lifx-products
case 0x1B:
return "LIFX A19";
case 0x1C:
return "LIFX BR30";
case 0x1D:
return "LIFX + A19";
case 0x1E:
return "LIFX + BR30";
case 0x1F:
return "LIFX Z";
Equivalent to:
prev_color = get_light_state(target)
set_light_from_hsbk(target, 0, 0, 0 or 1, temperature, 60 * 1000 * 5)
sleep(60 * 5)
powerOff(target)
set_light_from_hsbk(target, prev_color, 0) # requires firmware >= 1.5 for the Original 1000
The LIFX REST API doesn't seem to update the state (color) of the bulb during the transition, but this will.
On top of my head:
I was looking at the code, when I saw, that you spitted the target variable in the header into two pieces. One is the 6 byte large address and the other is the tags variable.
union {
//! All targeted tags ORed together.
uint64le_t tags;
//! Address of the targeted device.
uint8_t device_addr[LGTD_LIFX_ADDR_LENGTH];
} target;
But I can't find any information about the tags? What are they?
The worst thing about lifx is the onboarding process and trying to get firmware updates to work via the mobile app. Its even harder if you have new versions of android and 5ghz mixed networks.
It would be awesome if I just plugged the bulb in and lightsd connected to its SSID, onboarded it onto the network and gave it the latest firmware.
Is that possible?
I want to use lightsd with nginx, so I can connect/send request from remote machine.
lightsd runs listening on socket, what I've set up in nginx config. I tried maybe every configuration combination, nothing worked.
I tried it with examples/lightsc.py
, here is script output:
Couldn't infer lightsd's runtime directory, is lightsd installed? ([Errno 2] No such file or directory: 'lightsd')
Trying build/socket...
Connecting to lightsd@tcp://192.168.150.7:8449
Connected to tcp://192.168.150.7:8449, use the variable c to interact with your bulbs:
>>> r = c.get_light_state("*")
>>> from pprint import pprint
>>> pprint(r)
When I try to run c.get_light_state("*")
, it just hangs there an I need to kill process and lightsd doesn't show any connected clients.
Here is my nginx config, also with settings I tried to use.
upstream "lightsd" {
server unix:/run/lightsd/socket;
}
server {
listen 8449;
server_name 192.168.150.7;
location / {
# proxy_set_header Host $host;
# proxy_set_header Accept-Encoding "";
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# client_max_body_size 10m;
# client_body_buffer_size 128k;
# proxy_connect_timeout 90;
# proxy_send_timeout 90;
# proxy_read_timeout 90;
# proxy_buffers 32 4k;
# proxy_buffering off;
# proxy_redirect off;
proxy_pass http://lightsd;
}
}
Thanks for any help.
Howdy,
While I would love if the only way the LIFX lights were changed was via lightsd and a single light-sd client, I know that around my house, there are others who will use the app to make changes. I can also see cases where there could be multiple lightsd clients all making changes.
This brings up the idea of being able to get change notification events from lightsd whenever a light changes. I'm guessing (!!!) internally this wouldn't be too difficult as it appears it's pretty good about tracking light changes in something close to real-time.
I think it would mostly come down to supporting something like "unsolicited" messages from the lightsd to open/existing clients (maybe after that client turns on event subscriptions, to allow for compatibility). Then clients can be notified fairly quickly when things change outside of the client itself.
Pie in the sky? ;-)
lightsd parses floats manually so they can be stored in integers but fails to support numbers in E notation, which are part of the JSON standard.
The following functions should be fixed first:
Since I guess the E notation will mostly be triggered by client code doing float operations that tend towards 0.
But eventually everything number parsing above jsmn is affected in lightsd and should be fixed according to the JSON grammar:
number
int
int frac
int exp
int frac exp
int
digit
digit1-9 digits
- digit
- digit1-9 digits
frac
. digits
exp
e digits
digits
digit
digit digits
e
e
e+
e-
E
E+
E-
When using the python client to get light state, the lightsd daemon segfault, here is the traceback:
ipython shell using lightsc.py
>>> c.get_light_state("*")
Lightsd:
[2018-07-15T18:54:41.169086+02:00] [DEBUG] lightsd: scheduling next GET_LIGHT_STATE on [::ffff:192.168.0.20]:56700 in 800ms
[2018-07-15T18:54:41.169151+02:00] [DEBUG] lightsd: SET_LIGHT_STATE <-- [::ffff:192.168.0.19]:56700 - d0:73:d5:24:XX:XX hue=0, saturation=0, brightness=0xffff, kelvin=3500, dim=0, power=0, label=couloir2, tags=0
[2018-07-15T18:54:41.169191+02:00] [DEBUG] lightsd: [::ffff:192.168.0.19]:56700 GET_LIGHT_STATE for all bulbs on this gw has already been enqueued
[2018-07-15T18:54:41.169227+02:00] [DEBUG] lightsd: SET_LIGHT_STATE <-- [::ffff:192.168.0.19]:56700 - d0:73:d5:24:XX:XX hue=0, saturation=0, brightness=0xffff, kelvin=3500, dim=0, power=0, label=couloir2, tags=0
[2018-07-15T18:54:41.169262+02:00] [DEBUG] lightsd: [::ffff:192.168.0.19]:56700 GET_LIGHT_STATE for all bu[2018-07-15T18:54:41.169227+02:00] [DEBUG] lightsd: SET_LIGHT_STATE <-- [::ffff:192.168.0.19]:56700 - d0:73:d5:XX:XX hue=0, saturation=0, brightness=0xffff, kelvin=3500, dim=0, power=0, label=couloir2, tags=0
[2018-07-15T18:54:41.169262+02:00] [DEBUG] lightsd: [::ffff:192.168.0.19]:56700 GET_LIGHT_STATE for all bulbs on this gw has already been enqueued
[2018-07-15T18:54:41.169391+02:00] [DEBUG] lightsd: SET_LIGHT_STATE <-- [::ffff:192.168.0.20]:56700 - d0:73:d5:25:XX:XX hue=0, saturation=0, brightness=0xffff, kelvin=3500, dim=0, power=0xffff, label=salon, tags=0
[2018-07-15T18:54:41.169474+02:00] [DEBUG] lightsd: [::ffff:192.168.0.20]:56700 GET_LIGHT_STATE for all bulbs on this gw has already been enqueued
[2018-07-15T18:54:41.169511+02:00] [DEBUG] lightsd: SET_LIGHT_STATE <-- [::ffff:192.168.0.20]:56700 - d0:73:d5:25:XX:XX hue=0, saturation=0, brightness=0xffff, kelvin=3500, dim=0, power=0xffff, label=salon, tags=0
[2018-07-15T18:54:41.169549+02:00] [DEBUG] lightsd: [::ffff:192.168.0.20]:56700 GET_LIGHT_STATE for all bulbs on this gw has already been enqueued
Program received signal SIGSEGV, Segmentation fault.
0x000055555555fb8b in jsmn_alloc_token ()
(gdb) bt
#0 0x000055555555fb8b in jsmn_alloc_token ()
#1 0x00005555555600ca in jsmn_parse ()
#2 0x000055555555c5f5 in lgtd_client_read_callback ()
#3 0x00007ffff7bb7d82 in ?? () from /usr/lib/libevent_core-2.1.so.6
#4 0x00007ffff7bbd848 in ?? () from /usr/lib/libevent_core-2.1.so.6
#5 0x00007ffff7bbe28f in event_base_loop () from /usr/lib/libevent_core-2.1.so.6
#6 0x000055555556557f in main ()
(gdb)
On more pedantic systems (OpenBSD at the moment) with multiple interfaces the discovery will fail with this error.
This is because discovery packets aren't broadcasted properly: lightsd tries to send packets to 255.255.255.255 (INADDR_BROADCAST
) which becomes ambiguous as soon as the system has multiple network interfaces.
There is two solutions for that, I'll probably implement both and make them mutually exclusive:
I'm looking at implementing the first solution soonish, no ETA for the second solution since it requires more work as network interface discovery is OS-specific.
Claiming All rights reserved.
and immediately following that with a BSD header is confusing, would recommend striking the ARR notice.
Howdy! The LIFX LAN protocol allows you to change just part of a color -- change hue or saturation or brightness or a combination. Given the set_light_state call format for lightsd, how do you indicate which parameters have valid values for the set_light_state and which should be ignored for that call? (null value, -1/invalid value, etc)
Things I'm looking for:
It would be helpful if that was part of the documentation.
Thanks!
I'm currently trying to build lightsd on my RaspberryPi running the current raspbian-release as described here. Everything seems fine until lightsd should be signed:
Now signing changes and any dsc files...
signfile lightsd_1.1.2-1.dsc Louis Opter <[email protected]>
gpg: Verzeichnis `/home/pi/.gnupg' erzeugt
gpg: Neue Konfigurationsdatei `/home/pi/.gnupg/gpg.conf' erstellt
gpg: WARNUNG: Optionen in `/home/pi/.gnupg/gpg.conf' sind während dieses Laufes noch nicht wirksam
gpg: Schlüsselbund `/home/pi/.gnupg/secring.gpg' erstellt
gpg: Schlüsselbund `/home/pi/.gnupg/pubring.gpg' erstellt
gpg: übersprungen "Louis Opter <[email protected]>": Geheimer Schlüssel ist nicht vorhanden
gpg: /tmp/debsign.oKNJz0Or/lightsd_1.1.2-1.dsc: clearsign failed: Geheimer Schlüssel ist nicht vorhanden
debsign: gpg error occurred! Aborting....
debuild: fatal error at line 1295:
running debsign failed
Seems that there is a dependency with your private gpg key, @lopter?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.