Zigbee heating valve heartbeat check implemented

This commit is contained in:
Dirk Alders 2023-12-16 08:16:45 +01:00
parent 33042e3f3c
commit a2d4306fa6
4 changed files with 45 additions and 5 deletions

View File

@ -7,7 +7,7 @@ import time
from z_server import config from z_server import config
from z_server import tcp_socket from z_server import tcp_socket
from z_server.z_protocol import server as client_prot from z_server.z_protocol import server as client_prot
from z_server.z_protocol import DID_FOLLOWS_HEATING_SETPOINT, DID_BATTERY_LEVEL from z_server.z_protocol import DID_FOLLOWS_HEATING_SETPOINT, DID_BATTERY_LEVEL, DID_HEARTBEAT
from z_server import socket_protocol from z_server import socket_protocol
import sys import sys
@ -31,7 +31,10 @@ if __name__ == '__main__':
"fun": "FUN_HEA" # <-- Const, because script is for heat_vlv only "fun": "FUN_HEA" # <-- Const, because script is for heat_vlv only
} }
# #
if sys.argv[0].endswith('check_z_heat_vlv_follow'): if sys.argv[0].endswith('check_z_heat_vlv_heartbeat'):
sp.send(socket_protocol.SID_READ_REQUEST, DID_HEARTBEAT, data)
sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, DID_HEARTBEAT).get_data()
elif sys.argv[0].endswith('check_z_heat_vlv_follow'):
sp.send(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_HEATING_SETPOINT, data) sp.send(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_HEATING_SETPOINT, data)
sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, DID_FOLLOWS_HEATING_SETPOINT).get_data() sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, DID_FOLLOWS_HEATING_SETPOINT).get_data()
elif sys.argv[0].endswith('check_z_heat_vlv_battery'): elif sys.argv[0].endswith('check_z_heat_vlv_battery'):

1
check_z_heat_vlv_heartbeat Symbolic link
View File

@ -0,0 +1 @@
check_z_heat_vlv_follow

View File

@ -16,8 +16,11 @@ class base(object):
FOLLOW_REQUEST_ERROR = 60 # Seconds, till error comes up, if device does not follow the command FOLLOW_REQUEST_ERROR = 60 # Seconds, till error comes up, if device does not follow the command
FOLLOW_KEYS = ["current_heating_setpoint", ] FOLLOW_KEYS = ["current_heating_setpoint", ]
# #
BATTERY_LVL_WARNING = 10 BATTERY_LVL_WARNING = 20
BATTERY_LVL_ERROR = 5 BATTERY_LVL_ERROR = 10
#
LAST_MSG_WARNING = 6 * 24 * 60 * 60
LAST_MSG_ERROR = 24 * 24 * 60 * 60
def __init__(self, mqtt_client: mqtt.mqtt_client, topic): def __init__(self, mqtt_client: mqtt.mqtt_client, topic):
self.topic = topic self.topic = topic
@ -25,6 +28,8 @@ class base(object):
mqtt_client.add_callback(topic, self.__rx__) mqtt_client.add_callback(topic, self.__rx__)
mqtt_client.add_callback(topic + '/#', self.__rx__) mqtt_client.add_callback(topic + '/#', self.__rx__)
# #
self.last_device_msg = None
#
self.__target_storage__ = {} self.__target_storage__ = {}
self.__state_storage__ = {} self.__state_storage__ = {}
# #
@ -45,9 +50,24 @@ class base(object):
def status(self, key): def status(self, key):
# #
# HEARTBEAT
#
if key == "heartbeat":
if self.last_device_msg is None:
return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exists, but no data received or unknown monitoring"}
else:
dt = time.time() - self.last_device_msg
dt_disp = dt / 60 / 60
if dt > self.LAST_MSG_ERROR:
return {"status": nagios.Nagios.ERROR, "msg": "Last message %.1fh ago" % dt_disp}
elif dt > self.LAST_MSG_WARNING:
return {"status": nagios.Nagios.WARNING, "msg": "Last message %.1fh ago" % dt_disp}
else:
return {"status": nagios.Nagios.OK, "msg": "Last message %.1fh ago" % dt_disp}
#
# FOLLOW SETPOINT # FOLLOW SETPOINT
# #
if key in self.FOLLOW_KEYS: elif key in self.FOLLOW_KEYS:
tm_s, value_s = self.__state_storage__.get(key, (0, None)) tm_s, value_s = self.__state_storage__.get(key, (0, None))
try: try:
tm_t, value_t = self.__target_storage__[key] tm_t, value_t = self.__target_storage__[key]
@ -107,16 +127,30 @@ class livarno_sw_br_ct(base):
class brennenstuhl_heatingvalve(base): class brennenstuhl_heatingvalve(base):
BATTERY_LVL_WARNING = 10
BATTERY_LVL_ERROR = 5
def __init__(self, mqtt_client: mqtt.mqtt_client, topic): def __init__(self, mqtt_client: mqtt.mqtt_client, topic):
base.__init__(self, mqtt_client, topic) base.__init__(self, mqtt_client, topic)
def __rx__(self, client, userdata, message): def __rx__(self, client, userdata, message):
payload = json.loads(message.payload) payload = json.loads(message.payload)
#
# heartbeat
#
if message.topic == self.topic:
self.last_device_msg = time.time()
#
# follow setpoint
#
if "current_heating_setpoint" in payload: if "current_heating_setpoint" in payload:
if message.topic == self.topic + '/set': if message.topic == self.topic + '/set':
self.target("current_heating_setpoint", payload["current_heating_setpoint"]) self.target("current_heating_setpoint", payload["current_heating_setpoint"])
if message.topic == self.topic: if message.topic == self.topic:
self.state("current_heating_setpoint", payload["current_heating_setpoint"]) self.state("current_heating_setpoint", payload["current_heating_setpoint"])
#
# battery level
#
if "battery" in payload and message.topic == self.topic: if "battery" in payload and message.topic == self.topic:
self.battery = payload["battery"] self.battery = payload["battery"]

View File

@ -4,6 +4,7 @@ import socket_protocol
DID_FOLLOWS_HEATING_SETPOINT = 'current_heating_setpoint' DID_FOLLOWS_HEATING_SETPOINT = 'current_heating_setpoint'
DID_BATTERY_LEVEL = 'battery' DID_BATTERY_LEVEL = 'battery'
DID_HEARTBEAT = 'heartbeat'
class server(socket_protocol.pure_json_protocol): class server(socket_protocol.pure_json_protocol):
@ -18,6 +19,7 @@ class server(socket_protocol.pure_json_protocol):
if not self.__comm_inst__.IS_CLIENT: if not self.__comm_inst__.IS_CLIENT:
self.register_callback(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_HEATING_SETPOINT, self.device_status) self.register_callback(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_HEATING_SETPOINT, self.device_status)
self.register_callback(socket_protocol.SID_READ_REQUEST, DID_BATTERY_LEVEL, self.device_status) self.register_callback(socket_protocol.SID_READ_REQUEST, DID_BATTERY_LEVEL, self.device_status)
self.register_callback(socket_protocol.SID_READ_REQUEST, DID_HEARTBEAT, self.device_status)
def device_status(self, msg): def device_status(self, msg):
if msg.get_status() == socket_protocol.STATUS_OKAY: if msg.get_status() == socket_protocol.STATUS_OKAY: