Explorar o código

Tests: Add a schema check to device config tests

Schema check detects typos, wrong indentation, misplaced attributes,
and use of imaginary attributes that contributers made up on the spot.

Many errors detected by this.
Jason Rumney %!s(int64=2) %!d(string=hai) anos
pai
achega
a52aeca788
Modificáronse 62 ficheiros con 256 adicións e 180 borrados
  1. 1 1
      custom_components/tuya_local/devices/CT20W_pir_motion_detector.yaml
  2. 1 2
      custom_components/tuya_local/devices/README.md
  3. 2 2
      custom_components/tuya_local/devices/agl_ultramagic_lock.yaml
  4. 1 1
      custom_components/tuya_local/devices/asip_0622_planter.yaml
  5. 0 1
      custom_components/tuya_local/devices/aspen_asp200_fan.yaml
  6. 0 1
      custom_components/tuya_local/devices/atorch_s1wp.yaml
  7. 1 2
      custom_components/tuya_local/devices/aubess_rainpoint_irrigation_system.yaml
  8. 1 1
      custom_components/tuya_local/devices/beca_zht002_thermostat_c.yaml
  9. 0 2
      custom_components/tuya_local/devices/beok_tr9b_thermostat.yaml
  10. 3 3
      custom_components/tuya_local/devices/ble_hu06_lock.yaml
  11. 1 1
      custom_components/tuya_local/devices/ble_water_valve.yaml
  12. 2 2
      custom_components/tuya_local/devices/bresser_weather_station.yaml
  13. 2 2
      custom_components/tuya_local/devices/breville_lad208_dehumidifier.yaml
  14. 1 1
      custom_components/tuya_local/devices/breville_smartairconnect_purifier.yaml
  15. 0 1
      custom_components/tuya_local/devices/catit_pet_feeder.yaml
  16. 2 1
      custom_components/tuya_local/devices/cleanair_605b_humidifier.yaml
  17. 13 8
      custom_components/tuya_local/devices/cooper_hunter_air_conditioner.yaml
  18. 1 2
      custom_components/tuya_local/devices/diivoo_wt05.yaml
  19. 2 3
      custom_components/tuya_local/devices/dongguan_garage_door_opener.yaml
  20. 2 1
      custom_components/tuya_local/devices/dts238_7_energy_meter.yaml
  21. 0 3
      custom_components/tuya_local/devices/earu_smart_wifi_circuit_breaker_with_energy_monitor.yaml
  22. 1 1
      custom_components/tuya_local/devices/etop_ht_thermostat.yaml
  23. 1 2
      custom_components/tuya_local/devices/garza_irrigation_system.yaml
  24. 0 1
      custom_components/tuya_local/devices/goodcell_ev_charger.yaml
  25. 1 2
      custom_components/tuya_local/devices/holman_wx1_taptimer.yaml
  26. 1 2
      custom_components/tuya_local/devices/holman_wx2_taptimer.yaml
  27. 1 2
      custom_components/tuya_local/devices/holman_wx8_irrigation_controller.yaml
  28. 28 24
      custom_components/tuya_local/devices/hysen_hy08we2_thermostat.yaml
  29. 0 3
      custom_components/tuya_local/devices/immax_neo_light_vento.yaml
  30. 1 1
      custom_components/tuya_local/devices/inkbird_bbq4t_thermometer.yaml
  31. 1 1
      custom_components/tuya_local/devices/inkbird_bbq4t_thermometerv2.yaml
  32. 0 12
      custom_components/tuya_local/devices/inkbird_ibs_m1s.yaml
  33. 3 3
      custom_components/tuya_local/devices/inkbird_itc308_thermostat.yaml
  34. 0 1
      custom_components/tuya_local/devices/ironzon_fingerprint_lock.yaml
  35. 0 8
      custom_components/tuya_local/devices/its_45hd_heatpump.yaml
  36. 1 1
      custom_components/tuya_local/devices/kabum_smart500_vacuum.yaml
  37. 0 18
      custom_components/tuya_local/devices/ledlux_thermostat.yaml
  38. 1 1
      custom_components/tuya_local/devices/lenovo_e1_vacuum.yaml
  39. 0 1
      custom_components/tuya_local/devices/leos_loo_too.yaml
  40. 0 7
      custom_components/tuya_local/devices/lytmi_hdmisync_backlight.yaml
  41. 8 7
      custom_components/tuya_local/devices/minco_mh1823d_thermostat.yaml
  42. 4 2
      custom_components/tuya_local/devices/mrc_magnum_floorheater.yaml
  43. 1 1
      custom_components/tuya_local/devices/nx_100ap_air_purifier.yaml
  44. 2 2
      custom_components/tuya_local/devices/orion_outdoor_siren.yaml
  45. 2 2
      custom_components/tuya_local/devices/probreeze_pb20.yaml
  46. 0 1
      custom_components/tuya_local/devices/proscenic_m9_vacuum.yaml
  47. 1 1
      custom_components/tuya_local/devices/rgb_light_bar.yaml
  48. 1 1
      custom_components/tuya_local/devices/rotenso_ronir35wi_heatpump.yaml
  49. 0 1
      custom_components/tuya_local/devices/rotenso_ronix_heatpump.yaml
  50. 1 2
      custom_components/tuya_local/devices/sencor_air_conditioner.yaml
  51. 1 1
      custom_components/tuya_local/devices/smart_led_strip.yaml
  52. 0 1
      custom_components/tuya_local/devices/smart_siren_alarm.yaml
  53. 0 6
      custom_components/tuya_local/devices/suntec_coolfix_airconditioner.yaml
  54. 1 1
      custom_components/tuya_local/devices/tonepie_t1pro_catlitterbox.yaml
  55. 8 5
      custom_components/tuya_local/devices/tv_backlights.yaml
  56. 1 1
      custom_components/tuya_local/devices/ultenic_t10_vacuum.yaml
  57. 1 2
      custom_components/tuya_local/devices/vivosun_de0003_dehumidifier.yaml
  58. 0 1
      custom_components/tuya_local/devices/yp_petfeeeder.yaml
  59. 2 2
      custom_components/tuya_local/devices/yx316wifi_aroma_diffuser.yaml
  60. 3 4
      custom_components/tuya_local/devices/yym_805SW_aroma_nightlight.yaml
  61. 0 4
      custom_components/tuya_local/devices/zg205w_mmWave_presence_sensor.yaml
  62. 143 0
      tests/test_device_config.py

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

@@ -29,11 +29,11 @@ secondary_entities:
             value: true
             value: true
   - entity: sensor
   - entity: sensor
     class: battery
     class: battery
-    unit: "%"
     dps:
     dps:
       - id: 2
       - id: 2
         type: integer
         type: integer
         name: sensor
         name: sensor
