Package: python2wb
python2wbDescriptionA wrapper for paho-mqtt with which you can work with MQTTWiren Boardfrom Python.In the Wiren Board controller, information is exchanged through an MQTT broker, where devices are created according to the convention. Wiren Board has a standard tool for creating automation scriptswb-rules, but it has disadvantages: there are no community modules for different tasks, you cannot run and debug scripts on computer. Using Python allows you to write scripts the way you are used to and debug them in a familiar IDE: run the scripts locally on your computer and connect to the controller via MQTT.Files in the repository:Module source code in thepython2wbfolderExamples in theexamplesfolderIt was done “for oneself”, without guarantees and technical support, only for those who understand what they are doing.InstallInstall the module and dependencies using pip:pip install paho-mqtt python2wb.Starting workConnect the module to your script, create an object and specify the parameters for connecting to the MQTT broker. Minimal script example:# Import modulefrompython2wb.mqttimportWbMqtt# Creating an object and passing connection parameterswb=WbMqtt("wirenboard-a25ndemj.local",1883)# server, port, username, password# Declaring a function to handle subscriptionsdeflog(device_id,control_id,new_value):print("log:%s%s%s"%(device_id,control_id,new_value))# Subscription to all system device topicswb.subscribe('system/+',log)# Subscribe to LVA15 value of device metricswb.subscribe('metrics/load_average_15min',log)try:# Looping a script so it doesn't terminatewb.loop_forever()finally:# Cleaning virtual devices and subscriptions before exitingwb.clear()Deploying the project to the controllerAfter writing and debugging the project on the computer, you need to move it to the controller. Let's say the script will be in the folder/mnt/data/bin/python2wb/:Copy our files to the controller, for example, like this:scp -r ./* root@wirenboard-a25ndemj.local:/mnt/data/bin/python2wbGo to the controller console again and make the script file executablechmod +x /mnt/data/bin/python2wb/script.pyNext, create a description of the servicenano /etc/systemd/system/python2wb.service, for example with the following content:[Unit]
Description=python2wb
After=network.target

[Service]
ExecStart=python3 /mnt/data/bin/python2wb/script.py
WorkingDirectory=/mnt/data/bin/python2wb/
StandardOutput=inherit
StandardError=inherit
Restart=always
User=root

