Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OTP workaround and removing unsupported actions #219

Merged
merged 24 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f3fc384
handle timeouts as managed failure instead of general failure
elad-bar Jun 23, 2024
f3df5c5
handle timeouts as managed failure instead of general failure (#206)
elad-bar Jun 23, 2024
ee01117
improved log messages of status changes
elad-bar Jun 24, 2024
3f1d792
fix if statement for logging
elad-bar Jun 24, 2024
20f9c1c
Merge branch 'develop' into fix-timeouts-handling
elad-bar Jun 24, 2024
757e7ad
Merge pull request #207 from sh00t2kill/fix-timeouts-handling
elad-bar Jun 24, 2024
39c7036
Merge branch 'main' into develop
elad-bar Jul 4, 2024
64754ff
refactor states
elad-bar Jul 5, 2024
10abf1f
fix typo
elad-bar Jul 5, 2024
cb9539b
Merge pull request #211 from sh00t2kill/remove-turn-on-off
elad-bar Jul 5, 2024
b21984f
refactor new client initialization process to non-blocking call
elad-bar Jul 5, 2024
e0a1a12
Merge pull request #212 from sh00t2kill/remove-blocking-call-to-start…
elad-bar Jul 5, 2024
ea0c9a7
Add reset account password flow from setup or configure
elad-bar Jul 5, 2024
ec7812f
Merge pull request #213 from sh00t2kill/email-validation
elad-bar Jul 5, 2024
146a4ca
initialize session for reset password flow
elad-bar Jul 6, 2024
4746906
Merge pull request #214 from sh00t2kill/email-validation
elad-bar Jul 6, 2024
0e3c1f9
add is email exists before reset password
elad-bar Jul 6, 2024
8daaf6f
Merge pull request #215 from sh00t2kill/email-validation
elad-bar Jul 6, 2024
393b656
better handling clock icons
elad-bar Jul 7, 2024
f074d74
Merge branch 'develop' into email-validation
elad-bar Jul 7, 2024
c43341a
Merge pull request #217 from sh00t2kill/email-validation
elad-bar Jul 7, 2024
0c14f02
fix missing state
elad-bar Jul 8, 2024
13e47ce
Merge branch 'develop' into email-validation
elad-bar Jul 8, 2024
9f5f485
Merge pull request #218 from sh00t2kill/email-validation
elad-bar Jul 8, 2024
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
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
# Changelog

## v1.0.16

- Add email validation on setup and every startup
- Add reset account password flow from setup or configure (when integration already connected but OTP is required)
- Refactor new client initialization process to non-blocking call
- Improved log messages of status changes
- Removed vacuum actions
- Turn on - not supported
- Turn off - not supported
- Pause - acts as stop, calls stop, no need for duplicate functionality
- Toggle - Non turn on / off, no need
- Clean unused constants
- Refactor calculated status
- Move to dedicated class
- Adjust tests
- Remove on state, instead introduce idle state, off state remain

| Power Supply State | Robot State | Calculated State |
| ------------------ | --------------------------------------------------- | ---------------- |
| error | \* | error |
| \* | fault | error |
| holdDelay | notConnected, programming, init. scanning, finished | holddelay |
| holdWeekly | notConnected, programming, init. scanning, finished | holdweekly |
| on | init | init |
| on | programming, scanning | cleaning |
| programming | notConnected, init, scanning | cleaning |
| programming | programming | programming |
| programming | finished | off |
| off | \* (but fault) | off |

Unmatched matching, will be treated as off.

## v1.0.15

- Remove startup blocking call
Expand Down
23 changes: 23 additions & 0 deletions custom_components/mydolphin_plus/common/calculated_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from enum import StrEnum


class CalculatedState(StrEnum):
OFF = "off"
PROGRAMMING = "programming"
ERROR = "error"
CLEANING = "cleaning"
INIT = "init"
HOLD_DELAY = "holddelay"
HOLD_WEEKLY = "holdweekly"

@staticmethod
def is_on_state(value) -> bool:
is_on = value in [
CalculatedState.INIT,
CalculatedState.CLEANING,
CalculatedState.PROGRAMMING,
CalculatedState.HOLD_WEEKLY,
CalculatedState.HOLD_DELAY,
]

return is_on
40 changes: 21 additions & 19 deletions custom_components/mydolphin_plus/common/connectivity_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,44 @@


class ConnectivityStatus(StrEnum):
NotConnected = "Not connected"
Connecting = "Establishing connection to API"
Connected = "Connected to the API"
TemporaryConnected = "Connected with temporary API key"
Failed = "Failed to access API"
InvalidCredentials = "Invalid credentials"
MissingAPIKey = "Permanent API Key was not found"
Disconnected = "Disconnected by the system"
NotFound = "API Not found"
NOT_CONNECTED = "Not connected"
CONNECTING = "Establishing connection to API"
CONNECTED = "Connected to the API"
TEMPORARY_CONNECTED = "Connected with temporary API key"
FAILED = "Failed to access API"
INVALID_CREDENTIALS = "Invalid credentials"
MISSING_API_KEY = "Permanent API Key was not found"
DISCONNECTED = "Disconnected by the system"
API_NOT_FOUND = "API Not found"
INVALID_ACCOUNT = "Invalid account"

@staticmethod
def get_log_level(status: StrEnum) -> int:
if status in [
ConnectivityStatus.Connected,
ConnectivityStatus.Connecting,
ConnectivityStatus.Disconnected,
ConnectivityStatus.TemporaryConnected,
ConnectivityStatus.CONNECTED,
ConnectivityStatus.CONNECTING,
ConnectivityStatus.DISCONNECTED,
ConnectivityStatus.TEMPORARY_CONNECTED,
]:
return logging.INFO
elif status in [ConnectivityStatus.NotConnected]:
elif status in [ConnectivityStatus.NOT_CONNECTED]:
return logging.WARNING
else:
return logging.ERROR

@staticmethod
def get_ha_error(status: str) -> str | None:
errors = {
str(ConnectivityStatus.InvalidCredentials): "invalid_admin_credentials",
str(ConnectivityStatus.MissingAPIKey): "missing_permanent_api_key",
str(ConnectivityStatus.Failed): "invalid_server_details",
str(ConnectivityStatus.NotFound): "invalid_server_details",
str(ConnectivityStatus.INVALID_CREDENTIALS): "invalid_credentials",
str(ConnectivityStatus.INVALID_ACCOUNT): "invalid_account",
str(ConnectivityStatus.MISSING_API_KEY): "missing_permanent_api_key",
str(ConnectivityStatus.FAILED): "invalid_server_details",
str(ConnectivityStatus.API_NOT_FOUND): "invalid_server_details",
}

error_id = errors.get(status)

return error_id


IGNORED_TRANSITIONS = {ConnectivityStatus.Disconnected: [ConnectivityStatus.Failed]}
IGNORED_TRANSITIONS = {ConnectivityStatus.DISCONNECTED: [ConnectivityStatus.FAILED]}
122 changes: 28 additions & 94 deletions custom_components/mydolphin_plus/common/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
MANUFACTURER = "Maytronics"
DEFAULT_NAME = "MyDolphin Plus"
DOMAIN = "mydolphin_plus"
DATA = f"{DOMAIN}_DATA"
LEGACY_KEY_FILE = f"{DOMAIN}.key"
CONFIGURATION_FILE = f"{DOMAIN}.config.json"

INVALID_TOKEN_SECTION = "https://github.com/sh00t2kill/dolphin-robot#invalid-token"

CONF_TITLE = "title"
CONF_RESET_PASSWORD = "reset_password"

SIGNAL_DEVICE_NEW = f"{DOMAIN}_NEW_DEVICE_SIGNAL"
SIGNAL_AWS_CLIENT_STATUS = f"{DOMAIN}_AWS_CLIENT_STATUS_SIGNAL"
Expand All @@ -29,37 +29,25 @@
Platform.NUMBER,
]

