Skip to content

Commit

Permalink
handle not installed python packages
Browse files Browse the repository at this point in the history
  • Loading branch information
LKuemmel committed Oct 11, 2024
1 parent 1c3833b commit 8493cd9
Show file tree
Hide file tree
Showing 17 changed files with 127 additions and 122 deletions.
8 changes: 6 additions & 2 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 Down
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
29 changes: 29 additions & 0 deletions packages/helpermodules/utils/error_handling.py
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,30 @@ def error_counter_exceeded(self) -> bool:
def reset_error_counter(self):
Pub().pub(self.topic, self.error_timestamp)
self.error_timestamp = None


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: Konnte Modul " +
exception.args[0].split("'")[1] + " nicht finden. Bitte die Internetverbindung prüfen.")
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
2 changes: 0 additions & 2 deletions packages/modules/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

sys.modules['pymodbus'] = type(sys)('pymodbus')
sys.modules['aiohttp'] = type(sys)('aiohttp')
sys.modules['ipparser'] = type(sys)('ipparser')
sys.modules['ipparser.ipparser'] = type(sys)('ipparser.ipparser')
sys.modules['lxml'] = type(sys)('lxml')
sys.modules['lxml.html'] = type(sys)('lxml.html')
sys.modules['bs4'] = type(sys)('bs4')
Expand Down
58 changes: 1 addition & 57 deletions packages/modules/devices/kostal/kostal_plenticore/device.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
# !/usr/bin/env python3
from enum import IntEnum
from ipparser import ipparser
from itertools import chain
from typing import Any, Callable, Iterable, List, Union
from typing import Any, Callable, Iterable, Union
from pymodbus.constants import Endian
import functools
import logging