+        unit: "%"
   - entity: binary_sensor
   - entity: binary_sensor
     class: plug
     class: plug
     dps:
     dps:

+ 1 - 2
custom_components/tuya_local/devices/README.md

@@ -32,8 +32,7 @@ listing can also have an optional `name`, which is intended to specify the
 specific brand and model name or number of the matching device.  In future
 specific brand and model name or number of the matching device.  In future
 when local discovery is implemented to discover products by id, this name will
 when local discovery is implemented to discover products by id, this name will
 be displayed on discovery, and be available as manufacturer and model info
 be displayed on discovery, and be available as manufacturer and model info
-in device settings (so probably in future name will be split into manufacturer
-and model, but for now, putting them together as name is OK).
+in device settings.
 
 
 ### `primary_entity`
 ### `primary_entity`
 
 

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

@@ -104,7 +104,7 @@ secondary_entities:
         range:
         range:
           min: 1
           min: 1
           max: 1200
           max: 1200
-          unit: s
+        unit: s
   - entity: number
   - entity: number
     category: config
     category: config
     icon: "mdi:alarm"
     icon: "mdi:alarm"
@@ -117,4 +117,4 @@ secondary_entities:
         range:
         range:
           min: 0
           min: 0
           max: 100
           max: 100
-          unit: s
+        unit: s

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

@@ -1,5 +1,5 @@
 name: Planter
 name: Planter
-products:
+#products:
 #  - id:
 #  - id:
 #    name: ASIP-0622 indoor planter
 #    name: ASIP-0622 indoor planter
 primary_entity:
 primary_entity:

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

@@ -56,7 +56,6 @@ secondary_entities:
         name: current_temperature
         name: current_temperature
         type: integer
         type: integer
         unit: F
         unit: F
-        icon: "mdi:thermometer"
   - entity: light
   - entity: light
     name: Display
     name: Display
     category: config
     category: config

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

@@ -514,7 +514,6 @@ secondary_entities:
       - id: 137
       - id: 137
         type: integer
         type: integer
         name: value
         name: value
-        mode: box
         unit: min
         unit: min
         range:
         range:
           min: 0
           min: 0

+ 1 - 2
custom_components/tuya_local/devices/aubess_rainpoint_irrigation_system.yaml

@@ -1,8 +1,7 @@
 name: Irrigation system
 name: Irrigation system
 products:
 products:
   - id: 2ak7r2culspkc7hx
   - id: 2ak7r2culspkc7hx
-    model: RainPoint TTP106W
-    manufacturer: Aubess
+    name: Aubess RainPoint TTP106W
 primary_entity:
 primary_entity:
   entity: switch
   entity: switch
   icon: "mdi:pipe-valve"
   icon: "mdi:pipe-valve"

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

@@ -81,12 +81,12 @@ secondary_entities:
           max: 5
           max: 5
   - entity: number
   - entity: number
     name: High limit temperature ceiling
     name: High limit temperature ceiling
+    icon: "mdi:thermometer-alert"
     category: config
     category: config
     dps:
     dps:
       - id: 19
       - id: 19
         name: value
         name: value
         type: integer
         type: integer
-        icon: "mdi:thermometer-alert"
         range:
         range:
           min: 45
           min: 45
           max: 70
           max: 70

+ 0 - 2
custom_components/tuya_local/devices/beok_tr9b_thermostat.yaml

@@ -137,7 +137,6 @@ secondary_entities:
     name: High temperature limit
     name: High temperature limit
     category: config
     category: config
     class: temperature
     class: temperature
-    icon: "mdi:thermometer"
     dps:
     dps:
       - id: 19
       - id: 19
         type: integer
         type: integer
@@ -158,7 +157,6 @@ secondary_entities:
         name: value
         name: value
         type: integer
         type: integer
         unit: C
         unit: C
-        icon: "mdi:thermometer"
         range:
         range:
           min: 50
           min: 50
           max: 10000
           max: 10000

+ 3 - 3
custom_components/tuya_local/devices/ble_hu06_lock.yaml

@@ -201,9 +201,9 @@ secondary_entities:
         range:
         range:
           min: 10
           min: 10
           max: 180
           max: 180
-          mapping:
-            - step: 10
-          unit: s
+        mapping:
+          - step: 10
+        unit: s
   - entity: binary_sensor
   - entity: binary_sensor
     class: door
     class: door
     category: diagnostic
     category: diagnostic

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

@@ -6,7 +6,7 @@ products:
   - id: bfc513e1f9d4d259a10wzu
   - id: bfc513e1f9d4d259a10wzu
     name: Diivoo Water Timer Valve WT-03
     name: Diivoo Water Timer Valve WT-03
   - id: nxquc5lb
   - id: nxquc5lb
-    model: SOP10
+    name: SOP10
   - id: so5ybnw9
   - id: so5ybnw9
     name: BWC-495.bt Royal Gardineer
     name: BWC-495.bt Royal Gardineer
 primary_entity:
 primary_entity:

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

@@ -1,9 +1,9 @@
 # Bresser 7-in-1 ClimateConnect Tuya Smart Home Weather Centre
 # Bresser 7-in-1 ClimateConnect Tuya Smart Home Weather Centre
 # https://www.bresser.de/en/Weather-Time/BRESSER-7-in-1-ClimateConnect-Tuya-Smart-Home-Weather-Centre.html
 # https://www.bresser.de/en/Weather-Time/BRESSER-7-in-1-ClimateConnect-Tuya-Smart-Home-Weather-Centre.html
-name: Bresser weather station
+name: Weather station
 products:
 products:
   - id: 8qk6p78udvbjwlof
   - id: 8qk6p78udvbjwlof
-    model: C6085A
+    name: Bresser C6085A
 primary_entity:
 primary_entity:
   entity: sensor
   entity: sensor
   name: Indoor temperature
   name: Indoor temperature

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

@@ -155,7 +155,7 @@ secondary_entities:
     class: problem
     class: problem
     name: Tank full
     name: Tank full
     icon: "mdi:cup-outline"
     icon: "mdi:cup-outline"
-    icon-priority: 2
+    icon_priority: 2
     dps:
     dps:
       - id: 11
       - id: 11
         type: bitfield
         type: bitfield
@@ -165,7 +165,7 @@ secondary_entities:
           - dps_val: 8
           - dps_val: 8
             value: true
             value: true
             icon: "mdi:cup-water"
             icon: "mdi:cup-water"
-            icon-priority: 1
+            icon_priority: 1
           - value: false
           - value: false
   - entity: binary_sensor
   - entity: binary_sensor
     name: Defrost
     name: Defrost

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

