From a0733a6997b271e447b680d5c7fac28361e9661d Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sat, 18 Nov 2023 13:09:56 +0100 Subject: [PATCH 01/15] updates Valetudo Vacuum Camera - Topic internal variable autogenerated. - rand256 and hypfer templates updated for predefined zones and points --- src/hypfer_valetudo.json | 130 +++++++++++++++++++++++++++++++ src/rand256_valetudo_re.json | 142 ++++++++++++++++++++++++++++++++++ src/xiaomi-vacuum-map-card.ts | 53 +++++++++---- 3 files changed, 312 insertions(+), 13 deletions(-) create mode 100644 src/hypfer_valetudo.json create mode 100644 src/rand256_valetudo_re.json diff --git a/src/hypfer_valetudo.json b/src/hypfer_valetudo.json new file mode 100644 index 00000000..27f3a040 --- /dev/null +++ b/src/hypfer_valetudo.json @@ -0,0 +1,130 @@ +{ + "map_modes": { + "default_templates": [ + "vacuum_clean_zone", + "vacuum_goto" + ], + "templates": { + "vacuum_clean_segment": { + "name": "map_mode.vacuum_clean_segment", + "icon": "mdi:floor-plan", + "selection_type": "ROOM", + "repeats_type": "EXTERNAL", + "max_repeats": 3, + "service_call_schema": { + "service": "mqtt.publish", + "service_data": { + "topic": "[[topic]]/MapSegmentationCapability/clean/set", + "payload": "{\"segment_ids\": [[selection]], \"iterations\": [[repeats]], \"customOrder\": true}" + } + } + }, + "vacuum_clean_zone": { + "name": "map_mode.vacuum_clean_zone", + "icon": "mdi:select-drag", + "selection_type": "MANUAL_RECTANGLE", + "coordinates_rounding": true, + "coordinates_to_meters_divider": 100, + "repeats_type": "EXTERNAL", + "max_selections": 5, + "max_repeats": 3, + "service_call_schema": { + "service": "mqtt.publish", + "evaluate_data_as_template": true, + "service_data": { + "topic": "[[topic]]/ZoneCleaningCapability/start/set", + "payload": "{\"zones\": [{%for s in ('[[selection]]')|from_json %}{ \"points\": {\"pA\": { \"x\": {{s[0]}}, \"y\": {{s[1]}} }, \"pB\": { \"x\": {{s[2]}}, \"y\": {{s[1]}} }, \"pC\": { \"x\": {{s[2]}}, \"y\": {{s[3]}} }, \"pD\": { \"x\": {{s[0]}}, \"y\": {{s[3]}} } }, \"iterations\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}]}" + } + } + }, + "vacuum_clean_zone_predefined": { + "name": "map_mode.vacuum_clean_zone_predefined", + "icon": "mdi:floor-plan", + "selection_type": "PREDEFINED_RECTANGLE", + "repeats_type": "EXTERNAL", + "max_repeats": 3, + "service_call_schema": { + "service": "mqtt.publish", + "evaluate_data_as_template": true, + "service_data": { + "topic": "[[topic]]/ZoneCleaningCapability/start/set", + "payload": "{\"zones\": [{%for s in ('[[selection]]')|from_json %}{ \"points\": {\"pA\": { \"x\": {{s[0]}}, \"y\": {{s[1]}} }, \"pB\": { \"x\": {{s[2]}}, \"y\": {{s[1]}} }, \"pC\": { \"x\": {{s[2]}}, \"y\": {{s[3]}} }, \"pD\": { \"x\": {{s[0]}}, \"y\": {{s[3]}} } }, \"iterations\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}]}" + } + } + }, + "vacuum_goto": { + "name": "map_mode.vacuum_goto", + "icon": "mdi:map-marker-plus", + "selection_type": "MANUAL_POINT", + "coordinates_rounding": true, + "coordinates_to_meters_divider": 100, + "repeats_type": "NONE", + "service_call_schema": { + "service": "mqtt.publish", + "service_data": { + "topic": "[[topic]]/GoToLocationCapability/go/set", + "payload": "{ \"coordinates\": { \"x\": [[point_x]], \"y\": [[point_y]] } }" + } + } + }, + "vacuum_goto_predefined": { + "name": "map_mode.vacuum_goto_predefined", + "icon": "mdi:map-marker", + "max_selections": 1, + "selection_type": "PREDEFINED_POINT", + "repeats_type": "NONE", + "service_call_schema": { + "service": "mqtt.publish", + "service_data": { + "topic": "[[topic]]/GoToLocationCapability/go/set", + "payload": "{ \"coordinates\": { \"x\": \"[[point_x]]\", \"y\": \"[[point_y]]\" } }" + } + } + } + } + }, + "tiles": { + "from_sensors": [ + { + "tile_id": "filter_left", + "unique_id_regex": "_sensor_ConsumableMonitoringCapability_filter_main", + "label": "tile.filter_left.label", + "icon": "mdi:air-filter", + "unit": "unit.hour_shortcut", + "multiplier": 0.0166666666666666667 + }, + { + "tile_id": "main_brush_left", + "unique_id_regex": "_sensor_ConsumableMonitoringCapability_brush_main", + "label": "tile.main_brush_left.label", + "icon": "mdi:brush", + "unit": "unit.hour_shortcut", + "multiplier": 0.0166666666666666667 + }, + { + "tile_id": "side_brush_left", + "unique_id_regex": "_sensor_ConsumableMonitoringCapability_brush_side_right", + "label": "tile.side_brush_left.label", + "icon": "mdi:brush", + "unit": "unit.hour_shortcut", + "multiplier": 0.0166666666666666667 + }, + { + "tile_id": "cleaned_area", + "unique_id_regex": "_sensor_CurrentStatisticsCapability_area", + "label": "tile.cleaned_area.label", + "icon": "mdi:texture-box", + "unit": "unit.meter_squared_shortcut", + "multiplier": 0.0001 + }, + { + "tile_id": "cleaning_time", + "unique_id_regex": "_sensor_CurrentStatisticsCapability_time", + "label": "tile.cleaning_time.label", + "icon": "mdi:timer-sand", + "unit": "unit.minute_shortcut", + "multiplier": 0.0166666666666666667 + } + ] + } +} diff --git a/src/rand256_valetudo_re.json b/src/rand256_valetudo_re.json new file mode 100644 index 00000000..1ba35e0d --- /dev/null +++ b/src/rand256_valetudo_re.json @@ -0,0 +1,142 @@ +{ + "map_modes": { + "default_templates": [ + "vacuum_clean_zone", + "vacuum_clean_zone_predefined", + "vacuum_goto", + "vacuum_goto_predefined" + ], + "templates": { + "vacuum_clean_segment": { + "name": "map_mode.vacuum_clean_segment", + "icon": "mdi:floor-plan", + "id_type": "number", + "selection_type": "ROOM", + "repeats_type": "EXTERNAL", + "max_repeats": 3, + "service_call_schema": { + "service": "mqtt.publish", + "evaluate_data_as_template": true, + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{ \"command\": \"segmented_cleanup\", \"segment_ids\": [[selection]], \"repeats\": [[repeats]], \"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\" }" + } + } + }, + "vacuum_clean_zone": { + "name": "map_mode.vacuum_clean_zone", + "icon": "mdi:select-drag", + "selection_type": "MANUAL_RECTANGLE", + "coordinates_rounding": true, + "coordinates_to_meters_divider": 1000, + "repeats_type": "EXTERNAL", + "max_selections": 5, + "max_repeats": 3, + "service_call_schema": { + "service": "mqtt.publish", + "evaluate_data_as_template": true, + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{\"command\": \"zoned_cleanup\",\"zone_coordinates\": [{%for s in ('[[selection]]')|from_json %}{ \"x1\": {{s[0]}}, \"y1\": {{s[1]}}, \"x2\": {{s[2]}}, \"y2\": {{s[3]}}, \"repeats\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}],\"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\"}" + } + } + }, + "vacuum_clean_zone_predefined": { + "name": "map_mode.vacuum_clean_zone_predefined", + "icon": "mdi:floor-plan", + "selection_type": "PREDEFINED_RECTANGLE", + "repeats_type": "EXTERNAL", + "max_repeats": 3, + "service_call_schema": { + "service": "mqtt.publish", + "evaluate_data_as_template": true, + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{\"command\": \"zoned_cleanup\",\"zone_ids\": [{%for s in ('[[selection]]')|from_json %}{ \"id\": \"{{s}}\", \"repeats\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}],\"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\"}" + } + } + }, + "vacuum_goto": { + "name": "map_mode.vacuum_goto", + "icon": "mdi:map-marker-plus", + "selection_type": "MANUAL_POINT", + "coordinates_rounding": true, + "coordinates_to_meters_divider": 1000, + "repeats_type": "NONE", + "service_call_schema": { + "service": "mqtt.publish", + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{ \"command\": \"go_to\", \"spot_coordinates\": { \"x\": [[point_x]], \"y\": [[point_y]] } }" + } + } + }, + "vacuum_goto_predefined": { + "name": "map_mode.vacuum_goto_predefined", + "icon": "mdi:map-marker", + "max_selections": 1, + "selection_type": "PREDEFINED_POINT", + "repeats_type": "NONE", + "service_call_schema": { + "service": "mqtt.publish", + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{ \"command\": \"go_to\", \"spot_id\": \"[[selection_unwrapped]]\" }" + } + } + } + } + }, + "tiles": { + "from_attributes": [ + { + "tile_id": "filter_left", + "attribute": "filter", + "label": "tile.filter_left.label", + "icon": "mdi:air-filter", + "unit": "unit.hour_shortcut", + "hold_action": { + "action": "call-service", + "service": "mqtt.publish", + "confirmation": {}, + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{\"command\": \"reset_consumable\",\n\"consumable\": \"filter_work_time\"}" + } + } + }, + { + "tile_id": "main_brush_left", + "attribute": "mainBrush", + "label": "tile.main_brush_left.label", + "icon": "mdi:brush", + "unit": "unit.hour_shortcut", + "hold_action": { + "action": "call-service", + "service": "mqtt.publish", + "confirmation": {}, + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{\"command\": \"reset_consumable\",\n\"consumable\": \"main_brush_work_time\"}" + } + } + }, + { + "tile_id": "side_brush_left", + "attribute": "sideBrush", + "label": "tile.side_brush_left.label", + "icon": "mdi:brush", + "unit": "unit.hour_shortcut", + "hold_action": { + "action": "call-service", + "service": "mqtt.publish", + "confirmation": {}, + "service_data": { + "topic": "[[topic]]/custom_command", + "payload": "{\"command\": \"reset_consumable\",\n\"consumable\": \"side_brush_work_time\"}" + } + } + } + ] + } +} diff --git a/src/xiaomi-vacuum-map-card.ts b/src/xiaomi-vacuum-map-card.ts index dbc211a8..759e18b3 100644 --- a/src/xiaomi-vacuum-map-card.ts +++ b/src/xiaomi-vacuum-map-card.ts @@ -170,23 +170,47 @@ export class XiaomiVacuumMapCard extends LitElement { public static getStubConfig(hass: HomeAssistantFixed): XiaomiVacuumMapCardConfig | undefined { const entities = Object.keys(hass.states); const cameras = entities - .filter(e => e.substr(0, e.indexOf(".")) === "camera") + .filter(e => e.substring(0, e.indexOf(".")) === "camera") .filter(e => hass?.states[e].attributes["calibration_points"]); - const vacuums = entities.filter(e => e.substr(0, e.indexOf(".")) === "vacuum"); + const mqtt_cam = entities + .filter(e => e.substring(0, e.indexOf(".")) === "camera") + .filter(e => hass?.states[e].attributes["vacuum_topic"]); + const vacuums = entities.filter(e => e.substring(0, e.indexOf(".")) === "vacuum"); if (cameras.length === 0 || vacuums.length === 0) { return undefined; } - return { - type: "custom:" + CARD_CUSTOM_ELEMENT_NAME, - map_source: { - camera: cameras[0], - }, - calibration_source: { - camera: true, - }, - entity: vacuums[0], - vacuum_platform: PlatformGenerator.XIAOMI_MIIO_PLATFORM, - }; + console.log("cameras:", cameras); + console.log("mqtt_cam:", mqtt_cam); + if (mqtt_cam.length > 0){ + const topicValue = mqtt_cam.map(cameraId => hass?.states[cameraId]?.attributes["vacuum_topic"]); + console.log("Topic Value:", topicValue); + return { + type: "custom:" + CARD_CUSTOM_ELEMENT_NAME, + map_source: { + camera: cameras[0], + }, + calibration_source: { + camera: true, + }, + entity: vacuums[0], + vacuum_platform: PlatformGenerator.XIAOMI_MIIO_PLATFORM, + internal_variables: { + topic: topicValue[0] + } + }; + } else { + return { + type: "custom:" + CARD_CUSTOM_ELEMENT_NAME, + map_source: { + camera: cameras[0], + }, + calibration_source: { + camera: true, + }, + entity: vacuums[0], + vacuum_platform: PlatformGenerator.XIAOMI_MIIO_PLATFORM, + }; + } } public setConfig(config: XiaomiVacuumMapCardConfig): void { @@ -463,6 +487,7 @@ export class XiaomiVacuumMapCard extends LitElement { private _getAllAvailablePresets(): CardPresetConfig[] { const allPresets = this._getAllPresets(); + console.log(allPresets) const available = allPresets.filter( p => (p.conditions?.length ?? 0) === 0 || areConditionsMet(p, this.internalVariables, this.hass), ); @@ -995,6 +1020,8 @@ export class XiaomiVacuumMapCard extends LitElement { private static adjustRoomId(roomId: string | number, config: MapMode): string | number { if (config.idType === "number") { return +roomId; + const roomIdAsNumber = +roomId; + return isNaN(roomIdAsNumber) ? roomId : roomIdAsNumber; } return roomId; } From 4788a7f7316e664db6f767793b47a092929a687a Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:29:05 +0100 Subject: [PATCH 02/15] types.ts added zone config added events and map extraction data. --- src/types/types.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/types/types.ts b/src/types/types.ts index 1b29feaa..67e50a5b 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -211,6 +211,7 @@ export interface ConditionConfig { readonly attribute?: string; readonly value?: string; readonly value_not?: string; + readonly topic?: string; } export interface CalibrationPoint { @@ -282,11 +283,24 @@ export interface MapExtractorRoom { readonly y: number | undefined; } +export interface MapExtractorZone { + readonly zones: string | undefined; + readonly name: string | undefined; + readonly icon: string | undefined; + readonly x: number | undefined; + readonly y: number | undefined; +} + export interface RoomConfigEventData { readonly modeIndex: number; readonly rooms: Array; } +export interface PredefinedZoneConfigEventData { + readonly modeIndex: number; + readonly zones: Array; +} + export interface EntityConfig { entity: string; attribute?: string; From 78c25004aeff68e8e1915903e50e19eca91bed4f Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:23:33 +0100 Subject: [PATCH 03/15] added zones to en.json added label for predefined zones configuration --- src/localize/languages/en.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 2de7ad76..29a70cb5 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -259,6 +259,7 @@ "config_set": "Config set!\nOpen config editor to adjust it.", "config_set_failed": "Failed to update config.", "generate_rooms_config": "Generate rooms config", + "generate_zones_config": "Generate zones config", "copy_service_call": "Copy service call" }, "alerts": { From 3487e042b6be40c784486793d0c0f5a855325729 Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:34:28 +0100 Subject: [PATCH 04/15] Update package.json beta version 2.2.3 --- package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index be7c09b2..b065d403 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiaomi-vacuum-map-card", - "version": "v2.2.2", + "version": "2.2.3.beta.5", "description": "Xiaomi Vacuum Map Card", "keywords": [ "home-assistant", @@ -15,12 +15,13 @@ "author": "Piotr Machowski ", "license": "MIT", "dependencies": { + "change-perspective": "^1.0.1", "custom-card-helpers": "^1.9.0", "home-assistant-js-websocket": "^8.0.1", "lit": "^2.0.0", "pointer-tracker": "^2.4.0", "transformation-matrix": "^2.8.0", - "change-perspective": "^1.0.1" + "tslib": "^2.6.2" }, "devDependencies": { "@babel/core": "^7.15.0", @@ -43,8 +44,8 @@ "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-serve": "^1.1.0", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.30.0", - "typescript": "^4.4.3" + "rollup-plugin-typescript2": "^0.31.0", + "typescript": "^4.9.5" }, "scripts": { "start": "rollup -c rollup.config.dev.js --watch", From 1fec2fe26ee011c6c71fec6be433160657d3a67a Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:39:05 +0100 Subject: [PATCH 05/15] Update xiaomi-vacuum-map-card.ts Reverted changes for topic, added getpredefifinedzones --- src/xiaomi-vacuum-map-card.ts | 76 +++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/src/xiaomi-vacuum-map-card.ts b/src/xiaomi-vacuum-map-card.ts index 759e18b3..03962d21 100644 --- a/src/xiaomi-vacuum-map-card.ts +++ b/src/xiaomi-vacuum-map-card.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { css, CSSResultGroup, html, LitElement, PropertyValues, svg, SVGTemplateResult, TemplateResult } from "lit"; import { customElement, property, query, queryAll, state } from "lit/decorators"; @@ -21,11 +22,13 @@ import { CalibrationPoint, CardPresetConfig, MapExtractorRoom, + MapExtractorZone, PredefinedZoneConfig, + PredefinedZoneConfigEventData, TranslatableString, VariablesStorage, } from "./types/types"; -import { actionHandler } from "./action-handler-directive"; +import { actionHandler, XiaomiVacuumMapCardActionHandler } from "./action-handler-directive"; import { CARD_CUSTOM_ELEMENT_NAME, CARD_VERSION, @@ -39,6 +42,8 @@ import { EVENT_LOVELACE_DOM_DETAIL, EVENT_ROOM_CONFIG, EVENT_ROOM_CONFIG_GET, + EVENT_PREDEFINED_ZONE_CONFIG, + EVENT_PREDEFINED_ZONE_CONFIG_GET, EVENT_SELECTION_CHANGED, EVENT_SERVICE_CALL, EVENT_SERVICE_CALL_GET, @@ -84,6 +89,8 @@ import { DropdownMenu } from "./components/dropdown-menu"; import { TilesWrapper } from "./components/tiles-wrapper"; import { IconsWrapper } from "./components/icons-wrapper"; import { PresetSelector } from "./components/preset-selector"; +import { configColl } from "home-assistant-js-websocket"; +import { XiaomiVacuumMapCardEditor } from "./editor"; const line1 = " XIAOMI-VACUUM-MAP-CARD"; const line2 = ` ${localize("common.version")} ${CARD_VERSION}`; @@ -144,6 +151,7 @@ export class XiaomiVacuumMapCard extends LitElement { super(); this._handleAutogeneratedConfigGet = this._handleAutogeneratedConfigGet.bind(this); this._handleRoomsConfigGet = this._handleRoomsConfigGet.bind(this); + this._handlePredefinedZoneConfigGet = this._handlePredefinedZoneConfigGet.bind(this) this._handleServiceCallGet = this._handleServiceCallGet.bind(this); this._handleLovelaceDomEvent = this._handleLovelaceDomEvent.bind(this); } @@ -172,32 +180,9 @@ export class XiaomiVacuumMapCard extends LitElement { const cameras = entities .filter(e => e.substring(0, e.indexOf(".")) === "camera") .filter(e => hass?.states[e].attributes["calibration_points"]); - const mqtt_cam = entities - .filter(e => e.substring(0, e.indexOf(".")) === "camera") - .filter(e => hass?.states[e].attributes["vacuum_topic"]); const vacuums = entities.filter(e => e.substring(0, e.indexOf(".")) === "vacuum"); if (cameras.length === 0 || vacuums.length === 0) { return undefined; - } - console.log("cameras:", cameras); - console.log("mqtt_cam:", mqtt_cam); - if (mqtt_cam.length > 0){ - const topicValue = mqtt_cam.map(cameraId => hass?.states[cameraId]?.attributes["vacuum_topic"]); - console.log("Topic Value:", topicValue); - return { - type: "custom:" + CARD_CUSTOM_ELEMENT_NAME, - map_source: { - camera: cameras[0], - }, - calibration_source: { - camera: true, - }, - entity: vacuums[0], - vacuum_platform: PlatformGenerator.XIAOMI_MIIO_PLATFORM, - internal_variables: { - topic: topicValue[0] - } - }; } else { return { type: "custom:" + CARD_CUSTOM_ELEMENT_NAME, @@ -240,6 +225,7 @@ export class XiaomiVacuumMapCard extends LitElement { if (this._isInEditor()) { window.addEventListener(EVENT_AUTOGENERATED_CONFIG_GET, this._handleAutogeneratedConfigGet); window.addEventListener(EVENT_ROOM_CONFIG_GET, this._handleRoomsConfigGet); + window.addEventListener(EVENT_PREDEFINED_ZONE_CONFIG_GET, this._handlePredefinedZoneConfigGet); window.addEventListener(EVENT_SERVICE_CALL_GET, this._handleServiceCallGet) this.isInEditor = true; } @@ -254,6 +240,7 @@ export class XiaomiVacuumMapCard extends LitElement { if (this._isInEditor()) { window.removeEventListener(EVENT_AUTOGENERATED_CONFIG_GET, this._handleAutogeneratedConfigGet); window.removeEventListener(EVENT_ROOM_CONFIG_GET, this._handleRoomsConfigGet); + window.removeEventListener(EVENT_PREDEFINED_ZONE_CONFIG_GET, this._handlePredefinedZoneConfigGet); window.removeEventListener(EVENT_SERVICE_CALL_GET, this._handleServiceCallGet); } document.removeEventListener(EVENT_LOVELACE_DOM, this._handleLovelaceDomEvent); @@ -487,7 +474,6 @@ export class XiaomiVacuumMapCard extends LitElement { private _getAllAvailablePresets(): CardPresetConfig[] { const allPresets = this._getAllPresets(); - console.log(allPresets) const available = allPresets.filter( p => (p.conditions?.length ?? 0) === 0 || areConditionsMet(p, this.internalVariables, this.hass), ); @@ -888,6 +874,12 @@ export class XiaomiVacuumMapCard extends LitElement { window.dispatchEvent(event); } + private _handlePredefinedZoneConfigGet(): void { + const event = new Event(EVENT_PREDEFINED_ZONE_CONFIG); + (event as any).PredefinedZoneConfig = this._getPredefinedZonesConfig(); + window.dispatchEvent(event); + } + private async _handleServiceCallGet(): Promise { const currentPreset = this._getCurrentPreset(); const currentMode = this._getCurrentMode(); @@ -1017,13 +1009,45 @@ export class XiaomiVacuumMapCard extends LitElement { return undefined; } + private _getPredefinedZonesConfig(): PredefinedZoneConfigEventData | undefined { + const config = this._getCurrentPreset(); + const zones = this.hass.states[config.map_source?.camera ?? ""]?.attributes["zones"] as Record< + string, + MapExtractorZone + >; + const predefinedZonesConfig = new Array(); + if (zones) { + const mode = this.modes.filter(m => m.selectionType === SelectionType.PREDEFINED_RECTANGLE).reverse()[0]; + const modeIndex = mode ? this.modes.indexOf(mode) : -1; + for (const zone_id in zones) { + if (!zones.hasOwnProperty(zone_id)) continue; + const zone = zones[zone_id]; + const predefinedZoneConfig = { + id: zone.name ?? `${zone.name}`, + label: { + text: zone.name ?? `Zone ${zone.name}`, + x: zone.x, + y: zone.y, + }, + zones: zone.zones, + } as PredefinedZoneConfig; + + predefinedZonesConfig.push(predefinedZoneConfig); + } + return { modeIndex: modeIndex, zones: predefinedZonesConfig }; + } + return undefined; + } + + private static adjustRoomId(roomId: string | number, config: MapMode): string | number { if (config.idType === "number") { return +roomId; const roomIdAsNumber = +roomId; return isNaN(roomIdAsNumber) ? roomId : roomIdAsNumber; + } else { + return roomId; } - return roomId; } private async _run(debug: boolean): Promise { From a79ea2de80789ebed0271d3fa98501d7c8bc48e9 Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:42:24 +0100 Subject: [PATCH 06/15] Update editor.ts --- src/editor.ts | 62 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/src/editor.ts b/src/editor.ts index 5b86556e..a952b78b 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -3,7 +3,7 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; -import { RoomConfigEventData, TranslatableString, XiaomiVacuumMapCardConfig } from "./types/types"; +import { RoomConfigEventData, PredefinedZoneConfigEventData, TranslatableString, XiaomiVacuumMapCardConfig } from "./types/types"; import { localizeWithHass } from "./localize/localize"; import { PlatformGenerator } from "./model/generators/platform-generator"; import { @@ -13,6 +13,8 @@ import { EVENT_AUTOGENERATED_CONFIG_GET, EVENT_ROOM_CONFIG, EVENT_ROOM_CONFIG_GET, + EVENT_PREDEFINED_ZONE_CONFIG, + EVENT_PREDEFINED_ZONE_CONFIG_GET, EVENT_SELECTION_CHANGED, EVENT_SERVICE_CALL, EVENT_SERVICE_CALL_GET, @@ -34,6 +36,7 @@ export class XiaomiVacuumMapCardEditor extends LitElement implements Omit e.substr(0, e.indexOf(".")) === "camera"); - const vacuums = entityIds.filter(e => e.substr(0, e.indexOf(".")) === "vacuum"); + const cameras = entityIds.filter(e => e.substring(0, e.indexOf(".")) === "camera"); + const vacuums = entityIds.filter(e => e.substring(0, e.indexOf(".")) === "vacuum"); const platforms = PlatformGenerator.getPlatforms(); const roomsUnavailable = this.hass.states[this._camera]?.attributes?.["rooms"] === undefined || PlatformGenerator.getRoomsTemplate(this._vacuum_platform) === undefined; + const zonesUnavailable = + this.hass.states[this._camera]?.attributes?.["zones"] === undefined || + PlatformGenerator.getPedefinedZonesTemplate(this._vacuum_platform) === undefined; return html`
@@ -219,6 +231,11 @@ export class XiaomiVacuumMapCardEditor extends LitElement implements Omit ${this._localize("editor.label.generate_rooms_config")} + + ${this._localize("editor.label.generate_zones_config")} + ${this._localize("editor.label.copy_service_call")} @@ -280,6 +297,36 @@ export class XiaomiVacuumMapCardEditor extends LitElement implements Omit= 0) { + map_modes[PredefinedZoneConfig.modeIndex ?? -1] = { + ...map_modes[PredefinedZoneConfig.modeIndex ?? -1], + predefined_selections: PredefinedZoneConfig.zones, + }; + } else { + if (map_modes.length === 0) { + map_modes.push(...PlatformGenerator.generateDefaultModes(this._vacuum_platform)); + } + if (PredefinedZonesTemplate) { + map_modes.push({ + template: PredefinedZonesTemplate, + predefined_selections: PredefinedZoneConfig.zones, + }); + } + } + if (this._config) { + this._setConfig({ ...this._config, map_modes: map_modes }); + } + this._showToast("editor.label.config_set", "mdi:check", true); + } + private _handleServiceCall(e: Event): void { const serviceCall = (e as any).serviceCall as string; copyMessage(serviceCall ?? ""); @@ -311,6 +358,15 @@ export class XiaomiVacuumMapCardEditor extends LitElement implements Omit Date: Sun, 26 Nov 2023 11:43:33 +0100 Subject: [PATCH 07/15] Update const.ts --- src/const.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/const.ts b/src/const.ts index 531534f8..6696e992 100644 --- a/src/const.ts +++ b/src/const.ts @@ -14,6 +14,8 @@ export const EVENT_AUTOGENERATED_CONFIG_GET = "map-card-autogenerated-config-get export const EVENT_AUTOGENERATED_CONFIG = "map-card-autogenerated-config"; export const EVENT_ROOM_CONFIG_GET = "map-card-room-config-get"; export const EVENT_ROOM_CONFIG = "map-card-room-config"; +export const EVENT_PREDEFINED_ZONE_CONFIG_GET = "map-card-predefined-zone-config-get"; +export const EVENT_PREDEFINED_ZONE_CONFIG = "map-card-predefined-zone-config"; export const EVENT_SERVICE_CALL_GET = "map-card-service-call-get"; export const EVENT_SERVICE_CALL = "map-card-service-call"; export const EVENT_LOVELACE_DOM = "ll-custom"; @@ -23,4 +25,4 @@ export const EMPTY_MAP_MODE: MapModeConfig = { run_immediately: true, selection_type: SelectionType[SelectionType.ROOM], repeats_type: RepeatsType[RepeatsType.NONE] -} \ No newline at end of file +} From d676e38e4aef29f868a5b5aef8a789a2edf80d46 Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:46:50 +0100 Subject: [PATCH 08/15] Update rand256_valetudo_re.json --- .../platform_templates/rand256_valetudo_re.json | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/model/generators/platform_templates/rand256_valetudo_re.json b/src/model/generators/platform_templates/rand256_valetudo_re.json index c59aa7a9..96daa74e 100644 --- a/src/model/generators/platform_templates/rand256_valetudo_re.json +++ b/src/model/generators/platform_templates/rand256_valetudo_re.json @@ -1,4 +1,7 @@ { + "internal_variables": { + "topic": "topic" + }, "map_modes": { "default_templates": [ "vacuum_clean_zone", @@ -8,6 +11,7 @@ "vacuum_clean_segment": { "name": "map_mode.vacuum_clean_segment", "icon": "mdi:floor-plan", + "id_type": "number", "selection_type": "ROOM", "repeats_type": "EXTERNAL", "max_repeats": 3, @@ -41,7 +45,7 @@ "vacuum_clean_zone_predefined": { "name": "map_mode.vacuum_clean_zone_predefined", "icon": "mdi:floor-plan", - "selection_type": "ROOM", + "selection_type": "PREDEFINED_RECTANGLE", "repeats_type": "EXTERNAL", "max_repeats": 3, "service_call_schema": { @@ -49,7 +53,7 @@ "evaluate_data_as_template": true, "service_data": { "topic": "[[topic]]/custom_command", - "payload": "{\"command\": \"zoned_cleanup\",\"zone_ids\": [{%for s in ('[[selection]]')|from_json %}{ \"id\": \"{{s}}\", \"repeats\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}],\"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\"}" + "payload": "{\"command\": \"zoned_cleanup\",\"zone_coordinates\": [{%for s in ('[[selection]]')|from_json %}{ \"x1\": {{s[0]}}, \"y1\": {{s[1]}}, \"x2\": {{s[2]}}, \"y2\": {{s[3]}}, \"repeats\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}],\"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\"}" } } }, @@ -72,7 +76,7 @@ "name": "map_mode.vacuum_goto_predefined", "icon": "mdi:map-marker", "max_selections": 1, - "selection_type": "ROOM", + "selection_type": "PREDEFINED_POINT", "repeats_type": "NONE", "service_call_schema": { "service": "mqtt.publish", From 0261df31d1a0fad2750b4f2aaf5b4579469a80f7 Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:48:06 +0100 Subject: [PATCH 09/15] Update hypfer_valetudo.json --- .../generators/platform_templates/hypfer_valetudo.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/model/generators/platform_templates/hypfer_valetudo.json b/src/model/generators/platform_templates/hypfer_valetudo.json index 1ebf214e..e1aa763f 100644 --- a/src/model/generators/platform_templates/hypfer_valetudo.json +++ b/src/model/generators/platform_templates/hypfer_valetudo.json @@ -1,4 +1,7 @@ { + "internal_variables": { + "topic": "[[topic]]" + }, "map_modes": { "default_templates": [ "vacuum_clean_zone", @@ -40,7 +43,7 @@ "vacuum_clean_zone_predefined": { "name": "map_mode.vacuum_clean_zone_predefined", "icon": "mdi:floor-plan", - "selection_type": "ROOM", + "selection_type": "PREDEFINED_RECTANGLE", "repeats_type": "EXTERNAL", "max_repeats": 3, "service_call_schema": { @@ -71,7 +74,7 @@ "name": "map_mode.vacuum_goto_predefined", "icon": "mdi:map-marker", "max_selections": 1, - "selection_type": "ROOM", + "selection_type": "PREDEFINED_POINT", "repeats_type": "NONE", "service_call_schema": { "service": "mqtt.publish", From 29b3181f1b07112ed4721a50edbeabc46fa4933a Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:49:01 +0100 Subject: [PATCH 10/15] Update platform-generator.ts --- src/model/generators/platform-generator.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/model/generators/platform-generator.ts b/src/model/generators/platform-generator.ts index b9801908..10ed6443 100644 --- a/src/model/generators/platform-generator.ts +++ b/src/model/generators/platform-generator.ts @@ -152,6 +152,18 @@ export class PlatformGenerator { return undefined; } + public static getPedefinedZonesTemplate(platform: string): string | undefined { + const platformTemplate = this.getPlatformTemplate(platform); + for (const templateName in platformTemplate.map_modes.templates) { + const template = platformTemplate.map_modes.templates[templateName]; + if (template.selection_type === SelectionType[SelectionType.PREDEFINED_RECTANGLE]) { + console.log("got template:", templateName); + return templateName; + } + } + return undefined; + } + public static getCalibration(platform: string | undefined): CalibrationPoint[] | undefined { return this.getPlatformTemplate(PlatformGenerator.getPlatformName(platform)).calibration_points; } @@ -170,4 +182,5 @@ export class PlatformGenerator { } as unknown as PlatformTemplate) ); } + } From 548631246514b0215a1c1ed5ed2c25feb87edd89 Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 12:25:55 +0100 Subject: [PATCH 11/15] Delete src/hypfer_valetudo.json --- src/hypfer_valetudo.json | 130 --------------------------------------- 1 file changed, 130 deletions(-) delete mode 100644 src/hypfer_valetudo.json diff --git a/src/hypfer_valetudo.json b/src/hypfer_valetudo.json deleted file mode 100644 index 27f3a040..00000000 --- a/src/hypfer_valetudo.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "map_modes": { - "default_templates": [ - "vacuum_clean_zone", - "vacuum_goto" - ], - "templates": { - "vacuum_clean_segment": { - "name": "map_mode.vacuum_clean_segment", - "icon": "mdi:floor-plan", - "selection_type": "ROOM", - "repeats_type": "EXTERNAL", - "max_repeats": 3, - "service_call_schema": { - "service": "mqtt.publish", - "service_data": { - "topic": "[[topic]]/MapSegmentationCapability/clean/set", - "payload": "{\"segment_ids\": [[selection]], \"iterations\": [[repeats]], \"customOrder\": true}" - } - } - }, - "vacuum_clean_zone": { - "name": "map_mode.vacuum_clean_zone", - "icon": "mdi:select-drag", - "selection_type": "MANUAL_RECTANGLE", - "coordinates_rounding": true, - "coordinates_to_meters_divider": 100, - "repeats_type": "EXTERNAL", - "max_selections": 5, - "max_repeats": 3, - "service_call_schema": { - "service": "mqtt.publish", - "evaluate_data_as_template": true, - "service_data": { - "topic": "[[topic]]/ZoneCleaningCapability/start/set", - "payload": "{\"zones\": [{%for s in ('[[selection]]')|from_json %}{ \"points\": {\"pA\": { \"x\": {{s[0]}}, \"y\": {{s[1]}} }, \"pB\": { \"x\": {{s[2]}}, \"y\": {{s[1]}} }, \"pC\": { \"x\": {{s[2]}}, \"y\": {{s[3]}} }, \"pD\": { \"x\": {{s[0]}}, \"y\": {{s[3]}} } }, \"iterations\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}]}" - } - } - }, - "vacuum_clean_zone_predefined": { - "name": "map_mode.vacuum_clean_zone_predefined", - "icon": "mdi:floor-plan", - "selection_type": "PREDEFINED_RECTANGLE", - "repeats_type": "EXTERNAL", - "max_repeats": 3, - "service_call_schema": { - "service": "mqtt.publish", - "evaluate_data_as_template": true, - "service_data": { - "topic": "[[topic]]/ZoneCleaningCapability/start/set", - "payload": "{\"zones\": [{%for s in ('[[selection]]')|from_json %}{ \"points\": {\"pA\": { \"x\": {{s[0]}}, \"y\": {{s[1]}} }, \"pB\": { \"x\": {{s[2]}}, \"y\": {{s[1]}} }, \"pC\": { \"x\": {{s[2]}}, \"y\": {{s[3]}} }, \"pD\": { \"x\": {{s[0]}}, \"y\": {{s[3]}} } }, \"iterations\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}]}" - } - } - }, - "vacuum_goto": { - "name": "map_mode.vacuum_goto", - "icon": "mdi:map-marker-plus", - "selection_type": "MANUAL_POINT", - "coordinates_rounding": true, - "coordinates_to_meters_divider": 100, - "repeats_type": "NONE", - "service_call_schema": { - "service": "mqtt.publish", - "service_data": { - "topic": "[[topic]]/GoToLocationCapability/go/set", - "payload": "{ \"coordinates\": { \"x\": [[point_x]], \"y\": [[point_y]] } }" - } - } - }, - "vacuum_goto_predefined": { - "name": "map_mode.vacuum_goto_predefined", - "icon": "mdi:map-marker", - "max_selections": 1, - "selection_type": "PREDEFINED_POINT", - "repeats_type": "NONE", - "service_call_schema": { - "service": "mqtt.publish", - "service_data": { - "topic": "[[topic]]/GoToLocationCapability/go/set", - "payload": "{ \"coordinates\": { \"x\": \"[[point_x]]\", \"y\": \"[[point_y]]\" } }" - } - } - } - } - }, - "tiles": { - "from_sensors": [ - { - "tile_id": "filter_left", - "unique_id_regex": "_sensor_ConsumableMonitoringCapability_filter_main", - "label": "tile.filter_left.label", - "icon": "mdi:air-filter", - "unit": "unit.hour_shortcut", - "multiplier": 0.0166666666666666667 - }, - { - "tile_id": "main_brush_left", - "unique_id_regex": "_sensor_ConsumableMonitoringCapability_brush_main", - "label": "tile.main_brush_left.label", - "icon": "mdi:brush", - "unit": "unit.hour_shortcut", - "multiplier": 0.0166666666666666667 - }, - { - "tile_id": "side_brush_left", - "unique_id_regex": "_sensor_ConsumableMonitoringCapability_brush_side_right", - "label": "tile.side_brush_left.label", - "icon": "mdi:brush", - "unit": "unit.hour_shortcut", - "multiplier": 0.0166666666666666667 - }, - { - "tile_id": "cleaned_area", - "unique_id_regex": "_sensor_CurrentStatisticsCapability_area", - "label": "tile.cleaned_area.label", - "icon": "mdi:texture-box", - "unit": "unit.meter_squared_shortcut", - "multiplier": 0.0001 - }, - { - "tile_id": "cleaning_time", - "unique_id_regex": "_sensor_CurrentStatisticsCapability_time", - "label": "tile.cleaning_time.label", - "icon": "mdi:timer-sand", - "unit": "unit.minute_shortcut", - "multiplier": 0.0166666666666666667 - } - ] - } -} From 4c15a77e4a10936f230674504ab8f3d360ba4e1b Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 26 Nov 2023 12:27:39 +0100 Subject: [PATCH 12/15] Delete src/rand256_valetudo_re.json --- src/rand256_valetudo_re.json | 142 ----------------------------------- 1 file changed, 142 deletions(-) delete mode 100644 src/rand256_valetudo_re.json diff --git a/src/rand256_valetudo_re.json b/src/rand256_valetudo_re.json deleted file mode 100644 index 1ba35e0d..00000000 --- a/src/rand256_valetudo_re.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "map_modes": { - "default_templates": [ - "vacuum_clean_zone", - "vacuum_clean_zone_predefined", - "vacuum_goto", - "vacuum_goto_predefined" - ], - "templates": { - "vacuum_clean_segment": { - "name": "map_mode.vacuum_clean_segment", - "icon": "mdi:floor-plan", - "id_type": "number", - "selection_type": "ROOM", - "repeats_type": "EXTERNAL", - "max_repeats": 3, - "service_call_schema": { - "service": "mqtt.publish", - "evaluate_data_as_template": true, - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{ \"command\": \"segmented_cleanup\", \"segment_ids\": [[selection]], \"repeats\": [[repeats]], \"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\" }" - } - } - }, - "vacuum_clean_zone": { - "name": "map_mode.vacuum_clean_zone", - "icon": "mdi:select-drag", - "selection_type": "MANUAL_RECTANGLE", - "coordinates_rounding": true, - "coordinates_to_meters_divider": 1000, - "repeats_type": "EXTERNAL", - "max_selections": 5, - "max_repeats": 3, - "service_call_schema": { - "service": "mqtt.publish", - "evaluate_data_as_template": true, - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{\"command\": \"zoned_cleanup\",\"zone_coordinates\": [{%for s in ('[[selection]]')|from_json %}{ \"x1\": {{s[0]}}, \"y1\": {{s[1]}}, \"x2\": {{s[2]}}, \"y2\": {{s[3]}}, \"repeats\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}],\"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\"}" - } - } - }, - "vacuum_clean_zone_predefined": { - "name": "map_mode.vacuum_clean_zone_predefined", - "icon": "mdi:floor-plan", - "selection_type": "PREDEFINED_RECTANGLE", - "repeats_type": "EXTERNAL", - "max_repeats": 3, - "service_call_schema": { - "service": "mqtt.publish", - "evaluate_data_as_template": true, - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{\"command\": \"zoned_cleanup\",\"zone_ids\": [{%for s in ('[[selection]]')|from_json %}{ \"id\": \"{{s}}\", \"repeats\": [[repeats]]}{%if not loop.last%},{%endif%}{%endfor%}],\"afterCleaning\": \"{{ 'Base' if 'afterCleaning' in '[[afterCleaning]]' else '[[afterCleaning]]'}}\"}" - } - } - }, - "vacuum_goto": { - "name": "map_mode.vacuum_goto", - "icon": "mdi:map-marker-plus", - "selection_type": "MANUAL_POINT", - "coordinates_rounding": true, - "coordinates_to_meters_divider": 1000, - "repeats_type": "NONE", - "service_call_schema": { - "service": "mqtt.publish", - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{ \"command\": \"go_to\", \"spot_coordinates\": { \"x\": [[point_x]], \"y\": [[point_y]] } }" - } - } - }, - "vacuum_goto_predefined": { - "name": "map_mode.vacuum_goto_predefined", - "icon": "mdi:map-marker", - "max_selections": 1, - "selection_type": "PREDEFINED_POINT", - "repeats_type": "NONE", - "service_call_schema": { - "service": "mqtt.publish", - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{ \"command\": \"go_to\", \"spot_id\": \"[[selection_unwrapped]]\" }" - } - } - } - } - }, - "tiles": { - "from_attributes": [ - { - "tile_id": "filter_left", - "attribute": "filter", - "label": "tile.filter_left.label", - "icon": "mdi:air-filter", - "unit": "unit.hour_shortcut", - "hold_action": { - "action": "call-service", - "service": "mqtt.publish", - "confirmation": {}, - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{\"command\": \"reset_consumable\",\n\"consumable\": \"filter_work_time\"}" - } - } - }, - { - "tile_id": "main_brush_left", - "attribute": "mainBrush", - "label": "tile.main_brush_left.label", - "icon": "mdi:brush", - "unit": "unit.hour_shortcut", - "hold_action": { - "action": "call-service", - "service": "mqtt.publish", - "confirmation": {}, - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{\"command\": \"reset_consumable\",\n\"consumable\": \"main_brush_work_time\"}" - } - } - }, - { - "tile_id": "side_brush_left", - "attribute": "sideBrush", - "label": "tile.side_brush_left.label", - "icon": "mdi:brush", - "unit": "unit.hour_shortcut", - "hold_action": { - "action": "call-service", - "service": "mqtt.publish", - "confirmation": {}, - "service_data": { - "topic": "[[topic]]/custom_command", - "payload": "{\"command\": \"reset_consumable\",\n\"consumable\": \"side_brush_work_time\"}" - } - } - } - ] - } -} From bb4be41c4bb512528c53fabb68b1b77a2649d7ef Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:17:35 +0100 Subject: [PATCH 13/15] Update package.json Error during compiling on github --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b065d403..f57e3a41 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiaomi-vacuum-map-card", - "version": "2.2.3.beta.5", + "version": "2.2.3-beta.5", "description": "Xiaomi Vacuum Map Card", "keywords": [ "home-assistant", From b8dab26e6f10b28690d4384505c23ffe7458915f Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 19 Jan 2025 20:42:00 +0100 Subject: [PATCH 14/15] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f57e3a41..906cc3ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiaomi-vacuum-map-card", - "version": "2.2.3-beta.5", + "version": "2.2.4", "description": "Xiaomi Vacuum Map Card", "keywords": [ "home-assistant", From 2885a661b13100cacb1f86250ed0f7080a1fc1bb Mon Sep 17 00:00:00 2001 From: SCA075 <82227818+sca075@users.noreply.github.com> Date: Sun, 19 Jan 2025 20:46:47 +0100 Subject: [PATCH 15/15] Update xiaomi-vacuum-map-card.ts --- src/xiaomi-vacuum-map-card.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xiaomi-vacuum-map-card.ts b/src/xiaomi-vacuum-map-card.ts index 03962d21..56d41fb8 100644 --- a/src/xiaomi-vacuum-map-card.ts +++ b/src/xiaomi-vacuum-map-card.ts @@ -838,7 +838,9 @@ export class XiaomiVacuumMapCard extends LitElement { private _isInEditor(): boolean { function isInEditor(e: Element): boolean { - return e.parentElement?.tagName?.toLowerCase() === "hui-card-preview" + return (e.parentElement?.tagName?.toLowerCase() === "hui-card" && "preview" in (e.parentElement?.attributes ?? [])) + || (e.parentElement?.tagName?.toLowerCase() === "hui-section" && "preview" in (e.parentElement?.attributes ?? [])) + || e.parentElement?.tagName?.toLowerCase() === "hui-card-preview" || e.parentElement != null && isInEditor(e.parentElement) || e.parentNode?.toString() == "[object ShadowRoot]" && isInEditor((e.getRootNode() as ShadowRoot).host); }