Răsfoiți Sursa

dev: add AGENTS.md files for the integration and for device configs.

- add a JSON schema for the yaml files
- fix some of the issues found by the schema

Recently there has been a big shift from Issues to AI generated PRs.
The problem with this is that the AI does not always generate valid
configs, often inventing its own syntax and even worse sometimes even
making code modifications to implement the syntax it invented instead
of using the correct syntax.

Attempt to guide AI in the right direction by defining the schema in
a standard format (vscode uses JSON schemas for yaml, and that is
catching on elsewhere) rather than relying solely on the documentation
in devices/README.md
Jason Rumney 2 luni în urmă
părinte
comite
25e5cf8aaa
21 a modificat fișierele cu 523 adăugiri și 31 ștergeri
  1. 34 0
      AGENTS.md
  2. 4 0
      custom_components/tuya_local/devices/AGENTS.md
  3. 2 2
      custom_components/tuya_local/devices/HCT-626_dual_water_timer.yaml
  4. 1 1
      custom_components/tuya_local/devices/arlec_10_pathlights.yaml
  5. 461 0
      custom_components/tuya_local/devices/device_config_schema.json
  6. 12 12
      custom_components/tuya_local/devices/erz04c_energy_meter.yaml
  7. 0 1
      custom_components/tuya_local/devices/eurom_sani_bathroom_towel_radiator.yaml
  8. 0 1
      custom_components/tuya_local/devices/eurom_saniwallheat2000_heater.yaml
  9. 0 1
      custom_components/tuya_local/devices/eurom_walldesignheat2000_heater.yaml
  10. 0 1
      custom_components/tuya_local/devices/ferroli_titano_twin.yaml
  11. 2 2
      custom_components/tuya_local/devices/feyree_ev_portable_charger.yaml
  12. 1 1
      custom_components/tuya_local/devices/hapaw_pet_fountain.yaml
  13. 1 1
      custom_components/tuya_local/devices/hdmi_ambient65_light.yaml
  14. 1 1
      custom_components/tuya_local/devices/its_45hd_heatpump.yaml
  15. 0 1
      custom_components/tuya_local/devices/lohxa_sr208c_waterheater.yaml
  16. 0 1
      custom_components/tuya_local/devices/purline_m100_heater.yaml
  17. 1 1
      custom_components/tuya_local/devices/smartplugv1.yaml
  18. 1 1
      custom_components/tuya_local/devices/sobralik_water_fountain.yaml
  19. 0 1
      custom_components/tuya_local/devices/thermex_if50v_waterheater.yaml
  20. 1 1
      custom_components/tuya_local/devices/tuya_energy_meter.yaml
  21. 1 1
      custom_components/tuya_local/devices/wdyk_3phase_energymonitor.yaml

+ 34 - 0
AGENTS.md

