From 2e14bc441c2d0342a449398572463968025ed7ee Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Tue, 1 Aug 2023 09:24:57 +0200 Subject: [PATCH] RSE --- data/config/configuration.json | 1 + packages/control/general.py | 12 +++ packages/control/prepare.py | 1 + .../data_migration/data_migration.py | 98 ++++++++++++++++--- packages/helpermodules/home_configuration.py | 15 +++ packages/helpermodules/subdata.py | 4 +- .../internal_chargepoint_handler.py | 4 +- .../internal_chargepoint_handler/socket.py | 4 +- packages/modules/ripple_control_receiver.py | 9 +- runs/atreboot.sh | 5 + 10 files changed, 128 insertions(+), 25 deletions(-) create mode 100644 data/config/configuration.json create mode 100644 packages/helpermodules/home_configuration.py diff --git a/data/config/configuration.json b/data/config/configuration.json new file mode 100644 index 0000000000..0f627d29a2 --- /dev/null +++ b/data/config/configuration.json @@ -0,0 +1 @@ +{"openwb-version": 1, "ripple_control_receiver_configured": false, "max_c_socket": 16} \ No newline at end of file diff --git a/packages/control/general.py b/packages/control/general.py index 05b9564639..96606d7dfd 100644 --- a/packages/control/general.py +++ b/packages/control/general.py @@ -6,8 +6,10 @@ from typing import List, Optional from control import data +from helpermodules import home_configuration from helpermodules.pub import Pub from helpermodules import timecheck +from modules import ripple_control_receiver log = logging.getLogger(__name__) @@ -179,3 +181,13 @@ def grid_protection(self): "openWB/set/general/grid_protection_random_stop", 0) except Exception: log.exception("Fehler im General-Modul") + + def check_ripple_control_receiver(self): + configured = home_configuration.get_home_configuration_setting( + "ripple_control_receiver_configured") + if configured != self.data.ripple_control_receiver.configured: + self.data.ripple_control_receiver.configured = configured + Pub().pub("openWB/set/general/ripple_control_receiver/configured", configured) + if self.data.ripple_control_receiver.configured: + (self.data.ripple_control_receiver.r1_active, + self.data.ripple_control_receiver.r2_active) = ripple_control_receiver.read() diff --git a/packages/control/prepare.py b/packages/control/prepare.py index 2db06097a1..a5f02f185e 100644 --- a/packages/control/prepare.py +++ b/packages/control/prepare.py @@ -18,6 +18,7 @@ def setup_algorithm(self) -> None: """ bereitet die Daten für den Algorithmus vor und startet diesen. """ try: + data.data.general_data.check_ripple_control_receiver() for cp in data.data.cp_data.values(): cp.reset_values_at_start() data.data.bat_all_data.setup_bat() diff --git a/packages/helpermodules/data_migration/data_migration.py b/packages/helpermodules/data_migration/data_migration.py index ccbb59e68b..7af1656077 100644 --- a/packages/helpermodules/data_migration/data_migration.py +++ b/packages/helpermodules/data_migration/data_migration.py @@ -21,6 +21,7 @@ from control import data, ev from dataclass_utils import dataclass_from_dict from helpermodules.data_migration.id_mapping import MapId +from helpermodules.home_configuration import update_home_configuration from helpermodules.measurement_log import LegacySmartHomeLogData, get_names, get_totals, string_to_float, string_to_int from helpermodules.utils import thread_handler from helpermodules.pub import Pub @@ -65,19 +66,40 @@ def __len__(self): class MigrateData: + MAJOR_VERSION = 1 + MINOR_VERSION = 9 + PATCH_VERSION = 303 BACKUP_DATA_PATH = "./data/data_migration/var/www/html/openWB/web/logging/data" def __init__(self, id_map: Dict) -> None: self.id_map = dataclass_from_dict(MapId, id_map) def migrate(self): - self.extract_files("ladelog") - self.extract_files("daily") - self.extract_files("monthly") + self._extract() + self._check_version() thread_handler(self.convert_csv_to_json_chargelog(), None) thread_handler(self.convert_csv_to_json_measurement_log("daily"), None) thread_handler(self.convert_csv_to_json_measurement_log("monthly"), None) - self.move_serial_number_cloud_data() + self.move_serial_number() + self.move_cloud_data() + self.move_rse() + self.move_max_c_socket() + self.move_pddate() + self._remove_migration_data() + + def _check_version(self): + with open("./data/data_migration/var/www/html/openWB/web/version") as f: + version = f.read().replace("\n", "") + sub_version = version.split(".") + if not (int(sub_version[0]) == self.MAJOR_VERSION and + int(sub_version[1]) == self.MINOR_VERSION and + int(sub_version[2]) >= self.PATCH_VERSION): + self._remove_migration_data() + raise ValueError(f"Das Backup für die Datenübernahme muss mindestens mit Version {self.MAJOR_VERSION}." + f"{self.MINOR_VERSION}.{self.PATCH_VERSION} erstellt worden sein. " + f"Backup-Version ist {version}.") + + def _remove_migration_data(self): shutil.rmtree("./data/data_migration/var") os.remove("./data/data_migration/data_migration.tar.gz") @@ -89,11 +111,20 @@ def _file_to_extract_generator(self, members, log_folder_name: str): if tarinfo.name.startswith(f"var/www/html/openWB/web/logging/data/{log_folder_name}"): yield tarinfo - def extract_files(self, log_folder_name: str): + def _extract_files(self, log_folder_name: str): with tarfile.open('./data/data_migration/data_migration.tar.gz') as tar: tar.extractall(members=self._file_to_extract_generator( tar, log_folder_name), path="./data/data_migration") + def _extract(self): + self._extract_files("ladelog") + self._extract_files("daily") + self._extract_files("monthly") + with tarfile.open('./data/data_migration/data_migration.tar.gz') as tar: + tar.extract(member="var/www/html/openWB/openwb.conf", path="./data/data_migration") + with tarfile.open('./data/data_migration/data_migration.tar.gz') as tar: + tar.extract(member="var/www/html/openWB/web/version", path="./data/data_migration") + def convert_csv_to_json_chargelog(self) -> List[Thread]: """ konvertiert die alten Lade-Log-Dateien in das neue Format für 2.x. """ @@ -487,38 +518,77 @@ def _monthly_log_entry(self, file: str): log.exception(f"Fehler beim Konvertieren des Monats-Logs vom {file}, Reihe {row}") return entries - def move_serial_number_cloud_data(self) -> None: - def strip_openwb_conf_entry(entry: str, key: str) -> str: - value = entry.replace(f"{key}=", "") - return value.rstrip("\n") - with tarfile.open('./data/data_migration/data_migration.tar.gz') as tar: - tar.extract(member="var/www/html/openWB/openwb.conf", path="./data/data_migration") + def _strip_openwb_conf_entry(self, entry: str, key: str) -> str: + value = entry.replace(f"{key}=", "") + return value.rstrip("\n") + + def move_serial_number(self) -> None: with open("./data/data_migration/var/www/html/openWB/openwb.conf", "r") as file: serial_number = "" openwb_conf = file.readlines() for line in openwb_conf: if "snnumber" in line: - serial_number = strip_openwb_conf_entry(line, "snnumber") + serial_number = self._strip_openwb_conf_entry(line, "snnumber") break else: log.debug("Keine Seriennummer gefunden.") with open("/home/openwb/snnumber", "w") as file: file.write(f"snnumber={serial_number}") + def move_cloud_data(self) -> None: with open("./data/data_migration/var/www/html/openWB/openwb.conf", "r") as file: cloud_user = "" cloud_pw = "" openwb_conf = file.readlines() for line in openwb_conf: if "clouduser" in line: - cloud_user = strip_openwb_conf_entry(line, "clouduser") + cloud_user = self._strip_openwb_conf_entry(line, "clouduser") elif "cloudpw" in line: - cloud_pw = strip_openwb_conf_entry(line, "cloudpw") + cloud_pw = self._strip_openwb_conf_entry(line, "cloudpw") if cloud_user == "": log.debug("Keine Cloud-Zugangsdaten gefunden.") Pub().pub("openWB/set/command/data_migration/todo", {"command": "connectCloud", "data": {"username": cloud_user, "password": cloud_pw, "partner": 0}}) + def move_rse(self) -> None: + with open("./data/data_migration/var/www/html/openWB/openwb.conf", "r") as file: + rse = None + openwb_conf = file.readlines() + for line in openwb_conf: + if "rseenabled" in line: + rse = bool(self._strip_openwb_conf_entry(line, "rseenabled")) + break + else: + log.debug("Keine Rundsteuerempfänger-Konfiguration gefunden. Setze auf False.") + rse = False + update_home_configuration({"ripple_control_receiver_configured": rse}) + + def move_max_c_socket(self): + with open("./data/data_migration/var/www/html/openWB/openwb.conf", "r") as file: + max_c_socket = None + openwb_conf = file.readlines() + for line in openwb_conf: + if "ppbuchse" in line: + max_c_socket = int(self._strip_openwb_conf_entry(line, "ppbuchse")) + break + else: + log.debug("Keine max_c_socket-Konfiguration gefunden. Setze auf False.") + max_c_socket = 16 + update_home_configuration({"max_c_socket": max_c_socket}) + + def move_pddate(self) -> None: + with open("./data/data_migration/var/www/html/openWB/openwb.conf", "r") as file: + pddate = "" + openwb_conf = file.readlines() + for line in openwb_conf: + if "pddate" in line: + pddate = self._strip_openwb_conf_entry(line, "pddate") + break + else: + log.debug("Kein Produktionsdatum gefunden.") + with open("/home/openwb/pddate", "w") as file: + file.write(f"pddate={pddate}") + NOT_CONFIGURED = " wurde in openWB software2 nicht konfiguriert." def validate_ids(self) -> None: diff --git a/packages/helpermodules/home_configuration.py b/packages/helpermodules/home_configuration.py new file mode 100644 index 0000000000..263519a4a0 --- /dev/null +++ b/packages/helpermodules/home_configuration.py @@ -0,0 +1,15 @@ +import json +from typing import Dict + + +def update_home_configuration(new_setting: Dict) -> None: + with open("/home/openwb/configuration.json", "r") as f: + data = json.loads(f.read()) + with open("/home/openwb/configuration.json", "w") as f: + data.update(new_setting) + f.write(json.dumps(data)) + + +def get_home_configuration_setting(name: str): + with open("home/openwb/configuration.json", "r") as f: + return json.loads(f.read())[name] diff --git a/packages/helpermodules/subdata.py b/packages/helpermodules/subdata.py index dead6c91cb..910741da2a 100644 --- a/packages/helpermodules/subdata.py +++ b/packages/helpermodules/subdata.py @@ -541,7 +541,9 @@ def process_general_topic(self, var: general.General, msg: mqtt.MQTTMessage): """ try: if re.search("/general/", msg.topic) is not None: - if re.search("/general/ripple_control_receiver/", msg.topic) is not None: + if "openWB/general/ripple_control_receiver/configured" == msg.topic: + return + elif re.search("/general/ripple_control_receiver/", msg.topic) is not None: self.set_json_payload_class(var.data.ripple_control_receiver, msg) elif re.search("/general/chargemode_config/", msg.topic) is not None: if re.search("/general/chargemode_config/pv_charging/", msg.topic) is not None: diff --git a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py index cc1377350d..a2619c1758 100644 --- a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py +++ b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py @@ -26,8 +26,6 @@ except ImportError: log.info("failed to import RPi.GPIO! maybe we are not running on a pi") -SOCKET_MAX_CURRENT: int = 16 - class UpdateValues: def __init__(self, local_charge_point_num: int, parent_ip: str, parent_cp: str) -> None: @@ -198,7 +196,7 @@ def __init__(self, self.local_charge_point_num = local_charge_point_num if local_charge_point_num == 0: if mode == InternalChargepointMode.SOCKET.value: - self.module = Socket(SOCKET_MAX_CURRENT, local_charge_point_num, client_handler, global_data.parent_ip) + self.module = Socket(local_charge_point_num, client_handler, global_data.parent_ip) else: self.module = chargepoint_module.ChargepointModule( local_charge_point_num, client_handler, global_data.parent_ip) diff --git a/packages/modules/internal_chargepoint_handler/socket.py b/packages/modules/internal_chargepoint_handler/socket.py index d4c473c4b9..e8c6962ad3 100644 --- a/packages/modules/internal_chargepoint_handler/socket.py +++ b/packages/modules/internal_chargepoint_handler/socket.py @@ -3,6 +3,7 @@ import logging import time from typing import Callable, Tuple +from helpermodules.home_configuration import get_home_configuration_setting from modules.common.component_context import SingleComponentUpdateContext from modules.common.component_state import ChargepointState @@ -45,12 +46,11 @@ class ActorState(IntEnum): class Socket(ChargepointModule): def __init__(self, - socket_max_current: int, local_charge_point_num: int, client_handler: ClientHandler, parent_hostname: str) -> None: log.debug("Konfiguration als Buchse.") - self.socket_max_current = socket_max_current + self.socket_max_current = get_home_configuration_setting("max_c_socket") super().__init__(local_charge_point_num, client_handler, parent_hostname) def set_current(self, current: float) -> None: diff --git a/packages/modules/ripple_control_receiver.py b/packages/modules/ripple_control_receiver.py index 1e814cf8e9..ba79cb3f9f 100644 --- a/packages/modules/ripple_control_receiver.py +++ b/packages/modules/ripple_control_receiver.py @@ -1,6 +1,6 @@ import logging import time -from helpermodules.pub import Pub +from typing import Tuple log = logging.getLogger(__name__) has_gpio = True @@ -13,7 +13,7 @@ log.warning("RSE disabled!") -def read(): +def read() -> Tuple[bool, bool]: rse1: bool = False rse2: bool = False @@ -32,6 +32,5 @@ def read(): rse2 = not button2_state except Exception: GPIO.cleanup() - log.exception() - Pub().pub("openWB/set/general/ripple_control_receiver/r1_active", rse1) - Pub().pub("openWB/set/general/ripple_control_receiver/r2_active", rse2) + log.exception("Fehler beim Auslesen der Rundsteuer-Kontakte.") + return rse1, rse2 diff --git a/runs/atreboot.sh b/runs/atreboot.sh index 4040bea074..190133e2fb 100755 --- a/runs/atreboot.sh +++ b/runs/atreboot.sh @@ -290,6 +290,11 @@ chmod 666 "$LOGFILE" fi echo "mosquitto done" + # check for home configuration + if [[ ! -f "/home/openwb/configuration.json" ]]; then + sudo cp -a "${OPENWBBASEDIR}/data/config/configuration.json" "/home/openwb/configuration.json" + fi + # check for python dependencies echo "install required python packages with 'pip3'..." pip3 install -r "${OPENWBBASEDIR}/requirements.txt"