Wednesday, November 8, 2023

Domoticz with MicroPython part 2

For an index to all my stories click this text.

This is the second story in a series about sending data to and receiving data from Domoticz with MicroPython.

The reason why I am writing these is because I migrated to a new internet provider. That meant reprogramming all of my microcontrollers. They needed to contact my new router and got new IP addresses. It was a hell of a job.

So I decided to reprogram the sensors in MicroPython. What made this easy is that all my favorite microcontrollers (ESP8266, ESP32 and Raspberry Pi Pico) are supported by MicroPython.

The first story describes connecting a pushbutton to a Raspberry Pi Pico and sending it's data to Domoticz. You can use this for a myriad of purposes like a doorcontact, a windowcontact, doorbell, PIR, vibration sensor, rain sensor etc. etc. Another purpose is using your Pico with a pushbutton as a remote control for your lamps. You can re-read that story here:
http://lucstechblog.blogspot.com/2023/11/domoticz-with-micropython-part-1.html

This time we are going to do the opposite. We are going to attach a led to a Raspberry Pi Pico W and use a button on the Domoticz screen to set that led on or off. You can easily adapt this to an ESP8266 or ESP32 by just altering the pin number for the pin where the led is attached to.

This can also be used for many purposes. Think of setting a lamp on or of, starting/stopping a fan, opening a garage door, starting a pump, opening blinds etc etc etc.

Breadboard setup

For testing I attached a led to GPIO15 of the Pico



Nothing special in this setup. Just a led connected to GPIO15 and a 220 Ohm power delimiting resistor.

In a real world situation you would replace the led by an array to switch real lamps, a motor, or a fan etc. on or off.

You could even use the same setup from last story and add the led.
And like stated above you can easily adapt this to exchange the Raspberry Pi pico for an ESP8266 or ESP32. Just change the pin number accordingly in the program.

Sending data from Domoticz to the Pico

We have to have a way to make the microcontroller receive data from Domoticz. The easiest way to do this is to use the webserver framework. Normally we create a webserver in MicroPython and that sends or receives data from a computer or microcontroller. The webserver then presents a webpage on which that data is displayed.

We are going to use the webserver software but we are not going to build a webpage. We are only using that software to receive data from Domoticz and act on the received data.

Domoticz switch.

We need a switch in Domoticz that we can click to send data to the microcontroller. If you are just as lazy as I am you can use the same switch we used in the previous story. So look at : http://lucstechblog.blogspot.com/2023/11/domoticz-with-micropython-part-1.html
And follow the steps to build a virtual switch.

I will summarise the steps here:

- In the setup menu choose hardware
- Add a new device. Give it the name Virtual 1 and choose as type Dummy (Does nothing, use for virtual switches only)
- Click in the new entry Virtual 1 on Create Virtual Sensors
- In the pop-up menu give it the name MicroPython-test-switch and choose "Switch" as sensor type.
- Click on OK

- Move over to the Switches tab at the top of the screen.
- You can find the new switch there. Click on the edit button.
- Click on the switch Icon and make sure to use Generic

 


Your new switch will look like this.

The MicroPython program.

The program is like stated above the framework for a webserver. But I left out all the HTML code. So the only thing this does is acting on incoming signals.

Here is the full code:

import network
import socket
import time

from machine import Pin

led = Pin(15, Pin.OUT)

ssid = "YOUR-ROUTERS-NAME"
pw = "PASSWORD"

wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, pw)

print('Waiting for connection.',end="")
while wifi.isconnected() == False:
    time.sleep(1)
    print('', end='.')
print("")

ip = wifi.ifconfig()[0]

print("Connected with IP adress : "+ip)

addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

while True:        
        cl, addr = s.accept()
        print('client connected from', addr)
        request = cl.recv(1024)
        print(request)

        request = str(request)
        led_on = request.find('testlamp-on')
        led_off = request.find('testlamp-off')

        if led_on == 7:
            print("led on")
            led.value(1)

        if led_off == 7:
            print("led off")
            led.value(0)

        cl.close()

Most of this will be familiar to those who have worked with MicroPython before. Nevertheless I will go over the details.