@@ -0,0 +1,34 @@
+# Instructions for autonomous agents
+
+## Development environment
+
+- This project is a Home Assistant integration.
+- The source languages are Python, YAML and JSON
+- Use `pip install -r requirements-dev.txt` to install dependencies
+
+## Coding standards
+
+- Python files should be checked with `ruff check`, `ruff check --select -I`
+- Python files should be formatted consistently with `ruff format`
+- YAML files should be checked with yamllint
+- YAML files should be located in the custom_components/tuya_local/devices folder
+- Python files implementing the HA integration should be located in custom_components/tuya_local and its subfolders, with unit tests in tests and its subfolders.
+- JSON files for translations should be located in the custom_components/tuya_local/translations folder.
+- Icons should be defined in custom_components/tuya_local/icons.json, and use icons from the material design icons at https://pictogrammers.com/library/mdi/
+- Where possible, new devices should use existing translation_keys which are present in custom_components/tuya_local/translations/*.json and custom/components/tuya_local/icons.json
+- if new translation_keys are added, they should be generic, not device specific, and translations should be added to all files in custom_components/tuya_local/translations and relevant icons to custom_components/tuya_local/icons.json
+
+## Testing instructions
+
+- Find the CI plan in the .github/workflows folder
+- Ignore the .github/workflows/hacs-validate.yml workflow if not running from the main repository at https://github.com/make-all/tuya-local
+- run `pytest` to run every test defined for the project
+- run `pytest tests/test_device_config.py` to test only yaml file changes or additions
+- run `pytest tests/test_translations.py` to test only json file changes or additions
+- do not add new tests if only making a yaml or json file change
+- add new tests if making a python file change that introduces new functionality
+- fix any test or lint failures until the whole test suite passes
+
+## PR instructions
+
+- Always run `ruff check .`, `ruff check --select -I .`, `ruff format --check .` and `yamllint custom_components/tuya_local/devices` before committing

+ 4 - 0
custom_components/tuya_local/devices/AGENTS.md

@@ -0,0 +1,4 @@
+# Instructions for autonomous agents
+
+- The files in this directory are configuration files for devices.
+- Files should comply with the schema in device_config_schema.json

+ 2 - 2
custom_components/tuya_local/devices/HCT-626_dual_water_timer.yaml

@@ -196,7 +196,7 @@ entities:
             value: "Scheduled"
       - id: 38
         type: string
-        name: Schedule
+        name: schedule
         optional: true
   - entity: sensor
     name: Valve 2 state
@@ -217,5 +217,5 @@ entities:
             value: "Scheduled"
       - id: 108
         type: string
-        name: Schedule
+        name: schedule
         optional: true

+ 1 - 1
custom_components/tuya_local/devices/arlec_10_pathlights.yaml

@@ -83,7 +83,7 @@ entities:
   - entity: text
     name: Dreamlight music
     category: config
-    icon: "mdi:"
+    icon: "mdi:music"
     hidden: true
     dps:
       - id: 52

+ 461 - 0
custom_components/tuya_local/devices/device_config_schema.json

@@ -0,0 +1,461 @@
+{
+    "$id": "https://github.com/make-all/tuya-local/custom_components/tuya_local/devices/device_config_schema.json",
+    "title": "Tuya Local Device Configuration Schema",
+    "description": "Schema for validating Tuya Local device configuration files.",
+    "type": "object",
+    "properties": {
+        "name": {
+            "type": "string",
+            "description": "The name of the device."
+        },
+        "products": {
+            "type": "array",
+            "description": "List of products that match this config.",
+            "minItems": 1,
+            "items": {
+                "type": "object",
+                "properties": {
+                    "id": {
+                        "type": "string",
+                        "description": "The unique product_id from Tuya cloud info."
+                    },
+                    "manufacturer": {
+                        "type": "string",
+                        "description": "The manufacturer or brand of the device."
+                    },
+                    "model": {
+                        "type": "string",
+                        "description": "The model name of the device."
+                    },
+                    "model_id": {
+                        "type": "string",
+                        "description": "Optional model identifier for the device if it has both a readable name and a cryptic id."
+                    },
+                    "name": {
+                        "type": "string",
+                        "description": "Optional name to override the device name."
+                    }
+                },
+                "required": ["id"],
+                "additionalProperties": false
+            }
+        },
+        "entities": {
+            "type": "array",
+            "description": "List of entities provided by this device.",
+            "minItems": 1,
+            "items": {
+                "type": "object",
+                "properties": {
+                    "entity": {
+                        "type": "string",
+                        "enum": ["alarm_control_panel", "binary_sensor", "button", "camera", "climate", "cover", "event", "fan", "humidifier", "lawn_mower", "light", "lock", "number", "remote", "select", "sensor", "siren", "switch", "text", "time", "vacuum", "valve", "water_heater"],
+                        "description": "The type of entity (e.g., light, switch, sensor)."
+                    },
+                    "name": {
+                        "type": "string",
+                        "description": "Optional name of the entity if not defined by class or translation_key or needed to differentiate the entity."
+                    },
+                    "translation_key": {
+                        "type": "string",
+                        "pattern": "^[a-z0-9_]+$",
+                        "description": "Optional translation key for the entity."
+                    },
+                    "translation_only_key": {
+                        "type": "string",
+                        "pattern": "^[a-z0-9_]+$",
+                        "description": "Optional translation key which is not used when computing entitiy ids. Intended for adding translation keys to existing unnamed entities."
+                    },
+                    "translation_placeholders": {
+                        "type": "object",
+                        "description": "Optional translation placeholders for the entity.",
+                        "additionalProperties": {
+                            "type": "string"
+                        }
+                    },
+                    "class": {
+                        "type": "string",
+                        "description": "Optional device class for the entity."
+                    },
+                    "icon": {
+                        "type": "string",
+                        "pattern": "mdi:[a-z0-9_+-]+",
+                        "description": "Optional icon for the entity if not defined by class or translation_key."
+                    },
+                    "icon_priority": {
+                        "type": "integer",
+                        "description": "The priority order for choosing an icon when multiple are available. Lower numbers have higher priority. Default is 10.",
+                        "minimum": 1
+                    },
+                    "category": {
+                        "type": "string",
+                        "enum": ["config", "diagnostic"],
+                        "description": "Optional entity category (e.g., config, diagnostic)."
+                    },
+                    "hidden": {
+                        "type": ["boolean", "string"],
+                        "description": "true if the entity should be created as disabled by default. Useful for entities that are not commonly used or require advanced knowledge to use. If set to 'unavailable', the entity will be hidden when the 'available' dps indicates false."
+                    },
+                    "mode": {
+                        "type": "string",
+                        "enum": ["auto", "box", "slider"],
+                        "description": "The display mode of number entities (e.g., box, slider). Usually the default of auto is preferable, this should only be overridden with good reason (not personal preference)."
+                    },
+                    "deprecated": {
+                        "type": "string",
+                        "description": "if the entity is deprecated and should not be used for new setups, a string to output in the deprecation message in the log pointing the user to the replacement. This should not be used in new configs, but can be used in later modifications where a better representation of the entity is introduced. A comment with the date should be added when setting this to help with future cleanup."
+                    },
+                    "dps": {
+                        "type": "array",
+                        "description": "The list of DPs that this entity uses.",
+                        "minItems": 1,
+                        "items": {
+                            "type": "object",
+                            "properties": {
+                                "id": {
+                                    "type": "integer",
+                                    "description": "The DP number.",
+                                    "minimum": 1,
+                                    "maximum": 255
+                                },
+                                "type": {
+                                    "type": "string",
+                                    "enum": ["boolean", "integer", "string", "bitfield", "base64", "hex", "utf16b64", "json", "unixtime", "float"],
+                                    "description": "The type of the DP (e.g., boolean, integer, string)."
+                                },
+                                "name": {
+                                    "type": "string",
+                                    "pattern": "^[a-z0-9_]+$",
+                                    "description": "Name of the DP."
+                                },
+                                "optional": {
+                                    "type": "boolean",
+                                    "description": "true if the DP is optional and may not be present in every full poll from the device. Default is false, which should not be specified explicitly to avoid clutter."
+                                },
+                                "range": {
+                                    "type": "object",
+                                    "description": "The range of values for integer DPs.",
+                                    "properties": {
+                                        "min": {
+                                            "type": "integer",
+                                            "description": "Minimum value."
+                                        },
+                                        "max": {
+                                            "type": "integer",
+                                            "description": "Maximum value."
+                                        }
+                                    },
+                                    "required": ["min", "max"],
+                                    "additionalProperties": false
+                                },
+                                "precision": {
+                                    "type": "integer",
+                                    "minimum": 0,
+                                    "description": "The precision to use in HA UI for scaled integer dps. Default is based on the scale if not specified."
+                                },
+                                "class": {
+                                    "type": "string",
+                                    "enum": ["measurement", "total", "total_increasing"],
+                                    "description": "Optional state class for sensor DPs. (e.g., measurement, total, total_increasing)."
+                                },
+                                "sensitive": {
+                                    "type": "boolean",
+                                    "description": "true if the DP contains sensitive information and should not be included in diagnostics dumps. Default is false, which should not be specified explicitly to avoid clutter."
+                                },
+                                "hidden": {
+                                    "type": "boolean",
+                                    "description": "true if the DP should be hidden from the entities extra attribute list. Default false, which should not be specified explicitly to avoid clutter. Has no effect if used in a dp which is an official part of the entity API."
+                                },
+                                "readonly": {
+                                    "type": "boolean",
+                                    "description": "true if the DP is read-only. Rarely needed, as usually determined automatically based on the entity specification. Should not be specified explicitly unless needed to avoid clutter."
+                                },
+                                "force": {
+                                    "type": "boolean",
+                                    "description": "true to try to force the device to send this dp with full polls. May cause instability if the device does not expect this, generally only works on power/current/voltage sensors for some smartplugs that do not send them by default. Default is false, which should not be specified explicitly to avoid clutter."
+                                },
+                                "persist": {
+                                    "type": "boolean",
+                                    "description": "false to clear the last known value of this dp before each full poll. Only needed for dps that are expected to disappear (become null), but not required to be specified for events as they are automatically only fired when explicitly received. Default is true, which should not be specified explicitly to avoid clutter."
+                                },
+                                "format": {
+                                    "type": "array",
+                                    "description": "The format to extract multiple numeric fields from base64 or hex DP values. Used only for rgbhsv fields of lights currently.",
+                                    "minItems": 1,
+                                    "items": {
+                                        "type": "object",
+                                        "properties": {
+                                            "name": {
+                                                "type": "string",
+                                                "description": "The name of the sub-field."
+                                            },
+                                            "bytes": {
+                                                "type": "integer",
+                                                "description": "The size of the sub-field in bytes (default 1). Up to 4 bytes supported for extraction as integers, but filler fields can be bigger.",
+                                                "minimum": 1
+                                            },
+                                            "range": {
+                                                "type": "object",
+                                                "description": "The range of the data in the sub-field. Default is 0 to max value for the given byte size.",
+                                                "properties": {
+                                                    "min": {
+                                                        "type": "integer",
+                                                        "description": "Minimum value."
+                                                    },
+                                                    "max": {
+                                                        "type": "integer",
+                                                        "description": "Maximum value."
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        "required": ["name"],
+                                        "additionalProperties": false
+                                    }
+                                },
+                                "mask": {
+                                    "type": "string",
+                                    "pattern": "^[0-9a-fA-F]+$",
+                                    "description": "A hexadecimal mask to extract an integer from a base64 or hex DP value."
+                                },
+                                "mask_signed": {
+                                    "type": "boolean",
+                                    "description": "true if the masked integer is signed. Default is false, which should not be specified explicitly to avoid clutter."
+                                },
+                                "endianness": {
+                                    "type": "string",
+                                    "enum": ["big", "little"],
+                                    "description": "The endianness of masked data in the base64 or hex DP. Default is 'big', so only 'little' needs to be explicitly specified."
+                                },
+                                "unit": {
+                                    "type": "string",
+                                    "description": "The unit of measurement for a sensor DP (e.g., °C, %, W). Some units can use ASCII replacements like C for °C, F for °F, and ugm3 for μg/m³ to simplify input and avoid accidental incorrect Unicode character usage."
+                                },
+                                "mapping": {
+                                    "type": "array",
+                                    "description": "A list of mappings that potentially change the value in HA compared to the raw DP value.",
+                                    "minItems": 1,
+                                    "items": {
+                                        "type": "object",
+                                        "properties": {
+                                            "dps_val": {
+                                                "type": ["integer", "string", "boolean", "null"],
+                                                "description": "The DP value this mapping matches."
+                                            },
+                                            "value": {
+                                                "type": ["number", "string", "boolean", "null"],
+                                                "description": "An optional value to map to."
+                                            },
+                                            "value_redirect": {
+                                                "type": "string",
+                                                "pattern": "^[a-z0-9_]+$",
+                                                "description": "The name of a dp in the same dps list to redirect to for read and write."
+                                            },
+                                            "value_mirror": {
+                                                "type": "string",
+                                                "pattern": "^[a-z0-9_]+$",
+                                                "description": "The name of a dp in the same dps list to mirror the value from when read."
+                                            },
+                                            "scale": {
+                                                "type": "number",
+                                                "description": "An optional scale to apply when this mapping is matched.",
+                                                "exclusiveMinimum": 0
+                                            },
+                                            "step": {
+                                                "type": "integer",
+                                                "minimum": 1,
+                                                "description": "An optional step to apply when this mapping is matched."
+                                            },
+                                            "range": {
+                                                "type": "object",
+                                                "description": "An override for range of values for integer DPs when this mapping is matched.",
+                                                "properties": {
+                                                    "min": {
+                                                        "type": "integer",
+                                                        "description": "Minimum value."
+                                                    },
+                                                    "max": {
+                                                        "type": "integer",
+                                                        "description": "Maximum value."
+                                                    }
+                                                },
+                                                "required": ["min", "max"],
+                                                "additionalProperties": false
+                                            },
+                                            "target_range": {
+                                                "type": "object",
+                                                "description": "An optional target range to map the range of values to for integer DPs when this mapping is matched.",
+                                                "properties": {
+                                                    "min": {
+                                                        "type": "integer",
+                                                        "description": "Minimum value."
+                                                    },
+                                                    "max": {
+                                                        "type": "integer",
+                                                        "description": "Maximum value."
+                                                    }
+                                                },
+                                                "required": ["min", "max"],
+                                                "additionalProperties": false
+                                            },
+                                            "icon": {
+                                                "type": "string",
+                                                "pattern": "mdi:[a-z0-9_+-]+",
+                                                "description": "An optional icon to use when this mapping is matched."
+                                            },
+                                            "icon_priority": {
+                                                "type": "integer",
+                                                "description": "The priority order for choosing an icon when multiple are available. Lower numbers have higher priority. Default is 10.",
+                                                "minimum": 1
+                                            },
+                                            "invert": {
+                                                "type": "boolean",
+                                                "description": "true to invert the value within the range when this mapping is matched."
+                                            },
+                                            "default": {
+                                                "type": "boolean",
+                                                "description": "true if this mapping should be used as the default when no value was specified. Currently used only for a siren entity tone dp when there is no switch dp and the turn_on action is called without arguments."
+                                            },
+                                            "hidden": {
+                                                "type": "boolean",
+                                                "description": "true if this mapping should be hidden from the user in selection UIs. Default false, which should not be specified explicitly to avoid clutter."
+                                            },
+                                            "available": {
+                                                "type": "string",
+                                                "pattern": "^[a-z0-9_]+$",
+                                                "description": "The name of a dp in the same dps list that indicates whether this mapping is available."
+                                            },
+                                            "invalid": {
+                                                "type": "boolean",
+                                                "description": "true if this mapping indicates an invalid state."
+                                            },
+                                            "constraint": {
+                                                "type": "string",
+                                                "pattern": "^[a-z0-9_]+$",
+                                                "description": "An optional name of a dp within the same dps list to check conditions against. If unspecified, the conditions apply to the current dp."
+                                            },
+                                            "conditions": {
+                                                "type": "array",
+                                                "description": "A list of conditions that must be met for this mapping to apply.",
+                                                "minItems": 1,
+                                                "items": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "dps_val": {
+                                                            "type": ["integer", "string", "boolean", "array", "null"],
+                                                            "description": "The DP value of the constraint DP to match against."
+                                                        },
+                                                        "value": {
+                                                            "type": ["number", "string", "boolean", "null"],
+                                                            "description": "The value to map to."
+                                                        },
+                                                        "value_redirect": {
+                                                            "type": "string",
+                                                            "pattern": "^[a-z0-9_]+$",
+                                                            "description": "The name of a dp in the same dps list to redirect to."
+                                                        },
+                                                        "value_mirror": {
+                                                            "type": "string",
+                                                            "pattern": "^[a-z0-9_]+$",
+                                                            "description": "The name of a dp in the same dps list to mirror the value from when read."
+                                                        },
+                                                        "range": {
+                                                            "type": "object",
+                                                            "description": "An override for range of values for integer DPs when this condition is matched.",
+                                                            "properties": {
+                                                                "min": {
+                                                                    "type": "integer",
+                                                                    "description": "Minimum value."
+                                                                },
+                                                                "max": {
+                                                                    "type": "integer",
+                                                                    "description": "Maximum value."
+                                                                }
+                                                            },
+                                                            "required": ["min", "max"],
+                                                            "additionalProperties": false
+                                                        },
+                                                        "scale": {
+                                                            "type": "number",
+                                                            "description": "An optional scale to apply when this mapping is matched.",
+                                                            "exclusiveMinimum": 0
+                                                        },
+                                                        "step": {
+                                                            "type": "integer",
+                                                            "minimum": 1,
+                                                            "description": "An optional step to apply when this mapping is matched."
+                                                        },
+                                                        "target_range": {
+                                                            "type": "object",
+                                                            "description": "An optional target range to map the range of values to for integer DPs when this mapping is matched.",
+                                                            "properties": {
+                                                                "min": {
+                                                                    "type": "number",
+                                                                    "description": "Minimum value."
+                                                                },
+                                                                "max": {
+                                                                    "type": "number",
+                                                                    "description": "Maximum value."
+                                                                }
+                                                            },
+                                                            "required": ["min", "max"],
+                                                            "additionalProperties": false
+                                                        },
+                                                        "hidden": {
+                                                            "type": "boolean",
+                                                            "description": "true if this mapping should be hidden from the user in selection UIs. Default false, which should not be specified explicitly to avoid clutter."
+                                                        },
+                                                        "available": {
+                                                            "type": "string",
+                                                            "pattern": "^[a-z0-9_]+$",
+                                                            "description": "The name of a dp in the same dps list that indicates whether this mapping is available."
+                                                        },
+                                                        "invalid": {
+                                                            "type": "boolean",
+                                                            "description": "true if this condition indicates an invalid state."
+                                                        },
+                                                        "mapping": {
+                                                            "type": "array",
+                                                            "description": "An override list of mappings that potentially change the value in HA compared to the raw DP value when this condition is matched.",
+                                                            "minItems": 1,
+                                                            "items": {
+                                                                "type": "object",
+                                                                "properties": {
+                                                                    "dps_val": {
+                                                                        "type": ["integer", "string", "boolean", "null"],
+                                                                        "description": "The DP value this mapping matches."
+                                                                    },
+                                                                    "value": {
+                                                                        "type": ["number", "string", "boolean", "null"],
+                                                                        "description": "An optional value to map to."
+                                                                    }
+                                                                }
+                                                            }
+                                                        }
+                                                    },
+                                                    "required": ["dps_val"],
+                                                    "additionalProperties": false
+                                                }
+                                            }
+                                        },
+                                        "additionalProperties": false
+                                    }
+                                }
+                            },
+                            "required": ["id", "type", "name"],
+                            "additionalProperties": false
+                        }
+                    }
+                },
+                "required": ["entity", "dps"],
+                "additionalProperties": false
+            }
+        },
+        "legacy_type": {
+            "type": "string",
+            "description": "Optional legacy type for backward compatibility. Should not be used for new configs."
+        }
+    },
+    "required": ["name", "entities"],
+    "additionalProperties": false
+}

+ 12 - 12
custom_components/tuya_local/devices/erz04c_energy_meter.yaml

@@ -15,7 +15,7 @@ entities:
         mapping:
           - scale: 1000
       - id: 103
-        name: Device state A
+        name: device_state_a
         type: string
         mapping:
           - dps_val: close
@@ -28,7 +28,7 @@ entities:
           - dps_val: warning
             value: Warning
       - id: 113
-        name: Device state B
+        name: device_state_b
         type: string
         mapping:
           - dps_val: close
@@ -41,7 +41,7 @@ entities:
           - dps_val: warning
             value: Warning
       - id: 110
-        name: Power type A
+        name: power_type_a
         type: string
         mapping:
           - dps_val: normal
@@ -50,7 +50,7 @@ entities:
           - dps_val: warn
             value: Warn
       - id: 120
-        name: Power type B
+        name: power_type_b
         type: string
         mapping:
           - dps_val: normal
@@ -59,7 +59,7 @@ entities:
           - dps_val: warn
             value: Warn
       - id: 101
-        name: Sync request
+        name: sync_request
         type: string
         mapping:
           - dps_val: idle
@@ -68,7 +68,7 @@ entities:
           - dps_val: request
             value: Request
       - id: 124
-        name: Net state
+        name: net_state
         type: string
         mapping:
           - dps_val: cloud_net
@@ -136,7 +136,7 @@ entities:
         mapping:
           - scale: 1000
       - id: 104
-        name: Power statistics A
+        name: power_statistics
         type: integer
         unit: kWh
         class: measurement
@@ -144,7 +144,7 @@ entities:
         mapping:
           - scale: 100
       - id: 109
-        name: Today's electricity consumption A
+        name: energy_today
         type: integer
         unit: kWh
         class: measurement
@@ -152,7 +152,7 @@ entities:
         mapping:
           - scale: 1000
       - id: 112
-        name: Increased power consumption A
+        name: energy_increase
         type: integer
         unit: kWh
         class: measurement
@@ -219,7 +219,7 @@ entities:
         mapping:
           - scale: 1000
       - id: 114
-        name: Power statistics B
+        name: power_statistics
         type: integer
         unit: kWh
         class: total_increasing
@@ -227,7 +227,7 @@ entities:
         mapping:
           - scale: 100
       - id: 119
-        name: Today's electricity consumption B
+        name: energy_today
         type: integer
         unit: kWh
         class: measurement
@@ -235,7 +235,7 @@ entities:
         mapping:
           - scale: 1000
       - id: 122
-        name: Increased power consumption B
+        name: emergy_increase
         type: integer
         unit: kWh
         class: measurement

+ 0 - 1
custom_components/tuya_local/devices/eurom_sani_bathroom_towel_radiator.yaml

@@ -25,7 +25,6 @@ entities:
                 value: heat
               - dps_val: t
                 value: dry
-                icon: "mdi:hanger"
       - id: 2
         type: integer
         name: temperature

+ 0 - 1
custom_components/tuya_local/devices/eurom_saniwallheat2000_heater.yaml

@@ -15,7 +15,6 @@ entities:
             conditions:
               - dps_val: "off"
                 value: fan_only
-                icon: "mdi:fan"
               - dps_val: auto
                 value: heat
               - dps_val: "50_per"

+ 0 - 1
custom_components/tuya_local/devices/eurom_walldesignheat2000_heater.yaml

@@ -15,7 +15,6 @@ entities:
             conditions:
               - dps_val: "off"
                 value: fan_only
-                icon: "mdi:fan"
               - dps_val: auto
                 value: heat
               - dps_val: "50_perc"

+ 0 - 1
custom_components/tuya_local/devices/ferroli_titano_twin.yaml

@@ -20,7 +20,6 @@ entities:
                 value: electric
               - dps_val: eco
                 value: eco
-                icon: "mdi:leaf"
       - id: 2
         type: string
         name: work_mode

+ 2 - 2
custom_components/tuya_local/devices/feyree_ev_portable_charger.yaml

@@ -503,7 +503,7 @@ entities:
   - entity: text
     name: Alarm set 1
     category: config
-    icon: "mdi:"
+    icon: "mdi:alarm"
     hidden: true
     dps:
       - id: 11
@@ -513,7 +513,7 @@ entities:
   - entity: text
     name: Alarm set 2
     category: config
-    icon: "mdi:"
+    icon: "mdi:alarm"
     hidden: true
     dps:
       - id: 12

+ 1 - 1
custom_components/tuya_local/devices/hapaw_pet_fountain.yaml

@@ -83,7 +83,7 @@ entities:
   - entity: number
     name: Maintenance interval
     category: config
-    icon: "mdi:"
+    icon: "mdi:wrench-clock"
     dps:
       - id: 8
         type: integer

+ 1 - 1
custom_components/tuya_local/devices/hdmi_ambient65_light.yaml

@@ -358,7 +358,7 @@ entities:
             value: Combination Color 22
 
   - entity: text
-    translation_key: Scene
+    translation_key: scene
     icon: "mdi:palette"
     category: config
     hidden: true

+ 1 - 1
custom_components/tuya_local/devices/its_45hd_heatpump.yaml

@@ -32,7 +32,7 @@ entities:
         unit: C
       - id: 14
         type: integer
-        name: EEV
+        name: eev
       - id: 17
         type: string
         name: work_mode

+ 0 - 1
custom_components/tuya_local/devices/lohxa_sr208c_waterheater.yaml

@@ -17,7 +17,6 @@ entities:
             conditions:
               - dps_val: auto
                 value: eco
-                default: true
               - dps_val: heating
                 value: electric
               - dps_val: cold

+ 0 - 1
custom_components/tuya_local/devices/purline_m100_heater.yaml

@@ -15,7 +15,6 @@ entities:
             conditions:
               - dps_val: "off"
                 value: fan_only
-                icon: "mdi:fan"
             value: "heat"
       - id: 2
         name: temperature

+ 1 - 1
custom_components/tuya_local/devices/smartplugv1.yaml

@@ -1,7 +1,7 @@
 name: Energy monitoring smartplug
 legacy_type: kogan_switch
 products:
-  - id: 370053454855194e5607
+  - id: "370053454855194e5607"
     manufacturer: Gosund
     model: EP2
   - id: 37mnhia3pojleqfh

+ 1 - 1
custom_components/tuya_local/devices/sobralik_water_fountain.yaml

@@ -44,7 +44,7 @@ entities:
           - value: false
 
   - entity: button
-    translation_key: filter_Reset
+    translation_key: filter_reset
     category: config
     dps:
       - id: 5

+ 0 - 1
custom_components/tuya_local/devices/thermex_if50v_waterheater.yaml

@@ -22,7 +22,6 @@ entities:
                 value: eco
               - dps_val: "2"
                 value: electric
-                default: true
               - dps_val: "4"
                 value: away
               - dps_val: "1"

+ 1 - 1
custom_components/tuya_local/devices/tuya_energy_meter.yaml

@@ -16,7 +16,7 @@ entities:
         mapping:
           - scale: 1000
       - id: 103
-        name: Device state
+        name: device_state
         type: string
         mapping:
           - dps_val: close

+ 1 - 1
custom_components/tuya_local/devices/wdyk_3phase_energymonitor.yaml

@@ -10,7 +10,7 @@ entities:
         name: serial_number
       - id: 118
         type: integer
-        name: RkWh
+        name: rkwh
       - id: 119
         type: base64
         name: historical_voltage