Skip to content

Commit

Permalink
Merge branch 'main' into parse_response
Browse files Browse the repository at this point in the history
  • Loading branch information
rokam authored Jul 30, 2024
2 parents c6fc578 + 1858813 commit 7f66ca5
Show file tree
Hide file tree
Showing 8 changed files with 1,069 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/lint-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
label-pr:
runs-on: ubuntu-latest
if: "!contains( github.event.pull_request.labels.*.name, 'autorelease: pending') && !contains( github.event.pull_request.labels.*.name, 'autorelease: tagged')"
permissions:
pull-requests: write
steps:
Expand Down
9 changes: 7 additions & 2 deletions midealocal/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,13 @@ def _redact_data(data: str) -> str:
+ getattr(cr, "street_addresses", [])
)
for token in token_list:
m = len(token)
elm = r"\b" + token + r"\b"
item = token
if len(item) > 0 and item[0] == "'":
item = item[1:]
if len(item) == 0:
break
m = len(item)
elm = r"\b" + item + r"\b"
data = re.sub(elm, block * m, data)
return data

Expand Down
154 changes: 154 additions & 0 deletions midealocal/devices/b8/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
"""Midea local B8 device."""

import logging
from enum import IntEnum
from typing import Any

from midealocal.device import MideaDevice
from midealocal.devices.b8.const import (
B8CleanMode,
B8ControlType,
B8DeviceAttributes,
B8ErrorCanFixDescription,
B8ErrorType,
B8FanLevel,
B8FunctionType,
B8MopState,
B8Moviment,
B8Speed,
B8WaterLevel,
B8WorkMode,
B8WorkStatus,
)
from midealocal.devices.b8.message import (
MessageB8Response,
MessageQuery,
MessageSet,
MessageSetCommand,
)

_LOGGER = logging.getLogger(__name__)


class MideaB8Device(MideaDevice):
"""Midea B8 device."""

def __init__(
self,
name: str,
device_id: int,
ip_address: str,
port: int,
token: str,
key: str,
protocol: int,
model: str,
subtype: int,
customize: str, # noqa: ARG002
) -> None:
"""Initialize Midea B8 device."""
super().__init__(
name=name,
device_id=device_id,
device_type=0xB8,
ip_address=ip_address,
port=port,
token=token,
key=key,
protocol=protocol,
model=model,
subtype=subtype,
attributes={
B8DeviceAttributes.WORK_STATUS: B8WorkStatus.NONE.name.lower(),
B8DeviceAttributes.FUNCTION_TYPE: B8FunctionType.NONE.name.lower(),
B8DeviceAttributes.CONTROL_TYPE: B8ControlType.NONE.name.lower(),
B8DeviceAttributes.MOVE_DIRECTION: B8Moviment.NONE.name.lower(),
B8DeviceAttributes.CLEAN_MODE: B8CleanMode.NONE.name.lower(),
B8DeviceAttributes.FAN_LEVEL: B8FanLevel.OFF.name.lower(),
B8DeviceAttributes.AREA: 0,
B8DeviceAttributes.WATER_LEVEL: B8WaterLevel.OFF.name.lower(),
B8DeviceAttributes.VOICE_VOLUME: 0,
B8DeviceAttributes.MOP: B8MopState.OFF.name.lower(),
B8DeviceAttributes.CARPET_SWITCH: False,
B8DeviceAttributes.SPEED: B8Speed.HIGH.name.lower(),
B8DeviceAttributes.HAVE_RESERVE_TASK: False,
B8DeviceAttributes.BATTERY_PERCENT: 0,
B8DeviceAttributes.WORK_TIME: 0,
B8DeviceAttributes.UV_SWITCH: False,
B8DeviceAttributes.WIFI_SWITCH: False,
B8DeviceAttributes.VOICE_SWITCH: False,
B8DeviceAttributes.COMMAND_SOURCE: False,
B8DeviceAttributes.ERROR_TYPE: B8ErrorType.NO.name.lower(),
B8DeviceAttributes.ERROR_DESC: B8ErrorCanFixDescription.NO.name.lower(),
B8DeviceAttributes.DEVICE_ERROR: False,
B8DeviceAttributes.BOARD_COMMUNICATION_ERROR: False,
B8DeviceAttributes.LASER_SENSOR_SHELTER: False,
B8DeviceAttributes.LASER_SENSOR_ERROR: False,
},
)

