与MySensors网关通信的Python API
项目描述
PyMysensors 
Python API,用于与MySensors网关通信。目前支持串行协议v1.4、v1.5、v2.0 - v2.2。尚未实现v2.x的所有功能。
- 支持v2.x的串行API的smartsleep。
- 支持v2.x的串行API的MQTT客户端网关。
- 支持OTA更新,适用于DualOptiboot和MYSBootloader引导加载程序。
- 所有网关实例(串行、TCP(以太网)或MQTT)将在单独的线程中运行。
- 作为在单独线程中运行网关的替代方案,有所有网关使用asyncio的实验性实现。
需求
PyMysensors需要Python 3.7+。
安装
您可以从PyPI轻松安装它
pip3 install pymysensors
用法
目前最佳使用API的方式是实现回调处理程序
import mysensors.mysensors as mysensors
def event(message):
"""Callback for mysensors updates."""
print('sensor_update ' + str(message.node_id))
GATEWAY = mysensors.SerialGateway('/dev/ttyACM0', event)
GATEWAY.start()
在上面的示例中,当Mysensors网络中的节点被更新时,pymysensors将调用"event"。传递给回调处理程序的消息包含以下数据
Message
gateway - the gateway instance
node_id - the sensor node identifier
child_id - the child sensor id
type - the message type, for example "set" or "presentation" (int)
ack - True is message was an ACK, false otherwise (0 or 1)
sub_type - the message sub_type (int)
payload - the payload of the message (string)
注意:sub_type的内容根据上下文而异。在表示消息中,sub_type表示S_TYPE数据(如S_INFO)。在“set”和“req”消息中,sub_type表示V_TYPE数据(如V_TEXT)。
消息类型和子类型的符号名称在特定协议版本的const_X.py文件中定义。
网关及其网络的数据结构如下所述。
SerialGateway/TCPGateway/MQTTGateway
sensors - a dict containing all nodes for the gateway; node is of type Sensor
Sensor - a sensor node
children - a dict containing all child sensors for the node
sensor_id - node id on the MySensors network
type - 17 for node or 18 for repeater
sketch_name
sketch_version
battery_level
protocol_version - the mysensors protocol version used by the node
ChildSensor - a child sensor
id - child id on the parent node
type - data type, S_HUM, S_TEMP etc.
description - the child description sent when presenting the child
values - a dictionary of values (V_HUM, V_TEMP, etc.)
获取节点23,子传感器4的类型和值将按以下方式执行
s_type = GATEWAY.sensors[23].children[4].type
values = GATEWAY.sensors[23].children[4].values
类似地,打印找到的节点的所有sketch名称可能如下所示
for node in GATEWAY.sensors.values():
print(node.sketch_name)
在事件函数中获取子对象可以是
if GATEWAY.is_sensor(message.node_id, message.child_id):
child = GATEWAY.sensors[message.node_id].children[message.child_id]
else:
print("Child not available yet.")
要更新节点子传感器的值并将其发送到节点,请使用Gateway类中的set_child_value方法
# To set sensor 1 (int), child 1 (int), sub-type V_LIGHT (= 2) (int), with value 1.
GATEWAY.set_child_value(1, 1, 2, 1)
持久性
启用持久性模式后,您可以重新启动网关而无需重新启动传感器网络中的每个单独节点。要启用持久性模式,构造函数中的关键字参数persistence
应为True。可以指定配置文件的路径作为关键字参数persistence_file
。文件类型(.pickle或.json)将设置使用哪种持久性协议,pickle或json。JSON文件可以使用普通文本编辑器读取。如果自上次保存以来已进行更新,则将在每10秒的调度上执行持久性文件保存。确保在启动网关之前启动持久性保存。
GATEWAY.start_persistence()
协议版本
将关键字参数protocol_version
设置为使用MySensors串行API的哪个版本。默认值是'1.4'
。将protocol_version
设置为正在使用的版本。
串行网关
串行网关也支持设置波特率、读取超时和重连超时。
import mysensors.mysensors as mysensors
def event(message):
"""Callback for mysensors updates."""
print("sensor_update " + str(message.node_id))
GATEWAY = mysensors.SerialGateway(
'/dev/ttyACM0', baud=115200, timeout=1.0, reconnect_timeout=10.0,
event_callback=event, persistence=True,
persistence_file='some_folder/mysensors.pickle', protocol_version='2.2')
GATEWAY.start_persistence() # optional, remove this line if you don't need persistence.
GATEWAY.start()
除了串行网关外,还支持两种其他网关类型:tcp-ethernet网关和MQTT网关。
TCP以太网网关
以太网网关的初始化类似于串行网关。以太网网关支持设置tcp主机端口、接收超时和重连超时,除了通用设置和主机IP地址外。
GATEWAY = mysensors.TCPGateway(
'127.0.0.1', port=5003, timeout=1.0, reconnect_timeout=10.0,
event_callback=event, persistence=True,
persistence_file='some_folder/mysensors.pickle', protocol_version='1.4')
MQTT网关
MQTT网关需要MySensors串行API v2.0或更高版本,并且网关设备中加载了MQTT客户端网关示例sketch。网关还需要一个MQTT代理和一个连接到代理的python MQTT客户端接口。有关如何实现此操作和初始化MQTT网关的示例,请参阅mqtt.py。
空中(OTA)固件更新
调用Gateway
方法的update_fw
以设置一个或多个节点进行OTA固件更新。该方法接受三个位置参数和一个关键字参数。第一个参数应该是要更新的节点ID。这也可以是多个节点ID的列表。接下来的两个参数应该是表示固件类型和版本的整数。关键字参数是可选的,应该是包含新固件的hex文件的路径。
GATEWAY.update_fw([1, 2], 1, 2, fw_path='/path/to/firmware.hex')
在调用 update_fw
方法后,当 pymysensors 网关接收到下一个设置消息时,节点将被请求重启。重启后以及 MySensors 的 begin
方法期间,节点将发送固件配置请求。pymysensors 库将响应该配置请求。如果节点收到正确的固件配置响应,它将发送一个请求特定固件块的请求。pymysensors 库将处理此请求并发送固件响应消息。这种请求-响应对话将继续,直到发送所有固件块。如果传输的固件的 CRC 与固件配置响应的 CRC 匹配,节点将重启并加载新固件。
网关 ID
网关方法 get_gateway_id
尝试返回网关的唯一 ID。对于串行网关,这是 USB 设备的序列号;对于 TCP 网关,这是连接的网关的 MAC 地址;对于 MQTT 网关,这是发布主题前缀(in_prefix)。
连接回调
可以在网关上注册两个可选回调,当与网关设备建立连接和连接丢失时被调用。这两个回调都应该接受一个网关参数,即网关实例。连接丢失回调还应接受第二个参数作为可能的连接错误异常参数。如果连接丢失没有错误,例如断开连接时,错误参数将是 None
。
注意: MQTT 网关不支持这些回调,因为 MQTT 代理的连接由 pymysensors 外部处理。
def conn_made(gateway):
"""React when the connection is made to the gateway device."""
pass
GATEWAY.on_conn_made = conn_made
def conn_lost(gateway, error):
"""React when the connection is lost to the gateway device."""
pass
GATEWAY.on_conn_lost = conn_lost
异步网关
串行、TCP 和 MQTT 网关现在也有支持 asyncio 的版本。使用 AsyncSerialGateway
类、AsyncTCPGateway
类或 AsyncMQTTGateway
类来创建使用 asyncio 的网关。以下公共方法是异步网关中的协程
- get_gateway_id
- start_persistence
- start
- stop
- update_fw
有关如何使用此网关的示例,请参阅 async_main.py。
开发
安装开发所需的软件包。
pip install -r requirements_dev.txt
使用 Makefile 来运行常见的开发任务。
make
代码格式化
我们使用 black 代码格式化器来自动格式化代码。
black ./
发布
请参阅 发布说明。
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装软件包 的更多信息。