@@ -4,11 +4,11 @@ products:
 primary_entity:
 primary_entity:
   entity: fan
   entity: fan
   translation_only_key: fan_with_presets
   translation_only_key: fan_with_presets
+  icon: "mdi:air-purifier"
   dps:
   dps:
     - id: 1
     - id: 1
       name: switch
       name: switch
       type: boolean
       type: boolean
-      icon: "mdi:air-purifier"
     - id: 3
     - id: 3
       name: preset_mode
       name: preset_mode
       type: string
       type: string

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

@@ -25,7 +25,6 @@ secondary_entities:
       - id: 101
       - id: 101
         name: sensor
         name: sensor
         type: integer
         type: integer
-    type: integer
   - entity: button
   - entity: button
     class: restart
     class: restart
     name: Factory reset
     name: Factory reset

+ 2 - 1
custom_components/tuya_local/devices/cleanair_605b_humidifier.yaml

@@ -14,7 +14,8 @@ primary_entity:
       range:
       range:
         min: 30
         min: 30
         max: 75
         max: 75
-        step: 5
+      mapping:
+        - step: 5
     - id: 14
     - id: 14
       name: current_humidity
       name: current_humidity
       type: integer
       type: integer

+ 13 - 8
custom_components/tuya_local/devices/cooper_hunter_air_conditioner.yaml

@@ -145,14 +145,19 @@ secondary_entities:
       - id: 9
       - id: 9
         name: switch
         name: switch
         type: boolean
         type: boolean
-        constraint: mode
-        conditions:
-          - dps_val: auto
-            invalid: true
-          - dps_val: wind
-            invalid: true
-          - dps_val: hot
-            invalid: true
+        mapping:
+          - constraint: mode
+            conditions:
+              - dps_val: auto
+                invalid: true
+              - dps_val: wind
+                invalid: true
+              - dps_val: hot
+                invalid: true
+      - id: 4
+        name: mode
+        type: string
+        hidden: true
   - entity: switch
   - entity: switch
     name: Ioniser
     name: Ioniser
     category: config
     category: config

+ 1 - 2
custom_components/tuya_local/devices/diivoo_wt05.yaml

@@ -15,8 +15,7 @@
 name: Dual water timer
 name: Dual water timer
 products:
 products:
   - id: fdrbxxbg
   - id: fdrbxxbg
-    manufacturer: Diivoo
-    model: WT-05
+    name: Diivoo WT-05
 primary_entity:
 primary_entity:
   entity: switch
   entity: switch
   icon: "mdi:pipe-valve"
   icon: "mdi:pipe-valve"

+ 2 - 3
custom_components/tuya_local/devices/dongguan_garage_door_opener.yaml

@@ -2,11 +2,10 @@
 # Tuya Smart Life WiFi Motorized Swing Gate Sliding Gate Opener Dry Contact
 # Tuya Smart Life WiFi Motorized Swing Gate Sliding Gate Opener Dry Contact
 # 110V 240V Voice Control with Alexa Google Home
 # 110V 240V Voice Control with Alexa Google Home
 # https://www.aliexpress.com/item/1005003913566298.html
 # https://www.aliexpress.com/item/1005003913566298.html
-name: WiFi garage opener
+name: Garage opener
 products:
 products:
   - id: 1wwbzczt9hrtwqjr
   - id: 1wwbzczt9hrtwqjr
-    name: Dongguan garage door
-    model: PJ-WGDOOR01
+    name: Dongguan PJ-WGDOOR01
 primary_entity:
 primary_entity:
   entity: cover
   entity: cover
   class: garage
   class: garage

+ 2 - 1
custom_components/tuya_local/devices/dts238_7_energy_meter.yaml

@@ -51,7 +51,8 @@ secondary_entities:
         name: sensor
         name: sensor
         unit: kW
         unit: kW
         class: measurement
         class: measurement
-        scale: 10000
+        mapping:
+          - scale: 10000
   - entity: binary_sensor
   - entity: binary_sensor
     name: Fault
     name: Fault
     class: problem
     class: problem

+ 0 - 3
custom_components/tuya_local/devices/earu_smart_wifi_circuit_breaker_with_energy_monitor.yaml

@@ -36,7 +36,6 @@ secondary_entities:
         type: base64
         type: base64
         unit: V
         unit: V
         class: measurement
         class: measurement
-        persist: true
         name: sensor
         name: sensor
         mapping:
         mapping:
           - mask: "FFFF000000000000"
           - mask: "FFFF000000000000"
@@ -49,7 +48,6 @@ secondary_entities:
         optional: true
         optional: true
         force: true
         force: true
         type: base64
         type: base64
-        persist: true
         unit: A
         unit: A
         name: sensor
         name: sensor
         mapping:
         mapping:
@@ -64,7 +62,6 @@ secondary_entities:
         force: true
         force: true
         type: base64
         type: base64
         unit: kW
         unit: kW
-        persist: true
         name: sensor
         name: sensor
         mapping:
         mapping:
           - mask: "0000000000FFFFFF"
           - mask: "0000000000FFFFFF"

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

@@ -133,13 +133,13 @@ secondary_entities:
   - entity: number
   - entity: number
     name: Temperature correction
     name: Temperature correction
     category: config
     category: config
+    icon: "mdi:wrench-clock"
     mode: slider
     mode: slider
     dps:
     dps:
       - id: 27
       - id: 27
         name: value
         name: value
         type: integer
         type: integer
         unit: C
         unit: C
-        icon: "mdi:wrench-clock"
         range:
         range:
           min: -100
           min: -100
           max: 100
           max: 100

+ 1 - 2
custom_components/tuya_local/devices/garza_irrigation_system.yaml

@@ -1,8 +1,7 @@
 name: Garden irrigation system
 name: Garden irrigation system
 products:
 products:
   - id: xnajzurgqo1ugohn
   - id: xnajzurgqo1ugohn
-    model: ITV103W
-    manufacturer: Garza
+    name: Garza ITV103W
 primary_entity:
 primary_entity:
   entity: switch
   entity: switch
   icon: "mdi:watering-can"
   icon: "mdi:watering-can"

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

@@ -94,7 +94,6 @@ secondary_entities:
     name: Clear energy
     name: Clear energy
     class: restart
     class: restart
     category: config
     category: config
-    hidden: true
     dps:
     dps:
       - id: 16
       - id: 16
         type: boolean
         type: boolean

+ 1 - 2
custom_components/tuya_local/devices/holman_wx1_taptimer.yaml

@@ -1,8 +1,7 @@
 name: Tap timer
 name: Tap timer
 products:
 products:
   - id: zrsgzc8jktsricjj
   - id: zrsgzc8jktsricjj
