Skip to content

Commit

Permalink
repaired MQTT subscript and LWT online/offline reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
ironsheep committed Mar 1, 2023
1 parent f08c88e commit d637ee7
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 43 deletions.
9 changes: 8 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# ChangeLog

---- Next Rls -------- v1.8.1
Tue, 28 Feb 2023 17:24:07 -0700 v1.8.2

- fix LWT online/offline status updates of Daemon
- repair MQTT command subscription mechanism
- repaired the remote-control setup instructions for restart-service, updated config.ini.dist

Sun Feb 26 18:28:36 2023 -0700 v1.8.1

- Repair temperature units regression (#82)
- Disk Used sensor repaired (was reporting free vs. used) (#83)
- Refine the advertisement of the command endpoints

Sat, 25 Feb 2023 19:36:42 -0700 v1.8.0

Expand Down
49 changes: 29 additions & 20 deletions ISP-RPi-mqtt-daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
except ImportError:
apt_available = False

script_version = "1.8.1"
script_version = "1.8.2"
script_name = 'ISP-RPi-mqtt-daemon.py'
script_info = '{} v{}'.format(script_name, script_version)
project_name = 'RPi Reporter MQTT2HA Daemon'
Expand Down Expand Up @@ -143,8 +143,6 @@ def clean_identifier(name):
'* init mqtt_client_connected=[{}]'.format(mqtt_client_connected), debug=True)
mqtt_client_should_attempt_reconnect = True

command_base_topic = '{not-set}/command/{not-set}'

def on_connect(client, userdata, flags, rc):
global mqtt_client_connected
if rc == 0:
Expand All @@ -157,15 +155,6 @@ def on_connect(client, userdata, flags, rc):
mqtt_client_connected), debug=True)
client.on_publish = on_publish

# -------------------------------------------------------------------------
# Commands Subscription
if (len(commands) > 0):
print_line('MQTT subscription to {}/+ enabled'.format(command_base_topic), console=True, sd_notify=True)
client.on_message = on_message
client.subscribe('{}/+'.format(command_base_topic))
else:
print_line('MQTT subscripton to {}/+ disabled'.format(command_base_topic), console=True, sd_notify=True)
# -------------------------------------------------------------------------
else:
print_line('! Connection error with result code {} - {}'.format(str(rc),
mqtt.connack_string(rc)), error=True)
Expand All @@ -191,16 +180,17 @@ def on_subscribe(client, userdata, mid, granted_qos):
print_line('on_subscribe() - {} - {}'.format(str(mid),str(granted_qos)), debug=True, sd_notify=True)

def on_message(client, userdata, message):
print_line('on_message(). Topic=[{}] payload=[{}]'.format(message.topic, message.payload), console=True, sd_notify=True, debug=True)
print_line('on_message() Topic=[{}] payload=[{}]'.format(message.topic, message.payload), console=True, sd_notify=True, debug=True)

decoded_payload = message.payload.decode('utf-8')
command = message.topic.split('/')[-1]

if command in commands:
print_line('- Command "{}" Received - Run {} {} -'.format(command, commands[command], decoded_payload), console=True, debug=True)
subprocess.Popen(["/usr/bin/sh", "-c", commands[command].format(decoded_payload)])
else:
print_line('* Invalid Command received.', error=True)
if command != 'status':
if command in commands:
print_line('- Command "{}" Received - Run {} {} -'.format(command, commands[command], decoded_payload), console=True, debug=True)
subprocess.Popen(["/usr/bin/sh", "-c", commands[command].format(decoded_payload)])
else:
print_line('* Invalid Command received.', error=True)

# -----------------------------------------------------------------------------
# Load configuration file
Expand Down Expand Up @@ -1180,6 +1170,9 @@ def getNumberOfAvailableUpdates():
if apt_available:
getNumberOfAvailableUpdates()

command_base_topic = '{}/command/{}'.format(base_topic, sensor_name.lower())


# -----------------------------------------------------------------------------
# timer and timer funcs for ALIVE MQTT Notices handling
# -----------------------------------------------------------------------------
Expand All @@ -1190,7 +1183,12 @@ def getNumberOfAvailableUpdates():
def publishAliveStatus():
print_line('- SEND: yes, still alive -', debug=True)
mqtt_client.publish(lwt_sensor_topic, payload=lwt_online_val, retain=False)
mqtt_client.publish(lwt_command_topic, payload=lwt_online_val, retain=False)

def publishShuttingDownStatus():
print_line('- SEND: shutting down -', debug=True)
mqtt_client.publish(lwt_sensor_topic, payload=lwt_offline_val, retain=False)
mqtt_client.publish(lwt_command_topic, payload=lwt_offline_val, retain=False)

