Controlling Devices Using MQTT and Python-Part 2

Welcome back to the workshop/project. If you haven’t read part one then it is here- Continue to part 1

We can send commands to our device and change the name we will now.

  • Implement support for the backup name
  • Get the device to report status data

Implementing Support for the Backup Name

Because we can change the device name it is important that we have a fall back name in case of problems.

I am going to use the device client ID as this name. The code is below and is inserted into the check name function:

    if sensor_name==device_name or sensor_name==device_friendly_name:
        print("sensor name match")
        match_flag=True
    if sensor_name==device_backup_name:
        print("backup sensor name match")
        match_flag=True
if __name__ == "__main__" :
    
    r=random.randrange(1,10000)
    cname="sensor-"+str(r)
    device_backup_name=cname #set backup name

Device State

Most sensors publish their current state at regular intervals. So we need to create a new function called pub_data to do this.

Our code has to intervals a chatty interval and a normal interval

chatty_interval=1 #every second
data_pub_interval=300 #every 5 mins

In addition we also need to publish the device state after a change and so we need to add this to the pub_data() function.

So now our sensor will publish the state after any change and also at a preset interval.

In all case the retain flag is set.

The topic we will use is:

house/status/device/state

Device Status

It is useful to have information about the device we are controlling. This could be the IP address,battery level, device ID and names etc.

This information is in addition to the device state e.g ON/OFF etc

For this I am going to use the topic status, so we will publish this information on:

house/status/device/info

The status information will need to be published at regular intervals and we should be able to change this.

So first we set the status interval at the top of the script

pub_status_interval=60 #seconds

We now create a dictionary object to contain the information
status_data.

we will get the ip address of the host machine using the socket library so we need to import it.

hostname=socket.gethostname()
ip_address = socket.gethostbyname(hostname)
device_info ={"battery":3,"IPAddress":ip_address,"FName":"","DeviceID":""}
device_info["FName"]=device_friendly_name
device_info["DeviceID"]=deviceID

The code to publish the status data is in the pub_info() function.

Both the pub_data() and pub_info() functions are called every second from the main loop.

The device_info_pub_interval variable determines how often the status info data is published.

The code for this is in the script device2.py which you can download below.

Script Source code Download

download

Design Exercise

We are now going to finish our workshop by doing a little design exercise.

Scenario

We have 5 lights and 3 light groups

living room +dining room light in group1

main bedroom +spare bedroom light in group 2

outdoor light

All lights are in group 3

We have 5 temperature and humidity sensors one in each room and one outside

We have an outside water feature with a controllable pump. We can turn the pump on and off and change its flow rate. It has three positions. low,medium,high and always starts in the low position.

Exercise Task

Design a topic structure for our devices and assign friendly names and group names.

Task Answer

The topic structure we will be using is as described in the overview and will be

topic base+action +device name + command+value

so a command would be:

house/cmnd/main-bedroom-light/power/off or on

our action topics are

  • cmnd – command sent to the device
  • response – A response from the device to a command
  • status – Device status e.g up,uptime,battery,signal level,state.

Now we are in a position to create our commands

Lights

Device Command Response
Bedroom house/cmnd/bedroom-light/power/[off or on] house/response/bedroom-light
Spare-Room house/cmnd/spareroom-light/power/[off or on] house/response/spareroom-light
living Room house/cmnd/livingroom-light/power/[off or on] house/response/livingroom-light
Dining Room house/cmnd/livingroom-light/power/[off or on] house/response/livingroom-light
Outside house/cmnd/outside-light/[off or on] house/response/outside-light
All house/cmnd/group3/power/[off or on] house/response/[all lights in the group]
Upstairs lights house/cmnd/upstairs-light/power/[off or on] house/response/[all lights in the group]
Downstairs lights house/cmnd/downstairs-light/power/[off or on] house/response/[all lights in the group]

Payload contains the response value which is an echo of the cmnd so the command to turn the mainĀ  light on would get the response on.

house/response/main-light

Task 2
Complete the table for pump

Device Command Response
pump house/cmnd/ house/response/

Task Answer

Device Command Response
pump house/cmnd/pump/power/[on,off] house/response/pump
pump house/cmnd/pump/speed/[low,medium,high] house/response/pump

Note: Payload contains the response value which is an echo of the cmnd so the command to turn the pump on would get the response on.

house/response/pump

Questions

Q1 -Why is there no table for the temperature and humidity sensors?

Q2 – Could we use 1 and 0 for on and off and 0,1,2 for low medium and high?

Q3- We have used the topic structure to send the command could we use the payload instead or as well as.

Related tutorials and Resources

Answers

Q1- Because they only report data. However in real life they are usually configurable via a command and so you would also need a command topic for this.

Q2- Yes.

Q3 – Yes. For simple commands like power on and off the topic structure works well and is east to implement. For more complex data we usually use JSON which is sent in the payload.

End and Questions

That is the end of this workshop and your feedback would be appreciated.If you have any questions then please use the comments form to ask.

coffeeThis workshop is also available as a pdf with demo scripts on my buy me a coffee page

 

Please rate? And use Comments to let me know more

Leave a Reply

Your email address will not be published. Required fields are marked *