def build_query(self) -> list[MessageQuery]:
"""Midea B8 device build query."""
return [MessageQuery(self._protocol_version)]

def process_message(self, msg: bytes) -> dict[str, Any]:
"""Midea B8 device process message."""
message = MessageB8Response(msg)
_LOGGER.debug("[%s] Received: %s", self.device_id, message)
new_status = {}
for status in self._attributes:
if hasattr(message, str(status)):
value = getattr(message, str(status))
if isinstance(value, IntEnum): # lowercase name for IntEnums
value = value.name.lower()
self._attributes[status] = value
new_status[str(status)] = self._attributes[status]
return new_status

def _gen_set_msg_default_values(self) -> MessageSet:
msg = MessageSet(self._protocol_version)
msg.clean_mode = B8CleanMode[
self.attributes[B8DeviceAttributes.CLEAN_MODE].upper()
]
msg.fan_level = B8FanLevel[
self.attributes[B8DeviceAttributes.FAN_LEVEL].upper()
]
msg.water_level = B8WaterLevel[
self.attributes[B8DeviceAttributes.WATER_LEVEL].upper()
]
msg.voice_volume = self.attributes[B8DeviceAttributes.VOICE_VOLUME]
return msg

def set_work_mode(self, work_mode: B8WorkMode) -> None:
"""Midea B8 device set work mode."""
if work_mode == B8WorkMode.WORK:
self.set_attribute(
B8DeviceAttributes.CLEAN_MODE,
self.attributes[B8DeviceAttributes.CLEAN_MODE],
)
return

msg = MessageSetCommand(self._protocol_version, work_mode=work_mode)
self.build_send(msg)

def set_attribute(self, attr: str, value: bool | int | str) -> None:
"""Midea B8 device set attribute."""
try:
msg = self._gen_set_msg_default_values()
if attr == B8DeviceAttributes.CLEAN_MODE:
msg.clean_mode = B8CleanMode[str(value).upper()]
elif attr == B8DeviceAttributes.FAN_LEVEL:
msg.fan_level = B8FanLevel[str(value).upper()]
elif attr == B8DeviceAttributes.WATER_LEVEL:
msg.water_level = B8WaterLevel[str(value).upper()]
elif attr == B8DeviceAttributes.VOICE_VOLUME:
msg.voice_volume = int(value)

if msg is not None:
self.build_send(msg)
except KeyError:
_LOGGER.exception("Wrong value for attribute %s: %s", attr, value)


class MideaAppliance(MideaB8Device):
"""Midea B8 appliance."""
200 changes: 200 additions & 0 deletions midealocal/devices/b8/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
"""Midea local B8 device const."""

from enum import IntEnum, StrEnum


class B8DeviceAttributes(StrEnum):
"""Midea B8 device attributes."""

WORK_STATUS = "work_status"
FUNCTION_TYPE = "function_type"
CONTROL_TYPE = "control_type"
MOVE_DIRECTION = "move_direction"
CLEAN_MODE = "clean_mode"
FAN_LEVEL = "fan_level"
AREA = "area"
WATER_LEVEL = "water_level"
VOICE_VOLUME = "voice_volume"
MOP = "mop"
CARPET_SWITCH = "carpet_switch"
SPEED = "speed"
HAVE_RESERVE_TASK = "have_reserve_task"
BATTERY_PERCENT = "battery_percent"
WORK_TIME = "work_time"
UV_SWITCH = "uv_switch"
WIFI_SWITCH = "wifi_switch"
VOICE_SWITCH = "voice_switch"
COMMAND_SOURCE = "command_source"
ERROR_TYPE = "error_type"
ERROR_DESC = "error_desc"
DEVICE_ERROR = "device_error"
BOARD_COMMUNICATION_ERROR = "board_communication_error"
LASER_SENSOR_SHELTER = "laser_sensor_shelter"
LASER_SENSOR_ERROR = "laser_sensor_error"


class B8WorkMode(IntEnum):
"""Midea B8 work mode."""

CHARGE = 0x01
WORK = 0x02
STOP = 0x03
PAUSE = 0x1B


class B8WorkStatus(IntEnum):
"""Midea B8 work status."""