ATTR_EVENT = "Error"
ATTR_IS_ON = "is_on"
ATTR_FRIENDLY_NAME = "friendly_name"
ATTR_START_TIME = "start_time"
ATTR_STATUS = "status"
ATTR_RESET_FBI = "reset_fbi"
ATTR_RSSI = "RSSI"
ATTR_NETWORK_NAME = "network_name"
ATTR_INTENSITY = "intensity"
ATTR_EXPECTED_END_TIME = "expected_end_time"
ATTR_BATTERY_LEVEL = "battery_level"

ATTR_AWS_IOT_BROKER_STATUS = "aws_iot_broker_status"

ATTR_CALCULATED_STATUS = "calculated_status"
ATTR_PWS_STATUS = "pws_status"
ATTR_ROBOT_STATUS = "robot_status"
ATTR_ROBOT_TYPE = "robot_type"
ATTR_IS_BUSY = "busy"
ATTR_TURN_ON_COUNT = "turn_on_count"
ATTR_TIME_ZONE = "time_zone"

ATTR_ENABLE = "enable"
ATTR_DISABLED = "disabled"
ATTR_CALCULATED_STATUS = "Calculated State"
ATTR_POWER_SUPPLY_STATE = "Power Supply State"
ATTR_ROBOT_STATE = "Robot State"
ATTR_ROBOT_TYPE = "Robot Type"
ATTR_IS_BUSY = "Busy"
ATTR_TURN_ON_COUNT = "Turn On Count"
ATTR_TIME_ZONE = "Time Zone"

