mirror of
https://github.com/mitchellrj/eufy_robovac.git
synced 2025-11-25 12:42:40 +00:00
More detail and sync-friendly options
This commit is contained in:
@@ -16,43 +16,53 @@
|
||||
|
||||
import logging
|
||||
|
||||
from .property import DeviceProperty, StringEnum
|
||||
from .tuya import TuyaDevice
|
||||
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WorkMode:
|
||||
class WorkMode(StringEnum):
|
||||
AUTO = 'auto'
|
||||
NO_SWEEP = 'Nosweep'
|
||||
SMALL_ROOM = 'SmallRoom'
|
||||
EDGE = 'Edge'
|
||||
Spot = 'Spot'
|
||||
SPOT = 'Spot'
|
||||
|
||||
|
||||
class Direction:
|
||||
class Direction(StringEnum):
|
||||
LEFT = 'left'
|
||||
RIGHT = 'right'
|
||||
FORWARD = 'forward'
|
||||
BACKWARD = 'backward'
|
||||
|
||||
|
||||
class WorkStatus:
|
||||
class WorkStatus(StringEnum):
|
||||
RUNNING = 'Running'
|
||||
CHARGING = 'Charging'
|
||||
STAND_BY = 'standby'
|
||||
SLEEPING = 'Sleeping'
|
||||
RECHARGING = 'Recharge'
|
||||
|
||||
|
||||
class CleanSpeed:
|
||||
class CleanSpeed(StringEnum):
|
||||
NO_SUCTION = 'No_suction'
|
||||
STANDARD = 'Standard'
|
||||
BOOST_IQ = 'Boost_IQ'
|
||||
MAX = 'Max'
|
||||
|
||||
|
||||
class ErrorCode:
|
||||
pass
|
||||
class ErrorCode(StringEnum):
|
||||
NO_ERROR = 'no_error'
|
||||
WHEEL_STUCK = 'Wheel_stuck'
|
||||
R_BRUSH_STUCK = 'R_brush_stuck'
|
||||
CRASH_BAR_STUCK = 'Crash_bar_stuck'
|
||||
SENSOR_DIRTY = 'sensor_dirty'
|
||||
NOT_ENOUGH_POWER = 'N_enough_pow'
|
||||
STUCK_5_MIN = 'Stuck_5_min'
|
||||
FAN_STUCK = 'Fan_stuck'
|
||||
S_BRUSH_STUCK = 'S_brush_stuck'
|
||||
|
||||
|
||||
class Robovac(TuyaDevice):
|
||||
@@ -67,23 +77,34 @@ class Robovac(TuyaDevice):
|
||||
FIND_ROBOT = '103'
|
||||
BATTERY_LEVEL = '104'
|
||||
ERROR_CODE = '106'
|
||||
KEY_NAMES = {
|
||||
PLAY_PAUSE: 'play/pause',
|
||||
DIRECTION: 'direction',
|
||||
WORK_MODE: 'work mode',
|
||||
WORK_STATUS: 'work status',
|
||||
GO_HOME: 'go home',
|
||||
CLEAN_SPEED: 'clean speed',
|
||||
FIND_ROBOT: 'find robot',
|
||||
BATTERY_LEVEL: 'battery level',
|
||||
ERROR_CODE: 'error code'
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
play_pause = DeviceProperty(PLAY_PAUSE)
|
||||
direction = DeviceProperty(DIRECTION)
|
||||
work_mode = DeviceProperty(WORK_MODE, WorkMode)
|
||||
work_status = DeviceProperty(WORK_STATUS, WorkStatus, True)
|
||||
go_home = DeviceProperty(GO_HOME)
|
||||
clean_speed = DeviceProperty(CLEAN_SPEED, CleanSpeed)
|
||||
find_robot = DeviceProperty(FIND_ROBOT)
|
||||
battery_level = DeviceProperty(BATTERY_LEVEL, read_only=True)
|
||||
error_code = DeviceProperty(ERROR_CODE, ErrorCode, True)
|
||||
|
||||
async def async_play(self, callback=None):
|
||||
await self.async_set({self.PLAY_PAUSE: True}, callback)
|
||||
|
||||
async def async_pause(self, callback=None):
|
||||
await self.async_set({self.PLAY_PAUSE: False}, callback)
|
||||
|
||||
async def async_start_cleaning(self, callback=None):
|
||||
await self.async_set({self.WORK_MODE: WorkMode.AUTO}, callback)
|
||||
await self.async_set({self.WORK_MODE: str(WorkMode.AUTO)}, callback)
|
||||
|
||||
async def async_go_home(self, callback=None):
|
||||
await self.async_set({self.GO_HOME: True}, callback)
|
||||
|
||||
async def async_set_work_mode(self, work_mode, callback=None):
|
||||
await self.async_set({self.WORK_MODE: work_mode}, callback)
|
||||
|
||||
async def async_find_robot(self, callback=None):
|
||||
await self.async_set({self.FIND_ROBOT: True}, callback)
|
||||
|
||||
async def async_set_clean_speed(self, clean_speed, callback=None):
|
||||
await self.async_set({self.CLEAN_SPEED: str(clean_speed)}, callback)
|
||||
|
||||
@@ -45,6 +45,7 @@ from json.decoder import JSONDecodeError
|
||||
import logging
|
||||
import socket
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
|
||||
from cryptography.hazmat.backends.openssl import backend as openssl_backend
|
||||
@@ -156,7 +157,7 @@ class RequestResponseCommandMismatch(TuyaException):
|
||||
|
||||
|
||||
class TuyaCipher:
|
||||
"""The Tuya encryption cipher"""
|
||||
"""Tuya cryptographic helpers."""
|
||||
|
||||
def __init__(self, key, version):
|
||||
"""Initialize the cipher."""
|
||||
@@ -218,6 +219,7 @@ class TuyaCipher:
|
||||
intermediate = digest.finalize().hex()
|
||||
return intermediate[8:24]
|
||||
|
||||
|
||||
def crc(data):
|
||||
"""Calculate the Tuya-flavored CRC of some data."""
|
||||
c = 0xFFFFFFFF
|
||||
@@ -395,6 +397,22 @@ class Message:
|
||||
return cls(command, payload, sequence)
|
||||
|
||||
|
||||
def _call_async(fn, *args):
|
||||
loop = None
|
||||
if sys.version_info >= (3, 7):
|
||||
try:
|
||||
loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
def wrapper(fn, *args):
|
||||
asyncio.ensure_future(fn(*args))
|
||||
|
||||
loop.call_soon(wrapper, fn, *args)
|
||||
|
||||
|
||||
class TuyaDevice:
|
||||
"""Represents a generic Tuya device."""
|
||||
|
||||
@@ -438,10 +456,6 @@ class TuyaDevice:
|
||||
def __str__(self):
|
||||
return "{} ({}:{})".format(self.device_id, self.host, self.port)
|
||||
|
||||
@property
|
||||
def loop(self):
|
||||
return asyncio.get_running_loop()
|
||||
|
||||
async def async_connect(self, callback=None):
|
||||
sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
|
||||
sock.settimeout(self.timeout)
|
||||
@@ -482,7 +496,10 @@ class TuyaDevice:
|
||||
'dps': dps
|
||||
}
|
||||
message = Message(Message.SET_COMMAND, payload, encrypt_for=self)
|
||||
return await message.async_send(self, callback)
|
||||
await message.async_send(self, callback)
|
||||
|
||||
def set(self, dps):
|
||||
_call_async(self.async_set, dps)
|
||||
|
||||
async def _async_ping(self):
|
||||
self.last_ping = time.time()
|
||||
|
||||
Reference in New Issue
Block a user