Inital check_z_actor added + refactoring
This commit is contained in:
parent
51c0b9eaa9
commit
5a9b7a1847
1
check_z_actor
Symbolic link
1
check_z_actor
Symbolic link
@ -0,0 +1 @@
|
||||
check_z_heartbeat
|
@ -3,11 +3,12 @@
|
||||
|
||||
import argparse
|
||||
import nagios
|
||||
import os
|
||||
import time
|
||||
from z_server import config
|
||||
from z_server import tcp_socket
|
||||
from z_server.z_protocol import server as client_prot
|
||||
from z_server.z_protocol import DID_FOLLOWS_SETPOINT, DID_BATTERY_LEVEL, DID_HEARTBEAT, DID_LINKQUALITY
|
||||
from z_server.z_protocol import DIDS
|
||||
from z_server import socket_protocol
|
||||
import sys
|
||||
|
||||
@ -32,19 +33,14 @@ if __name__ == '__main__':
|
||||
"fun": args.fun
|
||||
}
|
||||
#
|
||||
if sys.argv[0].endswith('check_z_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_battery'):
|
||||
sp.send(socket_protocol.SID_READ_REQUEST, DID_BATTERY_LEVEL, data)
|
||||
sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, DID_BATTERY_LEVEL).get_data()
|
||||
elif sys.argv[0].endswith('check_z_linkquality'):
|
||||
sp.send(socket_protocol.SID_READ_REQUEST, DID_LINKQUALITY, data)
|
||||
sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, DID_LINKQUALITY).get_data()
|
||||
elif sys.argv[0].endswith('check_z_follow'):
|
||||
sp.send(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_SETPOINT, data)
|
||||
sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, DID_FOLLOWS_SETPOINT).get_data()
|
||||
else:
|
||||
sys.stderr.write('No action for command called "%s"\n' % sys.argv[0])
|
||||
|
||||
did = os.path.basename(sys.argv[0])[8:]
|
||||
#
|
||||
if did not in DIDS:
|
||||
print("Unknown data id %s. You might add it in z_server.z_protocol." % did)
|
||||
sys.exit(100)
|
||||
nagios.Nagios().exit(**sp_data)
|
||||
else:
|
||||
sp.send(socket_protocol.SID_READ_REQUEST, did, data)
|
||||
sp_data = sp.receive(socket_protocol.SID_READ_RESPONSE, did).get_data() or {
|
||||
"status": 101, "msg": "No answer from device for \"%s\". You might want to add it in z_server.devices" % did}
|
||||
nagios.Nagios().exit(**sp_data)
|
||||
|
@ -1 +1 @@
|
||||
check_z_follow
|
||||
check_z_heartbeat
|
@ -3,6 +3,7 @@ import logging
|
||||
import mqtt
|
||||
import nagios
|
||||
import time
|
||||
from z_protocol import DID_ACTOR, DID_BATTERY_LEVEL, DID_FOLLOWS_SETPOINT, DID_HEARTBEAT, DID_LINKQUALITY
|
||||
|
||||
try:
|
||||
from config import APP_NAME as ROOT_LOGGER_NAME
|
||||
@ -12,14 +13,13 @@ logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
|
||||
|
||||
|
||||
class base(object):
|
||||
MONITORING_HEARTBEAT = "heartbeat"
|
||||
MONITORING_BATTERY = "battery"
|
||||
MONITORING_FOLLOW_SETPOINT = "follow_setpoint"
|
||||
MONITORING_LINKQUALITY = "linkquality"
|
||||
KEY_BATTERY = 'battery'
|
||||
KEY_CURRENT_VALUE = None
|
||||
KEY_LINKQUALITY = 'linkquality'
|
||||
KEY_SETPOINT = None
|
||||
#
|
||||
FOLLOW_REQUEST_WARNING = 5 # Seconds, till warning 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_KEY = None
|
||||
#
|
||||
BATTERY_LVL_WARNING = 15
|
||||
BATTERY_LVL_ERROR = 5
|
||||
@ -42,9 +42,6 @@ class base(object):
|
||||
#
|
||||
self.__target_storage__ = {}
|
||||
self.__state_storage__ = {}
|
||||
#
|
||||
self.battery = None
|
||||
self.linkquality = None
|
||||
|
||||
def __rx__(self, client, userdata, message):
|
||||
try:
|
||||
@ -54,28 +51,22 @@ class base(object):
|
||||
else:
|
||||
if type(payload) is dict:
|
||||
#
|
||||
# Device values
|
||||
#
|
||||
if message.topic == self.topic:
|
||||
for key in [self.KEY_BATTERY, self.KEY_CURRENT_VALUE, self.KEY_LINKQUALITY, self.KEY_SETPOINT]:
|
||||
if key in payload:
|
||||
self.state(key, payload[key])
|
||||
#
|
||||
# Device setpoint
|
||||
#
|
||||
if message.topic == self.topic + '/set' and self.KEY_SETPOINT in payload:
|
||||
self.target(self.KEY_SETPOINT, payload[self.KEY_SETPOINT])
|
||||
#
|
||||
# heartbeat
|
||||
#
|
||||
if message.topic == self.topic:
|
||||
self.last_device_msg = time.time()
|
||||
#
|
||||
# follow setpoint
|
||||
#
|
||||
if self.FOLLOW_KEY is not None and self.FOLLOW_KEY in payload:
|
||||
if message.topic == self.topic + '/set':
|
||||
self.target(self.FOLLOW_KEY, payload[self.FOLLOW_KEY])
|
||||
if message.topic == self.topic:
|
||||
self.state(self.FOLLOW_KEY, payload[self.FOLLOW_KEY])
|
||||
#
|
||||
# battery level
|
||||
#
|
||||
if self.MONITORING_BATTERY in payload and message.topic == self.topic:
|
||||
self.battery = payload[self.MONITORING_BATTERY]
|
||||
#
|
||||
# linkquality
|
||||
#
|
||||
if self.MONITORING_LINKQUALITY in payload and message.topic == self.topic:
|
||||
self.linkquality = payload[self.MONITORING_LINKQUALITY]
|
||||
|
||||
def target(self, key, value):
|
||||
tm_t, value_t = self.__target_storage__.get(key, (0, None))
|
||||
@ -89,74 +80,81 @@ class base(object):
|
||||
|
||||
def status(self, key):
|
||||
#
|
||||
# ACTOR
|
||||
#
|
||||
if key == DID_ACTOR:
|
||||
return self.__nagios_return__(DID_ACTOR, nagios.Nagios.WARNING, "Not available for this device")
|
||||
#
|
||||
# HEARTBEAT
|
||||
#
|
||||
if key == self.MONITORING_HEARTBEAT:
|
||||
elif key == DID_HEARTBEAT:
|
||||
if self.last_device_msg is None:
|
||||
return self.__nagios_return__(self.MONITORING_HEARTBEAT, nagios.Nagios.UNKNOWN, "Device exists, but no data received")
|
||||
return self.__nagios_return__(DID_HEARTBEAT, nagios.Nagios.UNKNOWN, "Device exists, but no data received")
|
||||
else:
|
||||
dt = time.time() - self.last_device_msg
|
||||
dt_disp = dt / 60 / 60
|
||||
if dt > self.LAST_MSG_ERROR:
|
||||
return self.__nagios_return__(self.MONITORING_HEARTBEAT, nagios.Nagios.ERROR, "Last message %.1fh ago" % dt_disp)
|
||||
return self.__nagios_return__(DID_HEARTBEAT, nagios.Nagios.ERROR, "Last message %.1fh ago" % dt_disp)
|
||||
elif dt > self.LAST_MSG_WARNING:
|
||||
return self.__nagios_return__(self.MONITORING_HEARTBEAT, nagios.Nagios.WARNING, "Last message %.1fh ago" % dt_disp)
|
||||
return self.__nagios_return__(DID_HEARTBEAT, nagios.Nagios.WARNING, "Last message %.1fh ago" % dt_disp)
|
||||
else:
|
||||
return self.__nagios_return__(self.MONITORING_HEARTBEAT, nagios.Nagios.OK, "Last message %.1fh ago" % dt_disp)
|
||||
return self.__nagios_return__(DID_HEARTBEAT, nagios.Nagios.OK, "Last message %.1fh ago" % dt_disp)
|
||||
#
|
||||
# FOLLOW SETPOINT
|
||||
#
|
||||
elif key == self.MONITORING_FOLLOW_SETPOINT:
|
||||
if self.FOLLOW_KEY is None:
|
||||
return self.__nagios_return__(self.MONITORING_FOLLOW_SETPOINT, nagios.Nagios.UNKNOWN, "Device exist, but does not follow any setpoint.", force=True)
|
||||
tm_s, value_s = self.__state_storage__.get(self.FOLLOW_KEY, (0, None))
|
||||
elif key == DID_FOLLOWS_SETPOINT:
|
||||
if self.KEY_SETPOINT is None:
|
||||
return self.__nagios_return__(DID_FOLLOWS_SETPOINT, nagios.Nagios.UNKNOWN, "Device exist, but does not follow any setpoint.", force=True)
|
||||
tm_s, value_s = self.__state_storage__.get(self.KEY_SETPOINT, (0, None))
|
||||
try:
|
||||
tm_t, value_t = self.__target_storage__[self.FOLLOW_KEY]
|
||||
tm_t, value_t = self.__target_storage__[self.KEY_SETPOINT]
|
||||
except KeyError:
|
||||
if value_s is not None:
|
||||
return self.__nagios_return__(self.MONITORING_FOLLOW_SETPOINT, nagios.Nagios.OK, "Current temperature setpoint %.1f°C, but never received a setpoint. That might be okay." % value_s)
|
||||
return self.__nagios_return__(self.MONITORING_FOLLOW_SETPOINT, nagios.Nagios.UNKNOWN, "Device exists, but no data received")
|
||||
return self.__nagios_return__(DID_FOLLOWS_SETPOINT, nagios.Nagios.OK, "Current temperature setpoint %.1f°C, but never received a setpoint. That might be okay." % value_s)
|
||||
return self.__nagios_return__(DID_FOLLOWS_SETPOINT, nagios.Nagios.UNKNOWN, "Device exists, but no data received")
|
||||
else:
|
||||
tm = time.time()
|
||||
dt = tm - tm_t
|
||||
if value_t != value_s and dt > self.FOLLOW_REQUEST_ERROR:
|
||||
return self.__nagios_return__(self.MONITORING_FOLLOW_SETPOINT, nagios.Nagios.ERROR, "Requested setpoint %.1f°C unequal valve setpoint %.1f°C since %.1fmin" % (value_t, value_s, (time.time()-tm_s)/60))
|
||||
return self.__nagios_return__(DID_FOLLOWS_SETPOINT, nagios.Nagios.ERROR, "Requested setpoint %.1f°C unequal valve setpoint %.1f°C since %.1fmin" % (value_t, value_s, (time.time()-tm_s)/60))
|
||||
elif value_t != value_s and dt > self.FOLLOW_REQUEST_WARNING:
|
||||
return self.__nagios_return__(self.MONITORING_FOLLOW_SETPOINT, nagios.Nagios.WARNING, "Requested setpoint %.1f°C unequal valve setpoint %.1f°C since %.1fmin" % (value_t, value_s, (time.time()-tm_s)))
|
||||
return self.__nagios_return__(self.MONITORING_FOLLOW_SETPOINT, nagios.Nagios.OK, "Requested setpoint equal valve setpoint %.1f°C" % value_s)
|
||||
return self.__nagios_return__(DID_FOLLOWS_SETPOINT, nagios.Nagios.WARNING, "Requested setpoint %.1f°C unequal valve setpoint %.1f°C since %.1fmin" % (value_t, value_s, (time.time()-tm_s)))
|
||||
return self.__nagios_return__(DID_FOLLOWS_SETPOINT, nagios.Nagios.OK, "Requested setpoint equal valve setpoint %.1f°C" % value_s)
|
||||
#
|
||||
# BATTERY
|
||||
#
|
||||
elif key == self.MONITORING_BATTERY:
|
||||
if self.battery is None:
|
||||
return self.__nagios_return__(self.MONITORING_BATTERY, nagios.Nagios.UNKNOWN, "Device exists, but no data received or unknown monitoring")
|
||||
elif self.battery <= self.BATTERY_LVL_ERROR:
|
||||
return self.__nagios_return__(self.MONITORING_BATTERY, nagios.Nagios.ERROR, "Battery level critical low (%.1f%%)" % self.battery)
|
||||
elif self.battery <= self.BATTERY_LVL_WARNING:
|
||||
return self.__nagios_return__(self.MONITORING_BATTERY, nagios.Nagios.WARNING, "Battery level low (%.1f%%)" % self.battery)
|
||||
elif key == DID_BATTERY_LEVEL:
|
||||
battery_lvl = self.__state_storage__.get(self.KEY_BATTERY, (0, None))[1]
|
||||
if battery_lvl is None:
|
||||
return self.__nagios_return__(DID_BATTERY_LEVEL, nagios.Nagios.UNKNOWN, "Device exists, but no data received or unknown monitoring")
|
||||
elif battery_lvl <= self.BATTERY_LVL_ERROR:
|
||||
return self.__nagios_return__(DID_BATTERY_LEVEL, nagios.Nagios.ERROR, "Battery level critical low (%.1f%%)" % battery_lvl)
|
||||
elif battery_lvl <= self.BATTERY_LVL_WARNING:
|
||||
return self.__nagios_return__(DID_BATTERY_LEVEL, nagios.Nagios.WARNING, "Battery level low (%.1f%%)" % battery_lvl)
|
||||
else:
|
||||
return self.__nagios_return__(self.MONITORING_BATTERY, nagios.Nagios.OK, "Battery okay (%.1f%%)" % self.battery)
|
||||
return self.__nagios_return__(DID_BATTERY_LEVEL, nagios.Nagios.OK, "Battery okay (%.1f%%)" % battery_lvl)
|
||||
#
|
||||
# LINKQUALITY
|
||||
#
|
||||
elif key == self.MONITORING_LINKQUALITY:
|
||||
if self.linkquality is None:
|
||||
return self.__nagios_return__(self.MONITORING_LINKQUALITY, nagios.Nagios.UNKNOWN, "Device exists, but no data received or unknown monitoring")
|
||||
elif self.linkquality <= self.LINKQUALITY_ERROR:
|
||||
return self.__nagios_return__(self.MONITORING_LINKQUALITY, nagios.Nagios.ERROR, "Linkquality critical low (%d)" % self.linkquality)
|
||||
elif self.linkquality <= self.LINKQUALITY_WARNING:
|
||||
return self.__nagios_return__(self.MONITORING_LINKQUALITY, nagios.Nagios.WARNING, "Linkquality level low (%d)" % self.linkquality)
|
||||
elif key == DID_LINKQUALITY:
|
||||
linkquality = self.__state_storage__.get(self.KEY_LINKQUALITY, (0, None))[1]
|
||||
if linkquality is None:
|
||||
return self.__nagios_return__(DID_LINKQUALITY, nagios.Nagios.UNKNOWN, "Device exists, but no data received or unknown monitoring")
|
||||
elif linkquality <= self.LINKQUALITY_ERROR:
|
||||
return self.__nagios_return__(DID_LINKQUALITY, nagios.Nagios.ERROR, "Linkquality critical low (%d)" % linkquality)
|
||||
elif linkquality <= self.LINKQUALITY_WARNING:
|
||||
return self.__nagios_return__(DID_LINKQUALITY, nagios.Nagios.WARNING, "Linkquality level low (%d)" % linkquality)
|
||||
else:
|
||||
return self.__nagios_return__(self.MONITORING_LINKQUALITY, nagios.Nagios.OK, "Linkquality okay (%d)" % self.linkquality)
|
||||
return self.__nagios_return__(DID_LINKQUALITY, nagios.Nagios.OK, "Linkquality okay (%d)" % linkquality)
|
||||
|
||||
def __nagios_return__(self, monitoring_name, status, msg, force=False):
|
||||
def __nagios_return__(self, did, status, msg, force=False):
|
||||
tm = time.time()
|
||||
if monitoring_name not in self.__unknown_tm__:
|
||||
self.__unknown_tm__[monitoring_name] = None
|
||||
if did not in self.__unknown_tm__:
|
||||
self.__unknown_tm__[did] = None
|
||||
if status == nagios.Nagios.UNKNOWN and not force:
|
||||
if self.__unknown_tm__[monitoring_name] is None:
|
||||
self.__unknown_tm__[monitoring_name] = tm
|
||||
dt = tm - self.__unknown_tm__[monitoring_name]
|
||||
if self.__unknown_tm__[did] is None:
|
||||
self.__unknown_tm__[did] = tm
|
||||
dt = tm - self.__unknown_tm__[did]
|
||||
if dt >= self.LAST_MSG_ERROR:
|
||||
status = nagios.Nagios.UNKNOWN
|
||||
elif dt >= self.LAST_MSG_WARNING:
|
||||
@ -165,7 +163,7 @@ class base(object):
|
||||
status = nagios.Nagios.OK
|
||||
msg += " - since %.1fh" % (dt / 3600)
|
||||
else:
|
||||
self.__unknown_tm__[monitoring_name] = None
|
||||
self.__unknown_tm__[did] = None
|
||||
return {"status": status, "msg": msg}
|
||||
|
||||
|
||||
@ -202,7 +200,33 @@ class livarno_sw_br_ct(base):
|
||||
class brennenstuhl_heatingvalve(base):
|
||||
BATTERY_LVL_WARNING = 4
|
||||
BATTERY_LVL_ERROR = 3
|
||||
FOLLOW_KEY = "current_heating_setpoint"
|
||||
#
|
||||
ACTOR_WARN_OFFSET = 1.5
|
||||
ACTOR_ERR_OFFSET = 2.5
|
||||
#
|
||||
KEY_SETPOINT = "current_heating_setpoint"
|
||||
KEY_CURRENT_VALUE = "local_temperature"
|
||||
|
||||
def status(self, key):
|
||||
#
|
||||
# ACTOR
|
||||
#
|
||||
if key == DID_ACTOR:
|
||||
tm_s, value_s = self.__state_storage__.get(self.KEY_SETPOINT, (0, None))
|
||||
tm_c, value_c = self.__state_storage__.get(self.KEY_CURRENT_VALUE, (0, None))
|
||||
#
|
||||
if value_s is None or value_c is None:
|
||||
return self.__nagios_return__(DID_ACTOR, nagios.Nagios.UNKNOWN, "Device exists, but no data received")
|
||||
elif value_s <= 5:
|
||||
return self.__nagios_return__(DID_ACTOR, nagios.Nagios.OK, "No monitoring in Summer Mode")
|
||||
elif value_c > value_s + self.ACTOR_ERR_OFFSET:
|
||||
return self.__nagios_return__(DID_ACTOR, nagios.Nagios.ERROR, "Current Temperature much to high %.1f°C > %.1f°C" % (value_c, value_s))
|
||||
elif value_c > value_s + self.ACTOR_WARN_OFFSET:
|
||||
return self.__nagios_return__(DID_ACTOR, nagios.Nagios.WARNING, "Current Temperature to high %.1f°C > %.1f°C" % (value_c, value_s))
|
||||
else:
|
||||
return self.__nagios_return__(DID_ACTOR, nagios.Nagios.OK, "Current Temperature okay %.1f°C > %.1f°C" % (value_c, value_s))
|
||||
else:
|
||||
return super().status(key)
|
||||
|
||||
|
||||
class silvercrest_powerplug(base):
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 328d3471a748472695a61193becdda76c7eefe69
|
||||
Subproject commit 14e56ccdbf6594f699b4afcfb4acafe9b899e914
|
@ -2,10 +2,19 @@ import nagios
|
||||
import socket_protocol
|
||||
# from devdi.topic import topic_by_props
|
||||
|
||||
DID_FOLLOWS_SETPOINT = 'follow_setpoint'
|
||||
DID_ACTOR = 'actor'
|
||||
DID_BATTERY_LEVEL = 'battery'
|
||||
DID_FOLLOWS_SETPOINT = 'follow'
|
||||
DID_HEARTBEAT = 'heartbeat'
|
||||
DID_LINKQUALITY = 'linkquality'
|
||||
#
|
||||
DIDS = (
|
||||
DID_ACTOR,
|
||||
DID_BATTERY_LEVEL,
|
||||
DID_FOLLOWS_SETPOINT,
|
||||
DID_HEARTBEAT,
|
||||
DID_LINKQUALITY
|
||||
)
|
||||
|
||||
|
||||
class server(socket_protocol.pure_json_protocol):
|
||||
@ -15,10 +24,8 @@ class server(socket_protocol.pure_json_protocol):
|
||||
socket_protocol.pure_json_protocol.__init__(self, *args, **kwargs)
|
||||
#
|
||||
if not self.__comm_inst__.IS_CLIENT:
|
||||
self.register_callback(socket_protocol.SID_READ_REQUEST, DID_FOLLOWS_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_LINKQUALITY, self.device_status)
|
||||
self.register_callback(socket_protocol.SID_READ_REQUEST, DID_HEARTBEAT, self.device_status)
|
||||
for did in DIDS:
|
||||
self.register_callback(socket_protocol.SID_READ_REQUEST, did, self.device_status)
|
||||
|
||||
def device_status(self, msg):
|
||||
if msg.get_status() == socket_protocol.STATUS_OKAY:
|
||||
|
Loading…
x
Reference in New Issue
Block a user