Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion victron_ble/devices/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,27 @@
import struct
from dataclasses import dataclass
from enum import Enum
from typing import Any, Dict, Type
from typing import Any, Dict, Type, TypeVar

from Crypto.Cipher import AES
from Crypto.Util import Counter
from Crypto.Util.Padding import pad

from victron_ble.exceptions import AdvertisementKeyMismatchError

E = TypeVar("E", bound=Enum)


def parse_enum(enum_class: Type[E], value: int) -> E:
"""
Safely convert an int to an enum, returning the UNKNOWN member if the value is not valid.
The enum_class must have an UNKNOWN member defined.
"""
try:
return enum_class(value)
except ValueError:
return getattr(enum_class, "UNKNOWN")


# Sourced from VE.Direct docs
class OperationMode(Enum):
Expand Down Expand Up @@ -171,6 +184,7 @@ class ChargerError(Enum):


class OffReason(Enum):
UNKNOWN = -1
NO_REASON = 0x00000000
NO_INPUT_POWER = 0x00000001
SWITCHED_OFF_SWITCH = 0x00000002
Expand All @@ -186,6 +200,7 @@ class OffReason(Enum):


class AlarmReason(Enum):
UNKNOWN = -1
NO_ALARM = 0
LOW_VOLTAGE = 1
HIGH_VOLTAGE = 2
Expand Down
3 changes: 2 additions & 1 deletion victron_ble/devices/battery_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Device,
DeviceData,
kelvin_to_celsius,
parse_enum,
)


Expand Down Expand Up @@ -107,7 +108,7 @@ def parse_decrypted(self, decrypted: bytes) -> dict:
parsed = {
"remaining_mins": remaining_mins if remaining_mins != 0xFFFF else None,
"voltage": voltage / 100 if voltage != 0x7FFF else None,
"alarm": AlarmReason(alarm),
"alarm": parse_enum(AlarmReason, alarm),
"aux_mode": AuxMode(aux_mode),
"current": current / 1000 if current != 0x3FFFFF else None,
"consumed_ah": -consumed_ah / 10 if consumed_ah != 0xFFFFF else None,
Expand Down
4 changes: 3 additions & 1 deletion victron_ble/devices/dc_energy_meter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Device,
DeviceData,
kelvin_to_celsius,
parse_enum,
)
from victron_ble.devices.battery_monitor import AuxMode

Expand Down Expand Up @@ -54,7 +55,8 @@ def get_alarm(self) -> Optional[AlarmReason]:
"""
Return an enum indicating the current alarm reason or None otherwise
"""
return AlarmReason(self._data["alarm"]) if self._data["alarm"] > 0 else None
alarm = self._data["alarm"]
return parse_enum(AlarmReason, alarm) if alarm > 0 else None

def get_aux_mode(self) -> AuxMode:
"""
Expand Down
3 changes: 2 additions & 1 deletion victron_ble/devices/dcdc_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
DeviceData,
OffReason,
OperationMode,
parse_enum,
)


Expand Down Expand Up @@ -73,5 +74,5 @@ def parse_decrypted(self, decrypted: bytes) -> dict:
"output_voltage": (
output_voltage / 100 if output_voltage != 0x7FFF else None
),
"off_reason": OffReason(off_reason),
"off_reason": parse_enum(OffReason, off_reason),
}
3 changes: 2 additions & 1 deletion victron_ble/devices/orion_xs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
DeviceData,
OffReason,
OperationMode,
parse_enum,
)


Expand Down Expand Up @@ -94,5 +95,5 @@ def parse_decrypted(self, decrypted: bytes) -> dict:
"output_current": output_current / 10 if output_current != 0xFFFF else None,
"input_voltage": input_voltage / 100 if input_voltage != 0xFFFF else None,
"input_current": input_current / 10 if input_current != 0xFFFF else None,
"off_reason": OffReason(off_reason),
"off_reason": parse_enum(OffReason, off_reason),
}
7 changes: 4 additions & 3 deletions victron_ble/devices/smart_battery_protect.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
DeviceData,
OffReason,
OperationMode,
parse_enum,
)


Expand Down Expand Up @@ -91,11 +92,11 @@ def parse_decrypted(self, decrypted: bytes) -> dict:
OutputState(output_state) if output_state != 0xFF else None
),
"error_code": (ChargerError(error_code) if error_code != 0xFF else None),
"alarm_reason": AlarmReason(alarm_reason),
"warning_reason": AlarmReason(warning_reason),
"alarm_reason": parse_enum(AlarmReason, alarm_reason),
"warning_reason": parse_enum(AlarmReason, warning_reason),
"input_voltage": (input_voltage / 100 if input_voltage != 0x7FFF else None),
"output_voltage": (
output_voltage / 100 if output_voltage != 0xFFFF else None
),
"off_reason": OffReason(off_reason),
"off_reason": parse_enum(OffReason, off_reason),
}