Skip to content

Commit

Permalink
Merge branch 'master' into feature/buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
hobbypunk90 committed Feb 12, 2023
2 parents 8c1f315 + f35c698 commit 5a81c1c
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 188 deletions.
12 changes: 6 additions & 6 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 2,
};
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 160,
tabWidth: 2,
};
48 changes: 34 additions & 14 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# ChangeLog

Sat, 11 Feb 2023 14:28:59 -0700 v1.7.2

- Repair fetch of versions, now every 12 hours

Fri, 10 Feb 2023 17:27:06 -0700 v1.7.1

- Fix internal release number
- Forward formal releases via MQTT

Tue, 17 Aug 2022 18:37:21 -0600 v1.6.2

- (#63) Fix path to cut(1) command
- (#61) add filter to prevent df reporting "No such device or address" from breaking the script

Tue, 02 Aug 2022 18:37:21 -0600 v1.6.1

- Fix 'bullseye' name determination - remove extra sources output

Thu, 02 Dec 2021 16:36:15 -0600 v1.6.0

- Merged 4 pull requests:
Expand Down Expand Up @@ -44,12 +64,12 @@ Mon Aug 17 01:26:21 2020 -0600 v1.5.0
Sat Aug 15 03:25:26 2020 -0600 v1.4.4

- Fix log file grep (for some systems)
Add option for grep to treat dpkg log files a text (#8)
README: show new drives entry in MQTT payload
Add option for grep to treat dpkg log files a text (#8)
README: show new drives entry in MQTT payload

Tue Aug 11 18:42:34 2020 -0600 v1.4.3

- Add alternate locn for vcgen* cmd, use alternate drive space parser
- Add alternate locn for vcgen\* cmd, use alternate drive space parser

Sun Aug 9 18:25:57 2020 -0600 v1.4.2

Expand Down Expand Up @@ -85,8 +105,8 @@ Sat Aug 1 20:44:30 2020 -0600 v1.3.3
Sat Aug 1 19:10:26 2020 -0600 v1.3.2

- Fix uniqueID code, last upd date code
Last update date was being affected by log-rotate... move to another technique
Damaged unique ID generation with v1.3.0... fixed it now
Last update date was being affected by log-rotate... move to another technique
Damaged unique ID generation with v1.3.0... fixed it now

Sat Aug 1 16:02:38 2020 -0600 v1.3.1

Expand All @@ -95,11 +115,11 @@ Sat Aug 1 16:02:38 2020 -0600 v1.3.1
Sat Aug 1 15:14:06 2020 -0600 v1.3.0

- Add new Config Variables
Add fallback_domain and discovery_prefix to config file reader
Adjust discovery advert to use new prefix
Adjust hostname fetch to use new fallback
Add temp fallback to cpu when gpu not avail
Ship both cpu and gpu temps in status dict
Add fallback_domain and discovery_prefix to config file reader
Adjust discovery advert to use new prefix
Adjust hostname fetch to use new fallback
Add temp fallback to cpu when gpu not avail
Ship both cpu and gpu temps in status dict
- Add bug report info script and instru. in bug report template
- Add Jessie notes

Expand All @@ -116,10 +136,10 @@ Thu Jul 23 13:55:00 2020 -0600 v1.2.1
Wed Jul 22 21:34:06 2020 -0600 v1.2.0

- Update ISP-RPi-mqtt-daemon.py
Add two new endponts discovered per RPi (degr C and % space used)
Add test mode for failed to report in
Forward interval set to card
New option for testing stall
Add two new endponts discovered per RPi (degr C and % space used)
Add test mode for failed to report in
Forward interval set to card
New option for testing stall

Wed Jul 22 13:47:18 2020 -0600 v1.1.2

Expand Down
124 changes: 112 additions & 12 deletions ISP-RPi-mqtt-daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
import sdnotify
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE, SIG_DFL)
import requests
from urllib3.exceptions import InsecureRequestWarning

script_version = "1.7.0"
script_version = "1.7.2"
script_name = 'ISP-RPi-mqtt-daemon.py'
script_info = '{} v{}'.format(script_name, script_version)
project_name = 'RPi Reporter MQTT2HA Daemon'
Expand All @@ -34,6 +36,10 @@
# we'll use this throughout
local_tz = get_localzone()

# turn off insecure connection warnings (our KZ0Q site has bad certs)
# REF: https://www.geeksforgeeks.org/how-to-disable-security-certificate-checks-for-requests-in-python/
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

# TODO:
# - add announcement of free-space and temperatore endpoints

Expand All @@ -55,6 +61,8 @@

def print_line(text, error=False, warning=False, info=False, verbose=False, debug=False, console=True, sd_notify=False):
timestamp = strftime('%Y-%m-%d %H:%M:%S', localtime())
if(sd_notify):
text = '* NOTIFY: {}'.format(text)
if console:
if error:
print(Fore.RED + Style.BRIGHT + '[{}] '.format(
Expand Down Expand Up @@ -140,7 +148,7 @@ def on_connect(client, userdata, flags, rc):
print_line('on_connect() mqtt_client_connected=[{}]'.format(
mqtt_client_connected), debug=True)
client.on_publish = on_publish

# -------------------------------------------------------------------------
# Commands Subscription
if (len(commands) > 0):
Expand Down Expand Up @@ -176,10 +184,10 @@ def on_subscribe(client, userdata, mid, granted_qos):

def on_message(client, userdata, message):
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)])
Expand Down Expand Up @@ -252,6 +260,57 @@ def on_message(client, userdata, message):

print_line('Configuration accepted', console=False, sd_notify=True)

# -----------------------------------------------------------------------------
# Daemon variables monitored
# -----------------------------------------------------------------------------

daemon_version_list = [ 'NOT-LOADED' ]
daemon_last_fetch_time = 0.0

def getDaemonReleases():
# retrieve latest formal release versions list from repo
global daemon_version_list
global daemon_last_fetch_time

newVersionList = []
latestVersion = ''

response = requests.request('GET', 'http://kz0q.com/daemon-releases', verify=False)
if response.status_code != 200:
print_line('- getDaemonReleases() RQST status=({})'.format(response.status_code), error=True)
daemon_version_list = [ 'NOT-LOADED' ] # mark as NOT fetched
else:
content = response.text
lines = content.split('\n')
for line in lines:
if len(line) > 0:
#print_line('- RLS Line=[{}]'.format(line), debug=True)
lineParts = line.split(' ')
#print_line('- RLS lineParts=[{}]'.format(lineParts), debug=True)
if len(lineParts) >= 2:
currVersion = lineParts[0]
rlsType = lineParts[1]
if not currVersion in newVersionList:
if not 'latest' in rlsType.lower():
newVersionList.append(currVersion) # append to list
else:
latestVersion = currVersion

if len(newVersionList) > 1:
newVersionList.sort()
if len(latestVersion) > 0:
if not latestVersion in newVersionList:
newVersionList.insert(0, latestVersion) # append to list

daemon_version_list = newVersionList
print_line('- RQST daemon_version_list=({})'.format(daemon_version_list), debug=True)
daemon_last_fetch_time = time() # record when we last fetched the versions

getDaemonReleases() # and load them!
print_line('* daemon_last_fetch_time=({})'.format(daemon_last_fetch_time), debug=True)



# -----------------------------------------------------------------------------
# RPi variables monitored
# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -398,6 +457,24 @@ def getDeviceMemory():
rpi_memory_tuple = (mem_total, mem_free, mem_avail)
print_line('rpi_memory_tuple=[{}]'.format(rpi_memory_tuple), debug=True)

def refreshPackageInfo():
out = subprocess.Popen("/usr/bin/sudo /usr/bin/apt-get update",
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout, _ = out.communicate()
update_rslts = stdout.decode('utf-8')
print_line('update_rslts=[{}]'.format(update_rslts), warning=True, sd_notify=True)

def getUpdateCounts():
# /usr/bin/sudo
out = subprocess.Popen("/usr/bin/sudo /usr/bin/apt-get --assume-no dist-upgrade",
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout, _ = out.communicate()
package_rslts = stdout.decode('utf-8')
print_line('package_rslts=[{}]'.format(package_rslts), warning=True, sd_notify=True)

def getDeviceModel():
global rpi_model
Expand Down Expand Up @@ -435,7 +512,7 @@ def getDeviceModel():

def getLinuxRelease():
global rpi_linux_release
out = subprocess.Popen("/bin/cat /etc/apt/sources.list | /bin/egrep -v '#' | /usr/bin/awk '{ print $3 }' | /bin/grep . | /usr/bin/sort -u",
out = subprocess.Popen("/bin/cat /etc/apt/sources.list | /bin/egrep -v '#' | /usr/bin/awk '{ print $3 }' | /bin/sed -e 's/-/ /g' | /usr/bin/cut -f1 -d' ' | /bin/grep . | /usr/bin/sort -u",
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
Expand Down Expand Up @@ -689,8 +766,17 @@ def getFileSystemDrives():
# /dev/mmcblk0p1 253 55 198 22% /boot
# tmpfs 340 0 340 0% /run/user/1000

# FAILING Case v1.6.x (issue #61)
# [[/bin/df: /mnt/sabrent: No such device or address',
# '/dev/root 119756 19503 95346 17% /',
# '/dev/sda1 953868 882178 71690 93% /media/usb0',
# '/dev/sdb1 976761 93684 883078 10% /media/pi/SSD']]

tmpDrives = []
for currLine in trimmedLines:
if 'no such device' in currLine.lower():
print_line('BAD LINE FORMAT, Skipped=[{}]'.format(currLine), debug=True, warning=True)
continue
lineParts = currLine.split()
print_line('lineParts({})=[{}]'.format(
len(lineParts), lineParts), debug=True)
Expand Down Expand Up @@ -879,7 +965,6 @@ def getSystemThermalStatus():
print_line('rpi_throttle_status=[{}]'.format(
rpi_throttle_status), debug=True)


def interpretThrottleValue(throttleValue):
"""
01110000000000000010
Expand Down Expand Up @@ -982,7 +1067,6 @@ def getLastInstallDate():
print_line('rpi_last_update_date=[{}]'.format(
rpi_last_update_date), debug=True)


# get our hostnames so we can setup MQTT
getHostnames()
if(sensor_name == default_sensor_name):
Expand Down Expand Up @@ -1097,6 +1181,13 @@ def isAliveTimerRunning():

sd_notifier.notify('READY=1')

# -----------------------------------------------------------------------------
# Perform our MQTT Discovery Announcement...
# -----------------------------------------------------------------------------

# findings: both sudo and not sudo fail (suders doesn't contain daemon and shouldn't)
#refreshPackageInfo()
#getUpdateCounts()

# -----------------------------------------------------------------------------
# Perform our MQTT Discovery Announcement...
Expand Down Expand Up @@ -1172,7 +1263,7 @@ def isAliveTimerRunning():
(LD_CPU_USE, dict(
title="RPi CPU Use {}".format(rpi_hostname),
topic_category="sensor",
no_title_prefix="yes",
no_title_prefix="yes",
unit="%",
icon=LD_CPU_USE_ICON,
json_value=LD_CPU_USE_JSON,
Expand Down Expand Up @@ -1226,16 +1317,16 @@ def isAliveTimerRunning():
payload['~'] = sensor_base_topic
payload['avty_t'] = activity_topic_rel
payload['pl_avail'] = lwt_online_val
payload['pl_not_avail'] = lwt_offline_val
payload['pl_not_avail'] = lwt_offline_val
if 'trigger_type' in params:
payload['type'] = params['trigger_type']
if 'trigger_subtype' in params:
payload['subtype'] = params['trigger_subtype']
if 'icon' in params:
payload['ic'] = params['icon']
payload['ic'] = params['icon']
if 'json_attr' in params:
payload['json_attr_t'] = values_topic_rel
payload['json_attr_tpl'] = '{{{{ value_json.{} | tojson }}}}'.format(LDS_PAYLOAD_NAME)
payload['json_attr_tpl'] = '{{{{ value_json.{} | tojson }}}}'.format(LDS_PAYLOAD_NAME)
if 'device_ident' in params:
payload['dev'] = {
'identifiers': ["{}".format(uniqID)],
Expand Down Expand Up @@ -1316,6 +1407,7 @@ def isPeriodTimerRunning():
RPI_GPU_TEMP = "temp_gpu_c"
RPI_CPU_TEMP = "temp_cpu_c"
RPI_SCRIPT = "reporter"
RPI_SCRIPT_VERSIONS = "reporter_releases"
RPI_NETWORK = "networking"
RPI_INTERFACE = "interface"
SCRIPT_REPORT_INTERVAL = "report_interval"
Expand Down Expand Up @@ -1398,6 +1490,7 @@ def send_status(timestamp, nothing):
rpiData[RPI_CPU_TEMP] = forceSingleDigit(rpi_cpu_temp)

rpiData[RPI_SCRIPT] = rpi_mqtt_script.replace('.py', '')
rpiData[RPI_SCRIPT_VERSIONS] = ','.join(daemon_version_list)
rpiData[SCRIPT_REPORT_INTERVAL] = interval_in_minutes

rpiTopDict = OrderedDict()
Expand Down Expand Up @@ -1560,15 +1653,22 @@ def afterMQTTConnect():
# stopAliveTimer()
# exit(0)


afterMQTTConnect() # now instead of after?

# check every 12 hours (twice a day) = 12 hours * 60 minutes * 60 seconds
kVersionCheckIntervalInSeconds = (12 * 60 * 60)

# now just hang in forever loop until script is stopped externally
try:
while True:
# our INTERVAL timer does the work
sleep(10000)

timeNow = time()
if timeNow > daemon_last_fetch_time + kVersionCheckIntervalInSeconds:
getDaemonReleases() # and load them!


finally:
# cleanup used pins... just because we like cleaning up after us
stopPeriodTimer() # don't leave our timers running!
Expand Down
Loading

0 comments on commit 5a81c1c

Please sign in to comment.