5. ThingFlow Application¶
Now that our board is up and running, we can use ThingFlow to build a simple application.
ThingFlow is a Python 3 framework for building IoT event processing and filtering applications. It is centered around event streams, which are infinite sequences of timestamped sensor value samples. The key components in ThingFlow are sensors, which capture data from the outside world, things, which transform event streams, and the scheduler which manages the recurring sampling of sensors. ThingFlow allows you to write your IoT code as data flows (“from this to that”) instead of as procedural code (“if this then that”).
There are two implementations of ThingFlow in Python. The goal is to
provide a common API from very small sensor nodes (like the ESP8266) to
large servers (for event concentration and data science). We will be using
the MicroPython version, which may be found in the
of the thingflow-python
Due to the memory limitations of the ESP8266, the MicroPython version is very stripped down, and only supports a subset of the full ThingFlow API. That will be fine for our application, as the focus of our code will be to sample the light sensor and send the values over the network to a larger system for processing and / or storage.
Reading the Light Sensor¶
A sensor in ThingFlow is a Python object which satisfies two criteria:
- It provides a
sensor_idproperty which can be used in event messages to uniquely identify the sensor.
- It provides a
sample()method which returns the current value associated with the sensor.
The ThingFlow MicroPython implementation includes a sensor implementation for the TSL2591 lux sensor. We will first copy this over to the ESP8266 and verify that we can read the sensor.
Close any previous
screen sessions with your ESP8266 system, and
In a terminal session, go to the
micropython subdirectory of the
ThingFlow repository. From this directory, run the
utility. In this session type the following (substituting
ttyUSB0 for TTYDEVICE):
open TTYDEVICE ls
open command establishes a connection to your ESP8266. The
list the files on that system (MicroPython includes a very simple filesystem
implementation). Initially, you should only see the file
boot.py, which is
installed as a part of the firmware flash.
Now, run the command
lls. This lists the files on your host system, in the
directory where you ran
mpfshell. Now, run the following:
lcd sensors lls
This changes the host directory to the
sensors subdirectory and lists the
files. One of the files you should see is
tsl2591.py. This is the code which
implements the interface to the light sensor.
put tsl2591.py ls
This copies the file
tsl2591.py to the ESP8266 and lists the files on it.
We should now see our sensor code file, in addition to
Calling the Light Sensor¶
Next, we want to import and call the sensor code from the MicroPython REPL. There are two ways to do this:
- You can access the REPL directly from
mpfshell. Just enter the command
repl, and you will be in the REPL. You can later exit the REPL and get back to the main shell via the key combination CONTROL and “]”.
- Alternatively, you can exit
mpfshelland then run
screenagain to get a REPL directly.
Either way, once we are in the REPL, we want to import the Tsl2591 class from
tsl2591.py, instantiate an instance, and call its
Here is an example session:
>> from tsl2591 import Tsl2591 >>> tsl = Tsl2591('lux-1') >>> tsl.sample() 296.3712
lux-1 passed to the the
Tsl2591 constructor is the sensor id. In
this case, it can be an arbitrary string. The call to
sample() may take
almost a second to complete (it takes some time to properly sample the value
from the lux sensor). The value returned in the light reading in units of
lux. Try running the sample call again with your hand covering the light
sensor – it should return a lower value. Now, we have verified that the light
sensor is working for us!
If you get an error when instantiating or reading from the light sensor, you might have a bad connection or a problem with your sensor. Here’s what an error might look like in your REPL session:
>>> from tsl2591 import Tsl2591 >>> tsl = Tsl2591('lux-1') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "tsl2591.py", line 83, in __init__ File "tsl2591.py", line 91, in set_timing File "tsl2591.py", line 150, in enable File "tsl2591.py", line 61, in write_byte_data OSError: [Errno 19] ENODEV
If you get an error like this, double-check your wiring. If you believe all your connections are correct, you might check whether one of the physical connections is bad. Set your multitester to resistance mode. For each connection, place one lead on the pin of the ESP2866 board and the other on the associated pin of the TSL2591 board. The resistance should measure zero if there is indeed a connection.
A Light Sampling Application¶
Now, we will copy over the main module of ThingFlow and use the scheduler
to periodically call our sample method and print the result. First, start
mpfshell in the
micropython directory. Copy
to the ESP8266 as follows:
open TTYDEVICE put thingflow.py ls
You should see that
thingflow.py is now on the ESP8266.
Next, go back to the MicroPython REPL. We will import the ThingFlow core and our sensor. Then we will instantiate the sensor object and a scheduler. Finally, we will call the scheduler with the sensor, asking it to sample the sensor once every two seconds and print the resulting event. Here is the REPL session:
>>> from thingflow import * >>> from tsl2591 import Tsl2591 >>> tsl = Tsl2591('lux-1') >>> sched = Scheduler() >>> sched.schedule_sensor(tsl, 2.0, Output()) <closure> >>> sched.run_forever() ('lux-1', 344, 294.9023) ('lux-1', 345, 294.9023) ('lux-1', 347, 294.9023) ('lux-1', 349, 288.2113) ('lux-1', 351, 245.6161) ('lux-1', 352, 214.1184) ('lux-1', 354, 48.14401) ('lux-1', 356, 50.75521) ('lux-1', 358, 294.9023)
schedule_sensor() call takes three parameters: the sensor
object to be schedule, the sample interval in seconds, and the downstream
data flow. In this case we are just calling the
Output “thing” to
print the messages.
The tuples being printed have three elements: the sensor id, a timestamp, and the sensor reading.
In the next section, we’ll see how we can get these samples off the ESP2866 using its WiFi radio and the MQTT protocol.