From 21fa9acdc5f82e82257c3c1987ce54a59b44d2c9 Mon Sep 17 00:00:00 2001 From: Michael Arthur Date: Thu, 19 Sep 2024 11:13:20 +1200 Subject: [PATCH 1/4] add service for starting a mow --- custom_components/mammotion/__init__.py | 15 +- custom_components/mammotion/coordinator.py | 3 +- custom_components/mammotion/manifest.json | 2 +- custom_components/mammotion/services.yaml | 150 ++++++++++++++++++ custom_components/mammotion/strings.json | 92 +++++++++++ custom_components/mammotion/switch.py | 2 +- .../mammotion/translations/en.json | 92 +++++++++++ 7 files changed, 352 insertions(+), 4 deletions(-) create mode 100644 custom_components/mammotion/services.yaml diff --git a/custom_components/mammotion/__init__.py b/custom_components/mammotion/__init__.py index aa97cc5..9c18041 100644 --- a/custom_components/mammotion/__init__.py +++ b/custom_components/mammotion/__init__.py @@ -4,8 +4,11 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ADDRESS, CONF_MAC, Platform -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.helpers import device_registry as dr +from pymammotion.data.model.device_config import OperationSettings + +SERVICE_START_MOWING = "start_mow" from .const import ( CONF_AEP_DATA, @@ -16,6 +19,7 @@ CONF_SESSION_DATA, CONF_USE_WIFI, DEFAULT_RETRY_COUNT, + DOMAIN, ) from .coordinator import MammotionDataUpdateCoordinator @@ -78,6 +82,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: MammotionConfigEntry) -> entry.runtime_data = mammotion_coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) + async def async_start_mowing(service: ServiceCall) -> None: + operation_settings = OperationSettings.from_dict(service.data) + mammotion_coordinator._operation_settings = operation_settings + await mammotion_coordinator.async_plan_route() + await mammotion_coordinator.async_send_command("start_job") + await mammotion_coordinator.async_request_iot_sync() + + hass.services.async_register(DOMAIN, SERVICE_START_MOWING, async_start_mowing) + return True diff --git a/custom_components/mammotion/coordinator.py b/custom_components/mammotion/coordinator.py index 3a2bd66..0850bda 100644 --- a/custom_components/mammotion/coordinator.py +++ b/custom_components/mammotion/coordinator.py @@ -274,7 +274,8 @@ async def async_plan_route(self) -> None: speed=self._operation_settings.speed, ultra_wave=self._operation_settings.ultra_wave, # touch no touch etc toward=self._operation_settings.toward, # is just angle - toward_included_angle=self._operation_settings.toward_included_angle, # angle type relative etc + toward_included_angle=self._operation_settings.toward_included_angle, # angle relative to grid?? + toward_mode=self._operation_settings.toward_mode, blade_height=self._operation_settings.blade_height, channel_mode=self._operation_settings.channel_mode, # line mode is grid single double or single2 channel_width=self._operation_settings.channel_width, diff --git a/custom_components/mammotion/manifest.json b/custom_components/mammotion/manifest.json index 96e363e..600455a 100644 --- a/custom_components/mammotion/manifest.json +++ b/custom_components/mammotion/manifest.json @@ -1,7 +1,7 @@ { "domain": "mammotion", "name": "Mammotion", - "version": "0.1.38", + "version": "0.1.38-alpha", "issue_tracker": "https://github.com/mikey0000/Mammotion-HA/issues", "integration_type": "device", "bluetooth": [ diff --git a/custom_components/mammotion/services.yaml b/custom_components/mammotion/services.yaml new file mode 100644 index 0000000..f3698cc --- /dev/null +++ b/custom_components/mammotion/services.yaml @@ -0,0 +1,150 @@ +start_mow: + fields: + is_mow: + example: true + default: true + required: true + is_dump: + example: true + default: true + required: true + is_edge: + example: false + default: false + required: false + collect_grass_frequency: + example: 10 + default: 10 + required: false + job_mode: + example: 0 + default: 0 + required: true + selector: + select: + options: + - value: 0 + label: "Single Grid" + - value: 1 + label: "Double Grid" + - value: 2 + label: "Segment Grid" + - value: 3 + label: "No Grid" + job_version: + example: 0 + default: 0 + required: false + job_id: + example: 0 + default: 0 + required: false + speed: + example: 0.3 + default: 0.3 + required: false + ultra_wave: + example: 2 + default: 2 + selector: + select: + options: + - value: 0 + label: "Direct Touch" + - value: 1 + label: "Slow Touch" + - value: 2 + label: "Less Touch" + - value: 10 + label: "No Touch" + required: false + channel_mode: + example: 0 + default: 0 + required: false + channel_width: + example: 25 + default: 25 + required: false + rain_tactics: + example: 0 + default: 1 + required: false + blade_height: + example: 0 + default: 25 + required: false + path_order: + example: 0 + default: 0 + selector: + select: + options: + - value: 0 + label: "Border First" + - value: 1 + label: "Grid First" + required: false + toward: + example: 0 + default: 0 + required: false + toward_included_angle: + example: 0 + default: 0 + required: false + toward_mode: + example: 0 + default: 0 + selector: + select: + options: + - value: 0 + label: "Relative Angle" + - value: 1 + label: "Absolute Angle" + - value: 2 + label: "Random Angle" + required: false + border_mode: + example: 1 + default: 1 + selector: + select: + options: + - value: 0 + label: "None" + - value: 1 + label: "One Lap" + - value: 2 + label: "Two Laps" + - value: 3 + label: "Three Laps" + - value: 4 + label: "Four Laps" + required: false + obstacle_laps: + example: 1 + default: 1 + selector: + select: + options: + - value: 0 + label: "None" + - value: 1 + label: "One Lap" + - value: 2 + label: "Two Laps" + - value: 3 + label: "Three Laps" + - value: 4 + label: "Four Laps" + required: false + start_progress: + example: 0 + default: 0 + required: false + areas: + example: [1256568344, 2234234523, 32345235234] + default: [] + required: false diff --git a/custom_components/mammotion/strings.json b/custom_components/mammotion/strings.json index 272b35b..3d9deef 100644 --- a/custom_components/mammotion/strings.json +++ b/custom_components/mammotion/strings.json @@ -141,6 +141,98 @@ } } }, + "services": { + "start_mow": { + "name": "Start Mowing", + "description": "Start the mowing operation with custom settings.", + "fields": { + "is_mow": { + "name": "Is Mow", + "description": "Whether mowing is active." + }, + "is_dump": { + "name": "Is Dump", + "description": "Whether grass dumping is active." + }, + "is_edge": { + "name": "Is Edge", + "description": "Whether edge mode is active." + }, + "collect_grass_frequency": { + "name": "Grass Collection Frequency", + "description": "Frequency to collect grass (in minutes)." + }, + "job_mode": { + "name": "Job Mode", + "description": "Job mode for cutting." + }, + "job_version": { + "name": "Job Version", + "description": "Job version." + }, + "job_id": { + "name": "Job ID", + "description": "Job ID." + }, + "speed": { + "name": "Speed", + "description": "Mowing speed." + }, + "ultra_wave": { + "name": "Ultra Wave", + "description": "Bypass strategy for mowing." + }, + "channel_mode": { + "name": "Channel Mode", + "description": "Channel mode (grid, single, double, or single2)." + }, + "channel_width": { + "name": "Channel Width", + "description": "Width of the mowing channel (in cm)." + }, + "rain_tactics": { + "name": "Rain Tactics", + "description": "Rain handling tactics." + }, + "blade_height": { + "name": "Blade Height", + "description": "Height of the blade." + }, + "path_order": { + "name": "Path Order", + "description": "Mowing path order (border first or grid first)." + }, + "toward": { + "name": "Toward", + "description": "Direction angle for mowing." + }, + "toward_included_angle": { + "name": "Toward Included Angle", + "description": "Type of angle to use (relative, absolute, or random)." + }, + "toward_mode": { + "name": "Toward Mode", + "description": "Toward mode." + }, + "border_mode": { + "name": "Border Patrol Mode", + "description": "Border patrol mode (number of laps)." + }, + "obstacle_laps": { + "name": "Obstacle Laps", + "description": "Number of laps around obstacles." + }, + "start_progress": { + "name": "Start Progress", + "description": "Starting progress percentage." + }, + "areas": { + "name": "Areas", + "description": "List of areas to mow (represented as integers)." + } + } + } + }, "exceptions": { "device_not_ready": { "message": "Device is not ready." diff --git a/custom_components/mammotion/switch.py b/custom_components/mammotion/switch.py index f8983ee..b251883 100644 --- a/custom_components/mammotion/switch.py +++ b/custom_components/mammotion/switch.py @@ -86,7 +86,7 @@ async def async_setup_entry( ) -> None: """Set up the Mammotion switch entities.""" coordinator = entry.runtime_data - added_areas: set[int] = set() + added_areas: set[str] = set() @callback def add_entities() -> None: diff --git a/custom_components/mammotion/translations/en.json b/custom_components/mammotion/translations/en.json index 8bb9fc7..95acbbb 100644 --- a/custom_components/mammotion/translations/en.json +++ b/custom_components/mammotion/translations/en.json @@ -238,6 +238,98 @@ "name": "Device Tracking" } }, + "services": { + "start_mow": { + "name": "Start Mowing", + "description": "Start the mowing operation with custom settings.", + "fields": { + "is_mow": { + "name": "Is Mow", + "description": "Whether mowing is active." + }, + "is_dump": { + "name": "Is Dump", + "description": "Whether grass dumping is active." + }, + "is_edge": { + "name": "Is Edge", + "description": "Whether edge mode is active." + }, + "collect_grass_frequency": { + "name": "Grass Collection Frequency", + "description": "Frequency to collect grass (in minutes)." + }, + "job_mode": { + "name": "Job Mode", + "description": "Job mode for cutting." + }, + "job_version": { + "name": "Job Version", + "description": "Job version." + }, + "job_id": { + "name": "Job ID", + "description": "Job ID." + }, + "speed": { + "name": "Speed", + "description": "Mowing speed." + }, + "ultra_wave": { + "name": "Obstacle Detection", + "description": "Bypass strategy for mowing." + }, + "channel_mode": { + "name": "Channel Mode", + "description": "Channel mode (grid, single, double, or single2)." + }, + "channel_width": { + "name": "Channel Width", + "description": "Width of the mowing channel (in cm)." + }, + "rain_tactics": { + "name": "Rain Detection", + "description": "Rain detection." + }, + "blade_height": { + "name": "Blade Height", + "description": "Height of the blade." + }, + "path_order": { + "name": "Path Order", + "description": "Mowing path order (border first or grid first)." + }, + "toward": { + "name": "Angle", + "description": "Direction angle for mowing." + }, + "toward_included_angle": { + "name": "Angle Relative to Grid?", + "description": "Type of angle to use (relative, absolute, or random)." + }, + "toward_mode": { + "name": "Direction Mode", + "description": "Toward mode." + }, + "border_mode": { + "name": "Border Patrol Mode", + "description": "Border patrol mode (number of laps)." + }, + "obstacle_laps": { + "name": "Obstacle Laps", + "description": "Number of laps around obstacles." + }, + "start_progress": { + "name": "Start Progress", + "description": "Starting progress percentage." + }, + "areas": { + "name": "Areas", + "description": "List of areas to mow (represented as integers)." + } + } + } + }, "exceptions": { "device_not_ready": { "message": "Device is not ready." From 7914f01ad1c60c201b6bc0f69b75a975f89aa48a Mon Sep 17 00:00:00 2001 From: Michael Arthur Date: Thu, 19 Sep 2024 12:35:08 +1200 Subject: [PATCH 2/4] set a better default also fixes error with index which does exist --- custom_components/mammotion/switch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/mammotion/switch.py b/custom_components/mammotion/switch.py index b251883..7a485dc 100644 --- a/custom_components/mammotion/switch.py +++ b/custom_components/mammotion/switch.py @@ -97,11 +97,11 @@ def add_entities() -> None: area_name = coordinator.data.map.area_name new_areas = areas - added_areas if new_areas: - for index, area_id in new_areas: + for area_id in new_areas: existing_name: AreaHashName = next( (area for area in area_name if area.hash.__str__() == area_id), None ) - name = existing_name.name if existing_name else f"area {index+1}" + name = existing_name.name if existing_name else f"mowing area {area_id}" base_area_switch_entity = MammotionConfigAreaSwitchEntityDescription( key=f"{area_id}", area=area_id, From e3e5fd427efe9b72fcb1b4969ad9762ac3c68cdb Mon Sep 17 00:00:00 2001 From: Michael Arthur Date: Thu, 19 Sep 2024 13:05:14 +1200 Subject: [PATCH 3/4] add hash as an attribute so users can find it. --- custom_components/mammotion/switch.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/mammotion/switch.py b/custom_components/mammotion/switch.py index 7a485dc..61728c5 100644 --- a/custom_components/mammotion/switch.py +++ b/custom_components/mammotion/switch.py @@ -216,6 +216,7 @@ def __init__( self.coordinator = coordinator self.entity_description = entity_description self._attr_translation_key = entity_description.key + self._attr_extra_state_attributes = {"hash": entity_description.area} # TODO grab defaults from operation_settings self._attr_is_on = False # Default state From 8e0ce28c188ddd212c6686379e13014ece2001aa Mon Sep 17 00:00:00 2001 From: Michael Arthur Date: Thu, 19 Sep 2024 18:17:16 +1200 Subject: [PATCH 4/4] service call to start a mow with all the options --- custom_components/mammotion/__init__.py | 15 +-- custom_components/mammotion/coordinator.py | 30 +++--- custom_components/mammotion/lawn_mower.py | 97 +++++++++++++++++-- custom_components/mammotion/services.yaml | 96 ++++++++++++++---- .../mammotion/translations/en.json | 12 +-- 5 files changed, 191 insertions(+), 59 deletions(-) diff --git a/custom_components/mammotion/__init__.py b/custom_components/mammotion/__init__.py index 9c18041..c792035 100644 --- a/custom_components/mammotion/__init__.py +++ b/custom_components/mammotion/__init__.py @@ -4,11 +4,8 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ADDRESS, CONF_MAC, Platform -from homeassistant.core import HomeAssistant, ServiceCall +from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr -from pymammotion.data.model.device_config import OperationSettings - -SERVICE_START_MOWING = "start_mow" from .const import ( CONF_AEP_DATA, @@ -82,14 +79,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: MammotionConfigEntry) -> entry.runtime_data = mammotion_coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) - async def async_start_mowing(service: ServiceCall) -> None: - operation_settings = OperationSettings.from_dict(service.data) - mammotion_coordinator._operation_settings = operation_settings - await mammotion_coordinator.async_plan_route() - await mammotion_coordinator.async_send_command("start_job") - await mammotion_coordinator.async_request_iot_sync() - - hass.services.async_register(DOMAIN, SERVICE_START_MOWING, async_start_mowing) + # need to register service for triggering tasks + # hass.services.async_register(DOMAIN, SERVICE_START_tASK, async_start_mowing) return True diff --git a/custom_components/mammotion/coordinator.py b/custom_components/mammotion/coordinator.py index 0850bda..57d0bff 100644 --- a/custom_components/mammotion/coordinator.py +++ b/custom_components/mammotion/coordinator.py @@ -266,23 +266,23 @@ async def async_send_command(self, command: str, **kwargs: Any) -> None: translation_domain=DOMAIN, translation_key="command_failed" ) from exc - async def async_plan_route(self) -> None: + async def async_plan_route(self, operation_settings: OperationSettings) -> None: """Plan mow.""" route_information = GenerateRouteInformation( - one_hashs=self._operation_settings.areas, - rain_tactics=self._operation_settings.rain_tactics, - speed=self._operation_settings.speed, - ultra_wave=self._operation_settings.ultra_wave, # touch no touch etc - toward=self._operation_settings.toward, # is just angle - toward_included_angle=self._operation_settings.toward_included_angle, # angle relative to grid?? - toward_mode=self._operation_settings.toward_mode, - blade_height=self._operation_settings.blade_height, - channel_mode=self._operation_settings.channel_mode, # line mode is grid single double or single2 - channel_width=self._operation_settings.channel_width, - job_mode=self._operation_settings.job_mode, # taskMode - edge_mode=self._operation_settings.border_mode, # border laps - path_order=create_path_order(self._operation_settings, self.device_name), - obstacle_laps=self._operation_settings.obstacle_laps, + one_hashs=operation_settings.areas, + rain_tactics=operation_settings.rain_tactics, + speed=operation_settings.speed, + ultra_wave=operation_settings.ultra_wave, # touch no touch etc + toward=operation_settings.toward, # is just angle + toward_included_angle=operation_settings.toward_included_angle, # angle relative to grid?? + toward_mode=operation_settings.toward_mode, + blade_height=operation_settings.blade_height, + channel_mode=operation_settings.channel_mode, # line mode is grid single double or single2 + channel_width=operation_settings.channel_width, + job_mode=operation_settings.job_mode, # taskMode + edge_mode=operation_settings.border_mode, # border laps + path_order=create_path_order(operation_settings, self.device_name), + obstacle_laps=operation_settings.obstacle_laps, ) await self.async_send_command( diff --git a/custom_components/mammotion/lawn_mower.py b/custom_components/mammotion/lawn_mower.py index 799b897..548b97c 100644 --- a/custom_components/mammotion/lawn_mower.py +++ b/custom_components/mammotion/lawn_mower.py @@ -2,6 +2,9 @@ from __future__ import annotations +from typing import Any + +import voluptuous as vol from homeassistant.components.lawn_mower import ( LawnMowerActivity, LawnMowerEntity, @@ -9,7 +12,10 @@ ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers import config_validation as cv +from homeassistant.helpers import entity_platform from homeassistant.helpers.entity_platform import AddEntitiesCallback +from pymammotion.data.model.device_config import OperationSettings from pymammotion.data.model.report_info import ReportData from pymammotion.proto import has_field from pymammotion.proto.luba_msg import RptDevStatus @@ -20,6 +26,61 @@ from .coordinator import MammotionDataUpdateCoordinator from .entity import MammotionBaseEntity +SERVICE_START_MOWING = "start_mow" + +START_MOW_SCHEMA = { + vol.Optional("is_mow", default=True): cv.boolean, + vol.Optional("is_dump", default=True): cv.boolean, + vol.Optional("is_edge", default=False): cv.boolean, + vol.Optional("collect_grass_frequency", default=10): vol.All( + vol.Coerce(int), vol.Range(min=5, max=100) + ), + vol.Optional("job_mode", default=0): vol.Coerce(int), + vol.Optional("job_version", default=0): vol.Coerce(int), + vol.Optional("job_id", default=0): vol.Coerce(int), + vol.Optional("speed", default=0.3): vol.All( + vol.Coerce(float), vol.Range(min=0.2, max=1.2) + ), + vol.Optional("ultra_wave", default=2): vol.In([0, 1, 2, 10]), + vol.Optional("channel_mode", default=0): vol.In([0, 1, 2, 3]), + vol.Optional("channel_width", default=25): vol.All( + vol.Coerce(int), vol.Range(min=20, max=35) + ), + vol.Optional("rain_tactics", default=1): vol.In([0, 1]), + vol.Optional("blade_height", default=25): vol.All( + vol.Coerce(int), vol.Range(min=15, max=100) + ), + vol.Optional("path_order", default=0): vol.In([0, 1]), + vol.Optional("toward", default=0): vol.All( + vol.Coerce(int), vol.Range(min=-180, max=180) + ), + vol.Optional("toward_included_angle", default=0): vol.All( + vol.Coerce(int), vol.Range(min=-180, max=180) + ), + vol.Optional("toward_mode", default=0): vol.In([0, 1, 2]), + vol.Optional("border_mode", default=1): vol.In([0, 1, 2, 3, 4]), + vol.Optional("obstacle_laps", default=1): vol.In([0, 1, 2, 3, 4]), + vol.Optional("start_progress", default=0): vol.All( + vol.Coerce(int), vol.Range(min=0, max=100) + ), + vol.Required("areas"): vol.All( + cv.ensure_list, [cv.entity_id] + ), # This assumes `areas` are entity IDs from the integration +} + + +def get_entity_attribute(hass, entity_id, attribute_name): + # Get the state object of the entity + entity = hass.states.get(entity_id) + + # Check if the entity exists and has attributes + if entity and attribute_name in entity.attributes: + # Return the specific attribute + return entity.attributes[attribute_name] + else: + # Return None if the entity or attribute does not exist + return None + async def async_setup_entry( hass: HomeAssistant, @@ -30,6 +91,12 @@ async def async_setup_entry( coordinator = entry.runtime_data async_add_entities([MammotionLawnMowerEntity(coordinator)]) + platform = entity_platform.async_get_current_platform() + + platform.async_register_entity_service( + SERVICE_START_MOWING, START_MOW_SCHEMA, "async_start_mowing" + ) + class MammotionLawnMowerEntity(MammotionBaseEntity, LawnMowerEntity): """Representation of a Mammotion lawn mower.""" @@ -81,8 +148,24 @@ def activity(self) -> LawnMowerActivity | None: return LawnMowerActivity.DOCKED return None - async def async_start_mowing(self) -> None: + async def async_start_mowing(self, **kwargs: Any) -> None: """Start mowing.""" + if kwargs: + entity_ids = kwargs.get("areas", []) + + attributes = [ + get_entity_attribute(self.hass, entity_id, "hash") + for entity_id in entity_ids + if get_entity_attribute(self.hass, entity_id, "hash") is not None + ] + kwargs["areas"] = attributes + operational_settings = OperationSettings.from_dict(kwargs) + LOGGER.debug(kwargs) + await self.coordinator.async_plan_route(operational_settings) + await self.coordinator.async_send_command("start_job") + await self.coordinator.async_request_iot_sync() + return + # check if job in progress # if self.rpt_dev_status is None: @@ -91,9 +174,9 @@ async def async_start_mowing(self) -> None: ) work_area = self.report_data.work.area >> 16 - if work_area > 0 and ( - self.rpt_dev_status.sys_status == WorkMode.MODE_PAUSE - or self.rpt_dev_status.sys_status == WorkMode.MODE_READY + if work_area > 0 and self.rpt_dev_status.sys_status in ( + WorkMode.MODE_PAUSE, + WorkMode.MODE_READY, ): try: await self.coordinator.async_send_command("resume_execute_task") @@ -103,17 +186,13 @@ async def async_start_mowing(self) -> None: translation_domain=DOMAIN, translation_key="resume_failed" ) from exc try: - await self.coordinator.async_plan_route() + await self.coordinator.async_plan_route(self.coordinator.operation_settings) await self.coordinator.async_send_command("start_job") await self.coordinator.async_request_iot_sync() except COMMAND_EXCEPTIONS as exc: raise HomeAssistantError( translation_domain=DOMAIN, translation_key="start_failed" ) from exc - finally: - self.coordinator.async_set_updated_data( - self.coordinator.manager.mower(self.coordinator.device_name) - ) async def async_dock(self) -> None: """Start docking.""" diff --git a/custom_components/mammotion/services.yaml b/custom_components/mammotion/services.yaml index f3698cc..46cc241 100644 --- a/custom_components/mammotion/services.yaml +++ b/custom_components/mammotion/services.yaml @@ -1,48 +1,65 @@ start_mow: + target: + entity: + integration: mammotion + domain: lawn_mower fields: is_mow: example: true default: true - required: true + required: false + selector: + boolean: is_dump: example: true default: true - required: true + required: false + selector: + boolean: is_edge: example: false default: false required: false + selector: + boolean: collect_grass_frequency: example: 10 default: 10 required: false + selector: + number: + min: 5 + max: 100 + unit_of_measurement: "m²" job_mode: example: 0 default: 0 - required: true + required: false selector: - select: - options: - - value: 0 - label: "Single Grid" - - value: 1 - label: "Double Grid" - - value: 2 - label: "Segment Grid" - - value: 3 - label: "No Grid" + number: job_version: example: 0 default: 0 required: false + selector: + number: job_id: example: 0 default: 0 required: false + selector: + number: speed: example: 0.3 default: 0.3 required: false + selector: + number: + min: 0.2 + max: 1.2 + step: 0.1 + mode: box + unit_of_measurement: "m/s" ultra_wave: example: 2 default: 2 @@ -62,18 +79,45 @@ start_mow: example: 0 default: 0 required: false + selector: + select: + options: + - value: 0 + label: "Single Grid" + - value: 1 + label: "Double Grid" + - value: 2 + label: "Segment Grid" + - value: 3 + label: "No Grid" channel_width: example: 25 default: 25 required: false + selector: + number: + min: 20 + max: 35 rain_tactics: - example: 0 + example: 1 default: 1 required: false + selector: + options: + - value: 0 + label: "Off" + - value: 1 + label: "On" blade_height: example: 0 default: 25 required: false + selector: + number: + min: 15 + max: 100 + step: 5 + unit_of_measurement: "cm" path_order: example: 0 default: 0 @@ -89,10 +133,20 @@ start_mow: example: 0 default: 0 required: false + selector: + number: + min: -180 + max: 180 + unit_of_measurement: degrees toward_included_angle: example: 0 default: 0 required: false + selector: + number: + min: -180 + max: 180 + unit_of_measurement: degrees toward_mode: example: 0 default: 0 @@ -144,7 +198,15 @@ start_mow: example: 0 default: 0 required: false + selector: + number: + min: 0 + max: 100 + unit_of_measurement: "%" areas: - example: [1256568344, 2234234523, 32345235234] - default: [] - required: false + required: true + selector: + entity: + multiple: true + integration: mammotion + domain: switch diff --git a/custom_components/mammotion/translations/en.json b/custom_components/mammotion/translations/en.json index 95acbbb..cdca1eb 100644 --- a/custom_components/mammotion/translations/en.json +++ b/custom_components/mammotion/translations/en.json @@ -245,19 +245,19 @@ "fields": { "is_mow": { "name": "Is Mow", - "description": "Whether mowing is active." + "description": "Whether mowing is active. (Yuka)" }, "is_dump": { "name": "Is Dump", - "description": "Whether grass dumping is active." + "description": "Whether grass dumping is active. (Yuka)" }, "is_edge": { "name": "Is Edge", - "description": "Whether edge mode is active." + "description": "Whether edge mode is active. (Yuka)" }, "collect_grass_frequency": { "name": "Grass Collection Frequency", - "description": "Frequency to collect grass (in minutes)." + "description": "Frequency to collect grass (in meters squared). (Yuka)" }, "job_mode": { "name": "Job Mode", @@ -305,11 +305,11 @@ }, "toward_included_angle": { "name": "Angle Relative to Grid?", - "description": "Type of angle to use (relative, absolute, or random)." + "description": "When selecting grid change the second angle." }, "toward_mode": { "name": "Direction Mode", - "description": "Toward mode." + "description": "Angle mode." }, "border_mode": { "name": "Border Patrol Mode",