DYNAMIC_TYPE = "type"
DYNAMIC_DESCRIPTION = "description"
DYNAMIC_DESCRIPTION_JOYSTICK = "joystick"
DYNAMIC_DESCRIPTION_TEMPERATURE = "temperature"
DYNAMIC_TYPE_PWS_REQUEST = "pwsRequest"
DYNAMIC_TYPE_PWS_RESPONSE = "pwsResponse"
DYNAMIC_TYPE_IOT_RESPONSE = "iotResponse"
DYNAMIC_CONTENT = "content"
DYNAMIC_CONTENT_SERIAL_NUMBER = "robotSerial"
Expand All @@ -84,9 +72,6 @@
DATA_SECTION_WIFI = "wifi"
DATA_SECTION_CYCLE_INFO = "cycleInfo"
DATA_SECTION_FILTER_BAG_INDICATION = "filterBagIndication"
DATA_SECTION_WEEKLY_SETTINGS = "weeklySettings"
DATA_SECTION_DELAY = "delay"
DATA_SECTION_FEATURE = "featureEn"
DATA_SECTION_SYSTEM_STATE = "systemState"
DATA_SECTION_ROBOT_ERROR = "robotError"
DATA_SECTION_PWS_ERROR = "pwsError"
Expand All @@ -102,14 +87,11 @@
DATA_SYSTEM_STATE_TIME_ZONE = "timeZone"
DATA_SYSTEM_STATE_TIME_ZONE_NAME = "timeZoneName"

DATA_FEATURE_WEEKLY_TIMER = "weeklyTimer"

DATA_SCHEDULE_IS_ENABLED = "isEnabled"
DATA_SCHEDULE_CLEANING_MODE = "cleaningMode"
DATA_SCHEDULE_TIME = "time"
DATA_SCHEDULE_TIME_HOURS = "hours"
DATA_SCHEDULE_TIME_MINUTES = "minutes"
DATA_SCHEDULE_TRIGGERED_BY = "triggeredBy"

