Merge branch 'master' into patch-4

This commit is contained in:
Christopher Fenner
2024-02-01 09:56:34 +01:00
committed by GitHub
4 changed files with 125 additions and 28 deletions

View File

@@ -21,7 +21,6 @@ The easiest way to track your Raspberry Pi or Ubuntu computer system health and
* Easy update: You can update the script by calling it with command line argument --update * Easy update: You can update the script by calling it with command line argument --update
## Table of Contents ## Table of Contents
- [What is new](#what-is-new) - [What is new](#what-is-new)
@@ -40,6 +39,7 @@ The easiest way to track your Raspberry Pi or Ubuntu computer system health and
## What is new ## What is new
* 2024-01-28: Improved error handling for the MQTT connection
* 2024-01-28: Script version is displayed in home assistant device information * 2024-01-28: Script version is displayed in home assistant device information
* 2024-01-28: Update the script by calling it with command line argument --update * 2024-01-28: Update the script by calling it with command line argument --update
* 2024-01-27: Now you can run the script as a service (systemd) or as a cron job * 2024-01-27: Now you can run the script as a service (systemd) or as a cron job

View File

@@ -21,6 +21,9 @@ discovery_messages = True
# Binary sensor that displays when there are updates # Binary sensor that displays when there are updates
git_update = True git_update = True
# Enable remote update of the script via Home Assistant
update = True
# Retain flag for published topics # Retain flag for published topics
retain = True retain = True

View File

@@ -10,10 +10,12 @@ import time
import socket import socket
import paho.mqtt.client as paho import paho.mqtt.client as paho
import json import json
import config
import os import os
import sys
import argparse import argparse
import threading
import update import update
import config
# get device host name - used in mqtt topic # get device host name - used in mqtt topic
hostname = socket.gethostname() hostname = socket.gethostname()
@@ -112,7 +114,7 @@ def check_model_name():
if model_name == '': if model_name == '':
full_cmd = "cat /proc/cpuinfo | grep 'name'| uniq" full_cmd = "cat /proc/cpuinfo | grep 'name'| uniq"
model_name = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].decode("utf-8") model_name = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].decode("utf-8")
model_name = model_name.split(':')[1] model_name = model_name.split(':')[1].replace('\n', '')
return model_name return model_name
@@ -136,7 +138,7 @@ def get_manufacturer():
if 'Raspberry' not in check_model_name(): if 'Raspberry' not in check_model_name():
full_cmd = "cat /proc/cpuinfo | grep 'vendor'| uniq" full_cmd = "cat /proc/cpuinfo | grep 'vendor'| uniq"
pretty_name = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].decode("utf-8") pretty_name = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].decode("utf-8")
pretty_name = pretty_name.split(':')[1] pretty_name = pretty_name.split(':')[1].replace('\n', '')
else: else:
pretty_name = 'Raspberry Pi' pretty_name = 'Raspberry Pi'
@@ -150,16 +152,23 @@ def check_git_update(script_dir):
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print("Error updating git repository:", e.output) print("Error updating git repository:", e.output)
if any(s in git_update for s in ('Your branch is up to date', 'Your branch is up-to-date')): if any(s in git_update for s in ('Your branch is up to date', 'Your branch is up-to-date', 'Votre branche est à jour')):
git_update = 'off' git_update = {
else: "installed_ver": config.version,
git_update = 'on' "new_ver": config.version,
}
return(git_update) else:
git_update = {
"installed_ver": config.version,
"new_ver": check_git_version_remote(script_dir),
}
return(json.dumps(git_update))
def check_git_version(script_dir): def check_git_version(script_dir):
full_cmd = "git -C {} describe --tags `git -C {} rev-list --tags --max-count=1`".format(script_dir, script_dir) full_cmd = "git -C {} describe --tags `git -C {} rev-list --tags --max-count=1`".format(script_dir, script_dir)
git_version = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].decode("utf-8") git_version = subprocess.Popen(full_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0].decode("utf-8").replace('\n', '')
return(git_version) return(git_version)
@@ -182,7 +191,8 @@ def get_network_ip():
s.close() s.close()
return IP return IP
def print_measured_values(): def print_measured_values( cpu_load=0, cpu_temp=0, used_space=0, voltage=0, sys_clock_speed=0, swap=0, memory=0,
uptime_days=0, wifi_signal=0, wifi_signal_dbm=0, rpi5_fan_speed=0, git_update=False):
print(":: rpi-mqtt-monitor") print(":: rpi-mqtt-monitor")
print(" Version: " + config.version) print(" Version: " + config.version)
print("") print("")
@@ -226,7 +236,7 @@ def config_json(what_config):
"manufacturer": manufacturer, "manufacturer": manufacturer,
"model": model_name, "model": model_name,
"name": hostname, "name": hostname,
"sw_version": "rpi-mqtt-monitor " + config.version + " on " + os, "sw_version": config.version,
"configuration_url": "https://github.com/hjelev/rpi-mqtt-monitor" "configuration_url": "https://github.com/hjelev/rpi-mqtt-monitor"
} }
} }
@@ -297,22 +307,51 @@ def config_json(what_config):
elif what_config == "git_update": elif what_config == "git_update":
data["icon"] = "mdi:git" data["icon"] = "mdi:git"
data["name"] = "RPi MQTT Monitor" data["name"] = "RPi MQTT Monitor"
data["title"] = "Device Update"
data["device_class"] = "update" data["device_class"] = "update"
data["state_class"] = "measurement" data["state_class"] = "measurement"
data["payload_on"] = "on" data["payload_on"] = "on"
data["payload_off"] = "off" data["payload_off"] = "off"
data["value_template"] = "{{ 'on' if value_json.installed_ver != value_json.new_ver else 'off' }}"
elif what_config == "update":
version = check_git_version(script_dir).strip()
data["icon"] = "mdi:update"
data["name"] = "RPi MQTT Monitor Update"
data["title"] = "RPi MQTT Monitor v" + version
data["state_topic"] = config.mqtt_topic_prefix + "/" + hostname + "/" + "git_update"
data["value_template"] = "{{ {'installed_version': value_json.installed_ver, 'latest_version': value_json.new_ver } | to_json }}"
data["device_class"] = "firmware"
data["command_topic"] = "homeassistant/update/" + hostname + "/command"
data["payload_install"] = "install"
data['release_url'] = "https://github.com/hjelev/rpi-mqtt-monitor/releases/tag/" + version
else: else:
return "" return ""
# Return our built discovery config # Return our built discovery config
return json.dumps(data) return json.dumps(data)
def on_log(client, userdata, level, buf):
if level == paho.MQTT_LOG_ERR:
print("MQTT error: ", buf)
def on_connect(client, userdata, flags, rc):
if rc != 0:
print("Error: Unable to connect to MQTT broker, return code:", rc)
def publish_to_mqtt(cpu_load=0, cpu_temp=0, used_space=0, voltage=0, sys_clock_speed=0, swap=0, memory=0, def publish_to_mqtt(cpu_load=0, cpu_temp=0, used_space=0, voltage=0, sys_clock_speed=0, swap=0, memory=0,
uptime_days=0, uptime_seconds=0, wifi_signal=0, wifi_signal_dbm=0, rpi5_fan_speed=0, git_update=False): uptime_days=0, uptime_seconds=0, wifi_signal=0, wifi_signal_dbm=0, rpi5_fan_speed=0, git_update=False, update=False):
# connect to mqtt server # connect to mqtt server
client = paho.Client(client_id="rpi-mqtt-monitor-" + hostname) client = paho.Client(client_id="rpi-mqtt-monitor-" + hostname)
client.username_pw_set(config.mqtt_user, config.mqtt_password) client.username_pw_set(config.mqtt_user, config.mqtt_password)
client.connect(config.mqtt_host, int(config.mqtt_port)) client.on_log = on_log
client.on_connect = on_connect
try:
client.connect(config.mqtt_host, int(config.mqtt_port))
except Exception as e:
print("Error connecting to MQTT broker:", e)
return
# publish monitored values to MQTT # publish monitored values to MQTT
if config.cpu_load: if config.cpu_load:
@@ -407,6 +446,13 @@ def publish_to_mqtt(cpu_load=0, cpu_temp=0, used_space=0, voltage=0, sys_clock_s
time.sleep(config.sleep_time) time.sleep(config.sleep_time)
client.publish(config.mqtt_topic_prefix + "/" + hostname + "/git_update", git_update, qos=config.qos, retain=config.retain) client.publish(config.mqtt_topic_prefix + "/" + hostname + "/git_update", git_update, qos=config.qos, retain=config.retain)
time.sleep(config.sleep_time) time.sleep(config.sleep_time)
if config.update:
if config.discovery_messages:
client.publish("homeassistant/update/" + hostname + "/config",
config_json('update'), qos=config.qos)
time.sleep(config.sleep_time)
# client.publish(config.mqtt_topic_prefix + "/" + hostname + "/git_update", git_update, qos=config.qos, retain=config.retain)
time.sleep(config.sleep_time)
# disconnect from mqtt server # disconnect from mqtt server
client.disconnect() client.disconnect()
@@ -418,10 +464,16 @@ def bulk_publish_to_mqtt(cpu_load=0, cpu_temp=0, used_space=0, voltage=0, sys_cl
values = cpu_load, cpu_temp, used_space, voltage, int(sys_clock_speed), swap, memory, uptime_days, uptime_seconds, wifi_signal, wifi_signal_dbm, rpi5_fan_speed, git_update values = cpu_load, cpu_temp, used_space, voltage, int(sys_clock_speed), swap, memory, uptime_days, uptime_seconds, wifi_signal, wifi_signal_dbm, rpi5_fan_speed, git_update
values = str(values)[1:-1] values = str(values)[1:-1]
# connect to mqtt server
client = paho.Client(client_id="rpi-mqtt-monitor-" + hostname) client = paho.Client(client_id="rpi-mqtt-monitor-" + hostname)
client.username_pw_set(config.mqtt_user, config.mqtt_password) client.username_pw_set(config.mqtt_user, config.mqtt_password)
client.connect(config.mqtt_host, int(config.mqtt_port)) client.on_log = on_log
client.on_connect = on_connect
try:
client.connect(config.mqtt_host, int(config.mqtt_port))
except Exception as e:
print("Error connecting to MQTT broker:", e)
return
# publish monitored values to MQTT # publish monitored values to MQTT
client.publish(config.mqtt_topic_prefix + "/" + hostname, values, qos=config.qos, retain=config.retain) client.publish(config.mqtt_topic_prefix + "/" + hostname, values, qos=config.qos, retain=config.retain)
@@ -463,14 +515,10 @@ def parse_arguments():
exit() exit()
return args return args
def gather_and_send_info():
if __name__ == '__main__':
script_dir = os.path.dirname(os.path.realpath(__file__))
args = parse_arguments();
while True: while True:
# set all monitored values to False in case they are turned off in the config # set all monitored values to False in case they are turned off in the config
cpu_load = cpu_temp = used_space = voltage = sys_clock_speed = swap = memory = uptime_seconds = uptime_days = wifi_signal = wifi_signal_dbm = rpi5_fan_speed = git_update = False cpu_load = cpu_temp = used_space = voltage = sys_clock_speed = swap = memory = uptime_seconds = uptime_days = wifi_signal = wifi_signal_dbm = rpi5_fan_speed = git_update = update = False
# delay the execution of the script # delay the execution of the script
if hasattr(config, 'random_delay'): time.sleep(config.random_delay) if hasattr(config, 'random_delay'): time.sleep(config.random_delay)
@@ -505,19 +553,65 @@ if __name__ == '__main__':
rpi5_fan_speed = check_rpi5_fan_speed() rpi5_fan_speed = check_rpi5_fan_speed()
if config.git_update: if config.git_update:
git_update = check_git_update(script_dir) git_update = check_git_update(script_dir)
if config.update:
update = check_git_update(script_dir)
# Display collected values on screen if --display option is used # Display collected values on screen if --display option is used
if args.display: if args.display:
print_measured_values() print_measured_values(cpu_load, cpu_temp, used_space, voltage, sys_clock_speed, swap, memory, uptime_days, wifi_signal, wifi_signal_dbm, rpi5_fan_speed, git_update)
# Publish messages to MQTT # Publish messages to MQTT
if hasattr(config, 'group_messages') and config.group_messages: if hasattr(config, 'group_messages') and config.group_messages:
bulk_publish_to_mqtt(cpu_load, cpu_temp, used_space, voltage, sys_clock_speed, swap, memory, uptime_days, uptime_seconds, wifi_signal, wifi_signal_dbm, rpi5_fan_speed, git_update) bulk_publish_to_mqtt(cpu_load, cpu_temp, used_space, voltage, sys_clock_speed, swap, memory, uptime_days, uptime_seconds, wifi_signal, wifi_signal_dbm, rpi5_fan_speed, git_update)
else: else:
publish_to_mqtt(cpu_load, cpu_temp, used_space, voltage, sys_clock_speed, swap, memory, uptime_days, uptime_seconds, wifi_signal, wifi_signal_dbm, rpi5_fan_speed, git_update) publish_to_mqtt(cpu_load, cpu_temp, used_space, voltage, sys_clock_speed, swap, memory, uptime_days, uptime_seconds, wifi_signal, wifi_signal_dbm, rpi5_fan_speed, git_update, update)
# if not running as a service, break the loop after one iteration # if not running as a service, break the loop after one iteration
if not args.service: if not args.service:
break break
# if running as a service, sleep before the next iteration # if running as a service, sleep before the next iteration
time.sleep(config.service_sleep_time) time.sleep(config.service_sleep_time)
def on_message(client, userdata, msg):
global exit_flag
print("Received message: ", msg.payload.decode())
if msg.payload.decode() == "install":
version = check_git_version_remote(script_dir).strip()
update.do_update(version, git_update=True, config_update=True)
print("Update completed. Setting exit flag...")
exit_flag = True
exit_flag = False
if __name__ == '__main__':
script_dir = os.path.dirname(os.path.realpath(__file__))
args = parse_arguments();
if args.service:
client = paho.Client()
client.username_pw_set(config.mqtt_user, config.mqtt_password)
client.on_message = on_message
try:
client.connect(config.mqtt_host, int(config.mqtt_port))
except Exception as e:
print("Error connecting to MQTT broker:", e)
sys.exit(1) # Exit the script
client.subscribe("homeassistant/update/" + hostname + "/command") # Replace with your MQTT topic
print("Listening to topic : " + "homeassistant/update/" + hostname + "/command")
# Start the gather_and_send_info function in a new thread
thread = threading.Thread(target=gather_and_send_info)
thread.daemon = True # Set the daemon attribute to True
thread.start()
client.loop_start() # Start the MQTT client loop in a new thread
# Check the exit flag in the main thread
while True:
if exit_flag:
print("Exit flag set. Exiting the application...")
sys.exit(0)
time.sleep(1) # Check the exit flag every second
else:
gather_and_send_info()

View File

@@ -39,11 +39,11 @@ def display_config_differences(current_config, example_config, display=True):
else: else:
return False return False
def update_config_version(version): def update_config_version(version, script_dir):
with open('config.py', 'r') as f: with open(script_dir + '/config.py', 'r') as f:
lines = f.readlines() lines = f.readlines()
with open('config.py', 'w') as f: with open(script_dir + '/config.py', 'w') as f:
print(":: Updating config version to {}".format(version)) print(":: Updating config version to {}".format(version))
for line in lines: for line in lines:
if 'version = ' in line: if 'version = ' in line:
@@ -62,10 +62,10 @@ def do_update(version=config.version, git_update=True, config_update=True):
if display_config_differences(script_dir + '/config.py', script_dir + '/config.py.example') and config_update: if display_config_differences(script_dir + '/config.py', script_dir + '/config.py.example') and config_update:
print(":: Updating config.py") print(":: Updating config.py")
update_config(script_dir + 'config.py',script_dir + 'config.py.example') update_config(script_dir + '/config.py',script_dir + '/config.py.example')
if version != config.version: if version != config.version:
update_config_version(version) update_config_version(version, script_dir)
if __name__ == '__main__': if __name__ == '__main__':