NONE = 0x00
CHARGE = 0x01
WORK = 0x02
STOP = 0x03
CHARGING_ON_DOCK = 0x04
RESERVE_TASK_FINISHED = 0x05
CHARGE_FINISH = 0x06
CHARGING_WITH_WIRE = 0x07
PAUSE = 0x08
UPDATING = 0x09
SAVING_MAP = 0x0A
ERROR = 0x0B
SLEEP = 0x0C
CHARGE_PAUSE = 0x0D
RELOCATE = 0x0E
ELECTROLYSED_WATER_MAKING = 0x0F
DUST_COLLECTING = 0x10
BACK_DUST_COLLECTING = 0x11
SLEEP_IN_STATION = 0x12


class B8FunctionType(IntEnum):
"""Midea B8 function type."""

NONE = 0x00
DUST_BOX_CLEANING = 0x01
WATER_TANK_CLEANING = 0x02


class B8ControlType(IntEnum):
"""Midea B8 control type."""

NONE = 0x0
MANUAL = 0x1
AUTO = 0x2


class B8Moviment(IntEnum):
"""Midea B8 movement."""

NONE = 0x0
FORWARD = 0x1
BACK = 0x2
LEFT = 0x3
RIGHT = 0x4


class B8CleanMode(IntEnum):
"""Midea B8 clean mode."""

NONE = 0x00
RANDOM = 0x01
ARC = 0x02
EDGE = 0x03
EMPHASES = 0x04
SCREW = 0x05
BED = 0x06
WIDE_SCREW = 0x07
AUTO = 0x08
AREA = 0x09
ZONE_INDEX = 0x0A
ZONE_RECT = 0x0B
PATH = 0x0C


class B8FanLevel(IntEnum):
"""Midea B8 fan level."""

OFF = 0x0
SOFT = 0x1
NORMAL = 0x2
HIGH = 0x3
LOW = 0x4


class B8WaterLevel(IntEnum):
"""Midea B8 water level."""

OFF = 0x0
LOW = 0x1
NORMAL = 0x2
HIGH = 0x3


class B8MopState(IntEnum):
"""Midea B8 mop state."""

OFF = 0x0
ON = 0x1
LACK_WATER = 0x2


class B8Speed(IntEnum):
"""Midea B8 speed."""

LOW = 0x1
HIGH = 0x0


class B8ErrorType(IntEnum):
"""Midea B8 error type."""

NO = 0x00
CAN_FIX = 0x01
REBOOT = 0x02
WARNING = 0x03


class B8ErrorCanFixDescription(IntEnum):
"""Midea B8 error can fix description."""

NO = 0x0
FIX_DUST = 0x01
FIX_WHEEL_HANG = 0x02
FIX_WHEEL_OVERLOAD = 0x03
FIX_SIDE_BRUSH_OVERLOAD = 0x04
FIX_ROLL_BRUSH_OVERLOAD = 0x05
FIX_DUST_ENGINE = 0x06
FIX_FRONT_PANEL = 0x07
FIX_RADAR_MASK = 0x08
FIX_DROP_SENSOR = 0x09
FIX_LOW_BATTERY = 0x0A
FIX_ABNORMAL_POSTURE = 0x0B
FIX_LASER_SENSOR = 0x0C
FIX_EDGE_SENSOR = 0x0D
FIX_START_IN_FORBID_AREA = 0x0E
FIX_START_IN_STRONG_MAGNETIC = 0x0F
FIX_LASER_SENSOR_BLOCKED = 0x10


class B8ErrorRebootDescription(IntEnum):
"""Midea B8 error reboot description."""

NO = 0x00
REBOOT_LASER_COMM_FAIL = 0x01
REBOOT_ROBOT_COMM_FAIL = 0x02
REBOOT_INNER_FAIL = 0x03


class B8ErrorWarningDescription(IntEnum):
"""Midea B8 error warning description."""

NO = 0x00
WARN_LOCATION_FAIL = 0x01
WARN_LOW_BATTERY = 0x02
WARN_FULL_DUST = 0x03
WARN_LOW_WATER = 0x04


class B8StatusType(IntEnum):
"""B8 Status Type."""

X01 = 0x01
Loading

0 comments on commit 7f66ca5

Please sign in to comment.