Nagios Plugins
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

__init__.py 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import json
  2. import logging
  3. import mqtt
  4. import nagios
  5. import time
  6. try:
  7. from config import APP_NAME as ROOT_LOGGER_NAME
  8. except ImportError:
  9. ROOT_LOGGER_NAME = 'root'
  10. logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
  11. class base(object):
  12. FOLLOW_REQUEST_WARNING = 5 # Seconds, till warning comes up, if device does not follow the command
  13. FOLLOW_REQUEST_ERROR = 60 # Seconds, till error comes up, if device does not follow the command
  14. FOLLOW_KEY = None
  15. #
  16. BATTERY_LVL_WARNING = 15
  17. BATTERY_LVL_ERROR = 5
  18. #
  19. LAST_MSG_WARNING = 6 * 24 * 60 * 60
  20. LAST_MSG_ERROR = 24 * 24 * 60 * 60
  21. def __init__(self, mqtt_client: mqtt.mqtt_client, topic):
  22. self.topic = topic
  23. #
  24. mqtt_client.add_callback(topic, self.__rx__)
  25. mqtt_client.add_callback(topic + '/#', self.__rx__)
  26. #
  27. self.last_device_msg = None
  28. #
  29. self.__target_storage__ = {}
  30. self.__state_storage__ = {}
  31. #
  32. self.battery = None
  33. def __rx__(self, client, userdata, message):
  34. try:
  35. payload = json.loads(message.payload)
  36. except json.decoder.JSONDecodeError:
  37. pass
  38. else:
  39. if type(payload) is dict:
  40. #
  41. # heartbeat
  42. #
  43. if message.topic == self.topic:
  44. self.last_device_msg = time.time()
  45. #
  46. # follow setpoint
  47. #
  48. if self.FOLLOW_KEY is not None and self.FOLLOW_KEY in payload:
  49. if message.topic == self.topic + '/set':
  50. self.target(self.FOLLOW_KEY, payload[self.FOLLOW_KEY])
  51. if message.topic == self.topic:
  52. self.state(self.FOLLOW_KEY, payload[self.FOLLOW_KEY])
  53. #
  54. # battery level
  55. #
  56. if "battery" in payload and message.topic == self.topic:
  57. self.battery = payload["battery"]
  58. def target(self, key, value):
  59. tm_t, value_t = self.__target_storage__.get(key, (0, None))
  60. if value != value_t:
  61. self.__target_storage__[key] = time.time(), value
  62. logger.debug("Target value for device identified: %s: %s", key, repr(value))
  63. def state(self, key, value):
  64. self.__state_storage__[key] = time.time(), value
  65. logger.debug("Device state identified: %s: %s", key, repr(value))
  66. def status(self, key):
  67. #
  68. # HEARTBEAT
  69. #
  70. if key == "heartbeat":
  71. if self.last_device_msg is None:
  72. return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exists, but no data received or unknown monitoring"}
  73. else:
  74. dt = time.time() - self.last_device_msg
  75. dt_disp = dt / 60 / 60
  76. if dt > self.LAST_MSG_ERROR:
  77. return {"status": nagios.Nagios.ERROR, "msg": "Last message %.1fh ago" % dt_disp}
  78. elif dt > self.LAST_MSG_WARNING:
  79. return {"status": nagios.Nagios.WARNING, "msg": "Last message %.1fh ago" % dt_disp}
  80. else:
  81. return {"status": nagios.Nagios.OK, "msg": "Last message %.1fh ago" % dt_disp}
  82. #
  83. # FOLLOW SETPOINT
  84. #
  85. elif key == 'follow_setpoint':
  86. if self.FOLLOW_KEY is None:
  87. return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exist, but does not follow any setpoint."}
  88. tm_s, value_s = self.__state_storage__.get(self.FOLLOW_KEY, (0, None))
  89. try:
  90. tm_t, value_t = self.__target_storage__[self.FOLLOW_KEY]
  91. except KeyError:
  92. if value_s is not None:
  93. return {"status": nagios.Nagios.WARNING, "msg": "Current temperature setpoint %.1f°C (age=%.1fmin), but never received a setpoint" % (value_s, (time.time()-tm_s)/60)}
  94. return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exists, but no data received"}
  95. else:
  96. tm = time.time()
  97. dt = tm - tm_t
  98. if value_t != value_s and dt > self.FOLLOW_REQUEST_ERROR:
  99. return {"status": nagios.Nagios.ERROR, "msg": "Requested setpoint unequal valve setpoint %.1f°C since %.1fmin" % (value_s, (time.time()-tm_s)/60)}
  100. elif value_t != value_s and dt > self.FOLLOW_REQUEST_WARNING:
  101. return {"status": nagios.Nagios.WARNING, "msg": "Requested setpoint unequal valve setpoint %.1f°C since %.1fmin" % (value_s, (time.time()-tm_s))}
  102. return {"status": nagios.Nagios.OK, "msg": "Requested setpoint equal valve setpoint %.1f°C" % value_s}
  103. #
  104. # BATTERY
  105. #
  106. elif key == "battery":
  107. if self.battery is None:
  108. return {"status": nagios.Nagios.UNKNOWN, "msg": "Device exists, but no data received or unknown monitoring"}
  109. elif self.battery <= self.BATTERY_LVL_ERROR:
  110. return {"status": nagios.Nagios.ERROR, "msg": "Battery level critical low (%.1f%%)" % self.battery}
  111. elif self.battery <= self.BATTERY_LVL_WARNING:
  112. return {"status": nagios.Nagios.WARNING, "msg": "Battery level low (%.1f%%)" % self.battery}
  113. else:
  114. return {"status": nagios.Nagios.OK, "msg": "Battery okay (%.1f%%)" % self.battery}
  115. class group(object):
  116. def __init__(self, *args, **kwargs):
  117. pass
  118. class shelly_sw1(base):
  119. pass
  120. class tradfri_sw(base):
  121. pass
  122. class tradfri_sw_br(base):
  123. pass
  124. class tradfri_sw_br_ct(base):
  125. pass
  126. class tradfri_button(base):
  127. pass
  128. class livarno_sw_br_ct(base):
  129. pass
  130. class brennenstuhl_heatingvalve(base):
  131. BATTERY_LVL_WARNING = 4
  132. BATTERY_LVL_ERROR = 3
  133. FOLLOW_KEY = "current_heating_setpoint"
  134. class silvercrest_powerplug(base):
  135. pass
  136. class silvercrest_motion_sensor(base):
  137. pass
  138. class my_powerplug(base):
  139. pass
  140. class audio_status(base):
  141. pass
  142. class remote(base):
  143. pass