Skip to content

Instantly share code, notes, and snippets.

@prairiesnpr
Created April 15, 2019 00:00
Show Gist options
  • Save prairiesnpr/ccb8fc23b0bd9685aed53594e01afcef to your computer and use it in GitHub Desktop.
Save prairiesnpr/ccb8fc23b0bd9685aed53594e01afcef to your computer and use it in GitHub Desktop.
server_stats2mqtt.py
import paho.mqtt.client as mqtt
from urllib.parse import urlparse
import time, datetime
import json
import os
import yaml
import logging
import psutil
import threading
import re
from logging.handlers import RotatingFileHandler
class ServerStats():
def __init__(self):
self.stop = False
self.init_logging('Server_Metrics.log')
self.thread = threading.Event()
self.devices = {}
self.devices['cpu_usage'] = {'name':'Cpu Usage', 'device_class':'sensor', 'location':'server', 'unit_of_measurement':'%', 'value_template':'{{ value_json.cpu_usage}}', 'value':0}
self.devices['vmem_usage'] = {'name':'Virtual Memory', 'device_class':'sensor', 'location':'server', 'unit_of_measurement':'%', 'value_template':'{{ value_json.vmem_usage}}', 'value':0}
self.devices['smem_usage'] = {'name':'Swap Memory', 'device_class':'sensor', 'location':'server', 'unit_of_measurement':'%', 'value_template':'{{ value_json.smem_usage}}', 'value':0}
self.read_config()
self.connect_to_mqtt()
self.config_devices()
self.get_stats()
def get_stats(self):
self.devices['cpu_usage']['value'] = psutil.cpu_percent(interval=1)
self.devices['vmem_usage']['value'] = psutil.virtual_memory().percent
self.devices['smem_usage']['value'] = psutil.swap_memory().percent
state_topic = '%s/%s/%s/state' % (self.mqtt_topic, 'sensor', 'server')
self.mqttc.publish(state_topic, json.dumps({'cpu_usage': self.devices['cpu_usage']['value'],
'vmem_usage': self.devices['vmem_usage']['value'],
'smem_usage': self.devices['smem_usage']['value'],}))
if not self.thread.is_set() and not self.stop:
threading.Timer(10, self.get_stats).start()
def read_config(self):
"""read config, filename is config.yml"""
cur_dir = os.path.dirname(os.path.abspath(__file__))
config_file = os.path.join(cur_dir, 'config.yml')
with open(config_file, "r") as f:
config = list(yaml.load_all(f))[0]
if 'mqtt' in config:
self.mqtt_path = 'mqtt://%s:%s' % (config['mqtt']['server'], config['mqtt']['port'])
self.mqtt_topic = config['mqtt']['topic']
self.ha_state_topic = config['mqtt']['ha_state_topic']
def connect_to_mqtt(self):
self.mqttc = mqtt.Client()
url = urlparse(self.mqtt_path)
# Connect
self.mqttc.connect(url.hostname, url.port)
# Start subscribe, with QoS level 0
self.mqttc.subscribe(self.mqtt_topic + '/server_stats', 0)
self.mqttc.subscribe(self.ha_state_topic, 0)
# Assign event callbacks
self.mqttc.on_message = self.on_message
def on_message(self, client, obj, msg):
self.logger.debug(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
#isilentllc/switch/garage/set
if msg.topic == self.ha_state_topic:
if msg.payload == b'online':
self.logger.debug('Homeassistant boot event, resending Server Metrics device list.')
#Resend device info
self.config_devices()
def init_logging(self, path):
"""Start Logging"""
self.logger = logging.getLogger("Server Metrics Log")
self.logger.setLevel(logging.DEBUG)
handler = RotatingFileHandler(path, maxBytes=20000, backupCount=1)
self.logger.addHandler(handler)
self.logger.debug('Server Metrics Start Event')
def config_devices(self):
"""Configure devices in home assistant"""
state_topic = '%s/%s/%s/state' % (self.mqtt_topic, 'sensor', 'server')
for dev, config in self.devices.items():
config_topic = '%s/%s/%s/config' % (self.mqtt_topic, config['device_class'], dev)
config_payload = {#'device_class': config['device_class'],
'name': config['name'],
'state_topic': state_topic,
'unit_of_measurement': config['unit_of_measurement'],
'value_template': config['value_template'],
}
self.mqttc.publish(config_topic, json.dumps(config_payload))
if __name__ == "__main__":
try:
server_stats = ServerStats()
server_stats.mqttc.loop_start()
print('server2mqtt running')
while 1:
time.sleep(1)
except KeyboardInterrupt:
pass
except Exception as e:
print(e)
finally:
if server_stats:
server_stats.mqttc.loop_stop()
server_stats.stop = True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment