Skip to content

Commit

Permalink
handle not installed python packages (openWB#1940)
Browse files Browse the repository at this point in the history
* rename

* handle not installed python packages

* improve message
  • Loading branch information
LKuemmel authored Oct 15, 2024
1 parent 8cdbe88 commit c4229ba
Show file tree
Hide file tree
Showing 24 changed files with 223 additions and 214 deletions.
221 changes: 115 additions & 106 deletions packages/control/ocpp.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from datetime import datetime
import json
import logging
from ocpp.v16 import call, ChargePoint as OcppChargepoint
import websockets

from helpermodules.utils.error_handling import ImportErrorContext
with ImportErrorContext():
from ocpp.v16 import call, ChargePoint as OcppChargepoint
with ImportErrorContext():
import websockets
import asyncio
from typing import Callable, Optional

Expand All @@ -13,114 +17,119 @@

log = logging.getLogger(__name__)

try:
class OcppMixin:
def _get_formatted_time(self: OptionalProtocol) -> str:
return datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")

class OcppMixin:
def _get_formatted_time(self: OptionalProtocol) -> str:
return datetime.now().strftime("%Y-%m-%dT%H:%M:%SZ")

def _process_call(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
func: Callable) -> Optional[websockets.WebSocketClientProtocol]:
async def make_call() -> websockets.WebSocketClientProtocol:
async with websockets.connect(self.data.ocpp.url+chargebox_id,
subprotocols=[self.data.ocpp.version]) as ws:
try:
cp = OcppChargepoint(chargebox_id, ws, 2)
await cp.call(func)
except asyncio.exceptions.TimeoutError:
# log.exception("Erwarteter TimeOut StartTransaction")
pass
return ws
try:
if self.data.ocpp.active and chargebox_id:
return asyncio.run(make_call())
except websockets.exceptions.InvalidStatusCode:
fault_state.warning(f"Chargebox ID {chargebox_id} konnte nicht im OCPP-Backend gefunden werden oder "
"URL des Backends ist falsch.")
return None

def boot_notification(self: OptionalProtocol,
def _process_call(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
model: str,
serial_number: str) -> Optional[int]:
try:
self._process_call(chargebox_id, fault_state, call.BootNotification(
charge_point_model=model,
charge_point_vendor="openWB",
firmware_version=data.data.system_data["system"].data["version"],
meter_serial_number=serial_number
))
except Exception as e:
fault_state.from_exception(e)
func: Callable) -> Optional[websockets.WebSocketClientProtocol]:
async def make_call() -> websockets.WebSocketClientProtocol:
async with websockets.connect(self.data.ocpp.url+chargebox_id,
subprotocols=[self.data.ocpp.version]) as ws:
try:
cp = OcppChargepoint(chargebox_id, ws, 2)
await cp.call(func)
except asyncio.exceptions.TimeoutError:
# log.exception("Erwarteter TimeOut StartTransaction")
pass
return ws
try:
if self.data.ocpp.active and chargebox_id:
return asyncio.run(make_call())
except websockets.exceptions.InvalidStatusCode:
fault_state.warning(f"Chargebox ID {chargebox_id} konnte nicht im OCPP-Backend gefunden werden oder "
"URL des Backends ist falsch.")
return None

def start_transaction(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
connector_id: int,
id_tag: str,
imported: int) -> Optional[int]:
try:
ws = self._process_call(chargebox_id, fault_state, call.StartTransaction(
connector_id=connector_id,
id_tag=id_tag if id_tag else "",
meter_start=int(imported),
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
except Exception as e:
fault_state.from_exception(e)
return None
def boot_notification(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
model: str,
serial_number: str) -> Optional[int]:
try:
self._process_call(chargebox_id, fault_state, call.BootNotification(
charge_point_model=model,
charge_point_vendor="openWB",
firmware_version=data.data.system_data["system"].data["version"],
meter_serial_number=serial_number
))
except Exception as e:
fault_state.from_exception(e)

def start_transaction(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
connector_id: int,
id_tag: str,
imported: int) -> Optional[int]:
try:
ws = self._process_call(chargebox_id, fault_state, call.StartTransaction(
connector_id=connector_id,
id_tag=id_tag if id_tag else "",
meter_start=int(imported),
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
except Exception as e:
fault_state.from_exception(e)
return None

def transfer_values(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
connector_id: int,
imported: int) -> None:
try:
self._process_call(chargebox_id, fault_state, call.MeterValues(
connector_id=connector_id,
meter_value=[{"timestamp": self._get_formatted_time(),
"sampledValue": [
{
"value": f'{int(imported)}',
"context": "Sample.Periodic",
"format": "Raw",
"measurand": "Energy.Active.Import.Register",
"unit": "Wh"
},
]}],
))
log.debug(f"Zählerstand {imported} an Chargebox ID: {chargebox_id} übermittelt.")
except Exception as e:
fault_state.from_exception(e)

def transfer_values(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
connector_id: int,
imported: int) -> None:
try:
self._process_call(chargebox_id, fault_state, call.MeterValues(
connector_id=connector_id,
meter_value=[{"timestamp": self._get_formatted_time(),
"sampledValue": [
{
"value": f'{int(imported)}',
"context": "Sample.Periodic",
"format": "Raw",
"measurand": "Energy.Active.Import.Register",
"unit": "Wh"
},
]}],
))
log.debug(f"Zählerstand {imported} an Chargebox ID: {chargebox_id} übermittelt.")
except Exception as e:
fault_state.from_exception(e)
def send_heart_beat(self: OptionalProtocol, chargebox_id: str, fault_state: FaultState) -> None:
try:
self._process_call(chargebox_id, fault_state, call.Heartbeat())
log.debug(f"Heartbeat an Chargebox ID: {chargebox_id} gesendet.")
except Exception as e:
fault_state.from_exception(e)

def send_heart_beat(self: OptionalProtocol, chargebox_id: str, fault_state: FaultState) -> None:
try:
self._process_call(chargebox_id, fault_state, call.Heartbeat())
log.debug(f"Heartbeat an Chargebox ID: {chargebox_id} gesendet.")
except Exception as e:
fault_state.from_exception(e)
def stop_transaction(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
imported: int,
transaction_id: int,
id_tag: str) -> None:
try:
self._process_call(chargebox_id, fault_state, call.StopTransaction(meter_stop=int(imported),
timestamp=self._get_formatted_time(),
transaction_id=transaction_id,
reason="EVDisconnected",
id_tag=id_tag if id_tag else ""
))
log.debug(f"Transaction mit ID: {transaction_id} für Chargebox ID: {chargebox_id} mit Tag: {id_tag}"
f" und Zählerstand: {imported} beendet.")
except Exception as e:
fault_state.from_exception(e)
except NameError:
log.warning("OCPP-Modul nicht installiert. OCPP-Optionen sind deaktiviert.")

def stop_transaction(self: OptionalProtocol,
chargebox_id: str,
fault_state: FaultState,
imported: int,
transaction_id: int,
id_tag: str) -> None:
try:
self._process_call(chargebox_id, fault_state, call.StopTransaction(meter_stop=int(imported),
timestamp=self._get_formatted_time(),
transaction_id=transaction_id,
reason="EVDisconnected",
id_tag=id_tag if id_tag else ""
))
log.debug(f"Transaction mit ID: {transaction_id} für Chargebox ID: {chargebox_id} mit Tag: {id_tag} und "
f"Zählerstand: {imported} beendet.")
except Exception as e:
fault_state.from_exception(e)
class OcppMixin:
pass
9 changes: 6 additions & 3 deletions packages/helpermodules/modbusserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
from collections import defaultdict
import struct
from typing import Optional
from umodbus import conf
from umodbus.server.tcp import RequestHandler, get_server
from umodbus.utils import log_to_stream

from helpermodules.utils.error_handling import ImportErrorContext
with ImportErrorContext():
from umodbus import conf
from umodbus.server.tcp import RequestHandler, get_server
from umodbus.utils import log_to_stream

from helpermodules import timecheck
from helpermodules.hardware_configuration import get_serial_number
Expand Down
5 changes: 4 additions & 1 deletion packages/helpermodules/timecheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import copy
import logging
import datetime
from dateutil.relativedelta import relativedelta
from typing import Dict, List, Optional, Tuple, TypeVar, Union

from helpermodules.utils.error_handling import ImportErrorContext
with ImportErrorContext():
from dateutil.relativedelta import relativedelta

from helpermodules.abstract_plans import AutolockPlan, ScheduledChargingPlan, TimeChargingPlan

log = logging.getLogger(__name__)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging
import time

from helpermodules import timecheck
from helpermodules.messaging import MessageType
from helpermodules.pub import Pub


Expand Down Expand Up @@ -41,3 +43,31 @@ def error_counter_exceeded(self) -> bool:
def reset_error_counter(self):
self.error_timestamp = None
Pub().pub(self.topic, self.error_timestamp)


class ImportErrorContext:
def __init__(self):
pass

def __enter__(self):
return None

def __exit__(self, exception_type, exception, exception_traceback) -> bool:
if isinstance(exception, ModuleNotFoundError):
try:
msg = ("Importfehler: Das Python-Modul " + exception.args[0].split("'")[1] + " wurde nicht gefunden." +
" Bitte sicherstellen, dass diese openWB eine Verbindung zum Internet besitzt. Beim nächsten " +
"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
log.exception(msg)
now = time.time()
message_payload = {
"source": "command",
"type": MessageType.ERROR.value,
"message": msg,
"timestamp": int(now)
}
Pub().pub(f'openWB/system/messages/{(now * 1000):.0f}', message_payload)
return True
9 changes: 6 additions & 3 deletions packages/modules/backup_clouds/onedrive/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import pickle
import json
import paho.mqtt.publish as publish
import msal
import base64

from helpermodules.utils.error_handling import ImportErrorContext
with ImportErrorContext():
import msal

from helpermodules.messaging import MessageType
from modules.backup_clouds.onedrive.config import OneDriveBackupCloud, OneDriveBackupCloudConfiguration

Expand Down Expand Up @@ -87,7 +90,7 @@ def generateMSALAuthCode(cloudbackup: OneDriveBackupCloud) -> dict:
app = msal.PublicClientApplication(
client_id=cloudbackup.configuration.clientID,
authority=cloudbackup.configuration.authority
)
)

# create device flow to obtain auth code
flow = app.initiate_device_flow(cloudbackup.configuration.scope)
Expand All @@ -105,7 +108,7 @@ def generateMSALAuthCode(cloudbackup: OneDriveBackupCloud) -> dict:

publish.single(
"openWB/set/system/backup_cloud/config", cloudbackupconfig_to_mqtt, retain=True, hostname="localhost"
)
)

result["message"] = """Autorisierung gestartet, bitte den Link öffnen, Code eingeben,
und Zugang autorisieren. Anschließend Zugangsberechtigung abrufen."""
Expand Down
5 changes: 4 additions & 1 deletion packages/modules/backup_clouds/samba/backup_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import io
import re
import socket
from smb.SMBConnection import SMBConnection

from helpermodules.utils.error_handling import ImportErrorContext
with ImportErrorContext():
from smb.SMBConnection import SMBConnection

from modules.backup_clouds.samba.config import SambaBackupCloud, SambaBackupCloudConfiguration
from modules.common.abstract_device import DeviceDescriptor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from control import data
from helpermodules import pub, timecheck
from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
from helpermodules.utils.error_handling import CP_ERROR, ErrorTimerContext
from modules.chargepoints.external_openwb.config import OpenWBSeries
from modules.common.abstract_chargepoint import AbstractChargepoint
from modules.common.abstract_device import DeviceDescriptor
Expand Down
2 changes: 1 addition & 1 deletion packages/modules/chargepoints/mqtt/chargepoint_module.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
from helpermodules.utils.error_handling import CP_ERROR, ErrorTimerContext
from modules.chargepoints.mqtt.config import Mqtt
from modules.common.abstract_chargepoint import AbstractChargepoint
from modules.common.abstract_device import DeviceDescriptor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging

from helpermodules import hardware_configuration
from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
from helpermodules.utils.error_handling import CP_ERROR, ErrorTimerContext
from modules.chargepoints.openwb_dc_adapter.config import OpenWBDcAdapter
from modules.common.abstract_chargepoint import AbstractChargepoint
from modules.common.abstract_device import DeviceDescriptor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import time

from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
from helpermodules.utils.error_handling import CP_ERROR, ErrorTimerContext
from modules.chargepoints.openwb_pro.config import OpenWBPro
from modules.common.abstract_chargepoint import AbstractChargepoint
from modules.common.abstract_device import DeviceDescriptor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Optional

from control import data
from helpermodules.utils.error_counter import CP_ERROR, ErrorTimerContext
from helpermodules.utils.error_handling import CP_ERROR, ErrorTimerContext
from modules.chargepoints.openwb_series2_satellit.config import OpenWBseries2Satellit
from modules.common import modbus
from modules.common.abstract_chargepoint import AbstractChargepoint
Expand Down
Loading

0 comments on commit c4229ba

Please sign in to comment.