-    model: WX1
-    manufacturer: Holman
+    name: Holman WX1
     # DP decoding thanks to funtastix
     # DP decoding thanks to funtastix
 primary_entity:
 primary_entity:
   entity: switch
   entity: switch

+ 1 - 2
custom_components/tuya_local/devices/holman_wx2_taptimer.yaml

@@ -1,8 +1,7 @@
 name: Tap timer
 name: Tap timer
 products:
 products:
   - id: wfchjk5vc9bysjtk
   - id: wfchjk5vc9bysjtk
-    model: WX2
-    manufacturer: Holman
+    name: Holman WX2
 primary_entity:
 primary_entity:
   entity: switch
   entity: switch
   name: Manual 1
   name: Manual 1

+ 1 - 2
custom_components/tuya_local/devices/holman_wx8_irrigation_controller.yaml

@@ -1,8 +1,7 @@
 name: Irrigation Controller
 name: Irrigation Controller
 products:
 products:
   - id: 3c8bxnseywh7radc
   - id: 3c8bxnseywh7radc
-    model: WX8
-    manufacturer: Holman
+    name: Holman WX8
 primary_entity:
 primary_entity:
   entity: binary_sensor
   entity: binary_sensor
   class: running
   class: running

+ 28 - 24
custom_components/tuya_local/devices/hysen_hy08we2_thermostat.yaml

@@ -219,12 +219,13 @@ secondary_entities:
         range:
         range:
           min: 35
           min: 35
           max: 70
           max: 70
-        constraint: unit
-        conditions:
-          - dps_val: true
-            range:
-              min: 95
-              max: 158
+        mapping:
+          - constraint: unit
+            conditions:
+              - dps_val: true
+                range:
+                  min: 95
+                  max: 158
       - id: 101
       - id: 101
         type: boolean
         type: boolean
         name: unit
         name: unit
@@ -244,12 +245,13 @@ secondary_entities:
         range:
         range:
           min: 1
           min: 1
           max: 10
           max: 10
-        constraint: unit
-        conditions:
-          - dps_val: true
-            range:
-              min: 34
-              max: 50
+        mapping:
+          - constraint: unit
+            conditions:
+              - dps_val: true
+                range:
+                  min: 34
+                  max: 50
       - id: 101
       - id: 101
         type: boolean
         type: boolean
         name: unit
         name: unit
@@ -269,12 +271,13 @@ secondary_entities:
         range:
         range:
           min: 2
           min: 2
           max: 70
           max: 70
-        constraint: unit
-        conditions:
-          - dps_val: true
-            range:
-              min: 36
-              max: 158
+        mapping:
+          - constraint: unit
+            conditions:
+              - dps_val: true
+                range:
+                  min: 36
+                  max: 158
       - id: 101
       - id: 101
         type: boolean
         type: boolean
         name: unit
         name: unit
@@ -294,12 +297,13 @@ secondary_entities:
         range:
         range:
           min: 1
           min: 1
           max: 10
           max: 10
-        constraint: unit
-        conditions:
-          - dps_val: true
-            range:
-              min: 34
-              max: 50
+        mapping:
+          - constraint: unit
+            conditions:
+              - dps_val: true
+                range:
+                  min: 34
+                  max: 50
       - id: 101
       - id: 101
         type: boolean
         type: boolean
         name: unit
         name: unit

+ 0 - 3
custom_components/tuya_local/devices/immax_neo_light_vento.yaml

@@ -12,7 +12,6 @@ primary_entity:
     - id: 2
     - id: 2
       type: string
       type: string
       name: preset_mode
       name: preset_mode
-      category: config
       mapping:
       mapping:
         - dps_val: normal
         - dps_val: normal
           value: normal
           value: normal
@@ -23,7 +22,6 @@ primary_entity:
     - id: 3
     - id: 3
       name: speed
       name: speed
       type: integer
       type: integer
-      category: config
       range:
       range:
         min: 1
         min: 1
         max: 6
         max: 6
@@ -37,7 +35,6 @@ primary_entity:
     - id: 8
     - id: 8
       name: direction
       name: direction
       type: string
       type: string
-      category: config
 secondary_entities:
 secondary_entities:
   - entity: light
   - entity: light
     dps:
     dps:

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

@@ -60,7 +60,7 @@ secondary_entities:
         unit: F
         unit: F
   - entity: binary_sensor
   - entity: binary_sensor
     class: power
     class: power
-    category: diagnostics
+    category: diagnostic
     dps:
     dps:
       - id: 1
       - id: 1
         type: boolean
         type: boolean

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

@@ -65,7 +65,7 @@ secondary_entities:
         unit: F
         unit: F
   - entity: binary_sensor
   - entity: binary_sensor
     class: power
     class: power
-    category: diagnostics
+    category: diagnostic
     dps:
     dps:
       - id: 1
       - id: 1
         type: boolean
         type: boolean

+ 0 - 12
custom_components/tuya_local/devices/inkbird_ibs_m1s.yaml

@@ -32,7 +32,6 @@ primary_entity:
           endianness: little
           endianness: little
           mask: "FFFF00"
           mask: "FFFF00"
           constraint: type
           constraint: type
-          constraint_decode: true
           conditions:
           conditions:
             - dps_val: 0
             - dps_val: 0
               invalid: true
               invalid: true
@@ -59,7 +58,6 @@ secondary_entities:
           - endianness: little
           - endianness: little
             mask: "FF000000000000000000"
             mask: "FF000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -86,7 +84,6 @@ secondary_entities:
             endianness: little
             endianness: little
             mask: "FFFF0000000000000000000000"
             mask: "FFFF0000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -112,7 +109,6 @@ secondary_entities:
           - endianness: little
           - endianness: little
             mask: "FF00000000000000000000000000000000000000"
             mask: "FF00000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -139,7 +135,6 @@ secondary_entities:
             endianness: little
             endianness: little
             mask: "FFFF000000000000000000000000000000000000000000"
             mask: "FFFF000000000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -165,7 +160,6 @@ secondary_entities:
           - endianness: little
           - endianness: little
             mask: "FF0000000000000000000000000000000000000000000000000000000000"
             mask: "FF0000000000000000000000000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -194,7 +188,6 @@ secondary_entities:
             mask: >-
             mask: >-
               FFFF00000000000000000000000000000000000000000000000000000000000000
               FFFF00000000000000000000000000000000000000000000000000000000000000
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -222,7 +215,6 @@ secondary_entities:
             mask: "FF000000000000000000000000000000000000000\
             mask: "FF000000000000000000000000000000000000000\
               000000000000000000000000000000000000000"
               000000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -251,7 +243,6 @@ secondary_entities:
             mask: "FFFF00000000000000000000000000000000000000\
             mask: "FFFF00000000000000000000000000000000000000\
               00000000000000000000000000000000000000000000"
               00000000000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -279,7 +270,6 @@ secondary_entities:
             mask: "FF000000000000000000000000000000000000000000000\
             mask: "FF000000000000000000000000000000000000000000000\
               00000000000000000000000000000000000000000000000000000"
               00000000000000000000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -308,7 +298,6 @@ secondary_entities:
             mask: "FFFF00000000000000000000000000000000000000000000000\
             mask: "FFFF00000000000000000000000000000000000000000000000\
               0000000000000000000000000000000000000000000000000000000"
               0000000000000000000000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true