DATA_FILTER_BAG_INDICATION_RESET_FBI = "resetFBI"
DATA_FILTER_BAG_INDICATION_RESET_FBI_COMMAND = "resetFbi"
Expand All @@ -131,18 +113,18 @@
DEFAULT_ENABLE = False
DEFAULT_TIME_ZONE_NAME = "UTC"
DEFAULT_TIME_PART = 255
DEFAULT_BATTERY_LEVEL = "NA"

UPDATE_API_INTERVAL = timedelta(seconds=60)
UPDATE_ENTITIES_INTERVAL = timedelta(seconds=5)
LOCATE_OFF_INTERVAL_SECONDS = timedelta(seconds=10)
API_RECONNECT_INTERVAL = timedelta(seconds=30)
WS_RECONNECT_INTERVAL = timedelta(minutes=1)

WS_LAST_UPDATE = "last-update"

BASE_API = "https://mbapp18.maytronics.com/api"
LOGIN_URL = f"{BASE_API}/users/Login/"
EMAIL_VALIDATION_URL = f"{BASE_API}/users/isEmailExists/"
FORGOT_PASSWORD_URL = f"{BASE_API}/users/ForgotPassword/"
TOKEN_URL = f"{BASE_API}/IOT/getToken_DecryptSN/"
ROBOT_DETAILS_URL = f"{BASE_API}/serialnumbers/getrobotdetailsbymusn/"
ROBOT_DETAILS_BY_SN_URL = f"{BASE_API}/serialnumbers/getrobotdetailsbyrobotsn/"
Expand All @@ -161,6 +143,8 @@
API_RESPONSE_STATUS_SUCCESS = "1"
API_RESPONSE_UNIT_SERIAL_NUMBER = "eSERNUM"

API_RESPONSE_IS_EMAIL_EXISTS = "isEmailExists"

API_RESPONSE_DATA_TOKEN = "Token"
API_RESPONSE_DATA_ACCESS_KEY_ID = "AccessKeyId"
API_RESPONSE_DATA_SECRET_ACCESS_KEY = "SecretAccessKey"
Expand All @@ -177,9 +161,6 @@

BLOCK_SIZE = 16

MQTT_QOS_0 = 0
MQTT_QOS_1 = 1

MQTT_MESSAGE_ENCODING = "utf-8"

AWS_REGION = "eu-west-1"
Expand Down Expand Up @@ -220,7 +201,6 @@
}

ATTR_ERROR_DESCRIPTIONS = "Description"
ATTR_LED_MODE = "led_mode"
ATTR_ATTRIBUTES = "attributes"
ATTR_ACTIONS = "actions"
ATTR_INSTRUCTIONS = "instructions"
Expand Down Expand Up @@ -256,56 +236,22 @@
JOYSTICK_LEFT,
]

CLOCK_HOURS_ICONS = {
0: "mdi:clock-time-twelve",
1: "mdi:clock-time-one",
2: "mdi:clock-time-two",
3: "mdi:clock-time-three",
4: "mdi:clock-time-four",
5: "mdi:clock-time-five",
6: "mdi:clock-time-six",
7: "mdi:clock-time-seven",
8: "mdi:clock-time-eight",
9: "mdi:clock-time-nine",
10: "mdi:clock-time-ten",
11: "mdi:clock-time-eleven",
12: "mdi:clock-time-twelve",
13: "mdi:clock-time-one",
14: "mdi:clock-time-two",
15: "mdi:clock-time-three",
16: "mdi:clock-time-four",
17: "mdi:clock-time-five",
18: "mdi:clock-time-six",
19: "mdi:clock-time-seven",
20: "mdi:clock-time-eight",
21: "mdi:clock-time-nine",
22: "mdi:clock-time-ten",
23: "mdi:clock-time-eleven",
}

PWS_STATE_ON = "on"
PWS_STATE_OFF = "off"
PWS_STATE_HOLD_DELAY = "holddelay"
PWS_STATE_HOLD_WEEKLY = "holdweekly"
PWS_STATE_PROGRAMMING = "programming"
PWS_STATE_ERROR = "error"
PWS_STATE_CLEANING = "cleaning"

