diff --git a/packages/control/algorithm/common.py b/packages/control/algorithm/common.py index 98756e76a4..1cb9c0f37b 100644 --- a/packages/control/algorithm/common.py +++ b/packages/control/algorithm/common.py @@ -60,7 +60,7 @@ def get_min_current(chargepoint: Chargepoint) -> Tuple[List[float], List[int]]: # tested -def set_current_counterdiff(diff_curent: float, +def set_current_counterdiff(diff_current: float, current: float, chargepoint: Chargepoint, surplus: bool = False) -> None: @@ -68,7 +68,7 @@ def set_current_counterdiff(diff_curent: float, considered_current = consider_less_charging_chargepoint_in_loadmanagement( chargepoint, current) # gar nicht ladende Autos? - diff = max(considered_current - diff_curent, 0) + diff = max(considered_current - diff_current, 0) diffs = [diff if required_currents[i] != 0 else 0 for i in range(3)] if max(diffs) > 0: counters = data.data.counter_all_data.get_counters_to_check(chargepoint.num) diff --git a/packages/control/algorithm/integration_test/instant_charging_test.py b/packages/control/algorithm/integration_test/instant_charging_test.py index c9ab77124f..0042910933 100644 --- a/packages/control/algorithm/integration_test/instant_charging_test.py +++ b/packages/control/algorithm/integration_test/instant_charging_test.py @@ -119,8 +119,8 @@ def test_instant_charging_limit(params: ParamsLimit, all_cp_instant_charging_1p, data.data.counter_data["counter0"].data.set.raw_power_left = params.raw_power_left data.data.counter_data["counter0"].data.set.raw_currents_left = params.raw_currents_left_counter0 data.data.counter_data["counter6"].data.set.raw_currents_left = params.raw_currents_left_counter6 - mockget_component_name_by_id = Mock(return_value="Garage") - monkeypatch.setattr(loadmanagement, "get_component_name_by_id", mockget_component_name_by_id) + mock_get_component_name_by_id = Mock(return_value="Garage") + monkeypatch.setattr(loadmanagement, "get_component_name_by_id", mock_get_component_name_by_id) # execution Algorithm().calc_current() @@ -196,8 +196,8 @@ def test_control_parameter_instant_charging(params: ParamsControlParameter, all_ data.data.counter_data["counter0"].data.set.raw_power_left = 22080 data.data.counter_data["counter0"].data.set.raw_currents_left = [32]*3 data.data.counter_data["counter6"].data.set.raw_currents_left = [16]*3 - mockget_component_name_by_id = Mock(return_value="Garage") - monkeypatch.setattr(loadmanagement, "get_component_name_by_id", mockget_component_name_by_id) + mock_get_component_name_by_id = Mock(return_value="Garage") + monkeypatch.setattr(loadmanagement, "get_component_name_by_id", mock_get_component_name_by_id) # execution Algorithm().calc_current() diff --git a/packages/control/algorithm/integration_test/pv_charging_test.py b/packages/control/algorithm/integration_test/pv_charging_test.py index d1241ec512..985dcd3c0f 100644 --- a/packages/control/algorithm/integration_test/pv_charging_test.py +++ b/packages/control/algorithm/integration_test/pv_charging_test.py @@ -221,8 +221,8 @@ def test_surplus(params: ParamsSurplus, all_cp_pv_charging_3p, all_cp_charging_3 data.data.counter_data["counter0"].data.set.raw_power_left = params.raw_power_left data.data.counter_data["counter0"].data.set.raw_currents_left = params.raw_currents_left_counter0 data.data.counter_data["counter6"].data.set.raw_currents_left = params.raw_currents_left_counter6 - mockget_component_name_by_id = Mock(return_value="Garage") - monkeypatch.setattr(loadmanagement, "get_component_name_by_id", mockget_component_name_by_id) + mock_get_component_name_by_id = Mock(return_value="Garage") + monkeypatch.setattr(loadmanagement, "get_component_name_by_id", mock_get_component_name_by_id) data.data.cp_data["cp3"].data.set.charge_template.data.chargemode.pv_charging.phases_to_use = 1 data.data.cp_data["cp4"].data.set.charge_template.data.chargemode.pv_charging.phases_to_use = 1 data.data.cp_data["cp5"].data.set.charge_template.data.chargemode.pv_charging.phases_to_use = 1 diff --git a/packages/control/algorithm/surplus_controlled.py b/packages/control/algorithm/surplus_controlled.py index ca649d23ab..ef95e8cf52 100644 --- a/packages/control/algorithm/surplus_controlled.py +++ b/packages/control/algorithm/surplus_controlled.py @@ -64,7 +64,7 @@ def _set(self, dif_to_old_current = available_for_cp + cp.data.set.target_current - cp.data.set.current_prev # Wenn die Differenz zwischen altem und neuem Soll-Strom größer als der Regelbereich ist, trotzdem # nachregeln, auch wenn der Regelbereich eingehalten wird. Sonst würde zB nicht berücksichtigt werden, - # wenn noch ein Fahrzeug dazu kommmt. + # wenn noch ein Fahrzeug dazu kommt. if ((pv_charging.control_range[1] - pv_charging.control_range[0]) / (sum(counter.data.get.voltages) / len(counter.data.get.voltages)) < abs(dif_to_old_current)): current = available_for_cp diff --git a/packages/control/auto_phase_switch_test.py b/packages/control/auto_phase_switch_test.py index 321c63b4f2..dd31a25895 100644 --- a/packages/control/auto_phase_switch_test.py +++ b/packages/control/auto_phase_switch_test.py @@ -1,5 +1,5 @@ -import threading import pytest +from threading import Event from typing import List, Optional from unittest.mock import Mock from control.chargepoint.control_parameter import ControlParameter @@ -23,7 +23,7 @@ def vehicle() -> Ev: @pytest.fixture(autouse=True) def data_module() -> None: - data.data_init(threading.Event()) + data.data_init(Event()) data.data.general_data = General() data.data.pv_all_data = PvAll() data.data.bat_all_data = BatAll() diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py index d4cc07ebf5..451507ca2d 100644 --- a/packages/control/chargepoint/chargepoint.py +++ b/packages/control/chargepoint/chargepoint.py @@ -18,7 +18,7 @@ from dataclasses import asdict import dataclasses import logging -import threading +from threading import Thread, Event import traceback from typing import Dict, Optional, Tuple @@ -70,7 +70,7 @@ class Chargepoint(ChargepointRfidMixin): """ MAX_FAILED_PHASE_SWITCHES = 2 - def __init__(self, index: int, event: Optional[threading.Event]): + def __init__(self, index: int, event: Optional[Event]): try: self.template: CpTemplate = None self.chargepoint_module: AbstractChargepoint = None @@ -321,7 +321,7 @@ def initiate_control_pilot_interruption(self): # Wird die Ladung gestartet? if self.data.set.current_prev == 0 and self.data.set.current != 0: # Die CP-Unterbrechung erfolgt in Threads, da diese länger als ein Zyklus dauert. - if thread_handler(threading.Thread( + if thread_handler(Thread( target=self.chargepoint_module.interrupt_cp, args=(charging_ev.ev_template.data.control_pilot_interruption_duration,), name=f"cp{self.chargepoint_module.config.id}")): diff --git a/packages/control/chargepoint/chargepoint_data.py b/packages/control/chargepoint/chargepoint_data.py index 44eda96904..fda7661c88 100644 --- a/packages/control/chargepoint/chargepoint_data.py +++ b/packages/control/chargepoint/chargepoint_data.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, field -import threading +from threading import Event from typing import Dict, List, Optional, Protocol from control.chargepoint.chargepoint_template import CpTemplate @@ -174,7 +174,7 @@ class Config: ocpp_chargebox_id: Optional[str] = None def __post_init__(self): - self.event_update_state: threading.Event + self.event_update_state: Event @property def ev(self) -> int: @@ -217,7 +217,7 @@ class ChargepointData: set: Set = field(default_factory=set_factory) config: Config = field(default_factory=config_factory) - def set_event(self, event: Optional[threading.Event] = None) -> None: + def set_event(self, event: Optional[Event] = None) -> None: self.event_update_state = event if event: self.config.event_update_state = event diff --git a/packages/control/chargepoint/chargepoint_state_update.py b/packages/control/chargepoint/chargepoint_state_update.py index 0f6c608189..2cdc4e2e48 100644 --- a/packages/control/chargepoint/chargepoint_state_update.py +++ b/packages/control/chargepoint/chargepoint_state_update.py @@ -1,7 +1,6 @@ import copy import logging -from threading import Thread -import threading +from threading import Thread, Event from typing import Dict from control.chargepoint.chargepoint import Chargepoint @@ -14,13 +13,13 @@ class ChargepointStateUpdate: def __init__(self, index: int, - event_copy_data: threading.Event, - event_global_data_initialized: threading.Event, + event_copy_data: Event, + event_global_data_initialized: Event, cp_template_data: Dict, ev_data: Dict, ev_charge_template_data: Dict, ev_template_data: Dict) -> None: - self.event_update_state = threading.Event() + self.event_update_state = Event() self.event_copy_data = event_copy_data self.event_global_data_initialized = event_global_data_initialized self.chargepoint: Chargepoint = Chargepoint(index, self.event_update_state) diff --git a/packages/control/chargepoint/get_phases_test.py b/packages/control/chargepoint/get_phases_test.py index 9c5a981a5d..555a0529bd 100644 --- a/packages/control/chargepoint/get_phases_test.py +++ b/packages/control/chargepoint/get_phases_test.py @@ -1,4 +1,4 @@ -import threading +from threading import Event from unittest.mock import Mock from typing import Optional import pytest @@ -21,7 +21,7 @@ def cp() -> Chargepoint: @pytest.fixture(autouse=True) def general() -> None: - data.data_init(threading.Event()) + data.data_init(Event()) data.data.general_data = General() @@ -131,36 +131,36 @@ def __init__(self, prevent_phase_switch: bool, phases_in_use: int, imported_since_plugged: float, - phase_switch_suppported: bool, + phase_switch_supported: bool, expected_phases: int) -> None: self.name = name self.phases = phases self.prevent_phase_switch = prevent_phase_switch self.phases_in_use = phases_in_use self.imported_since_plugged = imported_since_plugged - self.phase_switch_suppported = phase_switch_suppported + self.phase_switch_supported = phase_switch_supported self.expected_phases = expected_phases cases_set_phases = [ SetPhasesParams(name="Phases don't change", phases=1, phases_in_use=1, prevent_phase_switch=True, - imported_since_plugged=0, phase_switch_suppported=True, expected_phases=1), + imported_since_plugged=0, phase_switch_supported=True, expected_phases=1), SetPhasesParams(name="Charging didn't started yet", phases=1, phases_in_use=3, prevent_phase_switch=True, - imported_since_plugged=0, phase_switch_suppported=True, expected_phases=1), + imported_since_plugged=0, phase_switch_supported=True, expected_phases=1), SetPhasesParams(name="EV doesn't support phase wich", phases=1, phases_in_use=3, prevent_phase_switch=True, - imported_since_plugged=1, phase_switch_suppported=True, expected_phases=3), + imported_since_plugged=1, phase_switch_supported=True, expected_phases=3), SetPhasesParams(name="Switch phases", phases=1, phases_in_use=3, prevent_phase_switch=False, - imported_since_plugged=1, phase_switch_suppported=True, expected_phases=1), + imported_since_plugged=1, phase_switch_supported=True, expected_phases=1), SetPhasesParams(name="Phase switch not supported by cp", phases=1, phases_in_use=3, prevent_phase_switch=False, - imported_since_plugged=1, phase_switch_suppported=False, expected_phases=1) + imported_since_plugged=1, phase_switch_supported=False, expected_phases=1) ] @pytest.mark.parametrize("params", cases_set_phases, ids=[c.name for c in cases_set_phases]) def test_set_phases(monkeypatch, cp: Chargepoint, params: SetPhasesParams): # setup - mock_phase_switch_suppported = Mock(name="phase_switch_suppported", return_value=params.phase_switch_suppported) - monkeypatch.setattr(Chargepoint, "cp_ev_support_phase_switch", mock_phase_switch_suppported) + mock_phase_switch_supported = Mock(name="phase_switch_supported", return_value=params.phase_switch_supported) + monkeypatch.setattr(Chargepoint, "cp_ev_support_phase_switch", mock_phase_switch_supported) cp.data.get.phases_in_use = params.phases_in_use cp.data.set.log.imported_since_plugged = params.imported_since_plugged charging_ev_data = cp.data.set.charging_ev_data diff --git a/packages/control/data.py b/packages/control/data.py index 5ba618dce2..1d7c779d01 100644 --- a/packages/control/data.py +++ b/packages/control/data.py @@ -4,7 +4,7 @@ """ import copy import logging -import threading +from threading import Event, Lock from functools import wraps from typing import Dict from control.bat import Bat @@ -30,27 +30,27 @@ from modules.common.abstract_io import AbstractIoDevice log = logging.getLogger(__name__) -bat_data_lock = threading.Lock() -bat_all_data_lock = threading.Lock() -graph_data_lock = threading.Lock() -counter_data_lock = threading.Lock() -counter_all_data_lock = threading.Lock() -cp_data_lock = threading.Lock() -cp_all_data_lock = threading.Lock() -cp_template_data_lock = threading.Lock() -ev_charge_template_data_lock = threading.Lock() -ev_data_lock = threading.Lock() -ev_template_data_lock = threading.Lock() -general_data_lock = threading.Lock() -io_actions_lock = threading.Lock() -io_states_lock = threading.Lock() -optional_data_lock = threading.Lock() -pv_data_lock = threading.Lock() -pv_all_data_lock = threading.Lock() -system_data_lock = threading.Lock() - - -def locked(lock: threading.Lock): +bat_data_lock = Lock() +bat_all_data_lock = Lock() +graph_data_lock = Lock() +counter_data_lock = Lock() +counter_all_data_lock = Lock() +cp_data_lock = Lock() +cp_all_data_lock = Lock() +cp_template_data_lock = Lock() +ev_charge_template_data_lock = Lock() +ev_data_lock = Lock() +ev_template_data_lock = Lock() +general_data_lock = Lock() +io_actions_lock = Lock() +io_states_lock = Lock() +optional_data_lock = Lock() +pv_data_lock = Lock() +pv_all_data_lock = Lock() +system_data_lock = Lock() + + +def locked(lock: Lock): def decorate(method): @wraps(method) def inner(*args, **kwargs): @@ -65,7 +65,7 @@ def inner(*args, **kwargs): class Data: - def __init__(self, event_module_update_completed: threading.Event): + def __init__(self, event_module_update_completed: Event): self.event_module_update_completed = event_module_update_completed self._bat_data: Dict[str, Bat] = {} self._bat_all_data = BatAll() @@ -489,7 +489,7 @@ def __exit__(self, exception_type, exception, exception_traceback) -> bool: data: Data -def data_init(event_module_update_completed: threading.Event): +def data_init(event_module_update_completed: Event): """instanziiert die Data-Klasse. """ global data diff --git a/packages/control/ev/ev.py b/packages/control/ev/ev.py index 02ae09396b..523f47ce4d 100644 --- a/packages/control/ev/ev.py +++ b/packages/control/ev/ev.py @@ -288,9 +288,9 @@ def _check_phase_switch_conditions(self, feed_in_yield = 0 all_surplus = data.data.counter_all_data.get_evu_counter().get_usable_surplus(feed_in_yield) required_surplus = control_parameter.min_current * max_phases_ev * 230 - get_power - unblanced_load_limit_reached = limit.limiting_value == LimitingValue.UNBALANCED_LOAD + unbalanced_load_limit_reached = limit.limiting_value == LimitingValue.UNBALANCED_LOAD condition_1_to_3 = (((get_medium_charging_current(get_currents) > max_current and - all_surplus > required_surplus) or unblanced_load_limit_reached) and + all_surplus > required_surplus) or unbalanced_load_limit_reached) and phases_in_use == 1) condition_3_to_1 = get_medium_charging_current( get_currents) < min_current and all_surplus <= 0 and phases_in_use > 1 diff --git a/packages/control/limiting_value.py b/packages/control/limiting_value.py index 7f83e0b3ec..8c19b321d3 100644 --- a/packages/control/limiting_value.py +++ b/packages/control/limiting_value.py @@ -7,7 +7,7 @@ class LimitingValue(Enum): CURRENT = ", da der Maximal-Strom an Zähler {} erreicht ist." POWER = ", da die maximale Leistung an Zähler {} erreicht ist." UNBALANCED_LOAD = ", da die maximale Schieflast an Zähler {} erreicht ist." - DIMMING = ", da die Dimmung die Ladeleistung bgrenzt." + DIMMING = ", da die Dimmung die Ladeleistung begrenzt." DIMMING_VIA_DIRECT_CONTROL = ", da die Dimmung per Direkt-Steuerung die Ladeleistung auf 4,2 kW begrenzt." RIPPLE_CONTROL_RECEIVER = (", da der Ladepunkt durch den RSE-Kontakt auf {}% der konfigurierten Anschlussleistung " "reduziert wird.") diff --git a/packages/control/ocpp.py b/packages/control/ocpp.py index 593c6c0427..104d1c2dde 100644 --- a/packages/control/ocpp.py +++ b/packages/control/ocpp.py @@ -74,10 +74,10 @@ def start_transaction(self: OptionalProtocol, timestamp=self._get_formatted_time() )) if ws: - tansaction_id = json.loads(ws.messages[0])[2]["transactionId"] - log.debug(f"Transaction ID: {tansaction_id} für Chargebox ID: {chargebox_id} mit Tag: {id_tag} und " - f"Zählerstand: {imported} erhalten.") - return tansaction_id + transaction_id = json.loads(ws.messages[0])[2]["transactionId"] + log.debug(f"Transaction ID: {transaction_id} für Chargebox ID: {chargebox_id} mit Tag: {id_tag} " + f"und Zählerstand: {imported} erhalten.") + return transaction_id except Exception as e: fault_state.from_exception(e) return None diff --git a/packages/control/optional.py b/packages/control/optional.py index 0b87d1fe38..96c1e66c57 100644 --- a/packages/control/optional.py +++ b/packages/control/optional.py @@ -1,8 +1,8 @@ """Optionale Module """ import logging -from math import ceil # Aufrunden -import threading +from math import ceil +from threading import Thread from typing import List from control import data @@ -102,7 +102,7 @@ def et_get_loading_hours(self, duration: float, remaining_time: float) -> List[i def et_get_prices(self): try: if self.et_module: - thread_handler(threading.Thread(target=self.et_module.update, args=(), name="electricity tariff")) + thread_handler(Thread(target=self.et_module.update, args=(), name="electricity tariff")) else: # Wenn kein Modul konfiguriert ist, Fehlerstatus zurücksetzen. if self.data.et.get.fault_state != 0 or self.data.et.get.fault_str != NO_ERROR: @@ -114,7 +114,7 @@ def et_get_prices(self): def ocpp_transfer_meter_values(self): try: if self.data.ocpp.active: - thread_handler(threading.Thread(target=self._transfer_meter_values, args=(), name="OCPP Client")) + thread_handler(Thread(target=self._transfer_meter_values, args=(), name="OCPP Client")) except Exception: log.exception("Fehler im OCPP-Optional-Modul") @@ -122,7 +122,7 @@ def _transfer_meter_values(self): for cp in data.data.cp_data.values(): try: if self.data.ocpp.boot_notification_sent is False: - # Boot-Notfification nicht in der init-Funktion aufrufen, da noch nicht alles initialisiert ist + # Boot-Notification nicht in der init-Funktion aufrufen, da noch nicht alles initialisiert ist self.boot_notification(cp.data.config.ocpp_chargebox_id, cp.chargepoint_module.fault_state, cp.chargepoint_module.config.type, diff --git a/packages/control/phase_switch.py b/packages/control/phase_switch.py index b83fdaa300..89d0edd407 100644 --- a/packages/control/phase_switch.py +++ b/packages/control/phase_switch.py @@ -1,7 +1,7 @@ """ Modul, das die Phasenumschaltung durchführt. """ import logging -import threading +from threading import Thread import time from control.ev.ev import Ev @@ -17,7 +17,7 @@ def thread_phase_switch(cp) -> None: """ try: log.debug("Starte Thread zur Phasenumschaltung an LP"+str(cp.num)) - return thread_handler(threading.Thread( + return thread_handler(Thread( target=_perform_phase_switch, args=(cp.chargepoint_module, cp.data.control_parameter.phases, diff --git a/packages/control/process.py b/packages/control/process.py index 622b2fd6b3..abf9090ec8 100644 --- a/packages/control/process.py +++ b/packages/control/process.py @@ -1,7 +1,7 @@ """ Starten des Lade-Vorgangs """ import logging -import threading +from threading import Thread from typing import List from control.bat_all import get_controllable_bat_components @@ -25,7 +25,7 @@ def __init__(self) -> None: def process_algorithm_results(self) -> None: try: - modules_threads: List[threading.Thread] = [] + modules_threads: List[Thread] = [] log.info("# Ladung starten.") for cp in data.data.cp_data.values(): try: @@ -68,7 +68,7 @@ def process_algorithm_results(self) -> None: log.exception("Fehler im Process-Modul für Ladepunkt "+str(cp)) for bat_component in get_controllable_bat_components(): modules_threads.append( - threading.Thread( + Thread( target=bat_component.set_power_limit, args=(data.data.bat_data[f"bat{bat_component.component_config.id}"].data.set.power_limit,), name=f"set power limit {bat_component.component_config.id}")) @@ -88,7 +88,7 @@ def process_algorithm_results(self) -> None: for io in data.data.system_data.values(): if isinstance(io, AbstractIoDevice): modules_threads.append( - threading.Thread( + Thread( target=io.write, args=(None, data.data.io_states[f"io_states{io.config.id}"].data.set.digital_output,), name=f"set output io{io.config.id}")) @@ -133,7 +133,7 @@ def _update_state(self, chargepoint: chargepoint.Chargepoint) -> None: log.info(f"LP{chargepoint.num}: set current {current} A, " f"state {ChargepointState(chargepoint.data.control_parameter.state).name}") - def _start_charging(self, chargepoint: chargepoint.Chargepoint) -> threading.Thread: - return threading.Thread(target=chargepoint.chargepoint_module.set_current, - args=(chargepoint.data.set.current,), - name=f"set current cp{chargepoint.chargepoint_module.config.id}") + def _start_charging(self, chargepoint: chargepoint.Chargepoint) -> Thread: + return Thread(target=chargepoint.chargepoint_module.set_current, + args=(chargepoint.data.set.current,), + name=f"set current cp{chargepoint.chargepoint_module.config.id}") diff --git a/packages/dataclass_utils/_dataclass_from_dict_test.py b/packages/dataclass_utils/_dataclass_from_dict_test.py index 21eb10eb2c..012b76f8ff 100644 --- a/packages/dataclass_utils/_dataclass_from_dict_test.py +++ b/packages/dataclass_utils/_dataclass_from_dict_test.py @@ -35,7 +35,7 @@ def __init__(self, a: str, o: Optional[dict] = None): self.o = o -class GnericDict: +class GenericDict: def __init__(self, a: str, o: Dict[int, float] = None): self.a = a self.o = o @@ -90,7 +90,7 @@ def test_from_dict_extends_generic(): def test_generic_dict(): # execution - actual = dataclass_from_dict(GnericDict, {"a": "aValue", "o": {1: 1.0}}) + actual = dataclass_from_dict(GenericDict, {"a": "aValue", "o": {1: 1.0}}) # evaluation assert actual.a == "aValue" diff --git a/packages/helpermodules/broker.py b/packages/helpermodules/broker.py index ef1bf9fc59..c9b6940c6f 100644 --- a/packages/helpermodules/broker.py +++ b/packages/helpermodules/broker.py @@ -48,10 +48,10 @@ def disconnect(self) -> None: class InternalBrokerPublisher: def __init__(self) -> None: try: - self.client = mqtt.Client(f"openWB-python-bulkpublisher-{get_name_suffix()}") + self.client = mqtt.Client(f"openWB-python-bulk-publisher-{get_name_suffix()}") self.client.connect("localhost", 1886) except Exception: - log.exception("Fehler beim Verbindungsaufbau zum Bulkpublisher") + log.exception("Fehler beim Verbindungsaufbau zum Bulk-Publisher") def start_loop(self) -> None: self.client.loop_start() diff --git a/packages/helpermodules/changed_values_handler.py b/packages/helpermodules/changed_values_handler.py index de14759ea0..3239bc520c 100644 --- a/packages/helpermodules/changed_values_handler.py +++ b/packages/helpermodules/changed_values_handler.py @@ -1,7 +1,7 @@ from dataclasses import fields, is_dataclass from enum import Enum import logging -import threading +from threading import Event from typing import Dict, List, Tuple from control import data @@ -15,12 +15,12 @@ # In den Metadaten wird unter dem Key der Topic-Suffix ab "openWB/ev/2/" angegeben. Der Topic-Prefix ("openWB/ev/2/") # wird automatisch ermittelt. -# Der Kontextmanager muss immer verwendet werden, wenn in den Funktionen Werte geändert werden, die nicht gepublished +# Der Kontextmanager muss immer verwendet werden, wenn in den Funktionen Werte geändert werden, die nicht veröffentlicht # werden. -# Metadaten werden nur für Felder erzeugt, die gepublished werden sollen, dh bei ganzen Klassen für das Feld der -# jeweiligen Klasse. Wenn Werte aus einer instanziierten Klasse gepublished werden sollen, erhält die übergeordnete +# Metadaten werden nur für Felder erzeugt, die veröffentlicht werden sollen, dh bei ganzen Klassen für das Feld der +# jeweiligen Klasse. Wenn Werte aus einer instanziierten Klasse veröffentlicht werden sollen, erhält die übergeordnete # Klasse keine Metadaten (siehe Beispiel unten). -# Damit die geänderten Werte automatisiert gepublished werden können, muss jede Klasse eine bestimmte Form haben: +# Damit die geänderten Werte automatisiert veröffentlicht werden können, muss jede Klasse eine bestimmte Form haben: # # @dataclass # class SampleClass: @@ -44,9 +44,9 @@ # @dataclass # class SampleData: -# # Wenn eine ganze Klasse als Dictionary gepublished werden soll, wie zB bei Konfigurationen, werden Metadaten für -# diese Klasse eingetragen. Die Felder der Konfigurationsklasse bekommen keine Metadaten, da diese nicht einzeln -# gepublished werden. +# # Wenn eine ganze Klasse als Dictionary veröffentlicht werden soll, wie zB bei Konfigurationen, werden Metadaten +# für diese Klasse eingetragen. Die Felder der Konfigurationsklasse bekommen keine Metadaten, da diese nicht einzeln +# veröffentlicht werden. # sample_field_class: SampleClass = field( # default_factory=sample_class, metadata={"topic": "get/field_class"}) # sample_field_int: int = field(default=0, metadata={"topic": "get/field_int"}) @@ -54,8 +54,8 @@ # default=0, metadata={"topic": "get/field_immutable"}) # sample_field_list: List = field(default_factory=currents_list_factory, metadata={ # "topic": "get/field_list"}) -# # Bei verschachtelten Klassen, wo der zu publishende Wert auf einer tieferen Ebene liegt, werden nur für den zu -# publishenden Wert Metadaten erzeugt. +# # Bei verschachtelten Klassen, wo der zu veröffentlichende Wert auf einer tieferen Ebene liegt, werden nur für +# den zu veröffentlichenden Wert Metadaten erzeugt. # sample_field_nested: SampleNested = field(default_factory=sample_nested) @@ -65,7 +65,7 @@ class ChangedValuesHandler: - def __init__(self, event_module_update_completed: threading.Event) -> None: + def __init__(self, event_module_update_completed: Event) -> None: self.prev_data: Data = Data(event_module_update_completed) def store_initial_values(self): @@ -77,7 +77,7 @@ def store_initial_values(self): def pub_changed_values(self): try: - # publishen der geänderten Werte + # veröffentlichen der geänderten Werte self._update_value("openWB/set/bat/", self.prev_data.bat_all_data.data, data.data.bat_all_data.data) self._update_value("openWB/set/chargepoint/", self.prev_data.cp_all_data.data.get, data.data.cp_all_data.data.get) @@ -135,7 +135,7 @@ def _update_value(self, topic_prefix, data_inst_previous, data_inst): class ChangedValuesContext: - def __init__(self, event_module_update_completed: threading.Event): + def __init__(self, event_module_update_completed: Event): self.changed_values_handler = ChangedValuesHandler(event_module_update_completed) def __enter__(self): diff --git a/packages/helpermodules/command.py b/packages/helpermodules/command.py index 8d4cc3eb8d..45609d3c35 100644 --- a/packages/helpermodules/command.py +++ b/packages/helpermodules/command.py @@ -3,7 +3,7 @@ import json import logging import subprocess -import threading +from threading import Event import time from typing import Dict, List, Optional import re @@ -62,7 +62,7 @@ class Command: ("io_device", "system/io", -1), ] - def __init__(self, event_command_completed: threading.Event): + def __init__(self, event_command_completed: Event): try: self.event_command_completed = event_command_completed self._get_max_ids() @@ -937,7 +937,7 @@ def __exit__(self, exception_type, exception, exception_traceback) -> bool: class CompleteCommandContext: - def __init__(self, event_command_completed: threading.Event): + def __init__(self, event_command_completed: Event): self.event_command_completed = event_command_completed def __enter__(self): diff --git a/packages/helpermodules/data_migration/data_migration.py b/packages/helpermodules/data_migration/data_migration.py index 18bffce836..cca56b8285 100644 --- a/packages/helpermodules/data_migration/data_migration.py +++ b/packages/helpermodules/data_migration/data_migration.py @@ -444,7 +444,7 @@ def _monthly_log_entry(self, file: str): alte Spaltenbelegung: 12, 19 oder 29 Felder! Wurde in 1.9 nicht vereinheitlicht! Allgemein: - 0: Datum "YYYMMDD" + 0: Datum "YYYYMMDD" EVU: 1-2: Bezug, Einspeisung PV: diff --git a/packages/helpermodules/exceptions/registry.py b/packages/helpermodules/exceptions/registry.py index ee3cc36d1e..6d892a48a0 100644 --- a/packages/helpermodules/exceptions/registry.py +++ b/packages/helpermodules/exceptions/registry.py @@ -1,5 +1,5 @@ import sys -from typing import Type, Optional, Callable, TypeVar, Generic, List, Union, Any +from typing import List, Type, Optional, Callable, TypeVar, Generic, Union, Any, Tuple from modules.common.fault_state_level import FaultStateLevel @@ -20,9 +20,9 @@ def __init__(self, type: Type[T], handler: Callable[[T], Any]): class ExceptionRegistry: - registry = [] # type: List[RegistryEntry] + registry: List[RegistryEntry] = [] - def translate_exception(self, exception: Exception) -> [str, FaultStateLevel]: + def translate_exception(self, exception: Exception) -> Tuple[str, FaultStateLevel]: entry = self.find_registry_entry(exception) if entry is None: return "{} {}".format(type(exception), exception.args), FaultStateLevel.ERROR diff --git a/packages/helpermodules/exceptions/requests.py b/packages/helpermodules/exceptions/requests.py index dd6ec0967a..684053f3ca 100644 --- a/packages/helpermodules/exceptions/requests.py +++ b/packages/helpermodules/exceptions/requests.py @@ -9,7 +9,7 @@ def handle_connection_error(e: ConnectionError): def handle_read_timeout(e: ReadTimeout): - return "Innerhalb des Timeouts wurde keine Anwort erhalten. Überprüfe Adresse und Netzwerk." + return "Innerhalb des Timeouts wurde keine Antwort erhalten. Überprüfe Adresse und Netzwerk." def handle_http_error(e: HTTPError): diff --git a/packages/helpermodules/measurement_logging/conftest.py b/packages/helpermodules/measurement_logging/conftest.py index 1a87dd9614..5e1059a91a 100644 --- a/packages/helpermodules/measurement_logging/conftest.py +++ b/packages/helpermodules/measurement_logging/conftest.py @@ -1,7 +1,7 @@ -import threading +from threading import Event import pytest -from control.chargepoint import chargepoint +from control.chargepoint import chargepoint from control.chargepoint.chargepoint_all import AllChargepoints from control import bat_all, counter, pv_all, pv from control import data @@ -9,7 +9,7 @@ @pytest.fixture(autouse=True) def data_module() -> None: - data.data_init(threading.Event()) + data.data_init(Event()) data.data.bat_data.update({"all": bat_all.BatAll(), "bat2": bat_all.Bat(2)}) data.data.counter_data.update({"counter0": counter.Counter(0)}) data.data.cp_all_data = AllChargepoints() diff --git a/packages/helpermodules/modbusserver.py b/packages/helpermodules/modbusserver.py index 73ac838c03..35a7dcb639 100644 --- a/packages/helpermodules/modbusserver.py +++ b/packages/helpermodules/modbusserver.py @@ -3,7 +3,7 @@ from socketserver import TCPServer from collections import defaultdict import struct -from typing import Optional +from typing import Optional, Union from helpermodules.utils.error_handling import ImportErrorContext with ImportErrorContext(): @@ -31,33 +31,32 @@ log.exception("Fehler im Modbus-Server") -def _form_int32(value, startreg): - secondreg = startreg + 1 +def _form_int32(value: Union[int, float], register: int): try: binary32 = struct.pack('>l', int(value)) high_byte, low_byte = struct.unpack('>hh', binary32) - data_store[startreg] = high_byte - data_store[secondreg] = low_byte + data_store[register] = high_byte + data_store[register + 1] = low_byte except Exception: log.exception("Fehler beim Füllen der Register") - data_store[startreg] = -1 - data_store[secondreg] = -1 + data_store[register] = -1 + data_store[register + 1] = -1 -def _form_int16(value, startreg): +def _form_int16(value: Union[int, float, bool], register: int): try: value = int(value) if (value > 32767 or value < -32768): raise Exception("Number to big") - data_store[startreg] = value + data_store[register] = value except Exception: log.exception("Fehler beim Füllen der Register") - data_store[startreg] = -1 + data_store[register] = -1 -def _form_str(value: Optional[str], startreg): +def _form_str(value: Optional[str], register: int): if value is None or len(value) == 0: - data_store[startreg] = 0 + data_store[register] = 0 else: bytes = value.encode("utf-8") length = len(bytes) @@ -72,50 +71,65 @@ def _form_str(value: Optional[str], startreg): else: stream_two_bytes = struct.pack(">bb", bytes[i], 0) stream_one_word = struct.unpack(">h", stream_two_bytes)[0] - data_store[startreg+register_offset] = stream_one_word + data_store[register + register_offset] = stream_one_word except Exception: - data_store[startreg+register_offset] = -1 + data_store[register + register_offset] = -1 finally: register_offset += 1 -def _get_pos(number, n): - return number // 10**n % 10 - 1 +def _charge_point_index(address: int): + return int(str(address)[-3]) - 1 + + +def _value_index(address: int): + return int(str(address)[-2:]) try: @app.route(slave_ids=[1], function_codes=[3, 4], addresses=list(range(0, 32000))) - def read_data_store(slave_id, function_code, address): + def read_data_store(slave_id: int, function_code: int, address: int): """" Return value of address. """ + # Mapping für einfache Zuordnung + int32_map = { + 0: lambda cp: cp.get.power, + 2: lambda cp: cp.get.imported, + 41: lambda cp: cp.get.exported, + } + int16_map = { + 4: lambda cp: cp.get.voltages[0] * 100, + 5: lambda cp: cp.get.voltages[1] * 100, + 6: lambda cp: cp.get.voltages[2] * 100, + 7: lambda cp: cp.get.currents[0] * 100, + 8: lambda cp: cp.get.currents[1] * 100, + 9: lambda cp: cp.get.currents[2] * 100, + 14: lambda cp: cp.get.plug_state, + 15: lambda cp: cp.get.charge_state, + 16: lambda cp: cp.get.evse_current, + 30: lambda cp: cp.get.powers[0], + 31: lambda cp: cp.get.powers[1], + 32: lambda cp: cp.get.powers[2], + 43: lambda _: 1, + } + str_map = { + 50: lambda _: serial_number, + 60: lambda cp: cp.get.rfid, + } + if address > 10099: Pub().pub("openWB/set/internal_chargepoint/global_data", {"heartbeat": timecheck.create_timestamp(), "parent_ip": None}) - chargepoint = SubData.internal_chargepoint_data[f"cp{_get_pos(address, 2)}"] - askedvalue = int(str(address)[-2:]) - if askedvalue == 00: - _form_int32(chargepoint.get.power, address) - elif askedvalue == 2: - _form_int32(chargepoint.get.imported, address) - elif 4 <= askedvalue <= 6: - _form_int16(chargepoint.get.voltages[askedvalue-4]*100, address) - elif 7 <= askedvalue <= 9: - _form_int16(chargepoint.get.currents[askedvalue-7]*100, address) - elif askedvalue == 14: - _form_int16(chargepoint.get.plug_state, address) - elif askedvalue == 15: - _form_int16(chargepoint.get.charge_state, address) - elif askedvalue == 16: - _form_int16(chargepoint.get.evse_current, address) - elif 30 <= askedvalue <= 32: - _form_int16(chargepoint.get.powers[askedvalue-30], address) - elif askedvalue == 41: - _form_int32(chargepoint.get.exported, address) - elif askedvalue == 43: - _form_int16(1, address) - elif askedvalue == 50: - _form_str(serial_number, address) - elif askedvalue == 60: - _form_str(chargepoint.get.rfid, address) + charge_point = SubData.internal_chargepoint_data[f"cp{_charge_point_index(address)}"] + requested_value = _value_index(address) + + if requested_value in int32_map: + _form_int32(int32_map[requested_value](charge_point), address) + elif requested_value in int16_map: + _form_int16(int16_map[requested_value](charge_point), address) + elif requested_value in str_map: + _form_str(str_map[requested_value](charge_point), address) + else: + log.warning(f"Unbekannte Adresse: {address}") return data_store[address] except Exception: @@ -123,28 +137,31 @@ def read_data_store(slave_id, function_code, address): try: @app.route(slave_ids=[1], function_codes=[6, 16], addresses=list(range(0, 32000))) - def write_data_store(slave_id, function_code, address, value): + def write_data_store(slave_id: int, function_code: int, address: int, value): """" Set value for address. """ if 10170 < address: - cp_topic = f"openWB/set/internal_chargepoint/{_get_pos(address, 2)}/data/" - askedvalue = int(str(address)[-2:]) - if askedvalue == 71: - Pub().pub(f"{cp_topic}set_current", value/100) - elif askedvalue == 80: - Pub().pub(f"{cp_topic}phases_to_use", value) - elif askedvalue == 81: - Pub().pub(f"{cp_topic}trigger_phase_switch", value) - elif askedvalue == 98: - Pub().pub(f"{cp_topic}cp_interruption_duration", value) - elif askedvalue == 99: - Pub().pub("openWB/set/command/modbus_server/todo", {"command": "systemUpdate", "data": {}}) + cp_topic = f"openWB/set/internal_chargepoint/{_charge_point_index(address)}/data/" + requested_value = _value_index(address) + + write_map = { + 71: lambda value: Pub().pub(f"{cp_topic}set_current", value / 100), + 80: lambda value: Pub().pub(f"{cp_topic}phases_to_use", value), + 81: lambda value: Pub().pub(f"{cp_topic}trigger_phase_switch", value), + 98: lambda value: Pub().pub(f"{cp_topic}cp_interruption_duration", value), + 99: lambda _: Pub().pub("openWB/set/command/modbus_server/todo", + {"command": "systemUpdate", "data": {}}) + } + if requested_value in write_map: + write_map[requested_value](value) + else: + log.warning(f"Unbekannte Adresse beim Schreiben: {address}") except Exception: log.exception("Fehler im Modbus-Server") def start_modbus_server(event_modbus_server): try: - # Wenn start_modbus_server aus SubData aufegrufen wird, wenn das Topic gesetzt wird, führt das zu einem + # Wenn start_modbus_server aus SubData aufgerufen wird, wenn das Topic gesetzt wird, führt das zu einem # circular Import. event_modbus_server.wait() event_modbus_server.clear() diff --git a/packages/helpermodules/setdata.py b/packages/helpermodules/setdata.py index eb8809c844..0b0e31d959 100644 --- a/packages/helpermodules/setdata.py +++ b/packages/helpermodules/setdata.py @@ -4,7 +4,7 @@ import copy import dataclasses from pathlib import Path -import threading +from threading import Event from typing import List, Optional, Tuple import re import paho.mqtt.client as mqtt @@ -23,10 +23,10 @@ class SetData: def __init__(self, - event_ev_template: threading.Event, - event_cp_config: threading.Event, - event_soc: threading.Event, - event_subdata_initialized: threading.Event): + event_ev_template: Event, + event_cp_config: Event, + event_soc: Event, + event_subdata_initialized: Event): self.event_ev_template = event_ev_template self.event_cp_config = event_cp_config self.event_soc = event_soc diff --git a/packages/helpermodules/skip_while_unchanged.py b/packages/helpermodules/skip_while_unchanged.py index 08cfad851c..54eec3b52b 100644 --- a/packages/helpermodules/skip_while_unchanged.py +++ b/packages/helpermodules/skip_while_unchanged.py @@ -1,4 +1,4 @@ -import threading +from threading import Lock from typing import Callable, TypeVar T = TypeVar("T") @@ -8,7 +8,7 @@ def skip_while_unchanged(source: Callable, initial=None): """Before each call check if value given by `source` has changed. If it has not, ignore the call""" def wrap(function: T) -> T: previous = [initial] - lock = threading.Lock() + lock = Lock() def wrapper(*args, **kwargs): with lock: diff --git a/packages/helpermodules/subdata.py b/packages/helpermodules/subdata.py index 05e3f73578..2a7d8d7a72 100644 --- a/packages/helpermodules/subdata.py +++ b/packages/helpermodules/subdata.py @@ -3,7 +3,7 @@ import importlib import logging from pathlib import Path -import threading +from threading import Event from typing import Dict, Union import re import subprocess @@ -71,22 +71,22 @@ class SubData: graph_data = graph.Graph() def __init__(self, - event_ev_template: threading.Event, - event_cp_config: threading.Event, - event_module_update_completed: threading.Event, - event_copy_data: threading.Event, - event_global_data_initialized: threading.Event, - event_command_completed: threading.Event, - event_subdata_initialized: threading.Event, - event_vehicle_update_completed: threading.Event, - event_start_internal_chargepoint: threading.Event, - event_stop_internal_chargepoint: threading.Event, - event_update_config_completed: threading.Event, - event_update_soc: threading.Event, - event_soc: threading.Event, - event_jobs_running: threading.Event, - event_modbus_server: threading.Event, - event_restart_gpio: threading.Event,): + event_ev_template: Event, + event_cp_config: Event, + event_module_update_completed: Event, + event_copy_data: Event, + event_global_data_initialized: Event, + event_command_completed: Event, + event_subdata_initialized: Event, + event_vehicle_update_completed: Event, + event_start_internal_chargepoint: Event, + event_stop_internal_chargepoint: Event, + event_update_config_completed: Event, + event_update_soc: Event, + event_soc: Event, + event_jobs_running: Event, + event_modbus_server: Event, + event_restart_gpio: Event,): self.event_ev_template = event_ev_template self.event_cp_config = event_cp_config self.event_module_update_completed = event_module_update_completed diff --git a/packages/helpermodules/system.py b/packages/helpermodules/system.py index eb6fe059f0..7b1dd3c727 100644 --- a/packages/helpermodules/system.py +++ b/packages/helpermodules/system.py @@ -3,7 +3,7 @@ import logging import os import subprocess -import threading +from threading import Thread import time from pathlib import Path from typing import Optional @@ -85,7 +85,7 @@ def create(): self.create_backup_and_send_to_cloud() except Exception as e: log.exception(f"Error in cloud backup: {e}") - thread_handler(threading.Thread(target=create, args=(), name="cloud backup")) + thread_handler(Thread(target=create, args=(), name="cloud backup")) def create_backup_and_send_to_cloud(self): if self.backup_cloud is not None: diff --git a/packages/helpermodules/utils/_exit_after.py b/packages/helpermodules/utils/_exit_after.py index ba77976165..717915b0ca 100644 --- a/packages/helpermodules/utils/_exit_after.py +++ b/packages/helpermodules/utils/_exit_after.py @@ -1,5 +1,5 @@ import _thread as thread -import threading +from threading import Timer import sys @@ -15,7 +15,7 @@ def exit_after(s): ''' def outer(fn): def inner(*args, **kwargs): - timer = threading.Timer(s, quit_function, args=[fn.__name__]) + timer = Timer(s, quit_function, args=[fn.__name__]) timer.start() try: result = fn(*args, **kwargs) diff --git a/packages/helpermodules/utils/_thread_handler.py b/packages/helpermodules/utils/_thread_handler.py index 9536731959..94c398755d 100644 --- a/packages/helpermodules/utils/_thread_handler.py +++ b/packages/helpermodules/utils/_thread_handler.py @@ -1,11 +1,11 @@ import logging -import threading +from threading import Thread, enumerate from typing import List, Optional log = logging.getLogger(__name__) -def joined_thread_handler(threads: List[threading.Thread], timeout: Optional[int]) -> List[str]: +def joined_thread_handler(threads: List[Thread], timeout: Optional[int]) -> List[str]: def split_chunks(to_split, n): for i in range(0, len(to_split), n): yield to_split[i:i + n] @@ -35,7 +35,7 @@ def split_chunks(to_split, n): return not_finished_threads -def thread_handler(thread: threading.Thread) -> bool: +def thread_handler(thread: Thread) -> bool: if is_thread_alive(thread.name): log.error(f"Thread {thread.name} ist bereits aktiv und wird nicht erneut gestartet.") return False @@ -45,4 +45,4 @@ def thread_handler(thread: threading.Thread) -> bool: def is_thread_alive(thread_name: str) -> bool: - return any(running_thread.name == thread_name for running_thread in threading.enumerate()) + return any(running_thread.name == thread_name for running_thread in enumerate()) diff --git a/packages/helpermodules/utils/error_handling.py b/packages/helpermodules/utils/error_handling.py index 0545c503f2..45998fddd1 100644 --- a/packages/helpermodules/utils/error_handling.py +++ b/packages/helpermodules/utils/error_handling.py @@ -60,7 +60,7 @@ def __exit__(self, exception_type, exception, exception_traceback) -> bool: "Neustart wird versucht, fehlende Software-Pakete zu installieren.") except IndexError: msg = "Importfehler: " + str(exception) - # pub_system_message() publlished an openWB/set/, dass wird beim Starten gelöscht + # pub_system_message() veröffentlicht an openWB/set/, dass wird beim Starten gelöscht log.exception(msg) now = time.time() message_payload = { diff --git a/packages/main.py b/packages/main.py index c6ccb2f096..9c159d9ad4 100755 --- a/packages/main.py +++ b/packages/main.py @@ -1,10 +1,11 @@ #!/usr/bin/env python3 """Starten der benötigten Prozesse """ -# flake8: noqa: F402 +# flake8: noqa: E402 import logging from helpermodules import logger from helpermodules.utils import thread_handler + # als erstes logging initialisieren, damit auch ImportError geloggt werden logger.setup_logging() log = logging.getLogger() @@ -13,9 +14,8 @@ from random import randrange import schedule import time -import threading +from threading import Event, Thread, enumerate import traceback -from threading import Thread from control.chargelog.chargelog import calculate_charge_cost from control import data, prepare, process @@ -72,7 +72,7 @@ def handler_with_control_interval(): logger.clear_in_memory_log_handler("main") log.info("# ***Start*** ") - log.debug(f"Threads: {threading.enumerate()}") + log.debug(f"Threads: {enumerate()}") Pub().pub("openWB/set/system/time", timecheck.create_timestamp()) handler_with_control_interval() logger.write_logs_to_file("main") @@ -197,24 +197,24 @@ def schedule_jobs(): prep = prepare.Prepare() general_internal_chargepoint_handler = GeneralInternalChargepointHandler() rfid = RfidReader() - event_ev_template = threading.Event() + event_ev_template = Event() event_ev_template.set() - event_cp_config = threading.Event() + event_cp_config = Event() event_cp_config.set() - event_soc = threading.Event() + event_soc = Event() event_soc.set() - event_copy_data = threading.Event() # set: Kopieren abgeschlossen, reset: es wird kopiert + event_copy_data = Event() # set: Kopieren abgeschlossen, reset: es wird kopiert event_copy_data.set() - event_global_data_initialized = threading.Event() - event_command_completed = threading.Event() + event_global_data_initialized = Event() + event_command_completed = Event() event_command_completed.set() - event_subdata_initialized = threading.Event() - event_update_config_completed = threading.Event() - event_modbus_server = threading.Event() - event_jobs_running = threading.Event() + event_subdata_initialized = Event() + event_update_config_completed = Event() + event_modbus_server = Event() + event_jobs_running = Event() event_jobs_running.set() - event_update_soc = threading.Event() - event_restart_gpio = threading.Event() + event_update_soc = Event() + event_restart_gpio = Event() gpio = InternalGpioHandler(event_restart_gpio) prep = prepare.Prepare() soc = update_soc.UpdateSoc(event_update_soc) @@ -250,7 +250,7 @@ def schedule_jobs(): t_comm.start() t_soc.start() t_internal_chargepoint.start() - threading.Thread(target=start_modbus_server, args=(event_modbus_server,), name="Modbus Control Server").start() + Thread(target=start_modbus_server, args=(event_modbus_server,), name="Modbus Control Server").start() # Warten, damit subdata Zeit hat, alle Topics auf dem Broker zu empfangen. event_update_config_completed.wait(300) Pub().pub("openWB/set/system/boot_done", True) diff --git a/packages/modbus_control_tester.py b/packages/modbus_control_tester.py index 232621e625..f11ccbba5e 100755 --- a/packages/modbus_control_tester.py +++ b/packages/modbus_control_tester.py @@ -28,7 +28,7 @@ class ReadMode(Enum): slave_id = 1 read_mode = ReadMode.READ_INPUT_REG read_client = modbus.ModbusTcpClient_(host, port=port) -Register = namedtuple("Register", "reg, action, length, type, name, expected") +Register = namedtuple("Register", ("reg", "action", "length", "type", "name", "expected")) REGISTERS = ( Register(10100, Actions.READ_NUMBER, 1, ModbusDataType.INT_32, name="Actual Power", expected=(0, 0)), Register(10102, Actions.READ_NUMBER, 1, ModbusDataType.INT_32, @@ -135,7 +135,7 @@ def evaluate_reg(reg): def read_all_registers(): heartbeat_read() for reg in REGISTERS: - if reg.reg == 10160: + if reg.reg % 100 == 60: while True: try: if evaluate_reg(reg): diff --git a/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py b/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py index 583a2ea1d9..75e656525e 100644 --- a/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py +++ b/packages/modules/chargepoints/openwb_pro/chargepoint_module_test.py @@ -148,10 +148,10 @@ def sample_wrong_charge_state_chargepoint_state(): return sample_wrong_charge_state_chargepoint_state -def sample_chargepoint_state_resetted(): - sample_chargepoint_state_resetted = sample_wrong_charge_state_chargepoint_state() - sample_chargepoint_state_resetted.plug_state = False - return sample_chargepoint_state_resetted +def sample_chargepoint_state_is_reset(): + sample_chargepoint_state_is_reset = sample_wrong_charge_state_chargepoint_state() + sample_chargepoint_state_is_reset.plug_state = False + return sample_chargepoint_state_is_reset @pytest.mark.parametrize( @@ -166,7 +166,7 @@ def sample_chargepoint_state_resetted(): sample_wrong_charge_state_chargepoint_state(), id="Timestamp gesetzt, Fehler aufgetreten, Timestamp nicht abgelaufen"), pytest.param(sample_wrong_charge_state(), 1652683182, ValueError, 1652683182, - sample_chargepoint_state_resetted(), + sample_chargepoint_state_is_reset(), id="Timestamp gesetzt, Fehler aufgetreten, Timestamp abgelaufen"), ]) def test_error_timestamp(sample_state, diff --git a/packages/modules/common/component_context.py b/packages/modules/common/component_context.py index 270ea05504..cad05f8d63 100644 --- a/packages/modules/common/component_context.py +++ b/packages/modules/common/component_context.py @@ -1,5 +1,5 @@ import logging -import threading +from threading import local from typing import Callable, Optional, List, Union, Any, Dict from helpermodules.constants import NO_ERROR @@ -51,7 +51,7 @@ class MultiComponentUpdateContext: for component in self.components: component.update() """ - __thread_local = threading.local() + __thread_local = local() def __init__(self, device_components: Union[Dict[Any, Any], List[Any]], error_handler: Optional[callable] = None): self.__device_components = \ diff --git a/packages/modules/configuration.py b/packages/modules/configuration.py index 59628e4494..ba1aa23150 100644 --- a/packages/modules/configuration.py +++ b/packages/modules/configuration.py @@ -296,7 +296,7 @@ def create_chargepoints_list(path_list): path_list = Path(_get_packages_path()/"modules"/"chargepoints").glob('**/chargepoint_module.py') cp_list = create_chargepoints_list(path_list) - # Nach Umbennnung der "Externen openWB" zu "Secondary openWB" soll der Eintrag weiterhin an zweiter Stelle + # Nach Umbenennung der "Externen openWB" zu "Secondary openWB" soll der Eintrag weiterhin an zweiter Stelle # stehen cp_list.remove({'value': 'external_openwb', 'text': 'Secondary openWB'}) cp_list.insert(1, {'value': 'external_openwb', 'text': 'Secondary openWB'}) diff --git a/packages/modules/devices/generic/virtual/counter_test.py b/packages/modules/devices/generic/virtual/counter_test.py index 5b93c4cebd..3c5dd7dcff 100644 --- a/packages/modules/devices/generic/virtual/counter_test.py +++ b/packages/modules/devices/generic/virtual/counter_test.py @@ -1,4 +1,4 @@ -import threading +from threading import Event from typing import Callable from unittest.mock import Mock @@ -24,7 +24,7 @@ @pytest.fixture(autouse=True) def init_data() -> None: - data.data_init(threading.Event()) + data.data_init(Event()) data.data.counter_all_data = CounterAll() data.data.counter_all_data.data.get.hierarchy = [{"id": 0, "type": "counter", "children": [ {"id": 6, "type": "counter", "children": [ diff --git a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py index 712c417cf1..15ce4895c2 100644 --- a/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py +++ b/packages/modules/internal_chargepoint_handler/internal_chargepoint_handler.py @@ -1,7 +1,7 @@ #!/usr/bin/python import copy import logging -import threading +from threading import Event, Thread import time from typing import Optional from helpermodules import timecheck @@ -80,9 +80,9 @@ class UpdateState: def __init__(self, cp_module: chargepoint_module.ChargepointModule, hierarchy_id: int) -> None: self.old_phases_to_use = 0 self.old_set_current = 0 - self.phase_switch_thread = None # type: Optional[threading.Thread] - self.cp_interruption_thread = None # type: Optional[threading.Thread] - self.actor_cooldown_thread = None # type: Optional[threading.Thread] + self.phase_switch_thread = None # type: Optional[Thread] + self.cp_interruption_thread = None # type: Optional[Thread] + self.actor_cooldown_thread = None # type: Optional[Thread] self.cp_module = cp_module self.hierarchy_id = hierarchy_id @@ -116,14 +116,14 @@ def update_state(self, data: InternalChargepoint, heartbeat_expired: bool) -> No self.__thread_cp_interruption(data.cp_interruption_duration) def __thread_phase_switch(self, phases_to_use: int) -> None: - self.phase_switch_thread = threading.Thread( + self.phase_switch_thread = Thread( target=self.cp_module.perform_phase_switch, args=(phases_to_use, 5), name=f"perform phase switch {self.cp_module.local_charge_point_num}") self.phase_switch_thread.start() log.debug("Thread zur Phasenumschaltung an LP"+str(self.cp_module.local_charge_point_num)+" gestartet.") def __thread_cp_interruption(self, duration: int) -> None: - self.cp_interruption_thread = threading.Thread( + self.cp_interruption_thread = Thread( target=self.cp_module.perform_cp_interruption, args=(duration,), name=f"perform cp interruption cp{self.cp_module.local_charge_point_num}") self.cp_interruption_thread.start() @@ -140,8 +140,8 @@ def __init__(self, hierarchy_id_cp0: int, parent_cp1: Optional[str], hierarchy_id_cp1: Optional[int], - event_start: threading.Event, - event_stop: threading.Event) -> None: + event_start: Event, + event_stop: Event) -> None: log.debug(f"Init internal chargepoint as {mode}") self.event_start = event_start self.event_stop = event_stop @@ -261,7 +261,7 @@ def __init__(self, self.old_plug_state = False def update(self, global_data: GlobalHandlerData, data: InternalChargepointData, rfid_data: RfidData) -> bool: - def __thread_active(thread: Optional[threading.Thread]) -> bool: + def __thread_active(thread: Optional[Thread]) -> bool: if thread: return thread.is_alive() else: @@ -291,8 +291,8 @@ def _check_heartbeat_expired(self, heartbeat) -> bool: class GeneralInternalChargepointHandler: def __init__(self) -> None: - self.event_stop = threading.Event() - self.event_start = threading.Event() + self.event_stop = Event() + self.event_start = Event() def handler(self): while True: diff --git a/packages/modules/internal_chargepoint_handler/rfid.py b/packages/modules/internal_chargepoint_handler/rfid.py index 94c67bd5f5..25f303c55a 100644 --- a/packages/modules/internal_chargepoint_handler/rfid.py +++ b/packages/modules/internal_chargepoint_handler/rfid.py @@ -97,7 +97,7 @@ def __init__(self) -> None: devices = [InputDevice(path) for path in list_devices()] for device in devices: log.debug(f"**** {device.path} {device.name} {device.phys} ****") - log.debug(device.capabilities(verbose=True)) + # log.debug(device.capabilities(verbose=True)) device_capabilities = device.capabilities() if ecodes.EV_KEY in device_capabilities: log.debug("device emits keyboard events") diff --git a/packages/modules/loadvars.py b/packages/modules/loadvars.py index f0b057dd49..ef1b07618a 100644 --- a/packages/modules/loadvars.py +++ b/packages/modules/loadvars.py @@ -1,5 +1,5 @@ import logging -import threading +from threading import Event, Thread from typing import List from control import data @@ -16,7 +16,7 @@ class Loadvars: def __init__(self) -> None: - self.event_module_update_completed = threading.Event() + self.event_module_update_completed = Event() def get_values(self) -> None: topic = "openWB/set/system/device/module_update_completed" @@ -37,17 +37,17 @@ def get_values(self) -> None: def _set_values(self) -> List[str]: """Threads, um Werte von Geräten abzufragen""" - modules_threads: List[threading.Thread] = [] + modules_threads: List[Thread] = [] for item in data.data.system_data.values(): try: if isinstance(item, AbstractDevice): - modules_threads.append(threading.Thread(target=item.update, args=(), + modules_threads.append(Thread(target=item.update, args=(), name=f"device{item.device_config.id}")) except Exception: log.exception(f"Fehler im loadvars-Modul bei Element {item}") for cp in data.data.cp_data.values(): try: - modules_threads.append(threading.Thread(target=cp.chargepoint_module.get_values, + modules_threads.append(Thread(target=cp.chargepoint_module.get_values, args=(), name=f"set values cp{cp.chargepoint_module.config.id}")) except Exception: log.exception(f"Fehler im loadvars-Modul bei Element {cp.num}") @@ -56,13 +56,13 @@ def _set_values(self) -> List[str]: def _update_values_of_level(self, elements, not_finished_threads: List[str]) -> None: """Threads, um von der niedrigsten Ebene der Hierarchie Werte ggf. miteinander zu verrechnen und zu veröffentlichen""" - modules_threads: List[threading.Thread] = [] + modules_threads: List[Thread] = [] for element in elements: try: if element["type"] == ComponentType.CHARGEPOINT.value: chargepoint = data.data.cp_data[f'{type_to_topic_mapping(element["type"])}{element["id"]}'] if self.thread_without_set_value(modules_threads, not_finished_threads) is False: - modules_threads.append(threading.Thread( + modules_threads.append(Thread( target=update_values, args=(chargepoint.chargepoint_module,), name=f"update values cp{chargepoint.chargepoint_module.config.id}")) @@ -70,14 +70,14 @@ def _update_values_of_level(self, elements, not_finished_threads: List[str]) -> component = get_finished_component_obj_by_id(element["id"], not_finished_threads) if component is None: continue - modules_threads.append(threading.Thread(target=update_values, args=( + modules_threads.append(Thread(target=update_values, args=( component,), name=f"component{component.component_config.id}")) except Exception: log.exception(f"Fehler im loadvars-Modul bei Element {element}") joined_thread_handler(modules_threads, data.data.general_data.data.control_interval/3) def thread_without_set_value(self, - modules_threads: List[threading.Thread], + modules_threads: List[Thread], not_finished_threads: List[str]) -> bool: for t in not_finished_threads: for module_thread in modules_threads: @@ -85,15 +85,14 @@ def thread_without_set_value(self, return True return False - def _get_io(self) -> List[threading.Thread]: - threads = [] # type: List[threading.Thread] + def _get_io(self) -> List[Thread]: + threads = [] # type: List[Thread] try: for io_device in data.data.system_data.values(): try: if isinstance(io_device, AbstractIoDevice): threads.append( - threading.Thread(target=io_device.read, - args=(), name="get io state")) + Thread(target=io_device.read, args=(), name="get io state")) except Exception: log.exception("Fehler im loadvars-Modul") except Exception: @@ -101,15 +100,13 @@ def _get_io(self) -> List[threading.Thread]: finally: return threads - def _set_io(self) -> List[threading.Thread]: - threads = [] # type: List[threading.Thread] + def _set_io(self) -> List[Thread]: + threads = [] # type: List[Thread] try: for io_device in data.data.system_data.values(): try: if isinstance(io_device, AbstractIoDevice): - threads.append(threading.Thread(target=update_values, - args=(io_device,), - name="publish io state")) + threads.append(Thread(target=update_values, args=(io_device,), name="publish io state")) except Exception: log.exception("Fehler im loadvars-Modul") except Exception: diff --git a/packages/modules/monitoring/zabbix/api.py b/packages/modules/monitoring/zabbix/api.py index a7b60337bc..ad274b0736 100644 --- a/packages/modules/monitoring/zabbix/api.py +++ b/packages/modules/monitoring/zabbix/api.py @@ -1,17 +1,18 @@ #!/usr/bin/env python3 import os +from typing import List from modules.common.abstract_device import DeviceDescriptor from modules.monitoring.zabbix.config import Zabbix from modules.common.configurable_monitoring import ConfigurableMonitoring -KEY_PATH = "/etc/zabbix/encrypt.psk" -CONFIG_PATH = "/etc/zabbix/zabbix_agent2.conf" +KEY_FILE = "/etc/zabbix/encrypt.psk" +CONFIG_FILE = "/etc/zabbix/zabbix_agent2.conf" -def set_value(lines, key, value): +def set_value(lines: List[str], key: str, value: str): for i, line in enumerate(lines): - if line.startswith(key): + if line.startswith(f"{key}="): lines[i] = f"{key}={value}\n" break else: @@ -19,19 +20,19 @@ def set_value(lines, key, value): 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: + os.system(f"sudo touch {KEY_FILE}") + os.system(f"sudo chmod 666 {KEY_FILE}") + os.system(f"sudo chmod 666 {CONFIG_FILE}") + with open(KEY_FILE, "w") as key_file: key_file.write(config.configuration.psk_key) - with open(CONFIG_PATH, "r+") as config_file: + with open(CONFIG_FILE, "r+") as config_file: lines = config_file.readlines() set_value(lines, "Server", config.configuration.destination_host) set_value(lines, "ServerActive", config.configuration.destination_host) set_value(lines, "Hostname", config.configuration.hostname) set_value(lines, "TLSConnect", "psk") set_value(lines, "TLSAccept", "psk") - set_value(lines, "TLSPSKFile", KEY_PATH) + set_value(lines, "TLSPSKFile", KEY_FILE) set_value(lines, "TLSPSKIdentity", config.configuration.psk_identifier) config_file.seek(0) config_file.writelines(lines) diff --git a/packages/modules/update_soc.py b/packages/modules/update_soc.py index 7c34a73672..998f4caab7 100644 --- a/packages/modules/update_soc.py +++ b/packages/modules/update_soc.py @@ -1,5 +1,4 @@ import logging -import threading from typing import List, Tuple import copy from threading import Event, Thread @@ -19,7 +18,7 @@ class UpdateSoc: - def __init__(self, event_update_soc: threading.Event) -> None: + def __init__(self, event_update_soc: Event) -> None: self.heartbeat = False self.event_vehicle_update_completed = Event() self.event_vehicle_update_completed.set() diff --git a/packages/modules/utils.py b/packages/modules/utils.py index f98df07609..1e2c8f5061 100644 --- a/packages/modules/utils.py +++ b/packages/modules/utils.py @@ -1,5 +1,5 @@ import logging -import threading +from threading import Event from control import data from helpermodules import pub @@ -7,7 +7,7 @@ log = logging.getLogger(__name__) -def wait_for_module_update_completed(event_module_update_completed: threading.Event, topic: str): +def wait_for_module_update_completed(event_module_update_completed: Event, topic: str): timeout = data.data.general_data.data.control_interval/2 event_module_update_completed.clear() pub.Pub().pub(topic, True) diff --git a/packages/modules/vehicles/http/soc.py b/packages/modules/vehicles/http/soc.py index 51735e02bd..cd5c9704a6 100644 --- a/packages/modules/vehicles/http/soc.py +++ b/packages/modules/vehicles/http/soc.py @@ -18,13 +18,13 @@ def fetch_soc(config: HttpSocSetup) -> CarState: soc_url = config.configuration.soc_url range_url = config.configuration.range_url if soc_url is None or soc_url == "none": - log.warn("http_soc: soc_url not defined - set soc to 0") + log.warning("http_soc: soc_url not defined - set soc to 0") soc = 0 else: soc_text = req.get_http_session().get(soc_url, timeout=5).text soc = int(soc_text) if range_url is None or range_url == "none": - log.warn("http_soc: range_url not defined - set range to 0.0") + log.warning("http_soc: range_url not defined - set range to 0.0") range = float(0) else: range_text = req.get_http_session().get(range_url, timeout=5).text