Skip to content
2 changes: 2 additions & 0 deletions packages/helpermodules/setdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,8 @@ def process_optional_topic(self, msg: mqtt.MQTTMessage):
elif ("openWB/set/optional/et/provider" in msg.topic or
"openWB/set/optional/ocpp/config" in msg.topic):
self._validate_value(msg, "json")
elif "openWB/set/optional/monitoring" in msg.topic:
self._validate_value(msg, "json")
elif "openWB/set/optional/rfid/active" in msg.topic:
self._validate_value(msg, bool)
elif "openWB/set/optional/int_display/rotation" in msg.topic:
Expand Down
9 changes: 9 additions & 0 deletions packages/helpermodules/subdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,15 @@ def process_optional_topic(self, var: optional.Optional, msg: mqtt.MQTTMessage):
elif re.search("/optional/ocpp/", msg.topic) is not None:
config_dict = decode_payload(msg.payload)
var.data.ocpp = dataclass_from_dict(Ocpp, config_dict)
elif re.search("/optional/monitoring/", msg.topic) is not None:
# do not reconfigure monitoring if topic is received on startup
if self.event_subdata_initialized.is_set():
config = decode_payload(msg.payload)
mod = importlib.import_module(f".monitoring.{config['type']}.api", "modules")
config = dataclass_from_dict(mod.device_descriptor.configuration_factory, config)
mod.create_config(config)
else:
log.debug("skipping monitoring config on startup")
else:
self.set_json_payload_class(var.data, msg)
except Exception:
Expand Down
3 changes: 3 additions & 0 deletions packages/helpermodules/update_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ class UpdateConfig:
"^openWB/optional/int_display/theme$",
"^openWB/optional/int_display/only_local_charge_points",
"^openWB/optional/led/active$",
"^openWB/optional/monitoring/config$",
"^openWB/optional/rfid/active$",
"^openWB/optional/ocpp/config$",

Expand Down Expand Up @@ -405,6 +406,7 @@ class UpdateConfig:
"^openWB/system/configurable/devices_components$",
"^openWB/system/configurable/electricity_tariffs$",
"^openWB/system/configurable/display_themes$",
"^openWB/system/configurable/monitoring$",
"^openWB/system/configurable/ripple_control_receivers$",
"^openWB/system/configurable/soc_modules$",
"^openWB/system/configurable/web_themes$",
Expand Down Expand Up @@ -512,6 +514,7 @@ class UpdateConfig:
("openWB/optional/int_display/theme", dataclass_utils.asdict(CardsDisplayTheme())),
("openWB/optional/int_display/only_local_charge_points", False),
("openWB/optional/led/active", False),
("openWB/optional/monitoring/config", NO_MODULE),
("openWB/optional/ocpp/config", dataclass_utils.asdict(Ocpp())),
("openWB/optional/rfid/active", False),
("openWB/system/backup_cloud/config", NO_MODULE),
Expand Down
35 changes: 35 additions & 0 deletions packages/modules/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def pub_configurable():
_pub_configurable_devices_components()
_pub_configurable_chargepoints()
_pub_configurable_ripple_control_receivers()
_pub_configurable_monitoring()


def _pub_configurable_backup_clouds() -> None:
Expand Down Expand Up @@ -336,5 +337,39 @@ def _pub_configurable_ripple_control_receivers() -> None:
log.exception("Fehler im configuration-Modul")


def _pub_configurable_monitoring() -> None:
try:
monitoring = []
path_list = Path(_get_packages_path()/"modules"/"monitoring").glob('**/config.py')
for path in path_list:
try:
if path.name.endswith("_test.py"):
# Tests überspringen
continue
dev_defaults = importlib.import_module(
f".monitoring.{path.parts[-2]}.api", "modules").device_descriptor.configuration_factory()
monitoring.append({
"value": dev_defaults.type,
"text": dev_defaults.name,
"defaults": dataclass_utils.asdict(dev_defaults)
})
except Exception:
log.exception("Fehler im configuration-Modul")
monitoring = sorted(monitoring, key=lambda d: d['text'].upper())
# "leeren" Eintrag an erster Stelle einfügen
monitoring.insert(0,
{
"value": None,
"text": "- kein Monitoring -",
"defaults": {
"type": None,
"configuration": {}
}
})
Pub().pub("openWB/set/system/configurable/monitoring", monitoring)
except Exception:
log.exception("Fehler im configuration-Modul")