import network
import socket
import time

from machine import Pin

led = Pin(15, Pin.OUT)


First things the program does is importing the necessary libraries. These are all included with your standard MicroPython distribution.

As you have seen on the breadboard layout above, the led is attached to GPIO15.

ssid = "YOUR-ROUTERS-NAME"
pw = "PASSWORD"

wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(ssid, pw)

print('Waiting for connection.',end="")
while wifi.isconnected() == False:
    time.sleep(1)
    print('', end='.')
print("")

ip = wifi.ifconfig()[0]

print("Connected with IP adress : "+ip)

Make sure you replace "YOUR-ROUTERS-NAME" and "PASSWORD" with your own routers credentials.

The next lines make sure the microcontroller (Pico or ESP) connects to your router. It first prints "Waiting for a connection "and prints every second a dot (".") as long as there is no connection made.



When the connection to your router has been established the program will print your microcontrollers IP-address in Thonny's shell.

addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

s = socket.socket()
s.bind(addr)
s.listen(1)

The program then opens a websocket. That is a connection through which we can send commands and data to the microcontroller.

while True:        
        cl, addr = s.accept()
        print('client connected from', addr)
        request = cl.recv(1024)
        print(request)

Here starts an endless loop. The program waits any data coming in. When there is anything received that is printed in Thonny's shell so we can see what data is received.

        request = str(request)
        led_on = request.find('testlamp-on')
        led_off = request.find('testlamp-off')

The received data is tested for some specific words. I used the words:
testlamp-on
testlamp-off


These are the words that Domoticz needs to send to the microcontroller to set the led on or off. You can change them in anything you like. Just make sure to note them down as we need to use them in Domoticz later on.

        if led_on == 7:
            print("led on")
            led.value(1)

        if led_off == 7:
            print("led off")
            led.value(0)

The comands in the previous section: led_on = request.find('testlamp-on') searches for the words "testlamp-on" and finds at what position in the received data these words where found.

If these words are found, they are found at position 7 in the received data. This means the words "testlamp-on" or "testlamp-off" start at the 7th letter in the received data.
So if these words are found at that position the lamp is set on or off.

        cl.close()

And this last command closes the connection. The while True loop starts over looking for a new connection.

Setting the led on or off from the browser.

As Domoticz is just sending a HTTP command and we can test if it works from our browser.

Start with the IP-address of the microcontroller which was printed in Thonny's shell. In my case that was 192.168.178.193 and let that follow by "/testlamp-on"
So the complete command is:
http://192.168.178.193/testlamp-on



Put that in your browsers address field and the lamp should go on.

http://192.168.178.193/testlamp-off

Should put the lamp off again.

Test if this works. If it does not check the code again, and check that the led was connected in the right way. Also make sure you use the right IP address.

Thonny's shell will show the following:



You can see the IP address from the client that connected to the microcontroller. In this example that IP address is 192.168.178.196 which is the IP-address from my computer.

The second line says:

b'GET /testlamp-on HTTP


And this shows that the text "testlamp-on" is indeed at the 7th position. which makes the webserver software set the led on.


Back to Domoticz

Now we know that the webserver works as expected we can make Domoticz send these commands.



Press on the edit button in your switches entry.



Fill in the commands:

http://192.168.178.193/testlamp-on
http://192.168.178.193/testlamp-off


In the fields On Action and Off action.
Do not forget to press the Save button.

And that is it.
Pressing the switch in Domoticz should turn the led on or off.

In the real world.

Setting a led on or off from your Domoticz home automation system is fun but not really related to the real world.
So exchange the led for a relay and you can control real lights, fan's, pumps, ledstrips, garden sprinklers and whatever more you might think off.

If you use this setup and the one from the previous story on a second controller you can push the pushbutton on the first controller and have that set the lamp on, on the second controller.
This way you can have a lamp automatically go on if a pir detects motion, or a door contact is made etc.

Another option would be changing the pushbutton from the previous story into an LDR. As soon as the sun rises have the second Pico lower the sun screens or blinds.

The possibilities are limited by your imagination.

So have fun
Till next time


Luc Volders