@@ -336,7 +325,6 @@ secondary_entities:
             mask: "FF00000000000000000000000000000000000000000000000000000000\
             mask: "FF00000000000000000000000000000000000000000000000000000000\
               00000000000000000000000000000000000000000000000000000000000000"
               00000000000000000000000000000000000000000000000000000000000000"
             constraint: type
             constraint: type
-            constraint_decode: true
             conditions:
             conditions:
               - dps_val: 0
               - dps_val: 0
                 invalid: true
                 invalid: true

+ 3 - 3
custom_components/tuya_local/devices/inkbird_itc308_thermostat.yaml

@@ -66,8 +66,8 @@ primary_entity:
       name: hvac_action
       name: hvac_action
       mapping:
       mapping:
         - dps_val: "0"
         - dps_val: "0"
-          icon: "mdi-thermometer-off"
-          icon-priority: 5
+          icon: "mdi:thermometer-off"
+          icon_priority: 5
           value: idle
           value: idle
         - dps_val: "1"
         - dps_val: "1"
           icon: "mdi:snowflake"
           icon: "mdi:snowflake"
@@ -220,7 +220,7 @@ secondary_entities:
   - entity: number
   - entity: number
     category: config
     category: config
     name: Heating hysteresis
     name: Heating hysteresis
-    icon: "mdi: thermometer-chevron-up"
+    icon: "mdi:thermometer-chevron-up"
     dps:
     dps:
       - id: 117
       - id: 117
         name: value
         name: value

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

@@ -39,7 +39,6 @@ primary_entity:
       type: integer
       type: integer
       name: unlock_voice
       name: unlock_voice
       optional: true
       optional: true
-      persist: true
     - id: 64
     - id: 64
       type: string
       type: string
       name: offline_password_timestamp
       name: offline_password_timestamp

+ 0 - 8
custom_components/tuya_local/devices/its_45hd_heatpump.yaml

@@ -71,38 +71,30 @@ primary_entity:
     - id: 30
     - id: 30
       type: boolean
       type: boolean
       name: chlorination
       name: chlorination
-      attribute: true
     - id: 32
     - id: 32
       type: boolean
       type: boolean
       name: aux_heat
       name: aux_heat
-      readonly: true
     - id: 40
     - id: 40
       type: integer
       type: integer
       name: model_code
       name: model_code
     - id: 101
     - id: 101
       type: integer
       type: integer
       name: current
       name: current
-      attribute: true
     - id: 102
     - id: 102
       type: integer
       type: integer
       name: voltage
       name: voltage
-      attribute: true
     - id: 103
     - id: 103
       type: integer
       type: integer
       name: power
       name: power
-      attribute: true
     - id: 104
     - id: 104
       type: integer
       type: integer
       name: energy
       name: energy
-      attribute: true
     - id: 105
     - id: 105
       type: boolean
       type: boolean
       name: electricity_monitor
       name: electricity_monitor
-      attribute: true
     - id: 106
     - id: 106
       type: boolean
       type: boolean
       name: linkage
       name: linkage
-      attribute: true
     - id: 108
     - id: 108
       type: boolean
       type: boolean
       name: dipswitch_1
       name: dipswitch_1

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

@@ -54,7 +54,7 @@ primary_entity:
           value: smart
           value: smart
         - dps_val: spiral
         - dps_val: spiral
           value: clean_spot
           value: clean_spot
-        - dps_value: single
+        - dps_val: single
           value: single_room
           value: single_room
         - dps_val: wall_follow
         - dps_val: wall_follow
           value: wall_follow
           value: wall_follow

+ 0 - 18
custom_components/tuya_local/devices/ledlux_thermostat.yaml

@@ -145,12 +145,6 @@ secondary_entities:
         range:
         range:
           min: 1
           min: 1
           max: 10
           max: 10
-        constraint: unit
-        conditions:
-          - dps_val: true
-            range:
-              min: 34
-              max: 50
         unit: C
         unit: C
   - entity: number
   - entity: number
     name: High temperature limit
     name: High temperature limit
@@ -163,12 +157,6 @@ secondary_entities:
         range:
         range:
           min: 2
           min: 2
           max: 70
           max: 70
-        constraint: unit
-        conditions:
-          - dps_val: true
-            range:
-              min: 36
-              max: 158
         unit: C
         unit: C
   - entity: number
   - entity: number
     name: Low temperature limit
     name: Low temperature limit
@@ -181,12 +169,6 @@ secondary_entities:
         range:
         range:
           min: 1
           min: 1
           max: 10
           max: 10
-        constraint: unit
-        conditions:
-          - dps_val: true
-            range:
-              min: 34
-              max: 50
         unit: C
         unit: C
   - entity: select
   - entity: select
     name: Initial state
     name: Initial state

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

@@ -192,7 +192,7 @@ secondary_entities:
       - id: 115
       - id: 115
         type: boolean
         type: boolean
         name: button
         name: button
-        optional: trus
+        optional: true
   - entity: select
   - entity: select
     name: Scheduled clean
     name: Scheduled clean
     icon: "mdi:robot-vacuum"
     icon: "mdi:robot-vacuum"

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

@@ -28,7 +28,6 @@ secondary_entities:
       - id: 2
       - id: 2
         type: string
         type: string
         name: option
         name: option
-        category: config
         mapping:
         mapping:
           - dps_val: auto_clean
           - dps_val: auto_clean
             value: Auto clean
             value: Auto clean

+ 0 - 7
custom_components/tuya_local/devices/lytmi_hdmisync_backlight.yaml

@@ -80,7 +80,6 @@ secondary_entities:
   - entity: number
   - entity: number
     category: config
     category: config
     name: Degree of diffusion
     name: Degree of diffusion
-    type: integer
     mode: slider
     mode: slider
     dps:
     dps:
       - id: 108
       - id: 108
@@ -95,12 +94,6 @@ secondary_entities:
             step: 10
             step: 10
   - entity: select
   - entity: select
     name: Scene
     name: Scene