def _get_packages_path() -> Path:
return Path(__file__).resolve().parents[2]/"packages"
41 changes: 41 additions & 0 deletions packages/modules/monitoring/zabbix/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
import os
from helpermodules.utils.run_command import run_command
from modules.common.abstract_device import DeviceDescriptor
from modules.monitoring.zabbix.config import Zabbix


KEY_PATH = "/etc/zabbix/encrypt.psk"
CONFIG_PATH = "/etc/zabbix/zabbix_agent2.conf"


def set_value(path, key, value):
with open(path, "r+") as file:
lines = file.readlines()
for i, line in enumerate(lines):
if line.startswith(key):
lines[i] = f"{key}={value}\n"
break
else:
lines.append(f"{key}={value}\n")
file.seek(0)
file.writelines(lines)
file.truncate()


def create_config(config: Zabbix):
os.system(f"sudo touch {KEY_PATH}")
os.system(f"sudo chmod 666 {KEY_PATH}")
os.system(f"sudo chmod 666 {CONFIG_PATH}")
with open(KEY_PATH, "w") as key_file:
key_file.write(config.configuration.psk_key)
set_value(CONFIG_PATH, "ServerActive", config.configuration.destination_host)
set_value(CONFIG_PATH, "Hostname", config.configuration.hostname)
set_value(CONFIG_PATH, "TLSConnect", "psk")
set_value(CONFIG_PATH, "TLSAccept", "psk")
set_value(CONFIG_PATH, "TLSPSKFile", KEY_PATH)
set_value(CONFIG_PATH, "TLSPSKIdentity", config.configuration.psk_identifier)
run_command(["sudo", "systemctl", "restart", "zabbix-agent2"], process_exception=True)


device_descriptor = DeviceDescriptor(configuration_factory=Zabbix)
23 changes: 23 additions & 0 deletions packages/modules/monitoring/zabbix/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from typing import Optional


class ZabbixConfiguration:
def __init__(self,
destination_host: Optional[str] = None,
hostname: Optional[str] = None,
psk_identifier: Optional[str] = None,
psk_key: Optional[str] = None):
self.destination_host = destination_host
self.hostname = hostname
self.psk_identifier = psk_identifier
self.psk_key = psk_key


class Zabbix:
def __init__(self,
name: str = "openWB (Zabbix)",
type: str = "zabbix",
configuration: ZabbixConfiguration = None) -> None:
self.name = name
self.type = type
self.configuration = configuration or ZabbixConfiguration()
25 changes: 16 additions & 9 deletions runs/install_packages.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#!/bin/bash
echo "install required packages with 'apt-get'..."
sudo apt-get -q update
sudo apt-get -q -y install \
vim bc jq socat sshpass sudo ssl-cert mmc-utils \
apache2 libapache2-mod-php \
php php-gd php-curl php-xml php-json \
git \
mosquitto mosquitto-clients \
python3-pip \
xserver-xorg x11-xserver-utils openbox-lxde-session lightdm lightdm-autologin-greeter accountsservice \
if [ ! -e zabbix-release_6.2-3+debian11_all.deb ]
then
wget https://repo.zabbix.com/zabbix/6.2/raspbian/pool/main/z/zabbix-release/zabbix-release_6.2-3%2Bdebian11_all.deb
sudo dpkg -i zabbix-release_6.2-3+debian11_all.deb
echo "download"
fi
sudo apt-get -q update
sudo apt-get -q -y install \
vim bc jq socat sshpass sudo ssl-cert mmc-utils \
apache2 libapache2-mod-php \
php php-gd php-curl php-xml php-json \
git \
mosquitto mosquitto-clients \
python3-pip \
xserver-xorg x11-xserver-utils openbox-lxde-session lightdm lightdm-autologin-greeter accountsservice \
chromium chromium-l10n
sudo apt install zabbix-agent2 zabbix-agent2-plugin-*
echo "done"