def aliveTimeoutHandler():
print_line('- MQTT TIMER INTERRUPT -', debug=True)
Expand Down Expand Up @@ -1273,6 +1271,16 @@ def isAliveTimerRunning():
error=True, sd_notify=True)
sys.exit(1)
else:
# -------------------------------------------------------------------------
# Commands Subscription
if (len(commands) > 0):
print_line('MQTT subscription to {}/+ enabled'.format(command_base_topic), console=True, sd_notify=True)
mqtt_client.on_message = on_message
mqtt_client.subscribe('{}/+'.format(command_base_topic))
else:
print_line('MQTT subscripton to {}/+ disabled'.format(command_base_topic), console=True, sd_notify=True)
# -------------------------------------------------------------------------

mqtt_client.publish(lwt_sensor_topic, payload=lwt_online_val, retain=False)
mqtt_client.publish(lwt_command_topic, payload=lwt_online_val, retain=False)
mqtt_client.loop_start()
Expand Down Expand Up @@ -1378,8 +1386,6 @@ def isAliveTimerRunning():
))
])

command_base_topic = '{}/command/{}'.format(base_topic, sensor_name.lower())

for [command, _] in commands.items():
#print_line('- REGISTER command: [{}]'.format(command), debug=True)
iconName = 'mdi:gesture-tap'
Expand Down Expand Up @@ -1809,5 +1815,8 @@ def afterMQTTConnect():

finally:
# cleanup used pins... just because we like cleaning up after us
publishShuttingDownStatus()
stopPeriodTimer() # don't leave our timers running!
stopAliveTimer()
mqtt_client.disconnect()
print_line('* MQTT Disconnect()', verbose=True)
31 changes: 12 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@ A simple Linux python script to query the Raspberry Pi on which it is running fo

![Discovery image](./Docs/images/DiscoveryV4.png)

This script should be configured to be run in **daemon mode** continously in the background as a systemd service (or optionally as a SysV init script). Instructions are provided below.

This script should be configured to be run in **daemon mode** continuously in the background as a systemd service (or optionally as a SysV init script). Instructions are provided below.

## Table of Contents

On this Page:

