From 1d3d7d7aa495b4296991f61585501f7f77a488a4 Mon Sep 17 00:00:00 2001 From: aschwith Date: Tue, 12 Sep 2023 17:00:19 +0200 Subject: [PATCH] neato/vorwerk: improved user_doc; fixed error message decoding; automatically decode mapID for extraction of boundary IDs. This is needed for single room cleaning --- neato/__init__.py | 4 +- neato/assets/webif2.jpg | Bin 0 -> 51016 bytes neato/plugin.yaml | 50 +++++++++- neato/robot.py | 10 +- neato/user_doc.rst | 157 +++++++++++++++++++++++++------ neato/webif/templates/index.html | 4 +- 6 files changed, 185 insertions(+), 40 deletions(-) create mode 100644 neato/assets/webif2.jpg diff --git a/neato/__init__.py b/neato/__init__.py index bc4057bd8..c3a3d2db7 100755 --- a/neato/__init__.py +++ b/neato/__init__.py @@ -140,6 +140,9 @@ def start_robot(self, boundary_id=None, map_id=None): response = self.robot.robot_command("start", boundary_id, map_id) return self.check_command_response(response) + def get_known_mapId(self): + self.logger.warning(f"Debug: MapID is {self.robot.mapId}") + return self.robot.mapId # returns boundaryIds (clean zones) for given mapID # returns True on success and False otherwise @@ -151,7 +154,6 @@ def dismiss_current_alert(self): response = self.robot.robot_command("dismiss_current_alert") return self.check_command_response(response) - # enable cleaning schedule # returns True on success and False otherwise def enable_schedule(self): diff --git a/neato/assets/webif2.jpg b/neato/assets/webif2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9611a32d771ff2705a4779481c4eeb91791a9113 GIT binary patch literal 51016 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 literal 0 HcmV?d00001 diff --git a/neato/plugin.yaml b/neato/plugin.yaml index 0d77baf71..c499cbe43 100755 --- a/neato/plugin.yaml +++ b/neato/plugin.yaml @@ -98,9 +98,53 @@ item_attributes: - command_startAvailable - clean_room -item_structs: NONE - # Definition of item-structure templates for this plugin (enter 'item_structs: NONE', if section should be empty) - #item_structs: NONE +item_structs: + Neato: + Name: + type: str + neato_attribute: 'name' + visu_acl: ro + State: + type: str + value: 'offline' + neato_attribute: 'state' + visu_acl: ro + StateAction: + type: str + neato_attribute: 'state_action' + visu_acl: ro + Command: + type: num + neato_attribute: 'command' + visu_acl: rw + IsDocked: + value: False + type: bool + neato_attribute: 'is_docked' + visu_acl: ro + IsScheduleEnabled: + value: False + type: bool + neato_attribute: 'is_schedule_enabled' + visu_acl: rw + IsCharging: + value: False + type: bool + neato_attribute: 'is_charging' + visu_acl: ro + ChargePercentage: + type: num + neato_attribute: 'charge_percentage' + visu_acl: ro + GoToBaseAvailable: + type: bool + value: False + neato_attribute: 'command_goToBaseAvailable' + visu_acl: ro + Alert: + type: str + neato_attribute: 'alert' + visu_acl: ro plugin_functions: enable_schedule: diff --git a/neato/robot.py b/neato/robot.py index ed68aa0df..d40f3d872 100755 --- a/neato/robot.py +++ b/neato/robot.py @@ -44,6 +44,7 @@ def __init__(self, email, password, vendor, token = ''): self.navigationMode = '' self.spotWidth = '' self.spotHeight = '' + self.mapId = 'unknown' # Meta self.name = "" @@ -158,13 +159,13 @@ def robot_command(self, command, arg1 = None, arg2 = None): self.logger.warning(f"Command returned {str(responseJson['result'])}: Retry starting with non-persistent-map") return self.robot_command(command = 'start_non-persistent-map') else: - self.logger.error("Sending command {command} failed. Result: {0}".format(str(responseJson['result']) )) - self.logger.error("Debug: send command response: {0}".format(start_cleaning_response.text)) + self.logger.error(f"Sending command {command} failed. Result: {str(responseJson['result'])}") + self.logger.error(f"Debug: send command response: {start_cleaning_response.text}") else: if 'message' in responseJson: - self.logger.error("Sending command {command} failed. Message: {0}".format(str(responseJson['message']))) + self.logger.error(f"Sending command {command} failed. Message: {str(responseJson['message'])}") if 'error' in responseJson: - self.logger.error("Sending command {command} failed. Error: {0}".format(str(responseJson['error']))) + self.logger.error(f"Sending command {command} failed. Error: {str(responseJson['error'])}") # - NOT on Charge BASE return start_cleaning_response @@ -286,6 +287,7 @@ def update_robot(self): self.navigationMode = response['cleaning']['navigationMode'] self.spotWidth = response['cleaning']['spotWidth'] self.spotHeight = response['cleaning']['spotHeight'] + self.mapId = response['cleaning']['mapId'] return response diff --git a/neato/user_doc.rst b/neato/user_doc.rst index e15714cfe..ccd0a315f 100755 --- a/neato/user_doc.rst +++ b/neato/user_doc.rst @@ -21,21 +21,102 @@ Die Informationen zur Konfiguration des Plugins sind unter :doc:`/plugins_doc/co Anforderungen ============= -- locale en_US.utf8 must be installed (sudo dpkg-reconfigure locales) - -Supported Hardware -================== - -=============== ========= ====== -Robot Supported Tested -=============== ========= ====== -Neato Botvac D3 yes no -Neato Botvac D4 yes no -Neato Botvac D5 yes yes -Neato Botvac D6 yes no -Neato Botvac D7 yes no -Vorwerk VR300 yes yes -=============== ========= ====== +1) Es muss auf dem SmarthomeNG Rechcner en_US.utf8 installiert sein (sudo dpkg-reconfigure locales) + +Unterstützte Hardware +===================== + +=============== ============= ========== +Roboter Unterstützt Getestet +=============== ============= ========== +Neato Botvac D3 ja nein +Neato Botvac D4 ja nein +Neato Botvac D5 ja ja +Neato Botvac D6 ja nein +Neato Botvac D7 ja nein +Vorwerk VR300 ja ja +=============== ============= ========== + + +Unterstützte Plugin Attribute +============================= + +Folgende Item Attribute (neato_attribute) werden vom Plugin unterstützt: + +=================== ========= ===================== +Attribut Itemtyp Lesend/Schreibend +=================== ========= ===================== +name str r +state str r +state_action str r +command num w +is_docked bool r +is_schedule_enabled bool r +is_charging bool r +charge_percentage num r +command_goToBaseAvailable bool r +alert str r +clean_room str w +=================== ========= ===================== + + + +Roboter Status +============== + +Das String Item für den Roboterstatus (state) kann folgende Zustände einnehmen: + +===================== +Roboterstatus (state) +===================== +invalid +invalid +idle +busy +paused +error +=============== + +Das Num Item für den Roboterzustand (state_action) kann folgende Zustände einnehmen: + +============================= ========= +Roboterzustand (state_action) dezimal +============================= ========= +Invalid 0 +House Cleaning 1 +Spot Cleaning 2 +Manual Cleaning 3 +Docking 4 +User Menu Active 5 +Suspended Cleaning 6 +Updating 7 +Copying Logs 8 +Recovering Location 9 +IEC Test 10 +Map cleaning 11 +Exploring map (creating a persistent map) 12 +Acquiring Persistent Map IDs 13 +Creating & Uploading Map 14 +Suspended Exploration 15 +============================= ========= + +Roboter Befehle +=============== + +Das Num Item für die Roboterbefehle (command) kann folgende Zustände einnehmen: + +============================= ========= +Befehl (command) dezimal +============================= ========= +Start cleaning 61 +Stop cleaning 62 +Pause cleaning 63 +Resume cleaning 64 +Find the robot 65 +Send to base 66 +Enable schedule 67 +Disable schedule 68 +============================= ========= Web Interface @@ -70,26 +151,42 @@ Im ersten Tab Vorwerk OAuth2 findet sich direkt die Schritt für Schritt Anleitu .. image:: assets/webif1.jpg :class: screenshot -Changelog +Im zweiten Tab Einstellungen findet sich zwei Optionen zum Löschen von gemeldeten Alarmmeldungen (z.B. Roboter Behälter leeren) und zum Auslesen aller bekannter RaumIDs (BoundardyIDs) zur +Einzelraumreinigung. Die bekannten Räume werden dazu in das Plugin Logfile geschrieben. Übergeben werden muss hierzu die Vorwerk MapID. Hierzu einmal manuell eine Einzelraumreinigung via Vorwerk/Neato +App anstoßen. Das Plugin extrahiert anschließend automatisch den Namen der MapID und schlägt diese als Eingabe im Eingabefeld des Webinterfaces vor. + +.. image:: assets/webif2.jpg + :class: screenshot + + +SmartVisu +========= + +Beispiele --------- -V1.6.8 added decoding of command availability status, e.g. "start" command available - If start command with persistent map is rejected due to "not_on_charge_base" error, retry start with non-persistent map. -V1.6.6 added option to clear errors/alarms in neato/vorwerk backend via plugin's webif +Beispiele für Integrationen in smartVisu: + +.. code-block:: html + +

