voc.infobeamer-cms: add infobeamer-monitor
This commit is contained in:
parent
2670d60906
commit
b5475df467
5 changed files with 217 additions and 0 deletions
4
bundles/infobeamer-monitor/files/config.toml
Normal file
4
bundles/infobeamer-monitor/files/config.toml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<%
|
||||
from tomlkit import dumps as toml_dumps
|
||||
from bundlewrap.utils.text import toml_clean
|
||||
%>${toml_clean(toml_dumps(repo.libs.faults.resolve_faults(config), sort_keys=True))}
|
15
bundles/infobeamer-monitor/files/infobeamer-monitor.service
Normal file
15
bundles/infobeamer-monitor/files/infobeamer-monitor.service
Normal file
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=infobeamer-monitor
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
ExecStart=/opt/infobeamer-cms/venv/bin/python monitor.py
|
||||
User=infobeamer-cms
|
||||
Group=infobeamer-cms
|
||||
WorkingDirectory=/opt/infobeamer-monitor/
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
155
bundles/infobeamer-monitor/files/monitor.py
Normal file
155
bundles/infobeamer-monitor/files/monitor.py
Normal file
|
@ -0,0 +1,155 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
from json import dumps
|
||||
from time import sleep
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
from requests import RequestException, get
|
||||
|
||||
try:
|
||||
# python 3.11
|
||||
from tomllib import loads as toml_load
|
||||
except ImportError:
|
||||
from rtoml import load as toml_load
|
||||
|
||||
with open("config.toml") as f:
|
||||
CONFIG = toml_load(f.read())
|
||||
|
||||
|
||||
logging.basicConfig(
|
||||
format="[%(levelname)s %(name)s] %(message)s",
|
||||
level=logging.INFO,
|
||||
)
|
||||
|
||||
LOG = logging.getLogger("main")
|
||||
MLOG = logging.getLogger("mqtt")
|
||||
|
||||
state = None
|
||||
|
||||
client = mqtt.Client()
|
||||
client.username_pw_set(CONFIG["mqtt"]["user"], CONFIG["mqtt"]["password"])
|
||||
client.connect(CONFIG["mqtt"]["host"], 1883, 60)
|
||||
client.loop_start()
|
||||
|
||||
|
||||
def mqtt_out(message, level="INFO", device=None):
|
||||
key = "infobeamer"
|
||||
if device:
|
||||
key += f"/{device['id']}"
|
||||
message = f"[{device['description']}] {message}"
|
||||
|
||||
client.publish(
|
||||
CONFIG["mqtt"]["topic"],
|
||||
dumps(
|
||||
{
|
||||
"level": level,
|
||||
"component": key,
|
||||
"msg": message,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def mqtt_dump_state(device):
|
||||
mqtt_out(
|
||||
"Sync status: {} - Location: {} - Running Setup: {} ({}) - Resolution: {}".format(
|
||||
"yes" if device["is_synced"] else "unknown",
|
||||
device["location"],
|
||||
device["setup"]["name"],
|
||||
device["setup"]["id"],
|
||||
device["run"].get("resolution", "unknown"),
|
||||
),
|
||||
device=device,
|
||||
)
|
||||
|
||||
|
||||
mqtt_out("Monitor starting up")
|
||||
while True:
|
||||
try:
|
||||
try:
|
||||
r = get("https://info-beamer.com/api/v1/device/list", auth=("", CONFIG["api_key"]))
|
||||
r.raise_for_status()
|
||||
ib_state = r.json()["devices"]
|
||||
except RequestException as e:
|
||||
LOG.exception("Could not get data from info-beamer")
|
||||
mqtt_out(
|
||||
f"Could not get data from info-beamer: {e!r}",
|
||||
level="WARN",
|
||||
)
|
||||
else:
|
||||
new_state = {}
|
||||
for device in ib_state:
|
||||
did = str(device["id"])
|
||||
|
||||
if did in new_state:
|
||||
mqtt_out("DUPLICATE DETECTED!", level="ERROR", device=device)
|
||||
continue
|
||||
|
||||
new_state[did] = device
|
||||
must_dump_state = False
|
||||
|
||||
if state is not None:
|
||||
if did not in state:
|
||||
LOG.info(
|
||||
"new device found: {} [{}]".format(
|
||||
did,
|
||||
device["description"],
|
||||
)
|
||||
)
|
||||
mqtt_out(
|
||||
'new device found with name "{}"!'.format(
|
||||
device["description"]
|
||||
),
|
||||
device=device,
|
||||
)
|
||||
if device["is_online"]:
|
||||
must_dump_state = True
|
||||
|
||||
else:
|
||||
if device["is_online"] != state[did]["is_online"]:
|
||||
online_status = (
|
||||
"online from {}".format(device["run"]["public_addr"])
|
||||
if device["is_online"]
|
||||
else "offline"
|
||||
)
|
||||
|
||||
LOG.info("device {} is now {}".format(did, online_status))
|
||||
mqtt_out(
|
||||
f"online status changed to {online_status}",
|
||||
device=device,
|
||||
)
|
||||
if device["is_online"]:
|
||||
must_dump_state = True
|
||||
|
||||
if device["is_online"]:
|
||||
if device["maintenance"]:
|
||||
mqtt_out(
|
||||
"maintenance required: {}".join(
|
||||
sorted(device["maintenance"])
|
||||
),
|
||||
level="WARN",
|
||||
device=device,
|
||||
)
|
||||
|
||||
if (
|
||||
device["is_synced"] != state[did]["is_synced"]
|
||||
or device["location"] != state[did]["location"]
|
||||
or device["setup"]["name"] != state[did]["setup"]["name"]
|
||||
or device["run"].get("resolution")
|
||||
!= state[did]["run"].get("resolution")
|
||||
):
|
||||
must_dump_state = True
|
||||
|
||||
if must_dump_state:
|
||||
mqtt_dump_state(device)
|
||||
|
||||
else:
|
||||
LOG.info("adding device {} to empty state".format(device["id"]))
|
||||
|
||||
state = new_state
|
||||
sleep(30)
|
||||
except KeyboardInterrupt:
|
||||
break
|
||||
|
||||
mqtt_out("Monitor exiting")
|
33
bundles/infobeamer-monitor/items.py
Normal file
33
bundles/infobeamer-monitor/items.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
assert node.has_bundle('infobeamer-cms') # uses same venv
|
||||
|
||||
files['/opt/infobeamer-monitor/config.toml'] = {
|
||||
'content_type': 'mako',
|
||||
'context': {
|
||||
'config': node.metadata.get('infobeamer-monitor'),
|
||||
},
|
||||
'triggers': {
|
||||
'svc_systemd:infobeamer-monitor:restart',
|
||||
},
|
||||
}
|
||||
|
||||
files['/opt/infobeamer-monitor/monitor.py'] = {
|
||||
'mode': '0755',
|
||||
'triggers': {
|
||||
'svc_systemd:infobeamer-monitor:restart',
|
||||
},
|
||||
}
|
||||
|
||||
files['/usr/local/lib/systemd/system/infobeamer-monitor.service'] = {
|
||||
'triggers': {
|
||||
'action:systemd-reload',
|
||||
'svc_systemd:infobeamer-monitor:restart',
|
||||
},
|
||||
}
|
||||
|
||||
svc_systemd['infobeamer-monitor'] = {
|
||||
'needs': {
|
||||
'file:/opt/infobeamer-monitor/config.toml',
|
||||
'file:/opt/infobeamer-monitor/monitor.py',
|
||||
'file:/usr/local/lib/systemd/system/infobeamer-monitor.service',
|
||||
},
|
||||
}
|
|
@ -2,6 +2,7 @@ nodes['voc.infobeamer-cms'] = {
|
|||
'hostname': 'infobeamer-cms.c3voc.de',
|
||||
'bundles': {
|
||||
'infobeamer-cms',
|
||||
'infobeamer-monitor',
|
||||
'redis',
|
||||
},
|
||||
'groups': {
|
||||
|
@ -68,6 +69,15 @@ nodes['voc.infobeamer-cms'] = {
|
|||
'Translations': 'translations',
|
||||
},
|
||||
},
|
||||
'infobeamer-monitor': {
|
||||
'api_key': vault.decrypt('encrypt$gAAAAABlitmDR1duKo_4KuMJBF_HbPO2GFo_gdoT1rvUKQ2kkugPbe2RljM4bxW5bmwhs5avjxiaSAvjnOBte9ioyPEr7cIh79WFEfMnsHeexlCHwMt6NV_t-8EAhuuEQEf3Py93g8zQ'),
|
||||
'mqtt': {
|
||||
'password': vault.decrypt('encrypt$gAAAAABhxakfhhwWn0vxhoO1FiMEpdCkomWvo0dHIuBrqDKav8WDpI6dXpb0hoXiWRsPV6p5m-8RlbfFbjPhz47AY-nFOOAAW6Yis3-IVD-U-InKJo9dvms='),
|
||||
'host': 'mqtt.c3voc.de',
|
||||
'topic': '/voc/alert',
|
||||
'user': vault.decrypt('encrypt$gAAAAABhxakKHC_kHmHP2mFHorb4niuNTH4F24w1D6m5JUxl117N7znlZA6fpMmY3_NcmBr2Ihw4hL3FjZr9Fm_1oUZ1ZQdADA=='),
|
||||
},
|
||||
},
|
||||
'nginx': {
|
||||
'vhosts': {
|
||||
'redirect': {
|
||||
|
|
Loading…
Reference in a new issue