-    format:
-      - name: scene_num
-        bytes: 2
-        range:
-          min: 1
-          max: 8
     icon: "mdi:palette"
     icon: "mdi:palette"
     category: config
     category: config
     dps:
     dps:

+ 8 - 7
custom_components/tuya_local/devices/minco_mh1823d_thermostat.yaml

@@ -223,13 +223,14 @@ secondary_entities:
         range:
         range:
           min: 5
           min: 5
           max: 65
           max: 65
-        constraint: unit
-        conditions:
-          - dps_val: f
-            value_redirect: max_temp_f
-            range:
-              min: 41
-              max: 150
+        mapping:
+          - constraint: unit
+            conditions:
+              - dps_val: f
+                value_redirect: max_temp_f
+                range:
+                  min: 41
+                  max: 150
       - id: 107
       - id: 107
         type: integer
         type: integer
         name: max_temp_f
         name: max_temp_f

+ 4 - 2
custom_components/tuya_local/devices/mrc_magnum_floorheater.yaml

@@ -341,7 +341,8 @@ secondary_entities:
         type: integer
         type: integer
         name: sensor
         name: sensor
         unit: "%"
         unit: "%"
-        mask: 00FF
+        mapping:
+          - mask: 00FF
   - entity: sensor
   - entity: sensor
     name: Yearly consumption
     name: Yearly consumption
     category: diagnostic
     category: diagnostic
@@ -350,7 +351,8 @@ secondary_entities:
         type: integer
         type: integer
         name: sensor
         name: sensor
         unit: "%"
         unit: "%"
-        mask: FF00
+        mapping:
+          - mask: FF00
   - entity: select
   - entity: select
     name: Floor covering
     name: Floor covering
     icon: "mdi:floor-plan"
     icon: "mdi:floor-plan"

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

@@ -5,11 +5,11 @@ products:
 primary_entity:
 primary_entity:
   entity: fan
   entity: fan
   translation_only_key: fan_with_presets
   translation_only_key: fan_with_presets
+  icon: "mdi:air-purifier"
   dps:
   dps:
     - id: 1
     - id: 1
       name: switch
       name: switch
       type: boolean
       type: boolean
-      icon: "mdi:air-purifier"
     - id: 3
     - id: 3
       name: preset_mode
       name: preset_mode
       type: string
       type: string

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

@@ -1,9 +1,9 @@
 name: Outdoor siren
 name: Outdoor siren
 products:
 products:
   - id: im2eqqhj72suwwko
   - id: im2eqqhj72suwwko
-    model: Orion SWS08HA
+    name: Orion SWS08HA
   - id: likuc5ld1ap3apcm
   - id: likuc5ld1ap3apcm
-    model: Elesion NX-4980
+    name: Elesion NX-4980
 primary_entity:
 primary_entity:
   entity: siren
   entity: siren
   dps:
   dps:

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

@@ -136,7 +136,7 @@ secondary_entities:
     name: Tank
     name: Tank
     class: problem
     class: problem
     icon: "mdi:cup-outline"
     icon: "mdi:cup-outline"
-    icon-priority: 2
+    icon_priority: 2
     category: diagnostic
     category: diagnostic
     dps:
     dps:
       - id: 11
       - id: 11
@@ -146,5 +146,5 @@ secondary_entities:
           - dps_val: 8
           - dps_val: 8
             value: true
             value: true
             icon: "mdi:cup-water"
             icon: "mdi:cup-water"
-            icon-priority: 1
+            icon_priority: 1
           - value: false
           - value: false

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

@@ -476,7 +476,6 @@ secondary_entities:
   - entity: select
   - entity: select
     name: Working mode
     name: Working mode
     icon: "mdi:vacuum"
     icon: "mdi:vacuum"
-    optional: true
     dps:
     dps:
       - id: 41
       - id: 41
         name: option
         name: option

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

@@ -67,4 +67,4 @@ secondary_entities:
           max: 86400
           max: 86400
         mapping:
         mapping:
           - scale: 60
           - scale: 60
-            steep: 60
+            step: 60

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

@@ -77,7 +77,7 @@ primary_entity:
       type: boolean
       type: boolean
       name: temperature_unit
       name: temperature_unit
       mapping:
       mapping:
-        - dps_vali: true
+        - dps_val: true
           value: F
           value: F
         - value: C
         - value: C
     - id: 104
     - id: 104

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

@@ -262,7 +262,6 @@ secondary_entities:
             value: false
             value: false
           - value: true
           - value: true
   - entity: sensor
   - entity: sensor
-    name:
     class: pm25
     class: pm25
     category: diagnostic
     category: diagnostic
     dps:
     dps:

+ 1 - 2
custom_components/tuya_local/devices/sencor_air_conditioner.yaml

@@ -1,8 +1,7 @@
 name: Air conditioner
 name: Air conditioner
 products:
 products:
   - id: ypgwqvhjrl5chq6h
   - id: ypgwqvhjrl5chq6h
-    model: SAC MT7048C Air Conditioner
-    manufacturer: Sencor
+    name: Sencor SAC MT7048C
 primary_entity:
 primary_entity:
   entity: climate
   entity: climate
   translation_only_key: aircon_extra
   translation_only_key: aircon_extra

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

@@ -37,11 +37,11 @@ primary_entity:
       range:
       range:
         min: 0
         min: 0
         max: 1000
         max: 1000
-      invert: true
       mapping:
       mapping:
         - target_range:
         - target_range:
             min: 2700
             min: 2700
             max: 6500
             max: 6500
+          invert: true
     - id: 24
     - id: 24
       name: rgbhsv
       name: rgbhsv
       type: hex
       type: hex

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

@@ -5,7 +5,6 @@ products:
 primary_entity:
 primary_entity:
   entity: alarm_control_panel
   entity: alarm_control_panel
   name: Status
   name: Status
-  trigger: true
   icon: "mdi:shield-off-outline"
   icon: "mdi:shield-off-outline"
   dps:
   dps:
     - id: 116
     - id: 116

+ 0 - 6
custom_components/tuya_local/devices/suntec_coolfix_airconditioner.yaml

@@ -22,12 +22,6 @@ primary_entity:
               value: fan_only
               value: fan_only
             - dps_val: Heat
             - dps_val: Heat
               value: heat
               value: heat
-              mapping:
-                - constraint: model_id
-                  conditions:
-                    - dps_val: C
-                      hidden: true
-                      invalid: true
     - id: 2
     - id: 2
       type: integer
       type: integer
       name: temperature
       name: temperature

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

@@ -29,7 +29,7 @@ secondary_entities:
         unit: visits
         unit: visits
   - entity: sensor
   - entity: sensor
     name: Time spent today
     name: Time spent today
