This week, we explain to people using Yoctopuce modules for the first time how to manage them with a Python program through a relatively simple but realistic example. Obviously, we assume that the said people have at least some idea of Python programming, but we explain everything else in details.
As an application example, we are going to control a Yocto-PowerRelay depending on the temperature given by a Yocto-Temperature. We assume that you have read the preceding posts of our For the beginners series and in particular the post on the logical structure of Yoctopuce devices.
We want to change the state of the Yocto-PowerRelay depending on the temperature measured by the Yocto-Temperature
Installation
The first thing that you must do is to install the Yoctopuce Python library. To do so, you have two options. Note that selecting one option or the other has a slight impact on what follows.
First option
You can download the library from the Yoctopuce web site, you can find it on the dedicated page. It is a large zip file that you can unzip wherever you deem fit on your machine. The essential directory is the "Sources " directory. You must then edit your PYTHONPATH environment variable and add to it the path of this "Sources " directory. If you use an IDE to program in Python, you must probably also tell it where this directory is located.
Second option
If you use a Linux machine, you can type the following command in a shell:
pip install yoctopuce
And the library is automatically downloaded and installed. Note, if you select this option, imports from the Yoctopuce library are slightly different. We'll get back to this later.
Testing the examples
When you have installed the library, you'll probably want to test the examples. If you have chosen the second option, you must however download the library, unzip the content of the "examples" directory wherever you deem fit. You can find in this directory at least one example for each Yoctopuce module. Let's suppose that you have a Yocto-Temperature, the corresponding example is located in "Doc-GettingStarted-Yocto-Temperature". Go to this directory, the script that you must run is called "helloword.py". If you have used the second method to install the library, edit the script and replace the two lines
from yocto_temperature import *
by
from yoctopuce.yocto_temperature import *
If you look closely at the source code of this example, you notice that it waits for an argument on its command line. This argument is the serial number of your Yocto-Temperature or "any" if you don't know it and if you don't want to look for it. Check that your Yocto-Temperature is indeed connected and type:
python helloworld.py any
and you obtain the current temperature at the rate of one measure per second. Use control-C to stop the script. Note, you can't run this example at the same time as the VirtualHub or as any other programm using the Yoctopuce API in native USB mode. Explanations for this are located in another post.
The example for the Yocto-PowerRelay works similarly. It is located in the "Doc-GettingStarted-Yocto-PowerRelay" directory. On top of the serial number on the command line, it requires the state in which it must switch the relay: A or B. For example, try
python helloworld.py any B
to switch the relay into state B, then
python helloworld.py any A
to switch the relay back into state A.
Your first program
The idea is to write a short program switching the relay when the temperature goes above a given temperature, let's say 25°C. Let's proceed step by step.
1. Imports
You must first include the correct library imports. There is obviously the essential "yocto_api.py". As we intend to use a temperature sensor and a relay, we also need "yocto_temperature.py" and "yocto_relay.py". You must therefore start your program with:
from yocto_temperature import *
from yocto_relay import *
Note, if you have used the second option to install the library, you must write
from yoctopuce.yocto_temperature import *
from yoctopuce.yocto_relay import *
2. API initialization
You must now initialize the API by indicating that you want to work in USB mode. Simply type:
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
sys.exit("init error :" + errmsg.value)
This call is supposed to return the value YAPI.SUCCESS. In the opposite case, the errmsg object contains the error message. The most common reason for an error at this stage is to try to run at the same time two programs which use the API in USB mode. You can find more details on the different uses of registerHub in another post.
3. Function retrieval
As you have read the post on the logical structure of Yoctopuce devices, you know that the Yocto-Temperature and the Yocto-PowerRelay host different functions among which you can find temperature and relay. It's these two functions that we are interested in. There are several ways to retrieve them.
FirstXXX
If you are sure to have only one temperature function and only one relay function available, you can keep it simple and use the FirstXXX of the Ytemperature and YRelay classes.
if t is None : sys.exit("No temperature sensor found");
r = YRelay.FirstRelay()
if r is None : sys.exit("No relay found");
These methods return the first occurrence of the looked for function, or None if nothing corresponds.
FindXXX and serial number
You can also use the FindXXX method of the YTemperature and YRelay classes, with the serial number of the modules. Let's suppose that the serial number of the Yocto-Temperature is TMPSENS1-3EA8F and that the serial number of the Yocto-PowerRelay is RELAYHI1-56FC0, you can use:
if not(r.isOnline()) : sys.exit("No relay found")
t = YTemperature.FindTemperature("TMPSENS1-3EA8F.temperature")
if not(t.isOnline()) : sys.exit("No temperature sensor found")
In the opposite to FirstXXX, FindXXX always returns a valid object, therefore you must check whether it truly corresponds to a connected module with the isOnline() method. This allows you to instantiate objects corresponding to modules which could be connected later in the life of the program.
FindXXX and logical names
Instead of the serial number, you can use a logical name that you have previously assigned with the VirtualHub.
Assigning a logical name to the relay of the Yocto-PowerRelay
Let's assume that you called the relay "myRelay" and the temperature sensor "myTemp". Then, you only need to write:
if not(r.isOnline()) : sys.exit("No relay found")
t = YTemperature.FindTemperature("myTemp")
if not(t.isOnline()) : sys.exit("No temperature sensor found")
The interest of logical names is twofold: first it allows you to more easily navigate in complex systems composed of many Yoctopuce modules, and secondly it allows you to build several copies of a system without having to adapt the code to the serial numbers of each copy.
The main loop
The main loop of our program serves to read the temperature of the sensor:
value = t.get_currentValue()
Then to adjust the position of the relay depending on this temperature
if value<24: r.set_state(YRelay.STATE_A)
Note that we switch the relay into state B if the temperature is above 25, while we go back to state A if the temperature goes below 24. This is called a schmitt trigger and prevents the relay from oscillating when the temperature is too close to the trigger threshold.
We could stop here, but you don't necessarily want to run this loop at maximal speed. In any case, the refreshing rate of the Yocto-Temperature is 10Hz. We can therefore insert a 100ms pause in the loop without it affecting the system's reactivity.
Note that it is best to use YAPI.Sleep() rather than the time.sleep() Python function, as the later completely blocks the program while the YAPI function allows the API to continue to manage its internal business with the modules during the pause.
Conclusion
This post is rather long, we quite agree. But if you put together all the pieces of code that we described, you realize that using Yoctopuce modules in a Python program requires in the end only a few lines of code:
from yocto_temperature import *
from yocto_relay import *
errmsg = YRefParam()
if YAPI.RegisterHub("usb", errmsg) != YAPI.SUCCESS:
sys.exit("init error: " + errmsg.value)
t = YTemperature.FirstTemperature()
if t is None : sys.exit("No temperature sensor found")
r = YRelay.FirstRelay()
if r is None : sys.exit("No relay found")
while True:
value = t.get_currentValue()
if value>25: r.set_state(YRelay.STATE_B)
if value<24: r.set_state(YRelay.STATE_A)
YAPI.Sleep(100,errmsg)
To finish up, note that you can find an interactive documentation of the Python Yoctopuce API in the Documentation directory of the library and on our web site.