ROBOT_STATE_FINISHED = "finished"
ROBOT_STATE_FAULT = "fault"
ROBOT_STATE_NOT_CONNECTED = "notConnected"
ROBOT_STATE_PROGRAMMING = "programming"
ROBOT_STATE_INIT = "init"
ROBOT_STATE_SCANNING = "scanning"

CONSIDERED_POWER_STATE = {
PWS_STATE_OFF: False,
PWS_STATE_ERROR: False,
PWS_STATE_ON: True,
PWS_STATE_CLEANING: True,
PWS_STATE_PROGRAMMING: True,
ROBOT_STATE_INIT: True,
}
CLOCK_HOURS_NONE = "mdi:timer-sand-paused"
CLOCK_HOURS_ICON = "mdi:clock-time-"
CLOCK_HOURS_TEXT = [
"twelve",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
]

FILTER_BAG_STATUS = {
"unknown": (-1, -1),
Expand Down Expand Up @@ -336,22 +282,13 @@
| VacuumEntityFeature.SEND_COMMAND
| VacuumEntityFeature.START
| VacuumEntityFeature.STOP
| VacuumEntityFeature.PAUSE
| VacuumEntityFeature.TURN_ON
| VacuumEntityFeature.TURN_OFF
| VacuumEntityFeature.LOCATE
)

STORAGE_DATA_KEY = "key"
STORAGE_DATA_LOCATING = "locating"
STORAGE_DATA_AWS_TOKEN_ENCRYPTED_KEY = "aws-token-encrypted-key"

STORAGE_DATA_FILE_CONFIG = "config"

STORAGE_DATA_FILES = [STORAGE_DATA_FILE_CONFIG]

DATA_KEYS = [CONF_USERNAME, CONF_PASSWORD]

DATA_KEY_STATUS = "Status"
DATA_KEY_VACUUM = "Vacuum"
DATA_KEY_LED_MODE = "LED Mode"
Expand All @@ -361,7 +298,6 @@
DATA_KEY_CYCLE_TIME = "Cycle Time"
DATA_KEY_CYCLE_TIME_LEFT = "Cycle Time Left"
DATA_KEY_AWS_BROKER = "AWS Broker"
DATA_KEY_WEEKLY_SCHEDULER = "Weekly Scheduler"
DATA_KEY_SCHEDULE = "Schedule"
DATA_KEY_RSSI = "RSSI"
DATA_KEY_NETWORK_NAME = "Network Name"
Expand All @@ -378,10 +314,8 @@
ACTION_ENTITY_SET_FAN_SPEED = "set_fan_speed"
ACTION_ENTITY_START = "start"
ACTION_ENTITY_STOP = "stop"
ACTION_ENTITY_PAUSE = "stop"
ACTION_ENTITY_TURN_ON = "turn_on"
ACTION_ENTITY_TURN_OFF = "turn_off"
ACTION_ENTITY_TOGGLE = "toggle"
ACTION_ENTITY_SEND_COMMAND = "send_command"
ACTION_ENTITY_LOCATE = "locate"
ACTION_ENTITY_SELECT_OPTION = "select_option"
Expand Down
10 changes: 10 additions & 0 deletions custom_components/mydolphin_plus/common/power_supply_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from enum import StrEnum


class PowerSupplyState(StrEnum):
ON = "on"
OFF = "off"
HOLD_DELAY = "holdDelay"
HOLD_WEEKLY = "holdWeekly"
PROGRAMMING = "programming"
ERROR = "error"
10 changes: 10 additions & 0 deletions custom_components/mydolphin_plus/common/robot_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from enum import StrEnum


class RobotState(StrEnum):
FAULT = "fault"
NOT_CONNECTED = "notConnected"
PROGRAMMING = "programming"
INIT = "init"
SCANNING = "scanning"
FINISHED = "finished"
Loading
Loading