-    mdi: "mdi:emoticon-poop"
+    icon: "mdi:emoticon-poop"
     class: duration
     class: duration
     dps:
     dps:
       - id: 8
       - id: 8

+ 8 - 5
custom_components/tuya_local/devices/tv_backlights.yaml

@@ -68,7 +68,6 @@ primary_entity:
 secondary_entities:
 secondary_entities:
   - entity: number
   - entity: number
     name: Backlight intensity
     name: Backlight intensity
-    type: integer
     mode: slider
     mode: slider
     icon: mdi:speedometer-medium
     icon: mdi:speedometer-medium
     dps:
     dps:
@@ -180,22 +179,26 @@ secondary_entities:
         type: integer
         type: integer
   - entity: sensor
   - entity: sensor
     category: diagnostic
     category: diagnostic
-    icon: mdi:arrow-expand-horizontal
+    class: distance
     name: Horizontal LED length
     name: Horizontal LED length
-    unit: dm
     dps:
     dps:
       - id: 116
       - id: 116
         name: sensor
         name: sensor
         type: integer
         type: integer
+        unit: m
+        mapping:
+          - scale: 10
   - entity: sensor
   - entity: sensor
     category: diagnostic
     category: diagnostic
-    icon: mdi:arrow-expand-vertical
+    class: distance
     name: Vertical LED length
     name: Vertical LED length
-    unit: dm
     dps:
     dps:
       - id: 117
       - id: 117
         name: sensor
         name: sensor
         type: integer
         type: integer
+        unit: m
+        mapping:
+          - scale: 10
   - entity: sensor
   - entity: sensor
     category: diagnostic
     category: diagnostic
     icon: mdi:speedometer-slow
     icon: mdi:speedometer-slow

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

@@ -27,7 +27,7 @@ primary_entity:
           value: random
           value: random
         - dps_val: smart
         - dps_val: smart
           value: smart
           value: smart
-        - dps_value: wall_follow
+        - dps_val: wall_follow
           value: wall_follow
           value: wall_follow
         - dps_val: mop
         - dps_val: mop
           value: mop
           value: mop

+ 1 - 2
custom_components/tuya_local/devices/vivosun_de0003_dehumidifier.yaml

@@ -1,8 +1,7 @@
 name: Dehumidifier
 name: Dehumidifier
 products:
 products:
   - id: qrjffdu2bjrd7v42
   - id: qrjffdu2bjrd7v42
-    name: DE0003 10L Smart Dehumidifier
-    manufacturer: Vivosun
+    name: Vivosun DE0003 10L
 primary_entity:
 primary_entity:
   entity: humidifier
   entity: humidifier
   class: dehumidifier
   class: dehumidifier

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

@@ -25,7 +25,6 @@ secondary_entities:
       - id: 15
       - id: 15
         name: sensor
         name: sensor
         type: integer
         type: integer
-    type: integer
   - entity: button
   - entity: button
     class: restart
     class: restart
     name: Factory reset
     name: Factory reset

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

@@ -1,9 +1,9 @@
 # DPS sample:  { "1": true, "2": true, "3": "MID", "7": true, "8": 1000,
 # DPS sample:  { "1": true, "2": true, "3": "MID", "7": true, "8": 1000,
 #                "9": "colourful1", "10": "", "11": 0 }
 #                "9": "colourful1", "10": "", "11": 0 }
-name: Aroma Diffuser With Lamp
+name: Aroma diffuser with lamp
 products:
 products:
   - id: arkdxfhlkpdyof9x
   - id: arkdxfhlkpdyof9x
-    model: YX316WIFI
+    name: YX316WIFI
 primary_entity:
 primary_entity:
   entity: fan
   entity: fan
   icon: "mdi:scent"
   icon: "mdi:scent"

+ 3 - 4
custom_components/tuya_local/devices/yym_805SW_aroma_nightlight.yaml

@@ -3,11 +3,11 @@
 name: Aroma diffuser
 name: Aroma diffuser
 products:
 products:
   - id: c0nh3LmEk0NDebrq
   - id: c0nh3LmEk0NDebrq
-    model: YYM-805SW
+    name: YYM-805SW
   - id: 4870500398f4abbfbae4
   - id: 4870500398f4abbfbae4
-    model: GX
+    name: GX
   - id: kgczidn0awas0prr
   - id: kgczidn0awas0prr
-    manufacturer: Tellur
+    name: Tellur
 primary_entity:
 primary_entity:
   entity: fan
   entity: fan
   dps:
   dps:
@@ -103,7 +103,6 @@ secondary_entities:
             value: "6 hours"
             value: "6 hours"
       - id: 4
       - id: 4
         name: remaining
         name: remaining
-        readolny: true
         optional: true
         optional: true
         type: integer
         type: integer
         range:
         range:

+ 0 - 4
custom_components/tuya_local/devices/zg205w_mmWave_presence_sensor.yaml

@@ -186,7 +186,6 @@ secondary_entities:
     name: Motion minimum detection distance
     name: Motion minimum detection distance
     category: config
     category: config
     icon: mdi:signal-distance-variant
     icon: mdi:signal-distance-variant
-    hidden: true
     dps:
     dps:
       - id: 110
       - id: 110
         type: integer
         type: integer
@@ -203,7 +202,6 @@ secondary_entities:
     name: Small motion minimum detection distance
     name: Small motion minimum detection distance
     category: config
     category: config
     icon: mdi:signal-distance-variant
     icon: mdi:signal-distance-variant
-    hidden: true
     dps:
     dps:
       - id: 111
       - id: 111
         type: integer
         type: integer
@@ -220,7 +218,6 @@ secondary_entities:
     name: Breathing minimum detection distance
     name: Breathing minimum detection distance
     category: config
     category: config
     icon: mdi:signal-distance-variant
     icon: mdi:signal-distance-variant
-    hidden: true
     dps:
     dps:
       - id: 112
       - id: 112
         type: integer
         type: integer
@@ -237,7 +234,6 @@ secondary_entities:
     name: Adaptive testing time
     name: Adaptive testing time
     category: config
     category: config
     icon: mdi:timer
     icon: mdi:timer
-    hidden: true
     dps:
     dps:
       - id: 113
       - id: 113
         type: integer
         type: integer

+ 143 - 0
tests/test_device_config.py

@@ -4,6 +4,7 @@ from unittest.mock import MagicMock
 
 
 from fuzzywuzzy import fuzz
 from fuzzywuzzy import fuzz
 from homeassistant.components.sensor import SensorDeviceClass
 from homeassistant.components.sensor import SensorDeviceClass
