update esppilight lib

content of the library is not filtered on 433mhz only
This commit is contained in:
Florian committed 2018-11-28 20:41:37 +01:00
1 parent a275e48ee1
commit 67dd7ac078
1030 files changed
+203335 -116

No files matched your search

@@ -0,0 +1,425 @@
API
===
- `Identification`_
- `Options`_
- `Actions`_
- `Webserver (REST Api)`_
- `Heartbeat`_
- `Buffer Sizes`_
Identification
--------------
All programs communicate with each other by using JSON objects. The normal identification process is as follows:
- Connect to pilight-daemon by using the pilight IP and port. The port pilight is running at is either a randomly chosen number or a fixed number as configured in the pilight settings.
- The pilight-daemon waits for the client to identify itself by sending the following JSON object:
.. code-block:: json
:linenos:
{
"action": "identify"
}
- Additionally, a client can send certain options to tell the daemon what level of communication is the client want to set-up. A full identification JSON looks like this:
.. code-block:: json
:linenos:
{
"action": "identify",
"options": {
"core": 1,
"receiver": 1,
"config": 1,
"forward": 0
},
"uuid": "0000-d0-63-00-000000",
"media": "all"
}
- After each action, the daemon will send either one of the following two status responses indicating a success or failure:
.. code-block:: json
:linenos:
{
"status": "success"
}
.. code-block:: json
:linenos:
{
"status": "failure"
}
Options
-------
The identification options define what communication is set-up between the daemon and the client.
- receiver
When the receiver option is set, the daemon will forward the received or sent codes to the client. An example:
.. code-block:: json
:linenos:
{
"origin": "receiver",
"protocol": "kaku_switch",
"code": {
"id": 1234,
"unit": 0,
"off": 1
}
}
{
"origin": "sender",
"protocol": "kaku_switch",
"code": {
"id": 1234,
"unit": 0,
"off": 1
}
}
In the received JSON messages, the origin will tell if an externally received message was received or a code sent by pilight self.
- config
When the config option is set, the daemon will communicate all configuration updates. An example:
.. code-block:: json
:linenos:
{
"origin": "config",
"devices": [ "mainlight" ],
"values": {
"state": "on"
}
}
|
- core
When the core option is set, the daemon will communicate pilight core information.
- stats
When the stats option is set, the daemon will communicate the RAM and CPU statistics.
.. code-block:: json
:linenos:
{
"origin": "core",
"values": {
"cpu": 0.07822473698105643,
"ram": 0.1535397936955158
},
"type": -1,
"uuid": "0000-d0-63-00-000000"
}
|
- forward
When the forward option is enabled, all incoming (valid) socket data will be forwarded to the client.
The uuid setting is meant for the client to send its unique UUID.
The media setting is used to tell the daemon what information is sent based on the specific media. As can be read in the GUI configuration, a user can create different GUIs based on different devices. The currently supported GUI types are all, web, mobile, and desktop. If you define your client as one of those GUI types, pilight will only send devices, GUI elements, config updates and rules that apply the specific GUI type, leaving the rest out. Therefore, you do not have to do any additional parsing on the client side.
These options can be updated on-the-fly while the client is running. The daemon will start or stop sending specific messages. To update these options, just send another identification request. An example identification object:
.. code-block:: json
:linenos:
{
"action": "identify",
"options": {
"stats": 1,
"receiver": 1
},
"uuid": "0000-d0-63-00-000000"
}
Actions
-------
As we have seen in the identification process, pilight can handle several actions. The first action we encounter is the identification action. The following list contains all possible actions the daemon can handle. Again, the daemon will respond to all actions with a success and failure so the client can check if the action succeeded.
- send
In case the client wants to send specific protocol codes, the send action is used. A sent action is accompanied by specific additional arguments:
.. code-block:: json
:linenos:
{
"action": "send",
"code": {
"protocol": [ "kaku_switch" ],
"id": 1234,
"unit": 0,
"off": 1
}
}
These are basically the command like arguments. If an argument requires a value, then the value is added to the argument (as with id and unit). If the argument does not take a value, than it is defaulted to 1 (as with off). The pilight-daemon will check if the code was valid, and report back with a failure if it was not.
- control
The control action is used to control registered devices by using their device IDs. The pilight-daemon will check if the values are valid and report back with a failure if they are not. An example control object:
.. code-block:: json
:linenos:
{
"action": "control",
"code": {
"device": "mainlight",
"state": "on",
"values": {
"dimlevel": 10
}
}
}
|
- registry
The pilight registry can be managed by the registry API. The registry is a multi-purpose storage solution within pilight. Developers can store any information they want inside it so it is retrievable later on. The registry allows three types of actions: set, get, remove. The syntax for each on of them is:
.. code-block:: json
:linenos:
{
"action": "registry",
"type": "set",
"key": "pilight.version",
"value": "6.0"
}
.. code-block:: json
:linenos:
{
"action": "registry",
"type": "get",
"key": "pilight.version"
}
.. code-block:: json
:linenos:
{
"action": "registry",
"type": "remove",
"key": "pilight.version"
}
The response to a get command is as follows:
.. code-block:: json
:linenos:
{
"action": "registry",
"value": "6.0",
"key": "pilight.version"
}
Please note that the pilight registry can only hold JSON string and number types.
- request config
The request config is used to request the full configuration object from the pilight-daemon:
.. code-block:: json
:linenos:
{
"action": "request config"
}
|
After this command, the pilight-daemon will send the raw JSON configuration as it is used internally.
.. code-block:: json
:linenos:
{
"devices": {
"tv": {
"uuid": "0000-00-00-07-646b93",
"origin": "0000-d0-63-00-000000",
"timestamp": 0,
"protocol": [ "relay" ],
"id": [{
"gpio": 3
}],
"state": "off",
"default": "off"
}
},
"rules": {
"tvswitch": {
"rule": "IF tv.state IS on THEN switch DEVICE tv TO off",
"active": 1
}
},
"gui": {
"television": {
"type": 4,
"order": 1,
"name": "tv",
"group": [ "Living" ],
"media": [ "all" ],
"readonly": 0
}
},
"settings": {
"log-level": 4,
"pid-file": "/var/run/pilight.pid",
"log-file": "/var/log/pilight.log",
"webserver-enable": 1,
"webserver-http-port": 5001,
"webserver-cache": 0,
"webserver-root": "/usr/local/share/pilight"
},
"hardware": {
"433gpio": {
"sender": 0,
"receiver": 1
}
},
"registry": {
"pilight": {
"version": {
"current": "6.0"
}
}
}
}
- request values
.. code-block:: json
:linenos:
{
"action": "request values"
}
pilight tries to make app development as easy as possible. This means that GUIs should only have to parse the GUI configuration object. The downside however is that the GUI object does not contain the device values. To solve this issue, the GUIs can request the values for all devices at once. The returned object will have the same information as the daemon communicates with the config option enabled, but now in bulk for all devices. An example:
.. code-block:: json
:linenos:
[{
"type": 4,
"devices": [ "tv" ],
"values": {
"timestamp": 0,
"state": "off"
}
},
{
"type": 1,
"devices": [ "bookShelfLight" ],
"values": {
"timestamp": 0,
"state": "off"
}
}]
Please be aware that right after the request values object, the pilight version object is sent. It is up to the GUIs to ignore or parse this information.
Webserver (REST API)
--------------------
The webserver has some special pages:
- The config page will present the latest configuration JSON object.
- The values page will present the latest values of all device.
The values and config page will by default only show the configuration that applies to a web GUI type. To retrieve the configuration relevant for other GUI types, use the media argument:
.. code-block:: console
http://x.x.x.x:5001/config?media=all
.. versionadded:: 4.0 Send codes through webserver
- The send page can be used to control devices. To use this function, call the send page with a URL-encoded "send" or "registry" JSON object like this:
.. code-block:: console
send%3F%7B%0A%09%22action%22%3A%20%22control%22%2C%0A%09%22code%22%3A%20%7B%0A%09%09%22device%22%3A%20%22mainlight%22%2C%0A%09%09%22state%22%3A%20%22on%22%2C%0A%09%09%22values%22%3A%20%7B%0A%09%09%09%22dimlevel%22%3A%20%2210%22%0A%09%09%7D%0A%09%7D%0A%7D
This will send the object as described earlier.
.. versionchanged:: 8.0 Implemented REST API instead of posting arbitrary JSON codes
- The send page has the same functionality as the ``pilight-send`` program and uses the same arguments:
.. code-block:: guess
http://x.x.x.x:5001/send?protocol=kaku_switch&on=1&id=1&unit=1
As can be seen, the URL arguments are the same as for the ``kaku_switch`` protocol:
.. code-block:: console
pi@pilight:~# pilight-send -p kaku_switch -H
...
[kaku_switch]
-t --on send an on signal
-f --off send an off signal
-u --unit=unit control a device with this unit code
-i --id=id control a device with this id
-a --all send command to all devices with this id
-l --learn send multiple streams so switch can learn
All protocols can be controlled using their respective arguments using the webserver send page as described in this example.
- The control page has the same functionality as the ``pilight-control`` program and uses the same arguments:
.. code-block:: guess
http://x.x.x.x/control?device=nasStatus&values[label]=computer%20is%20disconnected&values[color]=red
In this case a generic_label device is being controlled
Heartbeat
---------
One special function of the *pilight-daemon* is the heartbeat. The heartbeat is meant to check if a connection is still alive. The client has to send a "HEART\n" on which the *pilight-daemon* will respond with a "BEAT\n". This is the only exception in which not a JSON object is sent.
Buffer Sizes
------------
pilight will sends all streams in 1024 bits. If these streams are smaller than 1024 bits, everything was sent at once. If a stream is 1024 bits, then you will know it is a chunk of a bigger stream. In that case, read until you encounter the end of streams delimiter which is currently made up of two new lines "\n\n".
If multiple streams were buffered somewhere, you can also distinguish them by the double new line delimiters. An example:
.. code-block:: console
:linenos:
{"message":"test"}\n\n
{"message":"test"}\n\n
{"message":"test"}\n\n
As you can see. pilight wanted to send three messages, but the TCP sockets concatenated them to one.
The pilight socket_read function takes care of these buffered messages to check if we encountered concatenated multiple streams. pilight will then convert these messages back so the output is just one big stream separated by single newlines:
.. code-block:: console
:linenos:
{"message":"test"}\n
{"message":"test"}\n
{"message":"test"}\n
@@ -0,0 +1,173 @@
Debugging
=========
- `Introduction`_
- `Prerequisites`_
- `How to recognize a Bug?`_
- `How to Debug?`_
Introduction
------------
pilight is a product developed by a growing community. Due to its Open Source character, developers around the world can contribute code. Although all developers try to write bug free code, it is not always possible for the developers of pilight to check for every possible mistake that can be made. Especially, because not everyone has every hardware available for testing.
Prerequisites
-------------
If you found this page, you probably encountered a bug in the pilight code or noticed that things are not working as they should be. Before you continue reading, consider the following.
First, pilight offers code in several stages of stability:
#. Stable apt repository and GitHub master branch
This code has been tested to work without bugs for various weeks by the developer and a large community. If bugs are found in this version of pilight, the problem has probably already been fixed in the developmental code.
#. Nightly apt repository and GitHub development branch
This code always contains the very latest features and fixes. It is updated several times a week. However, this also means that not all bugs are already encountered when a user starts to use it.
Second, this page is made for those users using the developmental GitHub branch. This tutorial assumes the following:
#. You are aware of the distinction between bugs and changes in the pilight functionality.
#. You have read the GitHub commit messages to be sure that what you have encountered is indeed a bug and not a changed functionality.
#. You have enough experience working with your operating system.
#. You have the patience to help finding the problem.
#. You have some knowledge about programming (and the C language).
#. You know when to recognize a clear code bug.
#. You are able to manually compile pilight so debugging is possible. The automatically compiled versions do not support debugging as described here.
How to Recognize a Bug?
-----------------------
The two most encountered bugs are the memory issues or the segmentation faults. A memory bug can look like this:
.. code-block:: console
* glibc detected ./pilight-daemon: double free or corruption (!logfile): 0x0000000000c6ed50 **
This message means in this case that the variable logfile was freed twice.
A segmentation fault looks like this:
.. code-block:: console
pi@raspberrypi ~/pilight $ sudo service pilight start
[....] Starting : pilightSegmentation fault
failed!
This message means there has been a general error in which pilight so it cannot be started properly.
How to Debug?
-------------
To debug C code, the GNU Debugger is used, also called gdb. This program will run next to pilight without any performance issue, but when pilight crashes, it allows us to track the specific line where the error occurred. So first of all, make sure you have gdb installed. This is how you start gdb together with pilight:
.. code-block:: console
pi@pilight:~> sudo su
root@pilight:~# gdb --args pilight-daemon -D
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/local/sbin/pilight-daemon...done.
(gdb) run
Starting program: /usr/local/sbin/pilight-daemon -D
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[Jan 18 16:23:33:657363] pilight-daemon: DEBUG: ssdp sent search
[Jan 18 16:23:33:701618] pilight-daemon: NOTICE: no pilight daemon found, daemonizing
[Jan 18 16:23:33:718878] pilight-daemon: DEBUG: -- start parsed config file --
Now pilight will start as it you would have started it normally. Just let it run like this until it crashes or try to invoke the crash. If it crashes, you will see something like this:
.. code-block:: console
*** glibc detected *** /usr/local/sbin/pilight-daemon: double free or corruption (fasttop): 0x000369d8 ***
[New Thread 0xb228c470 (LWP 26235)]
Program received signal SIGABRT, Aborted.
[Switching to Thread 0xb4d7d470 (LWP 26230)]
0xb6dddbfc in __GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
67 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb)
Again, you see the **(gdb)** prompt that allows you to type new commands.
The first step is to get a backtrace of all functions called when this crash occurred:
.. code-block:: console
(gdb) backtrace
#0 0xb6dddbfc in __GI_raise (sig=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
#1 0xb6de197c in __GI_abort () at abort.c:92
#2 0xb6e15cf8 in __libc_message (do_abort=2,
fmt=0xb6ec78d0 "*** glibc detected *** %s: %s: 0x%s ***\n")
at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#3 0xb6e20584 in malloc_printerr (action=3,
str=0xb6ec7a6c "double free or corruption (fasttop)", ptr=<optimized out>)
at malloc.c:6283
#4 0xb6e24e00 in __GI___libc_free (mem=<optimized out>) at malloc.c:3738
#5 0x0000b5d8 in broadcast (param=<optimized out>) at daemon.c:260
#6 0xb6ee6bfc in start_thread (arg=0xb4d7d470) at pthread_create.c:306
#7 0xb6e7b758 in ?? ()
at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:116
from /lib/arm-linux-gnueabihf/libc.so.6
#8 0xb6e7b758 in ?? ()
at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:116
from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
Copy this output so it can be communicated on the forum.
The second step is to look for the exact line causing this crash. This can be done by zooming into each part of each function related to this bug. We start at the end and work our way to the beginning. To zoom into a function the command **frame** # is used in which the # is replaced by one of the numbers you see in the backtrace. As said earlier, we will start at the end:
.. code-block:: console
(gdb) frame 8
#8 0xb6e7b758 in ?? ()
at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:116
from /lib/arm-linux-gnueabihf/libc.so.6
116 ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S: No such file or directory.
This doesn't tell us anything useful. So we continue to the previous frame.
.. code-block:: console
(gdb) frame 7
#7 0xb6e7b758 in ?? ()
at ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S:116
from /lib/arm-linux-gnueabihf/libc.so.6
116 ../ports/sysdeps/unix/sysv/linux/arm/nptl/../clone.S: No such file or directory.
Still no useful information here.
.. code-block:: console
(gdb) frame 6
#6 0xb6ee6bfc in start_thread (arg=0xb4d7d470) at pthread_create.c:306
306 pthread_create.c: No such file or directory.
Nope.
.. code-block:: console
(gdb) frame 5
#5 0x0000b5d8 in broadcast (param=<optimized out>) at daemon.c:260
260 json_delete(jret);
Yes, finally something related to pilight. As you can see here, the conflicting line can be found in daemon.c in the function broadcast at line 260. The actual command that leaded to the crash was json_delete. Although we now know that this was the line causing the crash, the actual bug could lay elsewhere. Therefore we continue until the last pilight related frame.
No useful information in frame 4. So, frame 5 was the only interesting frame here. Make sure to copy the output of the informative frames so it can be used in a forum post later on.
To exit:
.. code-block:: console
(gdb) q
As you might have seen, this way of debugging makes it a lot easier to track bugging code. gdb will tell you the exact line on which the bug occurred to in can be easier tracked down and fixed.
@@ -0,0 +1,8 @@
Development
===========
.. toctree::
:maxdepth: 1
api
debugging