[Install]
WantedBy=multi-user.targetStart the service and place it in autostartsystemctl start python2wb ; systemctl enable python2wbWorking with device controlsThe wrapper hides long topic names from the user, providing a simple interface for interacting with device controls, allowing you to read and write data using a short path notationdevice_id/control_id:# Write value to device controlwb.set("wb-mr6c_226/K1",new_value)# Read value from controlprint(wb.get("wb-mr6c_226/K1"))Subscription to controlsIn addition, you can subscribe to one or more controls, including using the+wildcard character. Event processing occurs in the callback function that needs to be specified. The function returns:device_id— device identifier;control_id— control identifierwb-gpio/A1_OUTor list of controls["wb-gpio/A1_OUT", "wb-gpio/A2_OUT"];new_value— new value of the control, converted to one of the types (float,int,str).You can bind multiple subscriptions to one function:# Callback functiondeflog(device_id,control_id,new_value):print("log:%s%s%s"%(device_id,control_id,new_value))# Subscribe using wildcardswb.subscribe('wb-gpio/+',log)# Subscribe to one controlwb.subscribe("wb-mr6c_226/K1",log)# Subscribe to several controlswb.subscribe(["wb-gpio/A1_OUT","wb-gpio/A2_OUT"],log)You can also unsubscribe from the control if necessary:# Unsubscribe from one controlwb.unsubscribe("wb-mr6c_226/K1")# Unsubscribe from several controlswb.unsubscribe(["wb-gpio/A1_OUT","wb-gpio/A2_OUT"])Subscribe to errorsWhen working with devices through the wb-mqtt-serial driver, you can receive exchange errors that are published by the driver in MQTT:r — error reading from device;w — error writing to the device;p — the driver could not maintain the specified polling period.There can be several errors in one message, for examplerwporrp.Subscribe to errors of a specific control:# Callback functiondeflog_errors(device_id,control_id,error_value):print("log_errors:%s%s%s"%(device_id,control_id,error_value))# Subscribe to control errors wb-mr6c_226/K1wb.subscribe_errors("wb-mr6c_226/K1",log_errors)You can use the+wildcard, for example:# Subscribe to all errors of the wb-mr6c_226 modulewb.subscribe_errors("wb-mr6c_226/+",log_errors)You can also subscribe to errors from several controls through the list:# Subscribe to errors of several controlswb.subscribe_errors(["wb-gpio/A1_OUT","wb-gpio/A2_OUT"],log_errors)Unsubscribe from one or more controls:# Note from control errors wb-mr6c_226/K1wb.unsubscribe_errors("wb-mr6c_226/K1")# Note about control errors with wildcard characterwb.unsubscribe_errors("wb-mr6c_226/+")# Unsubscribe from errors of several controlswb.unsubscribe_errors(["wb-gpio/A1_OUT","wb-gpio/A2_OUT"])Subscribe to team topic /onIf you use a module in a converter, it will be useful to subscribe to a command topic in order to process actions in the web interface or third-party software. You can use the+wildcard character.# Callback functiondeflog_on(device_id,control_id,error_value):print("log_on:%s%s%s"%(device_id,control_id,error_value))# Subscribe to the command control topic wb-mr6c_226/K1wb.subscribe_on("wb-mr6c_226/K1",log_on)Subscription to arbitrary MQTT topicsSometimes you need to work with topics from third-party devices that do not know anything about the Wiren Board convention. For this purpose, there are functions for subscribing, unsubscribing and publishing with the full name of the topic. Event processing occurs in the callback function that needs to be specified. The function returns two parameters:mqtt_topic— full path to the topic;new_value— new value of type str.When subscribing, you can use wildcard characters+- subscribe to one level and#- subscribe to all levels below.Example:# Callback functiondeflog_raw(mqtt_topic,new_value):print("log_raw:%s%s"%(mqtt_topic,new_value))# Subscribe to topicwb.subscribe_raw('/wbrules/#',log_raw)# Publish a new value to a topicwb.publish_raw('/wbrules/log/info','New Log Value')# Unsubscribe from topicwb.unsubscribe_raw('/wbrules/#')Virtual devicesYou can also create virtual devices with an arbitrary number of controls and use them to interact with the user or store data:# Description of the virtual devicewb.create_virtual_device("my-device",# device id{"ru":"Моё устройство","en":"My Device"},# device title[{"name":"temp",# control identifier in mqtt. Required."title":{"ru":"Температура","en":"Temperature"},# control title. Required."type":"value",# control type. Required."default":50,# default value"order":1,# number fo sorting"units":"°C"# unit},{"name":"set_temp","title":{"ru":"Уставка","en":"Set Temperature"},"type":"value","readonly":False,# prohibits editing the control. Default True."default":12.5,"order":2,"units":"°C","min":0,"max":100},{"name":"slider","title":{"ru":"Ползунок","en":"Slider"},"type":"range","default":13,"order":3,"units":"%","min":10,"max":35},{"name":"switch","title":{"ru":"Переключатель","en":"Switch"},"type":"switch","default":1,"order":4,},{"name":"log","title":"Text Control",# you can have one line for all languages"type":"text","default":"","order":5,},],)The title of the device and controls can be specified using the line"My Device Title"or a dictionary indicating the languages ​​{"ru": "Switch", "en": "Switch 1"}.Controls are passed by an array of dictionaries. The description of the controls corresponds to the currentWiren Board convention, with the exception ofdefaultforswitch, the values ​​0and1should be used in the module.List of types and available options for each type:typePossible valuesdefaultorderunitsmin/maxreadonlyvalueany numbers: int, float+++++rangeany numbers: int, float+++++rgbformat "R;G;B", each 0...255++++texttext++++alarmtext++switch0 or 1+++pushbutton1++List of availableunits:ValueDescription, ENmm/hmm per hour, precipitation rate (rainfall rate)m/smeter per second, speedWwatt, powerkWhkilowatt hour, power consumptionVvoltagemVvoltage (millivolts)m^3/hcubic meters per hour, flowm^3cubic meters, volumeGcal/hgiga calories per hour, heat powercalcalories, energyGcalgiga calories, energyOhmresistancemOhmresistance (milliohms)barpressurembarpressure (100Pa)ssecondminminutehhourmmeterggramkgkilo grammolmole, amount of substancecdcandela, luminous intensity%, RHrelative humiditydeg Ctemperature%percentppmparts per millionppbparts per billionAampere, currentmAmilliampere, currentdegdegree, angleradradian, angleKnown issuesCreated virtual devices are not always deleted. It is possible that the script ends before the deletion procedures are completed.During installation, you need to create a description of the system for autorun, so you must update the controller software strictly via apt. When updating from a flash drive or in the web interface, the service description will be deleted. As a crutch, you can write a script on wb-rules that will run the script in Python :D