+import voluptuous as vol
 
 
 from custom_components.tuya_local.helpers.config import get_device_id
 from custom_components.tuya_local.helpers.config import get_device_id
 from custom_components.tuya_local.helpers.device_config import (
 from custom_components.tuya_local.helpers.device_config import (
@@ -19,6 +20,141 @@ from custom_components.tuya_local.sensor import TuyaLocalSensor
 
 
 from .const import GPPH_HEATER_PAYLOAD, KOGAN_HEATER_PAYLOAD
 from .const import GPPH_HEATER_PAYLOAD, KOGAN_HEATER_PAYLOAD
 
 
+
+PRODUCT_SCHEMA = vol.Schema(
+    {
+        vol.Required("id"): str,
+        vol.Optional("name"): str,
+    }
+)
+CONDMAP_SCHEMA = vol.Schema(
+    {
+        vol.Optional("dps_val"): vol.Maybe(vol.Any(str, int, bool, list)),
+        vol.Optional("value"): vol.Maybe(vol.Any(str, int, bool, float)),
+        vol.Optional("value_redirect"): str,
+        vol.Optional("value_mirror"): str,
+        vol.Optional("range"): {
+            vol.Required("min"): int,
+            vol.Required("max"): int,
+        },
+        vol.Optional("target_range"): {
+            vol.Required("min"): int,
+            vol.Required("max"): int,
+        },
+        vol.Optional("scale"): vol.Any(int, float),
+        vol.Optional("step"): vol.Any(int, float),
+        vol.Optional("mask"): str,
+        vol.Optional("endianness"): str,
+        vol.Optional("invert"): True,
+        vol.Optional("unit"): str,
+        vol.Optional("icon"): vol.Match(r"^mdi:"),
+        vol.Optional("icon_priority"): int,
+        vol.Optional("hidden"): True,
+        vol.Optional("invalid"): True,
+        vol.Optional("default"): True,
+    }
+)
+COND_SCHEMA = CONDMAP_SCHEMA.extend(
+    {
+        vol.Optional("mapping"): [CONDMAP_SCHEMA],
+    }
+)
+MAPPING_SCHEMA = CONDMAP_SCHEMA.extend(
+    {
+        vol.Optional("constraint"): str,
+        vol.Optional("conditions"): [COND_SCHEMA],
+    }
+)
+FORMAT_SCHEMA = vol.Schema(
+    {
+        vol.Required("name"): str,
+        vol.Required("bytes"): int,
+        vol.Optional("range"): {
+            vol.Required("min"): int,
+            vol.Required("max"): int,
+        },
+    }
+)
+DP_SCHEMA = vol.Schema(
+    {
+        vol.Required("id"): int,
+        vol.Required("type"): vol.In(
+            [
+                "string",
+                "integer",
+                "boolean",
+                "hex",
+                "base64",
+                "bitfield",
+                "unixtime",
+                "json",
+            ]
+        ),
+        vol.Required("name"): str,
+        vol.Optional("range"): {
+            vol.Required("min"): int,
+            vol.Required("max"): int,
+        },
+        vol.Optional("unit"): str,
+        vol.Optional("precision"): vol.Any(int, float),
+        vol.Optional("class"): str,
+        vol.Optional("optional"): True,
+        vol.Optional("persist"): False,
+        vol.Optional("hidden"): True,
+        vol.Optional("readonly"): True,
+        vol.Optional("force"): True,
+        vol.Optional("icon_priority"): int,
+        vol.Optional("mapping"): [MAPPING_SCHEMA],
+        vol.Optional("format"): [FORMAT_SCHEMA],
+    }
+)
+ENTITY_SCHEMA = vol.Schema(
+    {
+        vol.Required("entity"): vol.In(
+            [
+                "alarm_control_panel",
+                "binary_sensor",
+                "button",
+                "camera",
+                "climate",
+                "cover",
+                "event",
+                "fan",
+                "humidifier",
+                "lawn_mower",
+                "light",
+                "lock",
+                "number",
+                "remote",
+                "select",
+                "sensor",
+                "siren",
+                "switch",
+                "vacuum",
+                "water_heater",
+            ]
+        ),
+        vol.Optional("name"): str,
+        vol.Optional("class"): str,
+        vol.Optional(vol.Or("translation_key", "translation_only_key")): str,
+        vol.Optional("category"): vol.In(["config", "diagnostic"]),
+        vol.Optional("icon"): vol.Match(r"^mdi:"),
+        vol.Optional("icon_priority"): int,
+        vol.Optional("deprecated"): str,
+        vol.Optional("mode"): vol.In(["box", "slider"]),
+        vol.Required("dps"): [DP_SCHEMA],
+    }
+)
+YAML_SCHEMA = vol.Schema(
+    {
+        vol.Required("name"): str,
+        vol.Optional("legacy_type"): str,
+        vol.Optional("products"): [PRODUCT_SCHEMA],
+        vol.Required("primary_entity"): ENTITY_SCHEMA,
+        vol.Optional("secondary_entities"): [ENTITY_SCHEMA],
+    }
+)
+
 KNOWN_DPS = {
 KNOWN_DPS = {
     "alarm_control_panel": {
     "alarm_control_panel": {
         "required": ["alarm_state"],
         "required": ["alarm_state"],
@@ -342,6 +478,11 @@ class TestDeviceConfig(IsolatedAsyncioTestCase):
             if isinstance(parsed, str) or isinstance(parsed._config, str):
             if isinstance(parsed, str) or isinstance(parsed._config, str):
                 self.fail(f"unparsable yaml in {cfg}")
                 self.fail(f"unparsable yaml in {cfg}")
 
 
+            try:
+                YAML_SCHEMA(parsed._config)
+            except vol.MultipleInvalid as e:
+                self.fail(f"Validation error in {cfg}: {e}")
+
             self.assertIsNotNone(
             self.assertIsNotNone(
                 parsed._config.get("name"),
                 parsed._config.get("name"),
                 f"name missing from {cfg}",
                 f"name missing from {cfg}",
@@ -373,8 +514,10 @@ class TestDeviceConfig(IsolatedAsyncioTestCase):
 
 
     def test_match_quality(self):
     def test_match_quality(self):
         """Test the match_quality function."""
         """Test the match_quality function."""
+
         cfg = get_config("deta_fan")
         cfg = get_config("deta_fan")
         q = cfg.match_quality({**KOGAN_HEATER_PAYLOAD, "updated_at": 0})
         q = cfg.match_quality({**KOGAN_HEATER_PAYLOAD, "updated_at": 0})
+
         self.assertEqual(q, 0)
         self.assertEqual(q, 0)
         q = cfg.match_quality({**GPPH_HEATER_PAYLOAD})
         q = cfg.match_quality({**GPPH_HEATER_PAYLOAD})
         self.assertEqual(q, 0)
         self.assertEqual(q, 0)