{{ basic.button('RobotButton_Start', 'Neato.Robot.Command', 'Start', '', '61', 'midi') }}

+

{{ basic.button('RobotButton_Stop', 'Neato.Robot.Command', 'Stop', '', '62', 'midi') }}

+

{{ basic.button('RobotButton_Pause', 'Neato.Robot.Command', 'Pause', '', '63', 'midi') }}

+

{{ basic.button('RobotButton_Resume', 'Neato.Robot.Command', 'Resume', '', '64', 'midi') }}

+

{{ basic.button('RobotButton_Find', 'Neato.Robot.Command', 'Find', '', '65', 'midi') }}

-V1.6.5 added new function start_robot(boundary_id=None, map_id=None) to enable single room cleaning - added new function get_map_boundaries_robot(map_id=None) to request available map boundaries (rooms) for a given map - added new function dismiss_current_alert() to reset current alerts +

Name: {{ basic.value('RobotName', 'Neato.Robot.Name') }}

+ /** Get the robots name (str)*/ -V 1.6.4 fixed readout for docking state and go to base availability - combined all neato attribues into one +

Cleaning status: {{ basic.value('RobotState', 'Neato.Robot.State') }}

+ /** Get the robots cleaning status (str) */ -V 1.6.3 changed attribute charge_percentage from string to integer - added alert text output, e.g. dustbin full - Write obtained OAuth2 token obtained via web interface directly to config plugin.yaml +

Cleaning status action: {{ basic.value('RobotStateAction', 'Neato.Robot.StateAction') }}

+ /** Get the robots cleaning status action (str). Only when it's busy */ -V 1.6.2 Added webinterface +

Docking status: {{ basic.value('RobotDockingStatus', 'Neato.Robot.IsDocked') }}

+ /** Get the robots docking status (bool) */ -V 1.6.1 Added new Vorwerk Oauth2 based authentication feature (compatible with myKobold APP) +

Battery status: {{ basic.value('RobotBatteryState', 'Neato.Robot.ChargePercentage') }}

+ /** Get the robots battery charge status (num) */ -V 1.6.0 Initial working version diff --git a/neato/webif/templates/index.html b/neato/webif/templates/index.html index 564762495..552e2b38a 100755 --- a/neato/webif/templates/index.html +++ b/neato/webif/templates/index.html @@ -340,9 +340,9 @@ {{ _('Verfuegbare Boundary IDs (Raeume) ins Log schreiben') }}
- +
-