from helpermodules.cli import run_using_positional_cli_args
from modules.common import modbus
from modules.common.abstract_device import DeviceDescriptor
from modules.common.component_state import InverterState
from modules.common.configurable_device import ConfigurableDevice, ComponentFactoryByType, MultiComponentUpdater
from modules.common.store import get_counter_value_store
from modules.devices.kostal.kostal_plenticore.bat import KostalPlenticoreBat
from modules.devices.kostal.kostal_plenticore.inverter import KostalPlenticoreInverter
from modules.devices.kostal.kostal_plenticore.config import (KostalPlenticore, KostalPlenticoreBatSetup,
Expand Down Expand Up @@ -85,55 +80,4 @@ def _create_reader(tcp_client: modbus.ModbusTcpClient_, modbus_id: int) -> Calla
return functools.partial(tcp_client.read_holding_registers, unit=modbus_id, wordorder=Endian.Little)


def read_legacy_inverter(ip1: str, ip2: str, battery: int, ip3: str) -> InverterState:
# in IP3 kann ein aufeinanderfolgende Liste enthalten sein "192.168.0.1-3"
log.debug("Kostal Plenticore: WR1: %s, WR2: %s, WR3: %s, Battery: %s", ip1, ip2, ip3, battery)
inverter_component = KostalPlenticoreInverter(KostalPlenticoreInverterSetup(id=1))

def get_hybrid_inverter_state(ip: str) -> InverterState:
battery_component = KostalPlenticoreBat(1, KostalPlenticoreBatSetup())
with modbus.ModbusTcpClient_(ip, 1502) as client:
return update(
[inverter_component, battery_component], _create_reader(client, 71), set_inverter_state=False
)

def get_standard_inverter_state(ip: str) -> InverterState:
with modbus.ModbusTcpClient_(ip, 1502) as client:
return inverter_component.read_state(_create_reader(client, 71))

def inverter_state_sum(a: InverterState, b: InverterState) -> InverterState:
return InverterState(exported=a.exported + b.exported, power=a.power + b.power)

inverter_state = functools.reduce(
inverter_state_sum,
map(get_standard_inverter_state, filter("none".__ne__, chain([ip2], ipparser(ip3)))),
get_hybrid_inverter_state(ip1) if battery else get_standard_inverter_state(ip1)
)
inverter_component.update(inverter_state)
return inverter_state


def read_legacy_counter(ip1: str, ip2: str, battery: int, ip3: str, position: int) -> None:
log.debug("Kostal Plenticore: WR1: %s, Position: %s", ip1, position)
client = modbus.ModbusTcpClient_(ip1, 1502)
reader = _create_reader(client, 71)
counter_component = KostalPlenticoreCounter(None, KostalPlenticoreCounterSetup(id=None))
if LegacyCounterPosition(position) == LegacyCounterPosition.GRID:
with client:
counter_component.update(reader)
else:
with client:
counter_state = counter_component.get_values(reader)
bat_power = KostalPlenticoreBat(None, KostalPlenticoreBatSetup()).read_state(reader).power
inverter_power = read_legacy_inverter(ip1, ip2, battery, ip3).power
counter_state.power += inverter_power + bat_power
counter_state = counter_component.update_imported_exported(counter_state)
get_counter_value_store(None).set(counter_state)


def main(argv: List[str]):
run_using_positional_cli_args({"counter": read_legacy_counter, "inverter": read_legacy_inverter}, argv
)


device_descriptor = DeviceDescriptor(configuration_factory=KostalPlenticore)
7 changes: 5 additions & 2 deletions packages/modules/electricity_tariffs/energycharts/tariff.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from typing import Dict
from datetime import datetime, timedelta
from modules.common import req
import pytz

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

from modules.common import req
from modules.common.abstract_device import DeviceDescriptor
from modules.common.component_state import TariffState
from modules.electricity_tariffs.energycharts.config import EnergyChartsTariffConfiguration
Expand Down
5 changes: 4 additions & 1 deletion packages/modules/electricity_tariffs/rabot/tariff.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import datetime
import logging
from typing import Dict
import pytz
from requests.exceptions import HTTPError

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

from dataclass_utils import asdict
from helpermodules import timecheck
from helpermodules.pub import Pub
Expand Down
5 changes: 4 additions & 1 deletion packages/modules/electricity_tariffs/voltego/tariff.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
import datetime
import logging
from typing import Dict
import pytz
from requests.exceptions import HTTPError

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

from dataclass_utils import asdict
from helpermodules import timecheck
from helpermodules.pub import Pub
Expand Down
15 changes: 9 additions & 6 deletions packages/modules/vehicles/bmwbc/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
import datetime
import logging
from typing import Union

from helpermodules.utils.error_handling import ImportErrorContext
with ImportErrorContext():
from bimmer_connected.api.client import MyBMWClientConfiguration
from bimmer_connected.api.authentication import MyBMWAuthentication
from bimmer_connected.account import MyBMWAccount
from bimmer_connected.api.regions import Regions
from bimmer_connected.utils import MyBMWJSONEncoder

from modules.common.component_state import CarState
from modules.common.store import RAMDISK_PATH
from bimmer_connected.api.client import MyBMWClientConfiguration
from bimmer_connected.api.authentication import MyBMWAuthentication
from bimmer_connected.account import MyBMWAccount
from bimmer_connected.api.regions import Regions
from bimmer_connected.utils import MyBMWJSONEncoder


log = logging.getLogger(__name__)

Expand Down
44 changes: 22 additions & 22 deletions packages/modules/vehicles/evcc/vehicle_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions packages/modules/vehicles/evcc/vehicle_pb2.pyi
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# flake8: noqa
from google.protobuf.internal import containers as _containers
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from helpermodules.utils.error_handling import ImportErrorContext
with ImportErrorContext():
from google.protobuf.internal import containers as _containers
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional

DESCRIPTOR: _descriptor.FileDescriptor


class NewRequest(_message.Message):
__slots__ = ("token", "type", "config")

class ConfigEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
Expand All @@ -21,14 +25,17 @@ class NewRequest(_message.Message):
token: str
type: str
config: _containers.ScalarMap[str, str]
def __init__(self, token: _Optional[str] = ..., type: _Optional[str] = ..., config: _Optional[_Mapping[str, str]] = ...) -> None: ...
def __init__(self, token: _Optional[str] = ..., type: _Optional[str] = ...,
config: _Optional[_Mapping[str, str]] = ...) -> None: ...


class NewReply(_message.Message):
__slots__ = ("vehicle_id",)
VEHICLE_ID_FIELD_NUMBER: _ClassVar[int]
vehicle_id: int
def __init__(self, vehicle_id: _Optional[int] = ...) -> None: ...


class SoCRequest(_message.Message):
__slots__ = ("token", "vehicle_id")
TOKEN_FIELD_NUMBER: _ClassVar[int]
Expand All @@ -37,6 +44,7 @@ class SoCRequest(_message.Message):
vehicle_id: int
def __init__(self, token: _Optional[str] = ..., vehicle_id: _Optional[int] = ...) -> None: ...


class SoCReply(_message.Message):
__slots__ = ("soc",)
SOC_FIELD_NUMBER: _ClassVar[int]
Expand Down
Loading

0 comments on commit 8493cd9

Please sign in to comment.