mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-05-21 08:11:50 +02:00
potentially add mqtt
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
- [FEAT] : publish mqtt to homeassistant if a server is found
|
||||||
|
|
||||||
## 0.13-61 (30-06-2024)
|
## 0.13-61 (30-06-2024)
|
||||||
- [FIX] : safeguard to avoid embedded pulseaudio interference
|
- [FIX] : safeguard to avoid embedded pulseaudio interference
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ RUN \
|
|||||||
sed -i "/git clone/a chown -R 1000:1000 $HOME" /newinstaller.sh && \
|
sed -i "/git clone/a chown -R 1000:1000 $HOME" /newinstaller.sh && \
|
||||||
# Remove all instances of sudo from the newinstaller
|
# Remove all instances of sudo from the newinstaller
|
||||||
sed -i -e "s|== 0|== 7|g" -e "s|sudo -n true|true|g" -e "s|sudo -K|true|g" /newinstaller.sh && \
|
sed -i -e "s|== 0|== 7|g" -e "s|sudo -n true|true|g" -e "s|sudo -K|true|g" /newinstaller.sh && \
|
||||||
|
# Add MQTT dependencies
|
||||||
|
echo "dateparser" >> /requirements.txt && \
|
||||||
\
|
\
|
||||||
# Execute installer
|
# Execute installer
|
||||||
/./newinstaller.sh && \
|
/./newinstaller.sh && \
|
||||||
|
|||||||
@@ -108,11 +108,14 @@
|
|||||||
"pi_password": "password",
|
"pi_password": "password",
|
||||||
"ssl": "bool"
|
"ssl": "bool"
|
||||||
},
|
},
|
||||||
|
"services": [
|
||||||
|
"mqtt:want"
|
||||||
|
],
|
||||||
"slug": "birdnet-pi",
|
"slug": "birdnet-pi",
|
||||||
"tmpfs": true,
|
"tmpfs": true,
|
||||||
"udev": true,
|
"udev": true,
|
||||||
"url": "https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pi",
|
"url": "https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pi",
|
||||||
"usb": true,
|
"usb": true,
|
||||||
"version": "0.13-61",
|
"version": "0.13-62",
|
||||||
"video": true
|
"video": true
|
||||||
}
|
}
|
||||||
|
|||||||
28
birdnet-pi/rootfs/etc/cont-init.d/33-mqtt.sh
Normal file
28
birdnet-pi/rootfs/etc/cont-init.d/33-mqtt.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/with-contenv bashio
|
||||||
|
# shellcheck shell=bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Gives mqtt information
|
||||||
|
|
||||||
|
if bashio::services.available 'mqtt'; then
|
||||||
|
bashio::log.green "---"
|
||||||
|
bashio::log.blue "MQTT addon is active on your system! Birdnet-pi is now automatically configured to send its ouptut to MQTT"
|
||||||
|
bashio::log.blue "MQTT user : $(bashio::services "mqtt" "username")"
|
||||||
|
bashio::log.blue "MQTT password : $(bashio::services "mqtt" "password")"
|
||||||
|
bashio::log.blue "MQTT broker : tcp://$(bashio::services "mqtt" "host"):$(bashio::services "mqtt" "port")"
|
||||||
|
bashio::log.green "---"
|
||||||
|
|
||||||
|
# Apply MQTT settings
|
||||||
|
sed -i "s|%%mqtt_server%%|$(bashio::services "mqtt" "host")|g" /helpers/birdnet_to_mqtt.py
|
||||||
|
sed -i "s|%%mqtt_port%%|$(bashio::services "mqtt" "port")|g" /helpers/birdnet_to_mqtt.py
|
||||||
|
sed -i "s|%%mqtt_user%%|$(bashio::services "mqtt" "username")|g" /helpers/birdnet_to_mqtt.py
|
||||||
|
sed -i "s|%%mqtt_pass%%|$(bashio::services "mqtt" "password")|g" /helpers/birdnet_to_mqtt.py
|
||||||
|
|
||||||
|
# Copy script
|
||||||
|
cp /helpers/birdnet_to_mqtt.py /usr/bin/birdnet_to_mqtt.py
|
||||||
|
chmod 777 /usr/bin/birdnet_to_mqtt.py
|
||||||
|
|
||||||
|
# Start python
|
||||||
|
"$PYTHON_VIRTUAL_ENV" /usr/bin/birdnet_to_mqtt.py & true
|
||||||
|
|
||||||
|
fi
|
||||||
120
birdnet-pi/rootfs/helpers/birdnet_to_mqtt.py
Normal file
120
birdnet-pi/rootfs/helpers/birdnet_to_mqtt.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#! /usr/bin/env python3
|
||||||
|
# birdnet_to_mqtt.py
|
||||||
|
#
|
||||||
|
# from https://gist.github.com/JuanMeeske/08b839246a62ff38778f701fc1da5554
|
||||||
|
#
|
||||||
|
# monitor the records in the syslog file for info from the birdnet system on birds that it detects
|
||||||
|
# publish this data to mqtt
|
||||||
|
#
|
||||||
|
|
||||||
|
import time
|
||||||
|
import re
|
||||||
|
import dateparser
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
# Setup basic configuration for logging
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
SYSLOG_FILE_PATH = '/proc/1/fd/1'
|
||||||
|
MQTT_SERVER = "%%mqtt_server%%" # Replace with your MQTT server address or hostname
|
||||||
|
MQTT_PORT = %%mqtt_port%%
|
||||||
|
MQTT_KEEPALIVE = 60
|
||||||
|
MQTT_TOPIC_ALL_BIRDS = 'birdnet'
|
||||||
|
CLIENT_ID = 'python-mqtt'
|
||||||
|
USERNAME = "%%mqtt_user%%" # Replace with your MQTT username
|
||||||
|
PASSWORD = "%%mqtt_pass%%" # Replace with your MQTT password
|
||||||
|
# Extract the value of confidence and convert it to float
|
||||||
|
with open('/config/birdnet.conf', 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
for line in lines:
|
||||||
|
if line.startswith('CONFIDENCE='):
|
||||||
|
CONFIDENCE = float(line.split('=')[1].strip())
|
||||||
|
|
||||||
|
# Regular expression pattern to parse log entries
|
||||||
|
RE_BIRD_ENTRY = re.compile(
|
||||||
|
r'(\d{4}-\d{2}-\d{2};\d{2}:\d{2}:\d{2};[^;]+;[^;]+;\d+\.\d+;\d+\.\d+;\d+\.\d+;\d+\.\d+;\d+;\d+\.\d+;\d+\.\d+;)([^ ]+\.mp3)'
|
||||||
|
)
|
||||||
|
|
||||||
|
def file_row_generator(file_path):
|
||||||
|
""" Generator that yields new lines from a file continuously. """
|
||||||
|
with open(file_path, 'r') as file:
|
||||||
|
file.seek(0, 2) # Move the pointer to the end of the file
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
time.sleep(0.1) # Sleep briefly to avoid busy waiting
|
||||||
|
continue
|
||||||
|
yield line
|
||||||
|
|
||||||
|
def on_connect(client, userdata, flags, rc, properties=None):
|
||||||
|
""" Callback for when the client receives a CONNACK response from the server. """
|
||||||
|
if rc == 0:
|
||||||
|
logging.info("Connected to MQTT Broker!")
|
||||||
|
else:
|
||||||
|
logging.error(f"Failed to connect, return code {rc}\n")
|
||||||
|
|
||||||
|
def on_disconnect(client, userdata, rc, disconnect_flags, properties=None):
|
||||||
|
""" Callback for when the client disconnects from the server. """
|
||||||
|
logging.info(f"Disconnected from MQTT Broker with rc: {rc}")
|
||||||
|
|
||||||
|
# Setup MQTT client
|
||||||
|
mqtt_client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, CLIENT_ID)
|
||||||
|
mqtt_client.username_pw_set(USERNAME, PASSWORD)
|
||||||
|
mqtt_client.on_connect = on_connect
|
||||||
|
mqtt_client.on_disconnect = on_disconnect
|
||||||
|
|
||||||
|
# Connect to MQTT Broker
|
||||||
|
mqtt_client.connect(MQTT_SERVER, MQTT_PORT, MQTT_KEEPALIVE)
|
||||||
|
mqtt_client.loop_start()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Process each new line in the syslog file
|
||||||
|
for row in file_row_generator(SYSLOG_FILE_PATH):
|
||||||
|
try:
|
||||||
|
match = RE_BIRD_ENTRY.search(row)
|
||||||
|
if match:
|
||||||
|
details, mp3_filename = match.groups()
|
||||||
|
details_list = details.split(';')
|
||||||
|
detection_date = details_list[0]
|
||||||
|
detection_time = details_list[1]
|
||||||
|
species = details_list[2]
|
||||||
|
common_name = details_list[3]
|
||||||
|
latitude = float(details_list[5])
|
||||||
|
longitude = float(details_list[6])
|
||||||
|
|
||||||
|
confidence = float(details_list[4])
|
||||||
|
if confidence > CONFIDENCE:
|
||||||
|
bird_data = {
|
||||||
|
'SourceNode': 'BirdNET-Pi',
|
||||||
|
'Date': detection_date,
|
||||||
|
'Time': detection_time,
|
||||||
|
'ScientificName': species,
|
||||||
|
'CommonName': common_name,
|
||||||
|
'Confidence': confidence,
|
||||||
|
'Latitude': latitude,
|
||||||
|
'Longitude': longitude,
|
||||||
|
'ClipName': mp3_filename
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.info(f"Published bird data: {bird_data}")
|
||||||
|
|
||||||
|
# Publishing data to MQTT
|
||||||
|
mqtt_client.publish(MQTT_TOPIC_ALL_BIRDS, json.dumps(bird_data), qos=1)
|
||||||
|
else:
|
||||||
|
continue # Skip this iteration if no matching log entry is found
|
||||||
|
else:
|
||||||
|
continue # Skip this iteration if no matching log entry is found
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error processing row: {e}")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
mqtt_client.loop_stop()
|
||||||
|
mqtt_client.disconnect()
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
Reference in New Issue
Block a user