- [Features](#features)- key features of this reporter
- [Prerequisites](#prerequisites)
- [Prerequisites](#prerequisites)
- [Installation](#installation) - install prerequisites and the daemon project
- [Configuration](#configuration) - configuring the script to talk with your MQTT broker
- [Execution](#execution) - initial run by hand, then setup to run from boot
- [Integration](#integration) - a quick look at what's reported to MQTT about this RPi
- [Troubleshooting](#troubleshooting) - having start up issues? Check here for common problems
- [Troubleshooting](#troubleshooting) - having start up issues? Check here for common problems

Additional pages:

Expand All @@ -34,7 +33,6 @@ Additional pages:
- [The Associated Lovelace RPi Monitor Card](https://github.com/ironsheep/lovelace-rpi-monitor-card) - This is our companion Lovelace Card that makes displaying this RPi Monitor data very easy
- [ChangeLog](./ChangeLog) - We've been repairing or adding features to this script as users report issues or wishes. This is our list of changes


## Features

- Tested on Raspberry Pi's 2/3/4 with Jessie, Stretch and Buster
Expand Down Expand Up @@ -111,7 +109,7 @@ The monitored topic reports the following information:
| `throttle` | | reports the throttle status value plus interpretation thereof |
| `timestamp` | | date, time when this report was generated |

_NOTE: cpu load averages are divided by the number of cores_
NOTE: _cpu load averages are divided by the number of cores_

## Prerequisites

Expand Down Expand Up @@ -143,10 +141,10 @@ sudo apt-get install libraspberrypi-bin net-tools
### Packages for Arch Linux

```shell
sudo pacman -S python python-pip python-tzlocal python-notify2 python-colorama python-unidecode python-paho-mqtt python-requests inetutils
sudo pacman -S python python-pip python-tzlocal python-notify2 python-colorama python-unidecode python-paho-mqtt python-requests inetutils
```

**NOTE**: *for users of Arch Linux the number of updates available will NOT be reported (will always show as '-1'.) This is due to Arch Linux not using the apt package manager.*
**NOTE**: _for users of Arch Linux the number of updates available will NOT be reported (will always show as '-1'.) This is due to Arch Linux not using the apt package manager._

### With these extra packages installed, verify access to network information

Expand Down Expand Up @@ -185,7 +183,7 @@ wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

```

If you are seeing output from the `ifconfig` tool then continue on with the following steps. If you don't you may have missed installing `net-utils` in an earlier step.
If you are seeing output from the `ifconfig` tool then continue on with the following steps. If you don't you may have missed installing `net-utils` in an earlier step.

### Now finish with the script install

Expand Down Expand Up @@ -436,10 +434,7 @@ An example:
"load_5min_prcnt": 0,
"load_15min_prcnt": 0
},
"throttle": [
"throttled = 0x0",
"Not throttled"
],
"throttle": ["throttled = 0x0", "Not throttled"],
"temperature_c": 25.8,
"temp_gpu_c": 25.8,
"temp_cpu_c": 25.8,
Expand All @@ -450,11 +445,10 @@ An example:
}
```
**NOTE:** Where there's an IP address that interface is connected. Also, there are new `tx_data` and `rx_data` values which show traffic in bytes for this reporting interval for each network interface.
**NOTE:** Where there's an IP address that interface is connected. Also, there are new `tx_data` and `rx_data` values which show traffic in bytes for this reporting interval for each network interface.
This data can be subscribed to and processed by your home assistant installation. How you build your RPi dashboard from here is up to you!
## Troubleshooting
### Issue: Some of my RPi's don't show up in HA
Expand All @@ -467,7 +461,7 @@ We occasionaly have reports of users with more than one RPi on their network but
Most often fix: _reboot the missing RPi._
When you remove a sensor from Home Assistant it tells the MQTT broker to 'forget' everything it knows about the RPi. Some of the information is actually `stored by the MQTT broker` so it is available while the RPi is offline. Our Daemon script only broadcasts this `stored` information when it is first started. As a result the RPi will not re-appear after delete from Home Assistant until you reboot the RPi in question. (or, alternatively, stop then restart the script.). You may find reboot easier to do.
When you remove a sensor from Home Assistant it tells the MQTT broker to 'forget' everything it knows about the RPi. Some of the information is actually `stored by the MQTT broker` so it is available while the RPi is offline. Our Daemon script only broadcasts this `stored` information when it is first started. As a result the RPi will not re-appear after delete from Home Assistant until you reboot the RPi in question. (or, alternatively, stop then restart the script.). You may find reboot easier to do.
To reboot:
Expand Down Expand Up @@ -510,13 +504,12 @@ I find [MQTT Explorer](http://mqtt-explorer.com/) to be an excellent tool to use
Alternatively I also use **MQTTBox** when I want to send messages by hand to interact via MQTT. it is affered as a web extension or a native application.
#### Viewing the Daemon logs
When your script is being run as a Daemon it is logging. You can view the log output since last reboot with:
```bash
$ journalctl -b --no-pager -u isp-rpi-reporter.service
journalctl -b --no-pager -u isp-rpi-reporter.service
```
Alternatively you can create a simple script which you can run any time you want to see the log. Here's my show Daemon log script `showRpiLog`:
Expand All @@ -527,7 +520,7 @@ Alternatively you can create a simple script which you can run any time you want
(set -x;journalctl -b --no-pager -u isp-rpi-reporter.service)
```
**NOTE**: *the -b says 'since last boot' the --no-pager says just show it all without breaking it up into pages and requiring the enter key press for each page.*
**NOTE**: _the -b says 'since last boot' the --no-pager says just show it all without breaking it up into pages and requiring the enter key press for each page._
---
Expand Down
4 changes: 2 additions & 2 deletions RMTECTRL.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ An example to reboot or shutdown the Pi:
[Commands]
shutdown = /usr/bin/sudo /sbin/shutdown -h now 'shutdown rqst via MQTT'
reboot = /usr/bin/sudo /sbin/shutdown -r now 'reboot rqst via MQTT'
restart_service = /usr/bin/sudo systemctl restart {}
restart_service = /usr/bin/sudo systemctl restart isp-rpi-reporter.service
```

*NOTE* the message in the `{action} rqst via MQTT` message is logged in `/var/log/auth.log` so one can keep track of when commands are executed via MQTT.
Expand All @@ -109,7 +109,7 @@ the sudoers configuration file:

# add the following lines at the bottom.
# note that every service that we want to allow to restart must be specified here
daemon <raspberrypihostname> =NOPASSWD: /usr/bin/systemctl restart isp-rpi-reporter,/sbin/shutdown
daemon <raspberrypihostname> =NOPASSWD: /usr/bin/systemctl restart isp-rpi-reporter.service,/sbin/shutdown
```

NOTE: In some systems the path for `systemctl` / `reboot` / `shutdown` can be different. Make sure the path you specify is correct for your system.
Expand Down
2 changes: 1 addition & 1 deletion config.ini.dist
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
[Commands]
#shutdown = /usr/bin/sudo /sbin/shutdown -h now 'shutdown rqst via MQTT'
#reboot = /usr/bin/sudo /sbin/shutdown -r now 'reboot rqst via MQTT'
#restart_service = /usr/bin/sudo systemctl restart {}
#restart_service = /usr/bin/sudo systemctl restart isp-rpi-reporter.service

[MQTT]

Expand Down

0 comments on commit d637ee7

Please sign in to comment.