Added Midea Dishwasher Integration
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
+1
-1
@@ -1 +1 @@
|
|||||||
{"pid": 71, "version": 1, "ha_version": "2026.6.2", "start_ts": 1781272512.3211384}
|
{"pid": 71, "version": 1, "ha_version": "2026.6.2", "start_ts": 1781274194.4665778}
|
||||||
+277
-244
@@ -1,79 +1,78 @@
|
|||||||
- id: "1780072464609"
|
- id: '1780072464609'
|
||||||
alias: "Camera: Send Motion Notifications"
|
alias: 'Camera: Send Motion Notifications'
|
||||||
description:
|
description: Sends a push notification to your primary mobile device when Nest cameras
|
||||||
Sends a push notification to your primary mobile device when Nest cameras
|
|
||||||
detect activity.
|
detect activity.
|
||||||
triggers:
|
triggers:
|
||||||
- entity_id:
|
- entity_id:
|
||||||
- camera.entryway_camera
|
- camera.entryway_camera
|
||||||
- camera.front_door
|
- camera.front_door
|
||||||
- camera.hallway_camera
|
- camera.hallway_camera
|
||||||
- camera.living_room_camera
|
- camera.living_room_camera
|
||||||
trigger: state
|
trigger: state
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
- action: notify.notify
|
- action: notify.notify
|
||||||
data:
|
data:
|
||||||
title: Motion Detected!
|
title: Motion Detected!
|
||||||
message: Activity detected on one of your Nest security cameras.
|
message: Activity detected on one of your Nest security cameras.
|
||||||
mode: parallel
|
mode: parallel
|
||||||
max: 10
|
max: 10
|
||||||
- id: "1780125759253"
|
- id: '1780125759253'
|
||||||
alias: "Tablet: Dim Screen at Night"
|
alias: 'Tablet: Dim Screen at Night'
|
||||||
description: Drops tablet brightness to zero at night
|
description: Drops tablet brightness to zero at night
|
||||||
triggers:
|
triggers:
|
||||||
- at: 01:00:00
|
- at: 01:00:00
|
||||||
trigger: time
|
trigger: time
|
||||||
actions:
|
actions:
|
||||||
- action: notify.mobile_app_sm_t387w
|
- action: notify.mobile_app_sm_t387w
|
||||||
|
data:
|
||||||
|
message: command_screen_brightness_level
|
||||||
data:
|
data:
|
||||||
message: command_screen_brightness_level
|
command: 0
|
||||||
data:
|
- id: '1780125803824'
|
||||||
command: 0
|
alias: 'Tablet: Restore Screen in Morning'
|
||||||
- id: "1780125803824"
|
|
||||||
alias: "Tablet: Restore Screen in Morning"
|
|
||||||
description: Restores tablet brightness to normal in the morning
|
description: Restores tablet brightness to normal in the morning
|
||||||
triggers:
|
triggers:
|
||||||
- at: 07:00:00
|
- at: 07:00:00
|
||||||
trigger: time
|
trigger: time
|
||||||
actions:
|
actions:
|
||||||
- action: notify.mobile_app_sm_t387w
|
- action: notify.mobile_app_sm_t387w
|
||||||
|
data:
|
||||||
|
message: command_screen_brightness_level
|
||||||
data:
|
data:
|
||||||
message: command_screen_brightness_level
|
command: 180
|
||||||
data:
|
- id: '1780343863793'
|
||||||
command: 180
|
|
||||||
- id: "1780343863793"
|
|
||||||
alias: Front Door Notification
|
alias: Front Door Notification
|
||||||
description: ""
|
description: ''
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: state
|
- trigger: state
|
||||||
entity_id:
|
entity_id:
|
||||||
- binary_sensor.front_door
|
- binary_sensor.front_door
|
||||||
from:
|
from:
|
||||||
- "off"
|
- 'off'
|
||||||
to:
|
to:
|
||||||
- "on"
|
- 'on'
|
||||||
- trigger: state
|
- trigger: state
|
||||||
entity_id:
|
entity_id:
|
||||||
- binary_sensor.patio_door
|
- binary_sensor.patio_door
|
||||||
from:
|
from:
|
||||||
- "off"
|
- 'off'
|
||||||
to:
|
to:
|
||||||
- "on"
|
- 'on'
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
- target:
|
- target:
|
||||||
entity_id:
|
entity_id:
|
||||||
- light.kitchen_home_kitchen
|
- light.kitchen_home_kitchen
|
||||||
action: light.toggle
|
action: light.toggle
|
||||||
- delay: 00:00:15
|
- delay: 00:00:15
|
||||||
- target:
|
- target:
|
||||||
entity_id:
|
entity_id:
|
||||||
- light.kitchen_home_kitchen
|
- light.kitchen_home_kitchen
|
||||||
action: light.toggle
|
action: light.toggle
|
||||||
- data:
|
- data:
|
||||||
message: There is someone at the front door
|
message: There is someone at the front door
|
||||||
action: notify.notify
|
action: notify.notify
|
||||||
mode: single
|
mode: single
|
||||||
variables:
|
variables:
|
||||||
_cafe_metadata:
|
_cafe_metadata:
|
||||||
@@ -100,43 +99,42 @@
|
|||||||
y: -555
|
y: -555
|
||||||
graph_id: 7ad98446-4ce0-4b88-a400-430ac474a617
|
graph_id: 7ad98446-4ce0-4b88-a400-430ac474a617
|
||||||
graph_version: 1
|
graph_version: 1
|
||||||
- id: "1780441470361"
|
- id: '1780441470361'
|
||||||
alias: Reload Hilo Integrations on Reboot
|
alias: Reload Hilo Integrations on Reboot
|
||||||
description:
|
description: Reloads problematic integrations 2 minutes after Home Assistant starts
|
||||||
Reloads problematic integrations 2 minutes after Home Assistant starts
|
|
||||||
up.
|
up.
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: homeassistant
|
- trigger: homeassistant
|
||||||
event: start
|
event: start
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
- delay:
|
- delay:
|
||||||
hours: 0
|
hours: 0
|
||||||
minutes: 3
|
minutes: 3
|
||||||
seconds: 0
|
seconds: 0
|
||||||
milliseconds: 0
|
milliseconds: 0
|
||||||
- action: homeassistant.reload_config_entry
|
- action: homeassistant.reload_config_entry
|
||||||
metadata: {}
|
metadata: {}
|
||||||
target:
|
target:
|
||||||
device_id:
|
device_id:
|
||||||
- 3e67afd88a4b4d17552c8f370aaf40b5
|
- 3e67afd88a4b4d17552c8f370aaf40b5
|
||||||
- baad176ac2f415f3642e2d075bb6a977
|
- baad176ac2f415f3642e2d075bb6a977
|
||||||
data: {}
|
data: {}
|
||||||
mode: single
|
mode: single
|
||||||
- id: "1780509027967"
|
- id: '1780509027967'
|
||||||
alias: Notify When Ring Console Battery Low
|
alias: Notify When Ring Console Battery Low
|
||||||
description: ""
|
description: ''
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: numeric_state
|
- trigger: numeric_state
|
||||||
entity_id:
|
entity_id:
|
||||||
- sensor.entryway_keypad_battery
|
- sensor.entryway_keypad_battery
|
||||||
below: 25
|
below: 25
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
- data:
|
- data:
|
||||||
message: Keypad Battery Low. Please Charge ASAP
|
message: Keypad Battery Low. Please Charge ASAP
|
||||||
title: Ring Console Battery
|
title: Ring Console Battery
|
||||||
action: notify.notify
|
action: notify.notify
|
||||||
mode: single
|
mode: single
|
||||||
variables:
|
variables:
|
||||||
_cafe_metadata:
|
_cafe_metadata:
|
||||||
@@ -151,20 +149,20 @@
|
|||||||
y: 45
|
y: 45
|
||||||
graph_id: 816af3b7-3eac-47c3-8da3-8797d1774c0c
|
graph_id: 816af3b7-3eac-47c3-8da3-8797d1774c0c
|
||||||
graph_version: 1
|
graph_version: 1
|
||||||
- id: "1780516946807"
|
- id: '1780516946807'
|
||||||
alias: Notify When Front Door Sensor Battery Low
|
alias: Notify When Front Door Sensor Battery Low
|
||||||
description: ""
|
description: ''
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: numeric_state
|
- trigger: numeric_state
|
||||||
entity_id:
|
entity_id:
|
||||||
- sensor.front_door_battery
|
- sensor.front_door_battery
|
||||||
below: 25
|
below: 25
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
- data:
|
- data:
|
||||||
message: Front Door Sensor Battery Low. Please Change Batteries ASAP.
|
message: Front Door Sensor Battery Low. Please Change Batteries ASAP.
|
||||||
title: Ring Console Battery
|
title: Ring Console Battery
|
||||||
action: notify.notify
|
action: notify.notify
|
||||||
mode: single
|
mode: single
|
||||||
variables:
|
variables:
|
||||||
_cafe_metadata:
|
_cafe_metadata:
|
||||||
@@ -179,54 +177,51 @@
|
|||||||
y: 45
|
y: 45
|
||||||
graph_id: 816af3b7-3eac-47c3-8da3-8797d1774c0c
|
graph_id: 816af3b7-3eac-47c3-8da3-8797d1774c0c
|
||||||
graph_version: 1
|
graph_version: 1
|
||||||
- id: "1780813227139"
|
- id: '1780813227139'
|
||||||
alias: "Alert: Fridge or Freezer Power Outage"
|
alias: 'Alert: Fridge or Freezer Power Outage'
|
||||||
description:
|
description: Triggers an alert if the fridge or freezer smart plug power consumption
|
||||||
Triggers an alert if the fridge or freezer smart plug power consumption
|
|
||||||
drops to 0W for too long.
|
drops to 0W for too long.
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: numeric_state
|
- trigger: numeric_state
|
||||||
entity_id:
|
entity_id:
|
||||||
- sensor.freezer_power
|
- sensor.freezer_power
|
||||||
for:
|
for:
|
||||||
hours: 0
|
hours: 0
|
||||||
minutes: 45
|
minutes: 45
|
||||||
seconds: 0
|
seconds: 0
|
||||||
below: 1
|
below: 1
|
||||||
id: freezer_down
|
id: freezer_down
|
||||||
- trigger: numeric_state
|
- trigger: numeric_state
|
||||||
entity_id:
|
entity_id:
|
||||||
- sensor.fridge_power
|
- sensor.fridge_power
|
||||||
for:
|
for:
|
||||||
hours: 0
|
hours: 0
|
||||||
minutes: 20
|
minutes: 20
|
||||||
seconds: 0
|
seconds: 0
|
||||||
below: 1
|
below: 1
|
||||||
id: fridge_down
|
id: fridge_down
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
|
- if:
|
||||||
|
- condition: trigger
|
||||||
|
id: freezer_down
|
||||||
|
then:
|
||||||
|
- data:
|
||||||
|
title: "\U0001F6A8 URGENT: Freezer Power Failure"
|
||||||
|
message: The Freezer smart plug has drawn 0W of power for over 40 minutes!
|
||||||
|
Check the physical appliance immediately.
|
||||||
|
action: notify.notify
|
||||||
|
else:
|
||||||
- if:
|
- if:
|
||||||
- condition: trigger
|
- condition: trigger
|
||||||
id: freezer_down
|
id: fridge_down
|
||||||
then:
|
then:
|
||||||
- data:
|
- data:
|
||||||
title: "\U0001F6A8 URGENT: Freezer Power Failure"
|
title: "\U0001F6A8 URGENT: Fridge Power Failure"
|
||||||
message:
|
message: The Fridge smart plug has drawn 0W of power for over 20 minutes!
|
||||||
The Freezer smart plug has drawn 0W of power for over 40 minutes!
|
Check the physical appliance immediately.
|
||||||
Check the physical appliance immediately.
|
action: notify.notify
|
||||||
action: notify.notify
|
else: []
|
||||||
else:
|
|
||||||
- if:
|
|
||||||
- condition: trigger
|
|
||||||
id: fridge_down
|
|
||||||
then:
|
|
||||||
- data:
|
|
||||||
title: "\U0001F6A8 URGENT: Fridge Power Failure"
|
|
||||||
message:
|
|
||||||
The Fridge smart plug has drawn 0W of power for over 20 minutes!
|
|
||||||
Check the physical appliance immediately.
|
|
||||||
action: notify.notify
|
|
||||||
else: []
|
|
||||||
mode: single
|
mode: single
|
||||||
variables:
|
variables:
|
||||||
_cafe_metadata:
|
_cafe_metadata:
|
||||||
@@ -253,134 +248,172 @@
|
|||||||
y: 102
|
y: 102
|
||||||
graph_id: 5948b900-b45d-4c2e-ae73-c880acc3a1bf
|
graph_id: 5948b900-b45d-4c2e-ae73-c880acc3a1bf
|
||||||
graph_version: 1
|
graph_version: 1
|
||||||
- id: "1780989340205"
|
- id: '1780989340205'
|
||||||
alias: "Kitchen: Coffee Maker Active Notification"
|
alias: 'Kitchen: Coffee Maker Active Notification'
|
||||||
description:
|
description: Sends a mobile application push notification when the coffee maker
|
||||||
Sends a mobile application push notification when the coffee maker
|
|
||||||
power exceeds 1000W for 5 seconds.
|
power exceeds 1000W for 5 seconds.
|
||||||
triggers:
|
triggers:
|
||||||
- entity_id: sensor.coffee_maker_power
|
- entity_id: sensor.coffee_maker_power
|
||||||
above: 1000
|
above: 1000
|
||||||
for:
|
for:
|
||||||
hours: 0
|
hours: 0
|
||||||
minutes: 0
|
minutes: 0
|
||||||
seconds: 5
|
seconds: 5
|
||||||
trigger: numeric_state
|
trigger: numeric_state
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
- data:
|
- data:
|
||||||
title: ☕ Coffee Time
|
title: ☕ Coffee Time
|
||||||
message: Someone is Making Coffee
|
message: Someone is Making Coffee
|
||||||
action: notify.notify
|
action: notify.notify
|
||||||
- action: notify.persistent_notification
|
- action: notify.persistent_notification
|
||||||
metadata: {}
|
metadata: {}
|
||||||
data:
|
data:
|
||||||
title: ☕ Coffee Time
|
title: ☕ Coffee Time
|
||||||
message: Someone is Making Coffee
|
message: Someone is Making Coffee
|
||||||
- delay:
|
- delay:
|
||||||
hours: 0
|
hours: 0
|
||||||
minutes: 4
|
minutes: 4
|
||||||
seconds: 0
|
seconds: 0
|
||||||
milliseconds: 0
|
milliseconds: 0
|
||||||
mode: single
|
mode: single
|
||||||
- id: "1781024962776"
|
- id: '1781024962776'
|
||||||
alias: "Office: Turn On Lights on Motion then Door Open"
|
alias: 'Office: Turn On Lights on Motion then Door Open'
|
||||||
description:
|
description: Triggers when office door opens, but only if living room motion happened
|
||||||
Triggers when office door opens, but only if living room motion happened
|
|
||||||
in the last 30 seconds and light is off.
|
in the last 30 seconds and light is off.
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: state
|
- trigger: state
|
||||||
entity_id: binary_sensor.office_door_contact
|
entity_id: binary_sensor.office_door_contact
|
||||||
to: "on"
|
to: 'on'
|
||||||
conditions:
|
conditions:
|
||||||
- condition: time
|
- condition: time
|
||||||
after: "10:00:00"
|
after: '10:00:00'
|
||||||
before: "21:00:00"
|
before: '21:00:00'
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: light.playroom_light
|
entity_id: light.playroom_light
|
||||||
state: "off"
|
state: 'off'
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template:
|
value_template: '{{ (now() - states.binary_sensor.basement.last_changed).total_seconds()
|
||||||
"{{ (now() - states.binary_sensor.basement.last_changed).total_seconds()
|
< 30 }}'
|
||||||
< 30 }}"
|
|
||||||
actions:
|
actions:
|
||||||
- action: light.turn_on
|
- action: light.turn_on
|
||||||
target:
|
target:
|
||||||
entity_id: light.playroom_light
|
entity_id: light.playroom_light
|
||||||
data: {}
|
data: {}
|
||||||
mode: single
|
mode: single
|
||||||
- id: "1781034724187"
|
- id: '1781034724187'
|
||||||
alias: "Office: Turn Off Lights on Exit"
|
alias: 'Office: Turn Off Lights on Exit'
|
||||||
description:
|
description: Turns off office lights 2 minutes after the door closes, but only if living
|
||||||
Turns off office lights 2 minutes after the door closes, but only if living
|
|
||||||
room motion was detected after the door shut.
|
room motion was detected after the door shut.
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: state
|
- trigger: state
|
||||||
entity_id: binary_sensor.office_door_contact
|
entity_id: binary_sensor.office_door_contact
|
||||||
to: "off"
|
to: 'off'
|
||||||
for:
|
for:
|
||||||
minutes: 2
|
minutes: 2
|
||||||
conditions:
|
conditions:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: light.playroom_light
|
entity_id: light.playroom_light
|
||||||
state: "on"
|
state: 'on'
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template:
|
value_template: '{{ states.binary_sensor.basement.last_changed > states.binary_sensor.office_door_contact.last_changed
|
||||||
"{{ states.binary_sensor.basement.last_changed > states.binary_sensor.office_door_contact.last_changed
|
}}'
|
||||||
}}"
|
|
||||||
actions:
|
actions:
|
||||||
- action: light.turn_off
|
- action: light.turn_off
|
||||||
target:
|
target:
|
||||||
entity_id: light.playroom_light
|
entity_id: light.playroom_light
|
||||||
data: {}
|
data: {}
|
||||||
mode: single
|
mode: single
|
||||||
- id: "1781102033733"
|
- id: '1781102033733'
|
||||||
alias: Water Leak Detected
|
alias: Water Leak Detected
|
||||||
description: ""
|
description: ''
|
||||||
triggers:
|
triggers:
|
||||||
- type: moist
|
- type: moist
|
||||||
device_id: 59bc102f385d7a3524c8f21a5c53592b
|
device_id: 59bc102f385d7a3524c8f21a5c53592b
|
||||||
entity_id: c268ff8842e905515de2274d09c5ab9e
|
entity_id: c268ff8842e905515de2274d09c5ab9e
|
||||||
domain: binary_sensor
|
domain: binary_sensor
|
||||||
metadata:
|
metadata:
|
||||||
secondary: false
|
secondary: false
|
||||||
trigger: device
|
trigger: device
|
||||||
conditions: []
|
conditions: []
|
||||||
actions:
|
actions:
|
||||||
- action: notify.notify
|
- action: notify.notify
|
||||||
metadata: {}
|
metadata: {}
|
||||||
data:
|
data:
|
||||||
title: "\U0001F6A8 URGENT: Water Leak Detected"
|
title: "\U0001F6A8 URGENT: Water Leak Detected"
|
||||||
message: Water Leak Detected in Basement. Check Water Heater for Leaks.
|
message: Water Leak Detected in Basement. Check Water Heater for Leaks.
|
||||||
- action: persistent_notification.create
|
- action: persistent_notification.create
|
||||||
metadata: {}
|
metadata: {}
|
||||||
data:
|
data:
|
||||||
title: "\U0001F6A8 URGENT: Water Leak Detected"
|
title: "\U0001F6A8 URGENT: Water Leak Detected"
|
||||||
message: Water Leak Detected in Basement. Check Water Heater for Leaks.
|
message: Water Leak Detected in Basement. Check Water Heater for Leaks.
|
||||||
mode: single
|
mode: single
|
||||||
- id: "1781112110968"
|
- id: '1781112110968'
|
||||||
alias: "Freezer Safety: Alert if Plug Turns Off"
|
alias: 'Freezer Safety: Alert if Plug Turns Off'
|
||||||
description:
|
description: Triggers an immediate notification if the freezer smart plug is turned
|
||||||
Triggers an immediate notification if the freezer smart plug is turned
|
|
||||||
off.
|
off.
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: state
|
- trigger: state
|
||||||
entity_id: switch.freezer
|
entity_id: switch.freezer
|
||||||
to: "off"
|
to: 'off'
|
||||||
for:
|
for:
|
||||||
minutes: 1
|
minutes: 1
|
||||||
actions:
|
actions:
|
||||||
- action: notify.notify
|
- action: notify.notify
|
||||||
data:
|
data:
|
||||||
title: "\U0001F6A8 FREEZER PLUG TRIPPED!"
|
title: "\U0001F6A8 FREEZER PLUG TRIPPED!"
|
||||||
message:
|
message: The freezer smart plug turned off. Check it immediately to prevent
|
||||||
The freezer smart plug turned off. Check it immediately to prevent
|
food spoilage.
|
||||||
food spoilage.
|
- action: notify.persistent_notification
|
||||||
- action: notify.persistent_notification
|
metadata: {}
|
||||||
metadata: {}
|
data:
|
||||||
data:
|
title: "\U0001F6A8 FREEZER PLUG TRIPPED!"
|
||||||
title: "\U0001F6A8 FREEZER PLUG TRIPPED!"
|
message: The freezer smart plug turned off. Check it immediately to prevent
|
||||||
message:
|
food spoilage.
|
||||||
The freezer smart plug turned off. Check it immediately to prevent
|
mode: single
|
||||||
food spoilage.
|
- id: '1781275767970'
|
||||||
|
alias: 'Dishwasher: Cycle Finished Notification'
|
||||||
|
description: Alerts when the dishwasher finishes washing
|
||||||
|
triggers:
|
||||||
|
- entity_id: sensor.150633095332665_progress
|
||||||
|
from: Running
|
||||||
|
to: Idle
|
||||||
|
trigger: state
|
||||||
|
actions:
|
||||||
|
- action: notify.notify
|
||||||
|
data:
|
||||||
|
title: Dishwasher Done
|
||||||
|
message: The dishwasher cycle has completed successfully!
|
||||||
|
mode: single
|
||||||
|
- id: '1781275801564'
|
||||||
|
alias: 'Dishwasher: Rinse Aid Low Warning'
|
||||||
|
description: Alerts when rinse aid needs a refill
|
||||||
|
triggers:
|
||||||
|
- entity_id: binary_sensor.150633095332665_rinse_aid
|
||||||
|
to: 'on'
|
||||||
|
trigger: state
|
||||||
|
actions:
|
||||||
|
- action: notify.notify
|
||||||
|
data:
|
||||||
|
title: Dishwasher Maintenance
|
||||||
|
message: The dishwasher is low on rinse aid. Please refill it before the next
|
||||||
|
cycle!
|
||||||
|
mode: single
|
||||||
|
- id: '1781278655292'
|
||||||
|
alias: 'Dishwasher: Dishwasher Started Notification'
|
||||||
|
description: Alerts when the dishwasher starts washing
|
||||||
|
triggers:
|
||||||
|
- entity_id:
|
||||||
|
- sensor.150633095332665_progress
|
||||||
|
from:
|
||||||
|
- idle
|
||||||
|
to:
|
||||||
|
- running
|
||||||
|
trigger: state
|
||||||
|
conditions: []
|
||||||
|
actions:
|
||||||
|
- action: notify.notify
|
||||||
|
data:
|
||||||
|
title: Dishwasher Started
|
||||||
|
message: The dishwasher cycle has started!
|
||||||
mode: single
|
mode: single
|
||||||
|
|||||||
@@ -0,0 +1,346 @@
|
|||||||
|
"""Init for Midea LAN.
|
||||||
|
|
||||||
|
integration load process:
|
||||||
|
1. component setup: `async_setup`
|
||||||
|
1.1 use `hass.services.async_register` to register service
|
||||||
|
2. config entry setup: `async_setup_entry`
|
||||||
|
2.1 forward the Config Entry to the platform `async_forward_entry_setups`
|
||||||
|
2.2 register listener `update_listener`
|
||||||
|
3. unloading a config entry: `async_unload_entry`
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
import homeassistant.helpers.device_registry as dr
|
||||||
|
import voluptuous as vol
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_CUSTOMIZE,
|
||||||
|
CONF_DEVICE_ID,
|
||||||
|
CONF_IP_ADDRESS,
|
||||||
|
CONF_NAME,
|
||||||
|
CONF_PORT,
|
||||||
|
CONF_PROTOCOL,
|
||||||
|
CONF_TOKEN,
|
||||||
|
CONF_TYPE,
|
||||||
|
MAJOR_VERSION,
|
||||||
|
MINOR_VERSION,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
from midealocal.device import DeviceType, MideaDevice, ProtocolVersion
|
||||||
|
from midealocal.devices import device_selector
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
ALL_PLATFORM,
|
||||||
|
CONF_ACCOUNT,
|
||||||
|
CONF_KEY,
|
||||||
|
CONF_MODEL,
|
||||||
|
CONF_REFRESH_INTERVAL,
|
||||||
|
CONF_SUBTYPE,
|
||||||
|
DEVICES,
|
||||||
|
DOMAIN,
|
||||||
|
EXTRA_SWITCH,
|
||||||
|
)
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||||
|
"""Option flow signal update.
|
||||||
|
|
||||||
|
register update listener for config entry that will be called when entry is updated.
|
||||||
|
A listener is registered by adding the following to the `async_setup_entry`:
|
||||||
|
`config_entry.async_on_unload(config_entry.add_update_listener(update_listener))`
|
||||||
|
means the Listener is attached when the entry is loaded and detached at unload
|
||||||
|
"""
|
||||||
|
# Forward the unloading of an entry to platforms.
|
||||||
|
await hass.config_entries.async_unload_platforms(config_entry, ALL_PLATFORM)
|
||||||
|
# forward the Config Entry to the platforms
|
||||||
|
hass.async_create_task(
|
||||||
|
hass.config_entries.async_forward_entry_setups(config_entry, ALL_PLATFORM),
|
||||||
|
)
|
||||||
|
device_id: int = cast("int", config_entry.data.get(CONF_DEVICE_ID))
|
||||||
|
customize = config_entry.options.get(CONF_CUSTOMIZE, "")
|
||||||
|
ip_address = config_entry.options.get(CONF_IP_ADDRESS, None)
|
||||||
|
refresh_interval = config_entry.options.get(CONF_REFRESH_INTERVAL, None)
|
||||||
|
dev: MideaDevice = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
if dev:
|
||||||
|
dev.set_customize(customize)
|
||||||
|
if ip_address is not None:
|
||||||
|
dev.set_ip_address(ip_address)
|
||||||
|
if refresh_interval is not None:
|
||||||
|
dev.set_refresh_interval(refresh_interval)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa: ARG001
|
||||||
|
"""Set up midea_lan component when load this integration.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if entry is configured.
|
||||||
|
|
||||||
|
"""
|
||||||
|
hass.data.setdefault(DOMAIN, {})
|
||||||
|
attributes = []
|
||||||
|
for device_entities in MIDEA_DEVICES.values():
|
||||||
|
for attribute_name, attribute in cast(
|
||||||
|
"dict",
|
||||||
|
device_entities["entities"],
|
||||||
|
).items():
|
||||||
|
if (
|
||||||
|
attribute.get("type") in EXTRA_SWITCH
|
||||||
|
and attribute_name.value not in attributes
|
||||||
|
):
|
||||||
|
attributes.append(attribute_name.value)
|
||||||
|
|
||||||
|
def service_set_attribute(service: Any) -> None: # noqa: ANN401
|
||||||
|
"""Set service attribute func."""
|
||||||
|
device_id: int = service.data["device_id"]
|
||||||
|
attr = service.data["attribute"]
|
||||||
|
value = service.data["value"]
|
||||||
|
dev: MideaDevice = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
if dev:
|
||||||
|
if attr == "fan_speed" and value == "auto":
|
||||||
|
value = 102
|
||||||
|
item = None
|
||||||
|
if dev_ := MIDEA_DEVICES.get(dev.device_type):
|
||||||
|
item = cast("dict", dev_["entities"]).get(attr)
|
||||||
|
if (
|
||||||
|
item
|
||||||
|
and (item.get("type") in EXTRA_SWITCH)
|
||||||
|
or (
|
||||||
|
dev.device_type == DeviceType.AC
|
||||||
|
and attr == "fan_speed"
|
||||||
|
and value in range(103)
|
||||||
|
)
|
||||||
|
):
|
||||||
|
dev.set_attribute(attr=attr, value=value)
|
||||||
|
else:
|
||||||
|
_LOGGER.error(
|
||||||
|
"Appliance [%s] has no attribute %s or value is invalid",
|
||||||
|
device_id,
|
||||||
|
attr,
|
||||||
|
)
|
||||||
|
|
||||||
|
def service_send_command(service: Any) -> None: # noqa: ANN401
|
||||||
|
"""Send command to service func."""
|
||||||
|
device_id = service.data.get("device_id")
|
||||||
|
cmd_type = service.data.get("cmd_type")
|
||||||
|
cmd_body = service.data.get("cmd_body")
|
||||||
|
try:
|
||||||
|
cmd_body = bytearray.fromhex(cmd_body)
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.exception(
|
||||||
|
"Appliance [%s] invalid cmd_body, a hexadecimal string required",
|
||||||
|
device_id,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
dev = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
if dev:
|
||||||
|
dev.send_command(cmd_type, cmd_body)
|
||||||
|
|
||||||
|
# register service func calls:
|
||||||
|
# `service_set_attribute`, service.yaml key: `set_attribute`
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN,
|
||||||
|
"set_attribute",
|
||||||
|
service_set_attribute,
|
||||||
|
schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required("device_id"): vol.Coerce(int),
|
||||||
|
vol.Required("attribute"): vol.In(attributes),
|
||||||
|
vol.Required("value"): vol.Any(int, cv.boolean, str),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# register service func calls:
|
||||||
|
# `service_send_command`, service.yaml key: `send_command`
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN,
|
||||||
|
"send_command",
|
||||||
|
service_send_command,
|
||||||
|
schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required("device_id"): vol.Coerce(int),
|
||||||
|
vol.Required("cmd_type"): vol.In([2, 3]),
|
||||||
|
vol.Required("cmd_body"): str,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||||
|
"""Set up platform for current integration.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if entry is configured.
|
||||||
|
|
||||||
|
"""
|
||||||
|
device_type = config_entry.data.get(CONF_TYPE)
|
||||||
|
if device_type == CONF_ACCOUNT:
|
||||||
|
return True
|
||||||
|
name = config_entry.data.get(CONF_NAME)
|
||||||
|
device_id: int = config_entry.data[CONF_DEVICE_ID]
|
||||||
|
if name is None:
|
||||||
|
name = f"{device_id}"
|
||||||
|
if device_type is None:
|
||||||
|
device_type = 0xAC
|
||||||
|
token: str = config_entry.data.get(CONF_TOKEN) or ""
|
||||||
|
key: str = config_entry.data.get(CONF_KEY) or ""
|
||||||
|
ip_address = config_entry.options.get(CONF_IP_ADDRESS, None)
|
||||||
|
if ip_address is None:
|
||||||
|
ip_address = config_entry.data.get(CONF_IP_ADDRESS)
|
||||||
|
refresh_interval = config_entry.options.get(CONF_REFRESH_INTERVAL)
|
||||||
|
port: int = config_entry.data[CONF_PORT]
|
||||||
|
model: str = config_entry.data[CONF_MODEL]
|
||||||
|
subtype = config_entry.data.get(CONF_SUBTYPE, 0)
|
||||||
|
protocol: ProtocolVersion = ProtocolVersion(config_entry.data[CONF_PROTOCOL])
|
||||||
|
customize: str = config_entry.options.get(CONF_CUSTOMIZE, "")
|
||||||
|
if protocol == ProtocolVersion.V3 and (key == "" or token == ""):
|
||||||
|
_LOGGER.error("For V3 devices, the key and the token is required")
|
||||||
|
return False
|
||||||
|
# device_selector in `midealocal/devices/__init__.py`
|
||||||
|
# hass core version >= 2024.3
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 3):
|
||||||
|
device = await hass.async_add_import_executor_job(
|
||||||
|
device_selector,
|
||||||
|
name,
|
||||||
|
device_id,
|
||||||
|
device_type,
|
||||||
|
ip_address,
|
||||||
|
port,
|
||||||
|
token,
|
||||||
|
key,
|
||||||
|
protocol,
|
||||||
|
model,
|
||||||
|
subtype,
|
||||||
|
customize,
|
||||||
|
)
|
||||||
|
# hass core version < 2024.3
|
||||||
|
else:
|
||||||
|
device = device_selector(
|
||||||
|
name=name,
|
||||||
|
device_id=device_id,
|
||||||
|
device_type=device_type,
|
||||||
|
ip_address=ip_address,
|
||||||
|
port=port,
|
||||||
|
token=token,
|
||||||
|
key=key,
|
||||||
|
device_protocol=protocol,
|
||||||
|
model=model,
|
||||||
|
subtype=subtype,
|
||||||
|
customize=customize,
|
||||||
|
)
|
||||||
|
if device:
|
||||||
|
if refresh_interval is not None:
|
||||||
|
device.set_refresh_interval(refresh_interval)
|
||||||
|
device.open()
|
||||||
|
if DOMAIN not in hass.data:
|
||||||
|
hass.data[DOMAIN] = {}
|
||||||
|
if DEVICES not in hass.data[DOMAIN]:
|
||||||
|
hass.data[DOMAIN][DEVICES] = {}
|
||||||
|
hass.data[DOMAIN][DEVICES][device_id] = device
|
||||||
|
# Forward the setup of an entry to all platforms
|
||||||
|
await hass.config_entries.async_forward_entry_setups(config_entry, ALL_PLATFORM)
|
||||||
|
# Listener `update_listener` is
|
||||||
|
# attached when the entry is loaded
|
||||||
|
# and detached when it's unloaded
|
||||||
|
config_entry.async_on_unload(config_entry.add_update_listener(update_listener))
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||||
|
"""Clean up entities, unsubscribe event listener and close all connections.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if entry is unloaded.
|
||||||
|
|
||||||
|
"""
|
||||||
|
device_type = config_entry.data.get(CONF_TYPE)
|
||||||
|
if device_type == CONF_ACCOUNT:
|
||||||
|
return True
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
if device_id is not None:
|
||||||
|
dm = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
if dm is not None:
|
||||||
|
try:
|
||||||
|
dm.close()
|
||||||
|
except (OSError, ConnectionError, AttributeError) as e:
|
||||||
|
_LOGGER.warning("Failed to close Midea socket cleanly: %s", e)
|
||||||
|
hass.data[DOMAIN][DEVICES].pop(device_id)
|
||||||
|
# Forward the unloading of an entry to platforms
|
||||||
|
await hass.config_entries.async_unload_platforms(config_entry, ALL_PLATFORM)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||||
|
"""Migrate old entry.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if entry is migrated.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# 1 -> 2: convert device identifiers from int to str
|
||||||
|
if config_entry.version == 1:
|
||||||
|
_LOGGER.debug("Migrating configuration from version 1")
|
||||||
|
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 3):
|
||||||
|
hass.config_entries.async_update_entry(config_entry, version=2)
|
||||||
|
else:
|
||||||
|
config_entry.version = 2
|
||||||
|
hass.config_entries.async_update_entry(config_entry)
|
||||||
|
|
||||||
|
# Migrate device.
|
||||||
|
await _async_migrate_device_identifiers(hass, config_entry)
|
||||||
|
|
||||||
|
_LOGGER.debug("Migration to configuration version 2 successful")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def _async_migrate_device_identifiers(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Migrate the device identifiers to the new format."""
|
||||||
|
device_registry = dr.async_get(hass)
|
||||||
|
device_entry_found = False
|
||||||
|
for device_entry in dr.async_entries_for_config_entry(
|
||||||
|
device_registry,
|
||||||
|
config_entry.entry_id,
|
||||||
|
):
|
||||||
|
for identifier in device_entry.identifiers:
|
||||||
|
# Device found in registry. Update identifiers.
|
||||||
|
new_identifiers = {
|
||||||
|
(
|
||||||
|
DOMAIN,
|
||||||
|
str(identifier[1]),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Migrating device identifiers from %s to %s",
|
||||||
|
device_entry.identifiers,
|
||||||
|
new_identifiers,
|
||||||
|
)
|
||||||
|
device_registry.async_update_device(
|
||||||
|
device_id=device_entry.id,
|
||||||
|
new_identifiers=new_identifiers,
|
||||||
|
)
|
||||||
|
# Device entry found. Leave inner for loop.
|
||||||
|
device_entry_found = True
|
||||||
|
break
|
||||||
|
|
||||||
|
# Leave outer for loop if device entry is already found.
|
||||||
|
if device_entry_found:
|
||||||
|
break
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,50 @@
|
|||||||
|
"""Binary sensor for Midea Lan."""
|
||||||
|
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
|
from homeassistant.components.binary_sensor import (
|
||||||
|
BinarySensorDeviceClass,
|
||||||
|
BinarySensorEntity,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SENSORS, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up sensors for device."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_sensors = config_entry.options.get(CONF_SENSORS, [])
|
||||||
|
binary_sensors = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.BINARY_SENSOR and entity_key in extra_sensors:
|
||||||
|
sensor = MideaBinarySensor(device, entity_key)
|
||||||
|
binary_sensors.append(sensor)
|
||||||
|
async_add_entities(binary_sensors)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaBinarySensor(MideaEntity, BinarySensorEntity):
|
||||||
|
"""Represent a Midea binary sensor."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_class(self) -> BinarySensorDeviceClass | None:
|
||||||
|
"""Return device class."""
|
||||||
|
return cast("BinarySensorDeviceClass", self._config.get("device_class"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Return true if sensor state is on."""
|
||||||
|
return cast("bool", self._device.get_attribute(self._entity_key))
|
||||||
@@ -0,0 +1,707 @@
|
|||||||
|
"""Midea Climate entries."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any, ClassVar, TypeAlias, cast
|
||||||
|
|
||||||
|
from homeassistant.components.climate import (
|
||||||
|
ATTR_HVAC_MODE,
|
||||||
|
FAN_AUTO,
|
||||||
|
FAN_HIGH,
|
||||||
|
FAN_LOW,
|
||||||
|
FAN_MEDIUM,
|
||||||
|
PRESET_AWAY,
|
||||||
|
PRESET_BOOST,
|
||||||
|
PRESET_COMFORT,
|
||||||
|
PRESET_ECO,
|
||||||
|
PRESET_NONE,
|
||||||
|
PRESET_SLEEP,
|
||||||
|
SWING_BOTH,
|
||||||
|
SWING_HORIZONTAL,
|
||||||
|
SWING_OFF,
|
||||||
|
SWING_ON,
|
||||||
|
SWING_VERTICAL,
|
||||||
|
ClimateEntity,
|
||||||
|
ClimateEntityFeature,
|
||||||
|
HVACMode,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_TEMPERATURE,
|
||||||
|
CONF_DEVICE_ID,
|
||||||
|
CONF_SWITCHES,
|
||||||
|
MAJOR_VERSION,
|
||||||
|
MINOR_VERSION,
|
||||||
|
PRECISION_HALVES,
|
||||||
|
PRECISION_WHOLE,
|
||||||
|
Platform,
|
||||||
|
UnitOfTemperature,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from midealocal.device import DeviceType
|
||||||
|
from midealocal.devices.ac import DeviceAttributes as ACAttributes
|
||||||
|
from midealocal.devices.ac import MideaACDevice
|
||||||
|
from midealocal.devices.c3 import DeviceAttributes as C3Attributes
|
||||||
|
from midealocal.devices.c3 import MideaC3Device
|
||||||
|
from midealocal.devices.cc import DeviceAttributes as CCAttributes
|
||||||
|
from midealocal.devices.cc import MideaCCDevice
|
||||||
|
from midealocal.devices.cf import DeviceAttributes as CFAttributes
|
||||||
|
from midealocal.devices.cf import MideaCFDevice
|
||||||
|
from midealocal.devices.fb import DeviceAttributes as FBAttributes
|
||||||
|
from midealocal.devices.fb import MideaFBDevice
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN, FanSpeed
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
TEMPERATURE_MAX = 30
|
||||||
|
TEMPERATURE_MIN = 16
|
||||||
|
|
||||||
|
FAN_SILENT = "silent"
|
||||||
|
FAN_FULL_SPEED = "full"
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up climate entries."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
devs: list[
|
||||||
|
MideaACClimate
|
||||||
|
| MideaCCClimate
|
||||||
|
| MideaCFClimate
|
||||||
|
| MideaC3Climate
|
||||||
|
| MideaFBClimate
|
||||||
|
] = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.CLIMATE and (
|
||||||
|
config.get("default") or entity_key in extra_switches
|
||||||
|
):
|
||||||
|
if device.device_type == DeviceType.AC:
|
||||||
|
# add config_entry args to fix indoor_humidity error bug
|
||||||
|
devs.append(MideaACClimate(device, entity_key, config_entry))
|
||||||
|
elif device.device_type == DeviceType.CC:
|
||||||
|
devs.append(MideaCCClimate(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.CF:
|
||||||
|
devs.append(MideaCFClimate(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.C3:
|
||||||
|
devs.append(MideaC3Climate(device, entity_key, config["zone"]))
|
||||||
|
elif device.device_type == DeviceType.FB:
|
||||||
|
devs.append(MideaFBClimate(device, entity_key))
|
||||||
|
async_add_entities(devs)
|
||||||
|
|
||||||
|
|
||||||
|
MideaClimateDevice: TypeAlias = (
|
||||||
|
MideaACDevice | MideaCCDevice | MideaCFDevice | MideaC3Device | MideaFBDevice
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaClimate(MideaEntity, ClimateEntity):
|
||||||
|
"""Midea Climate Entries Base Class."""
|
||||||
|
|
||||||
|
# https://developers.home-assistant.io/blog/2024/01/24/climate-climateentityfeatures-expanded
|
||||||
|
_enable_turn_on_off_backwards_compatibility: bool = (
|
||||||
|
False # maybe remove after 2025.1
|
||||||
|
)
|
||||||
|
|
||||||
|
_device: MideaClimateDevice
|
||||||
|
|
||||||
|
_attr_max_temp: float = TEMPERATURE_MAX
|
||||||
|
_attr_min_temp: float = TEMPERATURE_MIN
|
||||||
|
_attr_target_temperature_high: float | None = TEMPERATURE_MAX
|
||||||
|
_attr_target_temperature_low: float | None = TEMPERATURE_MIN
|
||||||
|
_attr_temperature_unit: str = UnitOfTemperature.CELSIUS
|
||||||
|
|
||||||
|
def __init__(self, device: MideaClimateDevice, entity_key: str) -> None:
|
||||||
|
"""Midea Climate entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> ClimateEntityFeature:
|
||||||
|
"""Midea Climate supported features."""
|
||||||
|
features = (
|
||||||
|
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||||
|
| ClimateEntityFeature.FAN_MODE
|
||||||
|
| ClimateEntityFeature.PRESET_MODE
|
||||||
|
| ClimateEntityFeature.SWING_MODE
|
||||||
|
)
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2):
|
||||||
|
features |= ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
|
||||||
|
return features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hvac_mode(self) -> HVACMode:
|
||||||
|
"""Midea Climate hvac mode."""
|
||||||
|
if self._device.get_attribute("power"):
|
||||||
|
mode = cast("int", self._device.get_attribute("mode"))
|
||||||
|
return self.hvac_modes[mode]
|
||||||
|
return HVACMode.OFF
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature(self) -> float:
|
||||||
|
"""Midea Climate target temperature."""
|
||||||
|
return cast("float", self._device.get_attribute("target_temperature"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self) -> float | None:
|
||||||
|
"""Midea Climate current temperature."""
|
||||||
|
return cast("float | None", self._device.get_attribute("indoor_temperature"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_mode(self) -> str:
|
||||||
|
"""Midea Climate preset mode."""
|
||||||
|
if self._device.get_attribute("comfort_mode"):
|
||||||
|
mode = PRESET_COMFORT
|
||||||
|
elif self._device.get_attribute("eco_mode"):
|
||||||
|
mode = PRESET_ECO
|
||||||
|
elif self._device.get_attribute("boost_mode"):
|
||||||
|
mode = PRESET_BOOST
|
||||||
|
elif self._device.get_attribute("sleep_mode"):
|
||||||
|
mode = PRESET_SLEEP
|
||||||
|
elif self._device.get_attribute("frost_protect"):
|
||||||
|
mode = PRESET_AWAY
|
||||||
|
else:
|
||||||
|
mode = PRESET_NONE
|
||||||
|
return str(mode)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extra_state_attributes(self) -> dict:
|
||||||
|
"""Midea Climate extra state attributes."""
|
||||||
|
return cast("dict", self._device.attributes)
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Climate turn on."""
|
||||||
|
self._device.set_attribute(attr="power", value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Climate turn off."""
|
||||||
|
self._device.set_attribute(attr="power", value=False)
|
||||||
|
|
||||||
|
def set_temperature(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea Climate set temperature."""
|
||||||
|
if ATTR_TEMPERATURE not in kwargs:
|
||||||
|
return
|
||||||
|
temperature = float(int((float(kwargs[ATTR_TEMPERATURE]) * 2) + 0.5)) / 2
|
||||||
|
hvac_mode = kwargs.get(ATTR_HVAC_MODE)
|
||||||
|
if hvac_mode == HVACMode.OFF:
|
||||||
|
self.turn_off()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
mode = self.hvac_modes.index(hvac_mode.lower()) if hvac_mode else None
|
||||||
|
self._device.set_target_temperature(
|
||||||
|
target_temperature=temperature,
|
||||||
|
mode=mode,
|
||||||
|
zone=None,
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.exception("Error setting temperature with: %s", kwargs)
|
||||||
|
|
||||||
|
def set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||||
|
"""Midea Climate set hvac mode."""
|
||||||
|
if hvac_mode == HVACMode.OFF:
|
||||||
|
self.turn_off()
|
||||||
|
else:
|
||||||
|
self._device.set_attribute(
|
||||||
|
attr="mode",
|
||||||
|
value=self.hvac_modes.index(hvac_mode),
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_preset_mode(self, preset_mode: str) -> None:
|
||||||
|
"""Midea Climate set preset mode."""
|
||||||
|
old_mode = self.preset_mode
|
||||||
|
preset_mode = preset_mode.lower()
|
||||||
|
if preset_mode == PRESET_AWAY:
|
||||||
|
self._device.set_attribute(attr="frost_protect", value=True)
|
||||||
|
elif preset_mode == PRESET_COMFORT:
|
||||||
|
self._device.set_attribute(attr="comfort_mode", value=True)
|
||||||
|
elif preset_mode == PRESET_SLEEP:
|
||||||
|
self._device.set_attribute(attr="sleep_mode", value=True)
|
||||||
|
elif preset_mode == PRESET_ECO:
|
||||||
|
self._device.set_attribute(attr="eco_mode", value=True)
|
||||||
|
elif preset_mode == PRESET_BOOST:
|
||||||
|
self._device.set_attribute(attr="boost_mode", value=True)
|
||||||
|
elif old_mode == PRESET_AWAY:
|
||||||
|
self._device.set_attribute(attr="frost_protect", value=False)
|
||||||
|
elif old_mode == PRESET_COMFORT:
|
||||||
|
self._device.set_attribute(attr="comfort_mode", value=False)
|
||||||
|
elif old_mode == PRESET_SLEEP:
|
||||||
|
self._device.set_attribute(attr="sleep_mode", value=False)
|
||||||
|
elif old_mode == PRESET_ECO:
|
||||||
|
self._device.set_attribute(attr="eco_mode", value=False)
|
||||||
|
elif old_mode == PRESET_BOOST:
|
||||||
|
self._device.set_attribute(attr="boost_mode", value=False)
|
||||||
|
|
||||||
|
def update_state(self, status: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Climate update state."""
|
||||||
|
if not self.hass:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Climate update_state skipped for %s [%s]: HASS is None",
|
||||||
|
self.name,
|
||||||
|
type(self),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
|
class MideaACClimate(MideaClimate):
|
||||||
|
"""Midea AC Climate Entries."""
|
||||||
|
|
||||||
|
_device: MideaACDevice
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
device: MideaACDevice,
|
||||||
|
entity_key: str,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Midea AC Climate entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_hvac_modes = [
|
||||||
|
HVACMode.OFF,
|
||||||
|
HVACMode.AUTO,
|
||||||
|
HVACMode.COOL,
|
||||||
|
HVACMode.DRY,
|
||||||
|
HVACMode.HEAT,
|
||||||
|
HVACMode.FAN_ONLY,
|
||||||
|
]
|
||||||
|
self._fan_speeds: dict[str, int] = {
|
||||||
|
FAN_SILENT: 20,
|
||||||
|
FAN_LOW: 40,
|
||||||
|
FAN_MEDIUM: 60,
|
||||||
|
FAN_HIGH: 80,
|
||||||
|
FAN_FULL_SPEED: 100,
|
||||||
|
FAN_AUTO: 102,
|
||||||
|
}
|
||||||
|
self._attr_swing_modes: list[str] = [
|
||||||
|
SWING_OFF,
|
||||||
|
SWING_VERTICAL,
|
||||||
|
SWING_HORIZONTAL,
|
||||||
|
SWING_BOTH,
|
||||||
|
]
|
||||||
|
self._attr_preset_modes = [
|
||||||
|
PRESET_NONE,
|
||||||
|
PRESET_COMFORT,
|
||||||
|
PRESET_ECO,
|
||||||
|
PRESET_BOOST,
|
||||||
|
PRESET_SLEEP,
|
||||||
|
PRESET_AWAY,
|
||||||
|
]
|
||||||
|
self._attr_fan_modes = list(self._fan_speeds.keys())
|
||||||
|
# fix error humidity value, disable indoor_humidity
|
||||||
|
# add config_entry args to fix indoor_humidity error bug
|
||||||
|
self._indoor_humidity_enabled = (
|
||||||
|
"sensors" in config_entry.options
|
||||||
|
and "indoor_humidity" in config_entry.options["sensors"]
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fan_mode(self) -> str:
|
||||||
|
"""Midea AC Climate fan mode."""
|
||||||
|
fan_speed = cast("int", self._device.get_attribute(ACAttributes.fan_speed))
|
||||||
|
if fan_speed > FanSpeed.AUTO:
|
||||||
|
return str(FAN_AUTO)
|
||||||
|
if fan_speed > FanSpeed.FULL_SPEED:
|
||||||
|
return str(FAN_FULL_SPEED)
|
||||||
|
if fan_speed > FanSpeed.HIGH:
|
||||||
|
return str(FAN_HIGH)
|
||||||
|
if fan_speed > FanSpeed.MEDIUM:
|
||||||
|
return str(FAN_MEDIUM)
|
||||||
|
if fan_speed > FanSpeed.LOW:
|
||||||
|
return str(FAN_LOW)
|
||||||
|
return str(FAN_SILENT)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_step(self) -> float:
|
||||||
|
"""Midea AC Climate target temperature step."""
|
||||||
|
return float(
|
||||||
|
PRECISION_WHOLE if self._device.temperature_step == 1 else PRECISION_HALVES,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def swing_mode(self) -> str:
|
||||||
|
"""Midea AC Climate swing mode."""
|
||||||
|
swing_mode = (
|
||||||
|
1 if self._device.get_attribute(ACAttributes.swing_vertical) else 0
|
||||||
|
) + (2 if self._device.get_attribute(ACAttributes.swing_horizontal) else 0)
|
||||||
|
return self._attr_swing_modes[swing_mode]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_humidity(self) -> float | None:
|
||||||
|
"""Return the current indoor humidity, or None if unavailable."""
|
||||||
|
# fix error humidity, disable indoor_humidity in web UI
|
||||||
|
# https://github.com/wuwentao/midea_ac_lan/pull/641
|
||||||
|
if not self._indoor_humidity_enabled:
|
||||||
|
return None
|
||||||
|
raw = self._device.get_attribute("indoor_humidity")
|
||||||
|
if isinstance(raw, (int, float)) and raw not in {0, 0xFF}:
|
||||||
|
return float(raw)
|
||||||
|
# indoor_humidity is 0 or 255, return None
|
||||||
|
# https://github.com/wuwentao/midea_ac_lan/pull/614
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def outdoor_temperature(self) -> float:
|
||||||
|
"""Midea AC Climate outdoor temperature."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._device.get_attribute(ACAttributes.outdoor_temperature),
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_fan_mode(self, fan_mode: str) -> None:
|
||||||
|
"""Midea AC Climate set fan mode."""
|
||||||
|
fan_speed = self._fan_speeds.get(fan_mode)
|
||||||
|
if fan_speed:
|
||||||
|
self._device.set_attribute(attr=ACAttributes.fan_speed, value=fan_speed)
|
||||||
|
|
||||||
|
def set_swing_mode(self, swing_mode: str) -> None:
|
||||||
|
"""Midea AC Climate set swing mode."""
|
||||||
|
swing = self._attr_swing_modes.index(swing_mode)
|
||||||
|
swing_vertical = swing & 1 > 0
|
||||||
|
swing_horizontal = swing & 2 > 0
|
||||||
|
self._device.set_swing(
|
||||||
|
swing_vertical=swing_vertical,
|
||||||
|
swing_horizontal=swing_horizontal,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaCCClimate(MideaClimate):
|
||||||
|
"""Midea CC Climate Entries Base Class."""
|
||||||
|
|
||||||
|
_device: MideaCCDevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaCCDevice, entity_key: str) -> None:
|
||||||
|
"""Midea CC Climate entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_hvac_modes = [
|
||||||
|
HVACMode.OFF,
|
||||||
|
HVACMode.FAN_ONLY,
|
||||||
|
HVACMode.DRY,
|
||||||
|
HVACMode.HEAT,
|
||||||
|
HVACMode.COOL,
|
||||||
|
HVACMode.AUTO,
|
||||||
|
]
|
||||||
|
self._attr_swing_modes = [SWING_OFF, SWING_ON]
|
||||||
|
self._attr_preset_modes = [PRESET_NONE, PRESET_SLEEP, PRESET_ECO]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fan_modes(self) -> list[str] | None:
|
||||||
|
"""Midea CC Climate fan modes."""
|
||||||
|
return cast("list", self._device.fan_modes)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fan_mode(self) -> str:
|
||||||
|
"""Midea CC Climate fan mode."""
|
||||||
|
return cast("str", self._device.get_attribute(CCAttributes.fan_speed))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_step(self) -> float:
|
||||||
|
"""Midea CC Climate target temperature step."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._device.get_attribute(CCAttributes.temperature_precision),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def swing_mode(self) -> str:
|
||||||
|
"""Midea CC Climate swing mode."""
|
||||||
|
return str(
|
||||||
|
SWING_ON if self._device.get_attribute(CCAttributes.swing) else SWING_OFF,
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_fan_mode(self, fan_mode: str) -> None:
|
||||||
|
"""Midea CC Climate set fan mode."""
|
||||||
|
self._device.set_attribute(attr=CCAttributes.fan_speed, value=fan_mode)
|
||||||
|
|
||||||
|
def set_swing_mode(self, swing_mode: str) -> None:
|
||||||
|
"""Midea CC Climate set swing mode."""
|
||||||
|
self._device.set_attribute(
|
||||||
|
attr=CCAttributes.swing,
|
||||||
|
value=swing_mode == SWING_ON,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaCFClimate(MideaClimate):
|
||||||
|
"""Midea CF Climate Entries."""
|
||||||
|
|
||||||
|
_device: MideaCFDevice
|
||||||
|
|
||||||
|
_attr_target_temperature_step: float | None = PRECISION_WHOLE
|
||||||
|
|
||||||
|
def __init__(self, device: MideaCFDevice, entity_key: str) -> None:
|
||||||
|
"""Midea CF Climate entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_hvac_modes = [
|
||||||
|
HVACMode.OFF,
|
||||||
|
HVACMode.AUTO,
|
||||||
|
HVACMode.COOL,
|
||||||
|
HVACMode.HEAT,
|
||||||
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> ClimateEntityFeature:
|
||||||
|
"""Midea CF Climate supported features."""
|
||||||
|
features = ClimateEntityFeature.TARGET_TEMPERATURE
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2):
|
||||||
|
features |= ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
|
||||||
|
return features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea CF Climate min temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(CFAttributes.min_temperature))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea CF Climate max temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(CFAttributes.max_temperature))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_low(self) -> float:
|
||||||
|
"""Midea CF Climate target temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(CFAttributes.min_temperature))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_high(self) -> float:
|
||||||
|
"""Midea CF Climate target temperature high."""
|
||||||
|
return cast("float", self._device.get_attribute(CFAttributes.max_temperature))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self) -> float:
|
||||||
|
"""Midea CF Climate current temperature."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._device.get_attribute(CFAttributes.current_temperature),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaC3Climate(MideaClimate):
|
||||||
|
"""Midea C3 Climate Entries."""
|
||||||
|
|
||||||
|
_device: MideaC3Device
|
||||||
|
|
||||||
|
_powers: ClassVar[list[C3Attributes]] = [
|
||||||
|
C3Attributes.zone1_power,
|
||||||
|
C3Attributes.zone2_power,
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, device: MideaC3Device, entity_key: str, zone: int) -> None:
|
||||||
|
"""Midea C3 Climate entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._zone = zone
|
||||||
|
self._attr_hvac_modes = [
|
||||||
|
HVACMode.OFF,
|
||||||
|
HVACMode.AUTO,
|
||||||
|
HVACMode.COOL,
|
||||||
|
HVACMode.HEAT,
|
||||||
|
]
|
||||||
|
self._power_attr = MideaC3Climate._powers[zone]
|
||||||
|
|
||||||
|
def _temperature(self, minimum: bool) -> list[str]:
|
||||||
|
"""Midea C3 Climate temperature.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
List of temperatures
|
||||||
|
|
||||||
|
"""
|
||||||
|
# fmt: off
|
||||||
|
value = (C3Attributes.temperature_min
|
||||||
|
if minimum
|
||||||
|
else C3Attributes.temperature_max)
|
||||||
|
# fmt: on
|
||||||
|
return cast("list[str]", self._device.get_attribute(value))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> ClimateEntityFeature:
|
||||||
|
"""Midea C3 Climate supported features."""
|
||||||
|
features = ClimateEntityFeature.TARGET_TEMPERATURE
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2):
|
||||||
|
features |= ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
|
||||||
|
return features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_step(self) -> float:
|
||||||
|
"""Midea C3 Climate target temperature step."""
|
||||||
|
zone_temp_type = cast(
|
||||||
|
"list[str]",
|
||||||
|
self._device.get_attribute(C3Attributes.zone_temp_type),
|
||||||
|
)
|
||||||
|
return float(
|
||||||
|
PRECISION_WHOLE if zone_temp_type[self._zone] else PRECISION_HALVES,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea C3 Climate min temperature."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._temperature(True)[self._zone],
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea C3 Climate max temperature."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._temperature(False)[self._zone],
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_low(self) -> float:
|
||||||
|
"""Midea C3 Climate target temperature low."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._temperature(True)[self._zone],
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature_high(self) -> float:
|
||||||
|
"""Midea C3 Climate target temperature high."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._temperature(False)[self._zone],
|
||||||
|
)
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea C3 Climate turn on."""
|
||||||
|
self._device.set_attribute(attr=self._power_attr, value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea C3 Climate turn off."""
|
||||||
|
self._device.set_attribute(attr=self._power_attr, value=False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hvac_mode(self) -> HVACMode:
|
||||||
|
"""Midea C3 Climate hvac mode."""
|
||||||
|
mode = self._device.get_attribute(C3Attributes.mode)
|
||||||
|
if self._device.get_attribute(self._power_attr) and isinstance(mode, int):
|
||||||
|
return self.hvac_modes[mode]
|
||||||
|
return HVACMode.OFF
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature(self) -> float:
|
||||||
|
"""Midea C3 Climate target temperature."""
|
||||||
|
target_temperature = cast(
|
||||||
|
"list[str]",
|
||||||
|
self._device.get_attribute(C3Attributes.target_temperature),
|
||||||
|
)
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
target_temperature[self._zone],
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self) -> float | None:
|
||||||
|
"""Midea C3 Climate current temperature."""
|
||||||
|
return None
|
||||||
|
|
||||||
|
def set_temperature(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea C3 Climate set temperature."""
|
||||||
|
if ATTR_TEMPERATURE not in kwargs:
|
||||||
|
return
|
||||||
|
temperature = float(int((float(kwargs[ATTR_TEMPERATURE]) * 2) + 0.5)) / 2
|
||||||
|
hvac_mode = kwargs.get(ATTR_HVAC_MODE)
|
||||||
|
if hvac_mode == HVACMode.OFF:
|
||||||
|
self.turn_off()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
mode = self.hvac_modes.index(hvac_mode.lower()) if hvac_mode else None
|
||||||
|
self._device.set_target_temperature(
|
||||||
|
target_temperature=temperature,
|
||||||
|
mode=mode,
|
||||||
|
zone=self._zone,
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.exception("Error setting temperature with: %s", kwargs)
|
||||||
|
|
||||||
|
def set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||||
|
"""Midea C3 Climate set hvac mode."""
|
||||||
|
if hvac_mode == HVACMode.OFF:
|
||||||
|
self.turn_off()
|
||||||
|
else:
|
||||||
|
self._device.set_mode(self._zone, self.hvac_modes.index(hvac_mode))
|
||||||
|
|
||||||
|
|
||||||
|
class MideaFBClimate(MideaClimate):
|
||||||
|
"""Midea FB Climate Entries."""
|
||||||
|
|
||||||
|
_device: MideaFBDevice
|
||||||
|
|
||||||
|
_attr_max_temp: float = 35
|
||||||
|
_attr_min_temp: float = 5
|
||||||
|
_attr_target_temperature_high: float | None = 35
|
||||||
|
_attr_target_temperature_low: float | None = 5
|
||||||
|
_attr_target_temperature_step: float | None = PRECISION_WHOLE
|
||||||
|
|
||||||
|
def __init__(self, device: MideaFBDevice, entity_key: str) -> None:
|
||||||
|
"""Midea FB Climate entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_hvac_modes = [HVACMode.OFF, HVACMode.HEAT]
|
||||||
|
self._attr_preset_modes: list[str] = self._device.modes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> ClimateEntityFeature:
|
||||||
|
"""Midea FB Climate supported features."""
|
||||||
|
features = (
|
||||||
|
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE
|
||||||
|
)
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 2):
|
||||||
|
features |= ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON
|
||||||
|
return features
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_mode(self) -> str:
|
||||||
|
"""Midea FB Climate preset mode."""
|
||||||
|
return cast("str", self._device.get_attribute(attr=FBAttributes.mode))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hvac_mode(self) -> HVACMode:
|
||||||
|
"""Midea FB Climate hvac mode."""
|
||||||
|
return (
|
||||||
|
HVACMode.HEAT
|
||||||
|
if self._device.get_attribute(attr=FBAttributes.power)
|
||||||
|
else HVACMode.OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self) -> float:
|
||||||
|
"""Midea FB Climate current temperature."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._device.get_attribute(FBAttributes.current_temperature),
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_temperature(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea FB Climate set temperature."""
|
||||||
|
if ATTR_TEMPERATURE not in kwargs:
|
||||||
|
return
|
||||||
|
temperature = float(int((float(kwargs[ATTR_TEMPERATURE]) * 2) + 0.5)) / 2
|
||||||
|
hvac_mode = kwargs.get(ATTR_HVAC_MODE)
|
||||||
|
if hvac_mode == HVACMode.OFF:
|
||||||
|
self.turn_off()
|
||||||
|
else:
|
||||||
|
self._device.set_target_temperature(
|
||||||
|
target_temperature=temperature,
|
||||||
|
mode=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||||
|
"""Midea FB Climate set hvac mode."""
|
||||||
|
if hvac_mode == HVACMode.OFF:
|
||||||
|
self.turn_off()
|
||||||
|
else:
|
||||||
|
self.turn_on()
|
||||||
|
|
||||||
|
def set_preset_mode(self, preset_mode: str) -> None:
|
||||||
|
"""Midea FB Climate set preset mode."""
|
||||||
|
self._device.set_attribute(attr=FBAttributes.mode, value=preset_mode)
|
||||||
@@ -0,0 +1,998 @@
|
|||||||
|
"""Config flow for Midea LAN.
|
||||||
|
|
||||||
|
Setup current integration and add device entry via the web UI
|
||||||
|
enable by adding `config_flow: true` in `manifest.json`
|
||||||
|
|
||||||
|
`MideaLanConfigFlow`: add device entry
|
||||||
|
`MideaLanOptionsFlowHandler`: update the options of a config entry
|
||||||
|
|
||||||
|
job process:
|
||||||
|
1. run `async_step_user` when select `Add Device` from web UI
|
||||||
|
2. default auto discovery action run `async_step_discovery`
|
||||||
|
3. device available, run `async_step_auto` to show available device list in web UI
|
||||||
|
3.1 check local device json with `_load_device_config`
|
||||||
|
3.1.1 device exist with `_check_storage_device`,
|
||||||
|
send json data to `async_step_manually`
|
||||||
|
3.1.2 device NOT exist, get device data from cloud,
|
||||||
|
send to `async_step_manually`
|
||||||
|
- check login with `async_step_login`
|
||||||
|
4. add selected device detail with `async_step_manually`
|
||||||
|
5. run `_save_device_config` and `async_create_entry`
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
import voluptuous as vol
|
||||||
|
from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_CUSTOMIZE,
|
||||||
|
CONF_DEVICE,
|
||||||
|
CONF_DEVICE_ID,
|
||||||
|
CONF_IP_ADDRESS,
|
||||||
|
CONF_NAME,
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_PORT,
|
||||||
|
CONF_PROTOCOL,
|
||||||
|
CONF_SENSORS,
|
||||||
|
CONF_SWITCHES,
|
||||||
|
CONF_TOKEN,
|
||||||
|
CONF_TYPE,
|
||||||
|
MAJOR_VERSION,
|
||||||
|
MINOR_VERSION,
|
||||||
|
)
|
||||||
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||||
|
from homeassistant.helpers.json import save_json
|
||||||
|
from homeassistant.util.json import load_json
|
||||||
|
from midealocal.cloud import (
|
||||||
|
PRESET_ACCOUNT_DATA,
|
||||||
|
SUPPORTED_CLOUDS,
|
||||||
|
MideaCloud,
|
||||||
|
get_midea_cloud,
|
||||||
|
)
|
||||||
|
from midealocal.device import AuthException, MideaDevice, ProtocolVersion
|
||||||
|
from midealocal.discover import discover
|
||||||
|
from midealocal.exceptions import SocketException
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from aiohttp import ClientSession
|
||||||
|
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2024, 4):
|
||||||
|
from homeassistant.config_entries import ConfigFlowResult # pylint: disable=E0611
|
||||||
|
else:
|
||||||
|
from homeassistant.data_entry_flow import ( # type: ignore[assignment]
|
||||||
|
FlowResult as ConfigFlowResult,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
CONF_ACCOUNT,
|
||||||
|
CONF_KEY,
|
||||||
|
CONF_MODEL,
|
||||||
|
CONF_REFRESH_INTERVAL,
|
||||||
|
CONF_SERVER,
|
||||||
|
CONF_SUBTYPE,
|
||||||
|
DOMAIN,
|
||||||
|
EXTRA_CONTROL,
|
||||||
|
EXTRA_SENSOR,
|
||||||
|
)
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ADD_WAY = {
|
||||||
|
"discovery": "Discover automatically",
|
||||||
|
"manually": "Configure manually",
|
||||||
|
"list": "List all appliances only",
|
||||||
|
"cache": "Remove login cache",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Select DEFAULT_CLOUD from the list of supported cloud
|
||||||
|
DEFAULT_CLOUD: str = list(SUPPORTED_CLOUDS)[3]
|
||||||
|
|
||||||
|
STORAGE_PATH = f".storage/{DOMAIN}"
|
||||||
|
|
||||||
|
SKIP_LOGIN = "Skip Login (input any user/password)"
|
||||||
|
|
||||||
|
|
||||||
|
class MideaLanConfigFlow(ConfigFlow, domain=DOMAIN): # type: ignore[call-arg]
|
||||||
|
"""Define current integration setup steps.
|
||||||
|
|
||||||
|
Use ConfigFlow handle to support config entries
|
||||||
|
ConfigFlow will manage the creation of entries from user input, discovery
|
||||||
|
"""
|
||||||
|
|
||||||
|
VERSION = 2
|
||||||
|
MINOR_VERSION = 1
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
"""MideaLanConfigFlow class."""
|
||||||
|
self.available_device: dict = {}
|
||||||
|
self.devices: dict = {}
|
||||||
|
self.found_device: dict[str, Any] = {}
|
||||||
|
self.supports: dict = {}
|
||||||
|
self.unsorted: dict[int, Any] = {}
|
||||||
|
self.account: dict = {}
|
||||||
|
self.cloud: MideaCloud | None = None
|
||||||
|
self.session: ClientSession | None = None
|
||||||
|
for device_type, device_info in MIDEA_DEVICES.items():
|
||||||
|
self.unsorted[device_type] = device_info["name"]
|
||||||
|
|
||||||
|
sorted_device_names = sorted(self.unsorted.items(), key=lambda x: x[1])
|
||||||
|
for item in sorted_device_names:
|
||||||
|
self.supports[item[0]] = item[1]
|
||||||
|
# preset account
|
||||||
|
self.preset_account: str = bytes.fromhex(
|
||||||
|
format((PRESET_ACCOUNT_DATA[0] ^ PRESET_ACCOUNT_DATA[1]), "X"),
|
||||||
|
).decode("utf-8", errors="ignore")
|
||||||
|
# preset password
|
||||||
|
self.preset_password: str = bytes.fromhex(
|
||||||
|
format((PRESET_ACCOUNT_DATA[0] ^ PRESET_ACCOUNT_DATA[2]), "X"),
|
||||||
|
).decode("utf-8", errors="ignore")
|
||||||
|
self.preset_cloud_name: str = DEFAULT_CLOUD
|
||||||
|
|
||||||
|
def _save_device_config(self, data: dict[str, Any]) -> None:
|
||||||
|
"""Save device config to json file with device id."""
|
||||||
|
storage_path = Path(self.hass.config.path(STORAGE_PATH))
|
||||||
|
storage_path.mkdir(parents=True, exist_ok=True)
|
||||||
|
record_file = storage_path.joinpath(f"{data[CONF_DEVICE_ID]!s}.json")
|
||||||
|
save_json(str(record_file), data)
|
||||||
|
|
||||||
|
def _load_device_config(self, device_id: str) -> Any: # noqa: ANN401
|
||||||
|
"""Load device config from json file with device id.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Device configuration (json)
|
||||||
|
|
||||||
|
"""
|
||||||
|
record_file = Path(
|
||||||
|
self.hass.config.path(f"{STORAGE_PATH}", f"{device_id}.json"),
|
||||||
|
)
|
||||||
|
if record_file.exists():
|
||||||
|
with record_file.open(encoding="utf-8") as f:
|
||||||
|
return load_json(f.name, default={})
|
||||||
|
return {}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _check_storage_device(device: dict, storage_device: dict) -> bool:
|
||||||
|
"""Check input device with storage_device.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if storage device exist
|
||||||
|
|
||||||
|
"""
|
||||||
|
if storage_device.get(CONF_SUBTYPE) is None:
|
||||||
|
return False
|
||||||
|
return not (
|
||||||
|
device.get(CONF_PROTOCOL) == ProtocolVersion.V3
|
||||||
|
and (
|
||||||
|
storage_device.get(CONF_TOKEN) is None
|
||||||
|
or storage_device.get(CONF_KEY) is None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def _already_configured(self, device_id: str, ip_address: str) -> bool:
|
||||||
|
"""Check device from json with device_id or ip address.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if device is already configured
|
||||||
|
|
||||||
|
"""
|
||||||
|
for entry in self._async_current_entries():
|
||||||
|
if device_id == entry.data.get(
|
||||||
|
CONF_DEVICE_ID,
|
||||||
|
) or ip_address == entry.data.get(CONF_IP_ADDRESS):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def async_step_user(
|
||||||
|
self,
|
||||||
|
user_input: dict[str, Any] | None = None,
|
||||||
|
error: str | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Define config flow steps.
|
||||||
|
|
||||||
|
Using `async_step_<step_id>` and `async_step_user` will be the first step,
|
||||||
|
then select discovery mode
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
# user select a device discovery mode
|
||||||
|
if user_input is not None:
|
||||||
|
# default is auto discovery mode
|
||||||
|
if user_input["action"] == "discovery":
|
||||||
|
return await self.async_step_discovery()
|
||||||
|
# manual input device detail
|
||||||
|
if user_input["action"] == "manually":
|
||||||
|
self.found_device = {}
|
||||||
|
return await self.async_step_manually()
|
||||||
|
# remove cached login data and input new one
|
||||||
|
if user_input["action"] == "cache":
|
||||||
|
return await self.async_step_cache()
|
||||||
|
# only list all devices
|
||||||
|
return await self.async_step_list()
|
||||||
|
# user not input, show device discovery select form in UI
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="user",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{vol.Required("action", default="discovery"): vol.In(ADD_WAY)},
|
||||||
|
),
|
||||||
|
errors={"base": error} if error else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_cache(
|
||||||
|
self,
|
||||||
|
user_input: dict[str, Any] | None = None,
|
||||||
|
error: str | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Remove cached login data and can input a new one.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
# user input data exist
|
||||||
|
if user_input is not None:
|
||||||
|
# key is not None
|
||||||
|
if self.hass.data.get(DOMAIN):
|
||||||
|
self.hass.data[DOMAIN].pop("login_data", None)
|
||||||
|
self.hass.data[DOMAIN].pop("login_mode", None)
|
||||||
|
return await self.async_step_user()
|
||||||
|
# show cache info form in UI
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="cache",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required("action", default="remove"): vol.In(
|
||||||
|
{"action": "remove"},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
errors={"base": error} if error else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_login(
|
||||||
|
self,
|
||||||
|
user_input: dict[str, Any] | None = None,
|
||||||
|
error: str | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""User login steps.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
# get cloud servers configs
|
||||||
|
cloud_servers = await MideaCloud.get_cloud_servers()
|
||||||
|
default_keys = await MideaCloud.get_default_keys()
|
||||||
|
# add skip login option to web UI with key 99
|
||||||
|
cloud_servers[next(iter(default_keys))] = SKIP_LOGIN
|
||||||
|
# user input data exist
|
||||||
|
if user_input is not None:
|
||||||
|
if not self.hass.data.get(DOMAIN):
|
||||||
|
self.hass.data[DOMAIN] = {}
|
||||||
|
# check skip login option
|
||||||
|
if user_input[CONF_SERVER] == next(iter(default_keys)):
|
||||||
|
# use preset account and DEFAULT_CLOUD cloud
|
||||||
|
_LOGGER.debug("skip login matched, cloud_servers: %s", cloud_servers)
|
||||||
|
# get DEFAULT_CLOUD key from dict
|
||||||
|
key = next(
|
||||||
|
key
|
||||||
|
for key, value in cloud_servers.items()
|
||||||
|
if value == DEFAULT_CLOUD
|
||||||
|
)
|
||||||
|
cloud_server = cloud_servers[key]
|
||||||
|
account = self.preset_account
|
||||||
|
password = self.preset_password
|
||||||
|
# set a login_mode flag
|
||||||
|
self.hass.data[DOMAIN]["login_mode"] = "preset"
|
||||||
|
# use input data
|
||||||
|
else:
|
||||||
|
_LOGGER.debug("user input login matched")
|
||||||
|
cloud_server = cloud_servers[user_input[CONF_SERVER]]
|
||||||
|
account = user_input[CONF_ACCOUNT]
|
||||||
|
password = user_input[CONF_PASSWORD]
|
||||||
|
# set a login_mode flag
|
||||||
|
self.hass.data[DOMAIN]["login_mode"] = "input"
|
||||||
|
|
||||||
|
# cloud login MUST pass with user input or perset account
|
||||||
|
if await self._check_cloud_login(
|
||||||
|
cloud_name=cloud_server,
|
||||||
|
account=account,
|
||||||
|
password=password,
|
||||||
|
force_login=True,
|
||||||
|
):
|
||||||
|
# save passed account to cache, available before HA reboot
|
||||||
|
self.hass.data[DOMAIN]["login_data"] = {
|
||||||
|
CONF_ACCOUNT: account,
|
||||||
|
CONF_PASSWORD: password,
|
||||||
|
CONF_SERVER: cloud_server,
|
||||||
|
}
|
||||||
|
# return to next step after login pass
|
||||||
|
return await self.async_step_auto()
|
||||||
|
# return error with login failed
|
||||||
|
_LOGGER.debug(
|
||||||
|
"ERROR: Failed to login with %s account in %s server",
|
||||||
|
self.hass.data[DOMAIN]["login_mode"],
|
||||||
|
cloud_server,
|
||||||
|
)
|
||||||
|
return await self.async_step_login(error="login_failed")
|
||||||
|
# user not login, show login form in UI
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="login",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_ACCOUNT): str,
|
||||||
|
vol.Required(CONF_PASSWORD): str,
|
||||||
|
vol.Required(CONF_SERVER, default=1): vol.In(cloud_servers),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
errors={"base": error} if error else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_list(
|
||||||
|
self,
|
||||||
|
error: str | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""List all devices and show device info in web UI.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
# get all devices list
|
||||||
|
all_devices = discover()
|
||||||
|
# available devices exist
|
||||||
|
if len(all_devices) > 0:
|
||||||
|
table = (
|
||||||
|
"Appliance code|Type|IP address|SN|Supported\n:--:|:--:|:--:|:--:|:--:"
|
||||||
|
)
|
||||||
|
green = "<font color=gree>YES</font>"
|
||||||
|
red = "<font color=red>NO</font>"
|
||||||
|
for device_id, device in all_devices.items():
|
||||||
|
supported = device.get(CONF_TYPE) in self.supports
|
||||||
|
table += (
|
||||||
|
f"\n{device_id}|{f'{device.get(CONF_TYPE):02X}'}|"
|
||||||
|
f"{device.get(CONF_IP_ADDRESS)}|"
|
||||||
|
f"{device.get('sn')}|"
|
||||||
|
f"{green if supported else red}"
|
||||||
|
)
|
||||||
|
# no available device
|
||||||
|
else:
|
||||||
|
table = "Not found"
|
||||||
|
# show devices list result in UI
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="list",
|
||||||
|
description_placeholders={"table": table},
|
||||||
|
errors={"base": error} if error else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_discovery(
|
||||||
|
self,
|
||||||
|
discovery_info: dict[str, Any] | None = None,
|
||||||
|
error: str | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Discovery device with auto mode or ip address.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
# input is not None, using ip_address to discovery device
|
||||||
|
if discovery_info is not None:
|
||||||
|
# auto mode, ip_address is None
|
||||||
|
if discovery_info[CONF_IP_ADDRESS].lower() == "auto":
|
||||||
|
ip_address = None
|
||||||
|
# ip exist
|
||||||
|
else:
|
||||||
|
ip_address = discovery_info[CONF_IP_ADDRESS]
|
||||||
|
# use midea-local discover() to get devices list with ip_address
|
||||||
|
self.devices = discover(list(self.supports.keys()), ip_address=ip_address)
|
||||||
|
self.available_device = {}
|
||||||
|
for device_id, device in self.devices.items():
|
||||||
|
# remove exist devices and only return new devices
|
||||||
|
if not self._already_configured(
|
||||||
|
str(device_id),
|
||||||
|
device[CONF_IP_ADDRESS],
|
||||||
|
):
|
||||||
|
# fmt: off
|
||||||
|
self.available_device[device_id] = (
|
||||||
|
f"{device_id} ({self.supports.get(device.get(CONF_TYPE))})"
|
||||||
|
)
|
||||||
|
# fmt: on
|
||||||
|
if len(self.available_device) > 0:
|
||||||
|
return await self.async_step_auto()
|
||||||
|
return await self.async_step_discovery(error="no_devices")
|
||||||
|
# show discovery device input form with auto or ip address in web UI
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="discovery",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{vol.Required(CONF_IP_ADDRESS, default="auto"): str},
|
||||||
|
),
|
||||||
|
errors={"base": error} if error else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _check_cloud_login(
|
||||||
|
self,
|
||||||
|
cloud_name: str | None = None,
|
||||||
|
account: str | None = None,
|
||||||
|
password: str | None = None,
|
||||||
|
force_login: bool = False,
|
||||||
|
) -> bool:
|
||||||
|
"""Check cloud login.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
True if cloud login succeeded
|
||||||
|
|
||||||
|
"""
|
||||||
|
# set default args with perset account
|
||||||
|
if cloud_name is None or account is None or password is None:
|
||||||
|
cloud_name = self.preset_cloud_name
|
||||||
|
account = self.preset_account
|
||||||
|
password = self.preset_password
|
||||||
|
|
||||||
|
if self.session is None:
|
||||||
|
self.session = async_create_clientsession(self.hass)
|
||||||
|
|
||||||
|
# init cloud object or force reinit with new one
|
||||||
|
if self.cloud is None or force_login:
|
||||||
|
self.cloud = get_midea_cloud(
|
||||||
|
cloud_name,
|
||||||
|
self.session,
|
||||||
|
account,
|
||||||
|
password,
|
||||||
|
)
|
||||||
|
# check cloud login after self.cloud exist
|
||||||
|
if await self.cloud.login():
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Using account %s login to %s cloud pass",
|
||||||
|
account,
|
||||||
|
cloud_name,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
_LOGGER.debug(
|
||||||
|
"ERROR: unable to use account %s login to %s cloud",
|
||||||
|
account,
|
||||||
|
cloud_name,
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def _check_key_from_cloud(
|
||||||
|
self,
|
||||||
|
appliance_id: int,
|
||||||
|
default_key: bool = True,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Use perset DEFAULT_CLOUD account to get v3 device token and key.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Dictionary of keys
|
||||||
|
|
||||||
|
"""
|
||||||
|
device = self.devices[appliance_id]
|
||||||
|
|
||||||
|
if self.cloud is None:
|
||||||
|
return {"error": "cloud_none"}
|
||||||
|
|
||||||
|
# get device token/key from cloud
|
||||||
|
keys = await self.cloud.get_cloud_keys(appliance_id)
|
||||||
|
default_keys = await MideaCloud.get_default_keys()
|
||||||
|
# use token/key to connect device and confirm token result
|
||||||
|
for k, value in keys.items():
|
||||||
|
# skip default_key
|
||||||
|
if not default_key and k == next(iter(default_keys)):
|
||||||
|
continue
|
||||||
|
dm = MideaDevice(
|
||||||
|
name="",
|
||||||
|
device_id=appliance_id,
|
||||||
|
device_type=device.get(CONF_TYPE),
|
||||||
|
ip_address=device.get(CONF_IP_ADDRESS),
|
||||||
|
port=device.get(CONF_PORT),
|
||||||
|
token=value["token"],
|
||||||
|
key=value["key"],
|
||||||
|
device_protocol=ProtocolVersion.V3,
|
||||||
|
model=device.get(CONF_MODEL),
|
||||||
|
subtype=0,
|
||||||
|
attributes={},
|
||||||
|
)
|
||||||
|
if dm.connect():
|
||||||
|
try:
|
||||||
|
dm.authenticate()
|
||||||
|
except AuthException:
|
||||||
|
_LOGGER.debug("Unable to authenticate.")
|
||||||
|
dm.close_socket()
|
||||||
|
except SocketException:
|
||||||
|
_LOGGER.debug("Socket closed.")
|
||||||
|
else:
|
||||||
|
dm.close_socket()
|
||||||
|
return value
|
||||||
|
# return debug log with failed key
|
||||||
|
_LOGGER.debug(
|
||||||
|
"connect device using method %s token/key failed",
|
||||||
|
k,
|
||||||
|
)
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Unable to connect device with all the token/key",
|
||||||
|
)
|
||||||
|
return {"error": "connect_error"}
|
||||||
|
|
||||||
|
async def async_step_auto(
|
||||||
|
self,
|
||||||
|
user_input: dict[str, Any] | None = None,
|
||||||
|
error: str | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Discovery device detail info.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
# input device exist
|
||||||
|
if user_input is not None:
|
||||||
|
device_id = user_input[CONF_DEVICE]
|
||||||
|
device = self.devices[device_id]
|
||||||
|
# set device args with protocol decode data
|
||||||
|
# then get subtype from cloud, get v3 device token/key from cloud
|
||||||
|
self.found_device = {
|
||||||
|
CONF_DEVICE_ID: device_id,
|
||||||
|
CONF_TYPE: device.get(CONF_TYPE),
|
||||||
|
CONF_PROTOCOL: device.get(CONF_PROTOCOL),
|
||||||
|
CONF_IP_ADDRESS: device.get(CONF_IP_ADDRESS),
|
||||||
|
CONF_PORT: device.get(CONF_PORT),
|
||||||
|
CONF_MODEL: device.get(CONF_MODEL),
|
||||||
|
}
|
||||||
|
storage_device = self._load_device_config(device_id)
|
||||||
|
# device config already exist, load from local json without cloud
|
||||||
|
if self._check_storage_device(device, storage_device):
|
||||||
|
self.found_device = {
|
||||||
|
CONF_DEVICE_ID: device_id,
|
||||||
|
CONF_TYPE: device.get(CONF_TYPE),
|
||||||
|
CONF_PROTOCOL: device.get(CONF_PROTOCOL),
|
||||||
|
CONF_IP_ADDRESS: device.get(CONF_IP_ADDRESS),
|
||||||
|
CONF_PORT: device.get(CONF_PORT),
|
||||||
|
CONF_MODEL: device.get(CONF_MODEL),
|
||||||
|
CONF_NAME: storage_device.get(CONF_NAME),
|
||||||
|
CONF_SUBTYPE: storage_device.get(CONF_SUBTYPE),
|
||||||
|
CONF_TOKEN: storage_device.get(CONF_TOKEN),
|
||||||
|
CONF_KEY: storage_device.get(CONF_KEY),
|
||||||
|
}
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Loaded configuration for device %s from storage",
|
||||||
|
device_id,
|
||||||
|
)
|
||||||
|
return await self.async_step_manually()
|
||||||
|
# device config not exist in local
|
||||||
|
# check login cache, show login web if no cache
|
||||||
|
if not self.hass.data.get(DOMAIN) or not self.hass.data[DOMAIN].get(
|
||||||
|
"login_data",
|
||||||
|
):
|
||||||
|
return await self.async_step_login()
|
||||||
|
# login cached exist, cloud is None, reinit and login
|
||||||
|
if self.cloud is None and not await self._check_cloud_login(
|
||||||
|
cloud_name=self.hass.data[DOMAIN]["login_data"][CONF_SERVER],
|
||||||
|
account=self.hass.data[DOMAIN]["login_data"][CONF_ACCOUNT],
|
||||||
|
password=self.hass.data[DOMAIN]["login_data"][CONF_PASSWORD],
|
||||||
|
):
|
||||||
|
# print error in debug log and show login web
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Login with cached %s account %s failed in %s server",
|
||||||
|
self.hass.data[DOMAIN].get("login_mode"),
|
||||||
|
self.hass.data[DOMAIN]["login_data"][CONF_ACCOUNT],
|
||||||
|
self.hass.data[DOMAIN]["login_data"][CONF_SERVER],
|
||||||
|
)
|
||||||
|
# remove error cache and relogin
|
||||||
|
self.hass.data[DOMAIN].pop("login_data", None)
|
||||||
|
self.hass.data[DOMAIN].pop("login_mode", None)
|
||||||
|
return await self.async_step_login()
|
||||||
|
|
||||||
|
# get subtype from cloud
|
||||||
|
if self.cloud is not None and (
|
||||||
|
device_info := await self.cloud.get_device_info(device_id)
|
||||||
|
):
|
||||||
|
# set subtype with model_number
|
||||||
|
self.found_device[CONF_NAME] = device_info.get("name")
|
||||||
|
self.found_device[CONF_SUBTYPE] = device_info.get("model_number")
|
||||||
|
|
||||||
|
# MUST get a auth passed token/key for v3 device, disable add before pass
|
||||||
|
if device.get(CONF_PROTOCOL) == ProtocolVersion.V3:
|
||||||
|
# phase 1, try with user input login data
|
||||||
|
keys = await self._check_key_from_cloud(device_id)
|
||||||
|
|
||||||
|
# no available key, continue the phase 2
|
||||||
|
if not keys.get("token") or not keys.get("key"):
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Can't get valid token with %s account in %s server",
|
||||||
|
self.hass.data[DOMAIN]["login_mode"],
|
||||||
|
self.hass.data[DOMAIN]["login_data"][CONF_SERVER],
|
||||||
|
)
|
||||||
|
|
||||||
|
# exclude: user selected not login and phase 1 is preset account
|
||||||
|
if self.hass.data[DOMAIN]["login_mode"] == "preset":
|
||||||
|
return await self.async_step_auto(
|
||||||
|
error="can't get valid token from Midea server",
|
||||||
|
)
|
||||||
|
|
||||||
|
# get key phase 2: reinit cloud with preset account
|
||||||
|
if not await self._check_cloud_login(force_login=True):
|
||||||
|
return await self.async_step_auto(
|
||||||
|
error="Perset account login failed!",
|
||||||
|
)
|
||||||
|
# try to get a passed key, without default_key
|
||||||
|
keys = await self._check_key_from_cloud(
|
||||||
|
device_id,
|
||||||
|
default_key=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# phase 2 got no available token/key, disable device add
|
||||||
|
if not keys.get("token") or not keys.get("key"):
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Can't get available token from Midea server for device %s",
|
||||||
|
device_id,
|
||||||
|
)
|
||||||
|
return await self.async_step_auto(
|
||||||
|
error=(
|
||||||
|
f"Can't get available token from Midea server"
|
||||||
|
f" for device {device_id}"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
# get key pass
|
||||||
|
self.found_device[CONF_TOKEN] = keys["token"]
|
||||||
|
self.found_device[CONF_KEY] = keys["key"]
|
||||||
|
return await self.async_step_manually()
|
||||||
|
# v1/v2 device add without token/key
|
||||||
|
return await self.async_step_manually()
|
||||||
|
# show available device list in UI
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="auto",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(
|
||||||
|
CONF_DEVICE,
|
||||||
|
default=next(iter(self.available_device.keys())),
|
||||||
|
): vol.In(self.available_device),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
errors={"base": error} if error else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_manually(
|
||||||
|
self,
|
||||||
|
user_input: dict[str, Any] | None = None,
|
||||||
|
error: str | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Add device with device detail info.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
if user_input is not None:
|
||||||
|
try:
|
||||||
|
bytearray.fromhex(user_input[CONF_TOKEN])
|
||||||
|
bytearray.fromhex(user_input[CONF_KEY])
|
||||||
|
except ValueError:
|
||||||
|
return await self.async_step_manually(error="invalid_token")
|
||||||
|
|
||||||
|
device_id = user_input[CONF_DEVICE_ID]
|
||||||
|
# check device, discover already done or only manual add
|
||||||
|
if len(self.devices) < 1:
|
||||||
|
ip = user_input[CONF_IP_ADDRESS]
|
||||||
|
# discover device
|
||||||
|
self.devices = discover(
|
||||||
|
list(self.supports.keys()),
|
||||||
|
ip_address=ip,
|
||||||
|
)
|
||||||
|
# discover result MUST exist
|
||||||
|
if len(self.devices) != 1:
|
||||||
|
return await self.async_step_manually(error="invalid_device_ip")
|
||||||
|
# check all the input, disable error add
|
||||||
|
device_id = next(iter(self.devices.keys()))
|
||||||
|
|
||||||
|
# check if device_id is correctly set for that IP
|
||||||
|
if user_input[CONF_DEVICE_ID] != device_id:
|
||||||
|
return await self.async_step_manually(
|
||||||
|
error=f"For ip {ip} the device_id MUST be {device_id}",
|
||||||
|
)
|
||||||
|
|
||||||
|
device = self.devices[device_id]
|
||||||
|
if user_input[CONF_IP_ADDRESS] != device.get(CONF_IP_ADDRESS):
|
||||||
|
return await self.async_step_manually(
|
||||||
|
error=f"ip_address MUST be {device.get(CONF_IP_ADDRESS)}",
|
||||||
|
)
|
||||||
|
if user_input[CONF_PROTOCOL] != device.get(CONF_PROTOCOL):
|
||||||
|
return await self.async_step_manually(
|
||||||
|
error=f"protocol MUST be {device.get(CONF_PROTOCOL)}",
|
||||||
|
)
|
||||||
|
|
||||||
|
# try to get token/key with preset account
|
||||||
|
if user_input[CONF_PROTOCOL] == ProtocolVersion.V3 and (
|
||||||
|
len(user_input[CONF_TOKEN]) == 0 or len(user_input[CONF_KEY]) == 0
|
||||||
|
):
|
||||||
|
# init cloud with preset account
|
||||||
|
result = await self._check_cloud_login()
|
||||||
|
if not result:
|
||||||
|
return await self.async_step_manually(
|
||||||
|
error="Perset account login failed!",
|
||||||
|
)
|
||||||
|
# try to get a passed key
|
||||||
|
keys = await self._check_key_from_cloud(int(user_input[CONF_DEVICE_ID]))
|
||||||
|
|
||||||
|
# no available token/key, disable device add
|
||||||
|
if not keys.get("token") or not keys.get("key"):
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Can't get a valid token from Midea server for device %s",
|
||||||
|
user_input[CONF_DEVICE_ID],
|
||||||
|
)
|
||||||
|
return await self.async_step_manually(
|
||||||
|
error=(
|
||||||
|
f"Can't get a valid token from Midea server"
|
||||||
|
f" for device {user_input[CONF_DEVICE_ID]}"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# set token/key from preset account
|
||||||
|
user_input[CONF_KEY] = keys["key"]
|
||||||
|
user_input[CONF_TOKEN] = keys["token"]
|
||||||
|
|
||||||
|
self.found_device = {
|
||||||
|
CONF_DEVICE_ID: user_input[CONF_DEVICE_ID],
|
||||||
|
CONF_TYPE: user_input[CONF_TYPE],
|
||||||
|
CONF_PROTOCOL: user_input[CONF_PROTOCOL],
|
||||||
|
CONF_IP_ADDRESS: user_input[CONF_IP_ADDRESS],
|
||||||
|
CONF_PORT: user_input[CONF_PORT],
|
||||||
|
CONF_MODEL: user_input[CONF_MODEL],
|
||||||
|
CONF_TOKEN: user_input[CONF_TOKEN],
|
||||||
|
CONF_KEY: user_input[CONF_KEY],
|
||||||
|
}
|
||||||
|
|
||||||
|
# check device connection with all the input
|
||||||
|
dm = MideaDevice(
|
||||||
|
name="",
|
||||||
|
device_id=user_input[CONF_DEVICE_ID],
|
||||||
|
device_type=user_input[CONF_TYPE],
|
||||||
|
ip_address=user_input[CONF_IP_ADDRESS],
|
||||||
|
port=user_input[CONF_PORT],
|
||||||
|
token=user_input[CONF_TOKEN],
|
||||||
|
key=user_input[CONF_KEY],
|
||||||
|
device_protocol=user_input[CONF_PROTOCOL],
|
||||||
|
model=user_input[CONF_MODEL],
|
||||||
|
subtype=0,
|
||||||
|
attributes={},
|
||||||
|
)
|
||||||
|
if dm.connect():
|
||||||
|
try:
|
||||||
|
if user_input[CONF_PROTOCOL] == ProtocolVersion.V3:
|
||||||
|
dm.authenticate()
|
||||||
|
except SocketException:
|
||||||
|
_LOGGER.exception("Socket closed.")
|
||||||
|
except AuthException:
|
||||||
|
_LOGGER.exception(
|
||||||
|
"Unable to authenticate with provided key and token.",
|
||||||
|
)
|
||||||
|
dm.close_socket()
|
||||||
|
else:
|
||||||
|
dm.close_socket()
|
||||||
|
data = {
|
||||||
|
CONF_NAME: user_input[CONF_NAME],
|
||||||
|
CONF_DEVICE_ID: user_input[CONF_DEVICE_ID],
|
||||||
|
CONF_TYPE: user_input[CONF_TYPE],
|
||||||
|
CONF_PROTOCOL: user_input[CONF_PROTOCOL],
|
||||||
|
CONF_IP_ADDRESS: user_input[CONF_IP_ADDRESS],
|
||||||
|
CONF_PORT: user_input[CONF_PORT],
|
||||||
|
CONF_MODEL: user_input[CONF_MODEL],
|
||||||
|
CONF_SUBTYPE: user_input[CONF_SUBTYPE],
|
||||||
|
CONF_TOKEN: user_input[CONF_TOKEN],
|
||||||
|
CONF_KEY: user_input[CONF_KEY],
|
||||||
|
}
|
||||||
|
# save device json config when adding new device
|
||||||
|
self._save_device_config(data)
|
||||||
|
# finish add device entry
|
||||||
|
return self.async_create_entry(
|
||||||
|
title=f"{user_input[CONF_NAME]}",
|
||||||
|
data=data,
|
||||||
|
)
|
||||||
|
return await self.async_step_manually(
|
||||||
|
error="Device auth failed with input config",
|
||||||
|
)
|
||||||
|
protocol = self.found_device.get(CONF_PROTOCOL)
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="manually",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(
|
||||||
|
CONF_NAME,
|
||||||
|
default=(
|
||||||
|
self.found_device.get(CONF_NAME)
|
||||||
|
if self.found_device.get(CONF_NAME)
|
||||||
|
else self.supports.get(self.found_device.get(CONF_TYPE))
|
||||||
|
),
|
||||||
|
): str,
|
||||||
|
vol.Required(
|
||||||
|
CONF_DEVICE_ID,
|
||||||
|
default=self.found_device.get(CONF_DEVICE_ID),
|
||||||
|
): int,
|
||||||
|
vol.Required(
|
||||||
|
CONF_TYPE,
|
||||||
|
default=(
|
||||||
|
self.found_device.get(CONF_TYPE)
|
||||||
|
if self.found_device.get(CONF_TYPE)
|
||||||
|
else 0xAC
|
||||||
|
),
|
||||||
|
): vol.In(self.supports),
|
||||||
|
vol.Required(
|
||||||
|
CONF_IP_ADDRESS,
|
||||||
|
default=self.found_device.get(CONF_IP_ADDRESS),
|
||||||
|
): str,
|
||||||
|
vol.Required(
|
||||||
|
CONF_PORT,
|
||||||
|
default=(
|
||||||
|
self.found_device.get(CONF_PORT)
|
||||||
|
if self.found_device.get(CONF_PORT)
|
||||||
|
else 6444
|
||||||
|
),
|
||||||
|
): int,
|
||||||
|
vol.Required(
|
||||||
|
CONF_PROTOCOL,
|
||||||
|
default=protocol or ProtocolVersion.V3,
|
||||||
|
): vol.In(
|
||||||
|
[protocol] if protocol else ProtocolVersion,
|
||||||
|
),
|
||||||
|
vol.Required(
|
||||||
|
CONF_MODEL,
|
||||||
|
default=(
|
||||||
|
self.found_device.get(CONF_MODEL)
|
||||||
|
if self.found_device.get(CONF_MODEL)
|
||||||
|
else "Unknown"
|
||||||
|
),
|
||||||
|
): str,
|
||||||
|
vol.Required(
|
||||||
|
CONF_SUBTYPE,
|
||||||
|
default=(
|
||||||
|
self.found_device.get(CONF_SUBTYPE)
|
||||||
|
if self.found_device.get(CONF_SUBTYPE)
|
||||||
|
else 0
|
||||||
|
),
|
||||||
|
): int,
|
||||||
|
vol.Optional(
|
||||||
|
CONF_TOKEN,
|
||||||
|
default=(
|
||||||
|
self.found_device.get(CONF_TOKEN)
|
||||||
|
if self.found_device.get(CONF_TOKEN)
|
||||||
|
else ""
|
||||||
|
),
|
||||||
|
): str,
|
||||||
|
vol.Optional(
|
||||||
|
CONF_KEY,
|
||||||
|
default=(
|
||||||
|
self.found_device.get(CONF_KEY)
|
||||||
|
if self.found_device.get(CONF_KEY)
|
||||||
|
else ""
|
||||||
|
),
|
||||||
|
): str,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
errors={"base": error} if error else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@callback
|
||||||
|
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
|
||||||
|
"""Create the options flow with MideaLanOptionsFlowHandler.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow options handler
|
||||||
|
|
||||||
|
"""
|
||||||
|
return MideaLanOptionsFlowHandler(config_entry)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaLanOptionsFlowHandler(OptionsFlow):
|
||||||
|
"""define an Options Flow Handler to update the options of a config entry."""
|
||||||
|
|
||||||
|
def __init__(self, config_entry: ConfigEntry) -> None:
|
||||||
|
"""Initialize options flow."""
|
||||||
|
self._config_entry = config_entry
|
||||||
|
self._device_type = config_entry.data.get(CONF_TYPE)
|
||||||
|
if self._device_type is None:
|
||||||
|
self._device_type = 0xAC
|
||||||
|
if CONF_SENSORS in self._config_entry.options:
|
||||||
|
for key in self._config_entry.options[CONF_SENSORS]:
|
||||||
|
if key not in MIDEA_DEVICES[self._device_type]["entities"]:
|
||||||
|
self._config_entry.options[CONF_SENSORS].remove(key)
|
||||||
|
if CONF_SWITCHES in self._config_entry.options:
|
||||||
|
for key in self._config_entry.options[CONF_SWITCHES]:
|
||||||
|
if key not in MIDEA_DEVICES[self._device_type]["entities"]:
|
||||||
|
self._config_entry.options[CONF_SWITCHES].remove(key)
|
||||||
|
|
||||||
|
async def async_step_init(
|
||||||
|
self,
|
||||||
|
user_input: dict[str, Any] | None = None,
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Manage the options.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Config flow result
|
||||||
|
|
||||||
|
"""
|
||||||
|
if self._device_type == CONF_ACCOUNT:
|
||||||
|
return self.async_abort(reason="account_option")
|
||||||
|
if user_input is not None:
|
||||||
|
return self.async_create_entry(title="", data=user_input)
|
||||||
|
sensors = {}
|
||||||
|
switches = {}
|
||||||
|
for attribute, attribute_config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[cast("int", self._device_type)]["entities"],
|
||||||
|
).items():
|
||||||
|
attribute_name = (
|
||||||
|
attribute if isinstance(attribute, str) else attribute.value
|
||||||
|
)
|
||||||
|
if attribute_config.get("type") in EXTRA_SENSOR:
|
||||||
|
sensors[attribute_name] = attribute_config.get("name")
|
||||||
|
elif attribute_config.get(
|
||||||
|
"type",
|
||||||
|
) in EXTRA_CONTROL and not attribute_config.get("default"):
|
||||||
|
switches[attribute_name] = attribute_config.get("name")
|
||||||
|
ip_address = self._config_entry.options.get(CONF_IP_ADDRESS, None)
|
||||||
|
if ip_address is None:
|
||||||
|
ip_address = self._config_entry.data.get(CONF_IP_ADDRESS, None)
|
||||||
|
refresh_interval = self._config_entry.options.get(CONF_REFRESH_INTERVAL, 30)
|
||||||
|
extra_sensors = list(
|
||||||
|
set(sensors.keys()) & set(self._config_entry.options.get(CONF_SENSORS, [])),
|
||||||
|
)
|
||||||
|
extra_switches = list(
|
||||||
|
set(switches.keys())
|
||||||
|
& set(self._config_entry.options.get(CONF_SWITCHES, [])),
|
||||||
|
)
|
||||||
|
customize = self._config_entry.options.get(CONF_CUSTOMIZE, "")
|
||||||
|
data_schema = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_IP_ADDRESS, default=ip_address): str,
|
||||||
|
vol.Required(CONF_REFRESH_INTERVAL, default=refresh_interval): int,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if len(sensors) > 0:
|
||||||
|
data_schema = data_schema.extend(
|
||||||
|
{
|
||||||
|
vol.Required(
|
||||||
|
CONF_SENSORS,
|
||||||
|
default=extra_sensors,
|
||||||
|
): cv.multi_select(sensors),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if len(switches) > 0:
|
||||||
|
data_schema = data_schema.extend(
|
||||||
|
{
|
||||||
|
vol.Required(
|
||||||
|
CONF_SWITCHES,
|
||||||
|
default=extra_switches,
|
||||||
|
): cv.multi_select(switches),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
data_schema = data_schema.extend(
|
||||||
|
{
|
||||||
|
vol.Optional(
|
||||||
|
CONF_CUSTOMIZE,
|
||||||
|
default=customize,
|
||||||
|
): str,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.async_show_form(step_id="init", data_schema=data_schema)
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
"""Const for Midea Lan."""
|
||||||
|
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
|
from homeassistant.const import Platform
|
||||||
|
|
||||||
|
DOMAIN = "midea_ac_lan"
|
||||||
|
COMPONENT = "component"
|
||||||
|
DEVICES = "devices"
|
||||||
|
|
||||||
|
CONF_KEY = "key"
|
||||||
|
CONF_MODEL = "model"
|
||||||
|
CONF_SUBTYPE = "subtype"
|
||||||
|
CONF_ACCOUNT = "account"
|
||||||
|
CONF_SERVER = "server"
|
||||||
|
CONF_REFRESH_INTERVAL = "refresh_interval"
|
||||||
|
|
||||||
|
EXTRA_SENSOR = [Platform.SENSOR, Platform.BINARY_SENSOR]
|
||||||
|
EXTRA_SWITCH = [Platform.SWITCH, Platform.LOCK, Platform.SELECT, Platform.NUMBER]
|
||||||
|
EXTRA_CONTROL = [
|
||||||
|
Platform.CLIMATE,
|
||||||
|
Platform.WATER_HEATER,
|
||||||
|
Platform.FAN,
|
||||||
|
Platform.HUMIDIFIER,
|
||||||
|
Platform.LIGHT,
|
||||||
|
*EXTRA_SWITCH,
|
||||||
|
]
|
||||||
|
ALL_PLATFORM = EXTRA_SENSOR + EXTRA_CONTROL
|
||||||
|
|
||||||
|
|
||||||
|
class FanSpeed(IntEnum):
|
||||||
|
"""FanSpeed reference values."""
|
||||||
|
|
||||||
|
LOW = 20
|
||||||
|
MEDIUM = 40
|
||||||
|
HIGH = 60
|
||||||
|
FULL_SPEED = 80
|
||||||
|
AUTO = 100
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
"""Diagnostics support for Midea AC LAN."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_TOKEN,
|
||||||
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from .const import CONF_KEY
|
||||||
|
|
||||||
|
TO_REDACT = {CONF_TOKEN, CONF_KEY}
|
||||||
|
|
||||||
|
|
||||||
|
async def async_get_config_entry_diagnostics(
|
||||||
|
hass: HomeAssistant, # noqa: ARG001
|
||||||
|
entry: ConfigEntry,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Return diagnostics for a config entry.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Dictionary of config
|
||||||
|
|
||||||
|
"""
|
||||||
|
return {"entry": async_redact_data(entry.as_dict(), TO_REDACT)}
|
||||||
@@ -0,0 +1,320 @@
|
|||||||
|
"""Midea Fan entries."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from homeassistant.components.fan import FanEntity, FanEntityFeature
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_DEVICE_ID,
|
||||||
|
CONF_SWITCHES,
|
||||||
|
Platform,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from midealocal.device import DeviceType
|
||||||
|
from midealocal.devices.ac import DeviceAttributes as ACAttributes
|
||||||
|
from midealocal.devices.ac import MideaACDevice
|
||||||
|
from midealocal.devices.b6 import MideaB6Device
|
||||||
|
from midealocal.devices.ce import DeviceAttributes as CEAttributes
|
||||||
|
from midealocal.devices.ce import MideaCEDevice
|
||||||
|
from midealocal.devices.fa import MideaFADevice
|
||||||
|
from midealocal.devices.x40 import DeviceAttributes as X40Attributes
|
||||||
|
from midealocal.devices.x40 import MideaX40Device
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up fan entries."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
devs: list[
|
||||||
|
MideaFAFan | MideaB6Fan | MideaACFreshAirFan | MideaCEFan | MideaX40Fan
|
||||||
|
] = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.FAN and (
|
||||||
|
config.get("default") or entity_key in extra_switches
|
||||||
|
):
|
||||||
|
if device.device_type == DeviceType.FA:
|
||||||
|
devs.append(MideaFAFan(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.B6:
|
||||||
|
devs.append(MideaB6Fan(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.AC:
|
||||||
|
devs.append(MideaACFreshAirFan(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.CE:
|
||||||
|
devs.append(MideaCEFan(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.X40:
|
||||||
|
devs.append(MideaX40Fan(device, entity_key))
|
||||||
|
async_add_entities(devs)
|
||||||
|
|
||||||
|
|
||||||
|
# HA version >= 2024,8 support TURN_ON | TURN_OFF,for future changes, ref PR #285
|
||||||
|
try:
|
||||||
|
FAN_FEATURE_TURN_ON_OFF = FanEntityFeature["TURN_ON"] | FanEntityFeature["TURN_OFF"]
|
||||||
|
except KeyError:
|
||||||
|
FAN_FEATURE_TURN_ON_OFF = FanEntityFeature(0)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaFan(MideaEntity, FanEntity):
|
||||||
|
"""Midea Fan Entries Base Class."""
|
||||||
|
|
||||||
|
_enable_turn_on_off_backwards_compatibility = False # 2024.8~2025.1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_modes(self) -> list[str] | None:
|
||||||
|
"""Midea Fan preset modes."""
|
||||||
|
return (
|
||||||
|
self._device.preset_modes if hasattr(self._device, "preset_modes") else None
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Midea Fan is on."""
|
||||||
|
return cast("bool", self._device.get_attribute("power"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def oscillating(self) -> bool:
|
||||||
|
"""Midea Fan oscillating."""
|
||||||
|
return cast("bool", self._device.get_attribute("oscillate"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_mode(self) -> str | None:
|
||||||
|
"""Midea Fan preset mode."""
|
||||||
|
return cast("str", self._device.get_attribute("mode"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fan_speed(self) -> int | None:
|
||||||
|
"""Midea Fan fan speed."""
|
||||||
|
return cast("int", self._device.get_attribute("fan_speed"))
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Fan turn off."""
|
||||||
|
self._device.set_attribute(attr="power", value=False)
|
||||||
|
|
||||||
|
def oscillate(self, oscillating: bool) -> None:
|
||||||
|
"""Midea Fan oscillate."""
|
||||||
|
self._device.set_attribute(attr="oscillate", value=oscillating)
|
||||||
|
|
||||||
|
def set_preset_mode(self, preset_mode: str) -> None:
|
||||||
|
"""Midea Fan set preset mode."""
|
||||||
|
self._device.set_attribute(attr="mode", value=preset_mode.capitalize())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def percentage(self) -> int | None:
|
||||||
|
"""Midea Fan percentage."""
|
||||||
|
if not self.fan_speed:
|
||||||
|
return None
|
||||||
|
return int(round(self.fan_speed * self.percentage_step)) # noqa: RUF046
|
||||||
|
|
||||||
|
def set_percentage(self, percentage: int) -> None:
|
||||||
|
"""Midea Fan set percentage."""
|
||||||
|
fan_speed = round(percentage / self.percentage_step)
|
||||||
|
self._device.set_attribute(attr="fan_speed", value=fan_speed)
|
||||||
|
|
||||||
|
async def async_set_percentage(self, percentage: int) -> None:
|
||||||
|
"""Midea Fan async set percentage."""
|
||||||
|
if percentage == 0:
|
||||||
|
await self.async_turn_off()
|
||||||
|
else:
|
||||||
|
await self.hass.async_add_executor_job(self.set_percentage, percentage)
|
||||||
|
|
||||||
|
def update_state(self, status: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Fan update state."""
|
||||||
|
if not self.hass:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Fan update_state skipped for %s [%s]: HASS is None",
|
||||||
|
self.name,
|
||||||
|
type(self),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
|
class MideaFAFan(MideaFan):
|
||||||
|
"""Midea FA Fan Entries."""
|
||||||
|
|
||||||
|
_device: MideaFADevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaFADevice, entity_key: str) -> None:
|
||||||
|
"""Midea FA Fan entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_supported_features = (
|
||||||
|
FanEntityFeature.SET_SPEED
|
||||||
|
| FanEntityFeature.OSCILLATE
|
||||||
|
| FanEntityFeature.PRESET_MODE
|
||||||
|
| FAN_FEATURE_TURN_ON_OFF
|
||||||
|
)
|
||||||
|
self._attr_speed_count = self._device.speed_count
|
||||||
|
|
||||||
|
def turn_on(
|
||||||
|
self,
|
||||||
|
percentage: int | None = None,
|
||||||
|
preset_mode: str | None = None,
|
||||||
|
**kwargs: Any, # noqa: ANN401, ARG002
|
||||||
|
) -> None:
|
||||||
|
"""Midea FA Fan turn on."""
|
||||||
|
fan_speed = int(percentage / self.percentage_step + 0.5) if percentage else None
|
||||||
|
self._device.turn_on(fan_speed=fan_speed, mode=preset_mode)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaB6Fan(MideaFan):
|
||||||
|
"""Midea B6 Fan Entries."""
|
||||||
|
|
||||||
|
_device: MideaB6Device
|
||||||
|
|
||||||
|
def __init__(self, device: MideaB6Device, entity_key: str) -> None:
|
||||||
|
"""Midea B6 Fan entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_supported_features = (
|
||||||
|
FanEntityFeature.SET_SPEED
|
||||||
|
| FanEntityFeature.PRESET_MODE
|
||||||
|
| FAN_FEATURE_TURN_ON_OFF
|
||||||
|
)
|
||||||
|
self._attr_speed_count = self._device.speed_count
|
||||||
|
|
||||||
|
def turn_on(
|
||||||
|
self,
|
||||||
|
percentage: int | None = None,
|
||||||
|
preset_mode: str | None = None,
|
||||||
|
**kwargs: Any, # noqa: ANN401, ARG002
|
||||||
|
) -> None:
|
||||||
|
"""Midea B6 Fan turn on."""
|
||||||
|
fan_speed = int(percentage / self.percentage_step + 0.5) if percentage else None
|
||||||
|
self._device.turn_on(fan_speed=fan_speed, mode=preset_mode)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaACFreshAirFan(MideaFan):
|
||||||
|
"""Midea AC Fresh Air Fan Entries."""
|
||||||
|
|
||||||
|
_device: MideaACDevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaACDevice, entity_key: str) -> None:
|
||||||
|
"""Midea AC Fresh Air Fan entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_supported_features = (
|
||||||
|
FanEntityFeature.SET_SPEED
|
||||||
|
| FanEntityFeature.PRESET_MODE
|
||||||
|
| FAN_FEATURE_TURN_ON_OFF
|
||||||
|
)
|
||||||
|
self._attr_speed_count = 100
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_modes(self) -> list[str] | None:
|
||||||
|
"""Midea AC Fan preset modes."""
|
||||||
|
return cast("list", self._device.fresh_air_fan_speeds)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Midea AC Fan is on."""
|
||||||
|
return cast("bool", self._device.get_attribute(ACAttributes.fresh_air_power))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def fan_speed(self) -> int:
|
||||||
|
"""Midea AC Fan fan speed."""
|
||||||
|
return cast("int", self._device.get_attribute(ACAttributes.fresh_air_fan_speed))
|
||||||
|
|
||||||
|
def turn_on(
|
||||||
|
self,
|
||||||
|
percentage: int | None = None, # noqa: ARG002
|
||||||
|
preset_mode: str | None = None, # noqa: ARG002
|
||||||
|
**kwargs: Any, # noqa: ANN401, ARG002
|
||||||
|
) -> None:
|
||||||
|
"""Midea AC Fan tun on."""
|
||||||
|
self._device.set_attribute(attr=ACAttributes.fresh_air_power, value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea AC Fan turn off."""
|
||||||
|
self._device.set_attribute(attr=ACAttributes.fresh_air_power, value=False)
|
||||||
|
|
||||||
|
def set_percentage(self, percentage: int) -> None:
|
||||||
|
"""Midea AC Fan set percentage."""
|
||||||
|
fan_speed = int(percentage / self.percentage_step + 0.5)
|
||||||
|
self._device.set_attribute(
|
||||||
|
attr=ACAttributes.fresh_air_fan_speed,
|
||||||
|
value=fan_speed,
|
||||||
|
)
|
||||||
|
|
||||||
|
def set_preset_mode(self, preset_mode: str) -> None:
|
||||||
|
"""Midea AC Fan set preset mode."""
|
||||||
|
self._device.set_attribute(attr=ACAttributes.fresh_air_mode, value=preset_mode)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def preset_mode(self) -> str | None:
|
||||||
|
"""Midea AC Fan preset mode."""
|
||||||
|
return cast("str", self._device.get_attribute(attr=ACAttributes.fresh_air_mode))
|
||||||
|
|
||||||
|
|
||||||
|
class MideaCEFan(MideaFan):
|
||||||
|
"""Midea CE Fan Entries."""
|
||||||
|
|
||||||
|
_device: MideaCEDevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaCEDevice, entity_key: str) -> None:
|
||||||
|
"""Midea CE Fan entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_supported_features = (
|
||||||
|
FanEntityFeature.SET_SPEED
|
||||||
|
| FanEntityFeature.PRESET_MODE
|
||||||
|
| FAN_FEATURE_TURN_ON_OFF
|
||||||
|
)
|
||||||
|
self._attr_speed_count = self._device.speed_count
|
||||||
|
|
||||||
|
def turn_on(
|
||||||
|
self,
|
||||||
|
percentage: int | None = None, # noqa: ARG002
|
||||||
|
preset_mode: str | None = None, # noqa: ARG002
|
||||||
|
**kwargs: Any, # noqa: ANN401, ARG002
|
||||||
|
) -> None:
|
||||||
|
"""Midea CE Fan turn on."""
|
||||||
|
self._device.set_attribute(attr=CEAttributes.power, value=True)
|
||||||
|
|
||||||
|
async def async_set_percentage(self, percentage: int) -> None:
|
||||||
|
"""Midea CE Fan async set percentage."""
|
||||||
|
await self.hass.async_add_executor_job(self.set_percentage, percentage)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaX40Fan(MideaFan):
|
||||||
|
"""Midea X40 Fan Entries."""
|
||||||
|
|
||||||
|
_device: MideaX40Device
|
||||||
|
|
||||||
|
def __init__(self, device: MideaX40Device, entity_key: str) -> None:
|
||||||
|
"""Midea X40 Fan entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_supported_features = (
|
||||||
|
FanEntityFeature.SET_SPEED
|
||||||
|
| FanEntityFeature.OSCILLATE
|
||||||
|
| FAN_FEATURE_TURN_ON_OFF
|
||||||
|
)
|
||||||
|
self._attr_speed_count = 2
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Midea X40 Fan is on."""
|
||||||
|
return cast("int", self._device.get_attribute(attr=X40Attributes.fan_speed)) > 0
|
||||||
|
|
||||||
|
def turn_on(
|
||||||
|
self,
|
||||||
|
percentage: int | None = None, # noqa: ARG002
|
||||||
|
preset_mode: str | None = None, # noqa: ARG002
|
||||||
|
**kwargs: Any, # noqa: ANN401, ARG002
|
||||||
|
) -> None:
|
||||||
|
"""Midea X40 Fan turn on."""
|
||||||
|
self._device.set_attribute(attr=X40Attributes.fan_speed, value=1)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea X40 Fan turn off."""
|
||||||
|
self._device.set_attribute(attr=X40Attributes.fan_speed, value=0)
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
"""Midea Humidifier entries."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any, TypeAlias, cast
|
||||||
|
|
||||||
|
from homeassistant.components.humidifier import (
|
||||||
|
HumidifierDeviceClass,
|
||||||
|
HumidifierEntity,
|
||||||
|
HumidifierEntityFeature,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from midealocal.device import DeviceType
|
||||||
|
from midealocal.devices.a1 import MideaA1Device
|
||||||
|
from midealocal.devices.fd import MideaFDDevice
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up humidifier entries."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
devs: list[MideaA1Humidifier | MideaFDHumidifier] = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.HUMIDIFIER and (
|
||||||
|
config.get("default") or entity_key in extra_switches
|
||||||
|
):
|
||||||
|
if device.device_type == DeviceType.A1:
|
||||||
|
devs.append(MideaA1Humidifier(device, entity_key))
|
||||||
|
if device.device_type == DeviceType.FD:
|
||||||
|
devs.append(MideaFDHumidifier(device, entity_key))
|
||||||
|
async_add_entities(devs)
|
||||||
|
|
||||||
|
|
||||||
|
MideaHumidifierDevice: TypeAlias = MideaFDDevice | MideaA1Device
|
||||||
|
|
||||||
|
|
||||||
|
class MideaHumidifier(MideaEntity, HumidifierEntity):
|
||||||
|
"""Midea Humidifier Entries Base Class."""
|
||||||
|
|
||||||
|
_device: MideaHumidifierDevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaHumidifierDevice, entity_key: str) -> None:
|
||||||
|
"""Midea Humidifier entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_humidity(self) -> float | None:
|
||||||
|
"""Midea Humidifier current humidity."""
|
||||||
|
return cast("float", self._device.get_attribute("current_humidity"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_humidity(self) -> float:
|
||||||
|
"""Midea Humidifier target humidity."""
|
||||||
|
return cast("float", self._device.get_attribute("target_humidity"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self) -> str:
|
||||||
|
"""Midea Humidifier mode."""
|
||||||
|
return cast("str", self._device.get_attribute("mode"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available_modes(self) -> list[str] | None:
|
||||||
|
"""Midea Humidifier available modes."""
|
||||||
|
return cast("list", self._device.modes)
|
||||||
|
|
||||||
|
def set_humidity(self, humidity: int) -> None:
|
||||||
|
"""Midea Humidifier set humidity."""
|
||||||
|
self._device.set_attribute("target_humidity", humidity)
|
||||||
|
|
||||||
|
def set_mode(self, mode: str) -> None:
|
||||||
|
"""Midea Humidifier set mode."""
|
||||||
|
self._device.set_attribute("mode", mode)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Midea Humidifier is on."""
|
||||||
|
return cast("bool", self._device.get_attribute(attr="power"))
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Humidifier turn on."""
|
||||||
|
self._device.set_attribute(attr="power", value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Humidifier turn off."""
|
||||||
|
self._device.set_attribute(attr="power", value=False)
|
||||||
|
|
||||||
|
def update_state(self, status: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Humidifier update state."""
|
||||||
|
if not self.hass:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Humidifier update_state skipped for %s [%s]: HASS is None",
|
||||||
|
self.name,
|
||||||
|
type(self),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
|
class MideaA1Humidifier(MideaHumidifier):
|
||||||
|
"""Midea A1 Humidifier Entries."""
|
||||||
|
|
||||||
|
_device: MideaA1Device
|
||||||
|
|
||||||
|
def __init__(self, device: MideaA1Device, entity_key: str) -> None:
|
||||||
|
"""Midea A1 Humidifier entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_min_humidity: float = 35
|
||||||
|
self._attr_max_humidity: float = 85
|
||||||
|
self._attr_device_class = HumidifierDeviceClass.DEHUMIDIFIER
|
||||||
|
self._attr_supported_features = HumidifierEntityFeature.MODES
|
||||||
|
|
||||||
|
|
||||||
|
class MideaFDHumidifier(MideaHumidifier):
|
||||||
|
"""Midea FD Humidifier Entries."""
|
||||||
|
|
||||||
|
_device: MideaFDDevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaFDDevice, entity_key: str) -> None:
|
||||||
|
"""Midea FD Humidifier entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_min_humidity: float = 35
|
||||||
|
self._attr_max_humidity: float = 85
|
||||||
|
self._attr_device_class = HumidifierDeviceClass.HUMIDIFIER
|
||||||
|
self._attr_supported_features = HumidifierEntityFeature.MODES
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
"""Midea Light entries."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from homeassistant.components.light import (
|
||||||
|
ATTR_BRIGHTNESS,
|
||||||
|
ATTR_COLOR_TEMP_KELVIN,
|
||||||
|
ATTR_EFFECT,
|
||||||
|
ColorMode,
|
||||||
|
LightEntity,
|
||||||
|
LightEntityFeature,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from midealocal.devices.x13 import DeviceAttributes as X13Attributes
|
||||||
|
from midealocal.devices.x13 import Midea13Device
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up light entries."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
devs = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.LIGHT and (
|
||||||
|
config.get("default") or entity_key in extra_switches
|
||||||
|
):
|
||||||
|
devs.append(MideaLight(device, entity_key))
|
||||||
|
async_add_entities(devs)
|
||||||
|
|
||||||
|
|
||||||
|
def _calc_supported_features(device: Midea13Device) -> LightEntityFeature:
|
||||||
|
supported_features = LightEntityFeature(0)
|
||||||
|
if device.get_attribute(X13Attributes.effect):
|
||||||
|
supported_features |= LightEntityFeature.EFFECT
|
||||||
|
return supported_features
|
||||||
|
|
||||||
|
|
||||||
|
def _calc_supported_color_modes(device: Midea13Device) -> set[ColorMode]:
|
||||||
|
# https://github.com/home-assistant/core/blob/c34731185164aaf44419977c4086e9a7dd6c0a7f/homeassistant/components/light/__init__.py#L1278
|
||||||
|
supported = set[ColorMode]()
|
||||||
|
|
||||||
|
if device.get_attribute(X13Attributes.color_temperature) is not None:
|
||||||
|
supported.add(ColorMode.COLOR_TEMP)
|
||||||
|
if device.get_attribute(X13Attributes.rgb_color) is not None:
|
||||||
|
supported.add(ColorMode.HS)
|
||||||
|
if not supported and device.get_attribute(X13Attributes.brightness) is not None:
|
||||||
|
supported = {ColorMode.BRIGHTNESS}
|
||||||
|
|
||||||
|
if not supported:
|
||||||
|
supported = {ColorMode.ONOFF}
|
||||||
|
|
||||||
|
return supported
|
||||||
|
|
||||||
|
|
||||||
|
class MideaLight(MideaEntity, LightEntity):
|
||||||
|
"""Midea Light Entries."""
|
||||||
|
|
||||||
|
_attr_color_mode: ColorMode | str | None = None
|
||||||
|
_attr_supported_color_modes: set[ColorMode] | set[str] | None = None
|
||||||
|
_attr_supported_features: LightEntityFeature = LightEntityFeature(0)
|
||||||
|
|
||||||
|
_device: Midea13Device
|
||||||
|
|
||||||
|
def __init__(self, device: Midea13Device, entity_key: str) -> None:
|
||||||
|
"""Midea Light entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._attr_supported_features = _calc_supported_features(device)
|
||||||
|
self._attr_supported_color_modes = _calc_supported_color_modes(device)
|
||||||
|
self._attr_color_mode = self._calc_color_mode(self._attr_supported_color_modes)
|
||||||
|
|
||||||
|
def _calc_color_mode(self, supported: set[ColorMode]) -> ColorMode:
|
||||||
|
"""Midea Light calculate color mode.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Calculated color mode
|
||||||
|
|
||||||
|
"""
|
||||||
|
# https://github.com/home-assistant/core/blob/c34731185164aaf44419977c4086e9a7dd6c0a7f/homeassistant/components/light/__init__.py#L925
|
||||||
|
if ColorMode.HS in supported and self.hs_color is not None:
|
||||||
|
return ColorMode.HS
|
||||||
|
if ColorMode.COLOR_TEMP in supported and self.color_temp_kelvin is not None:
|
||||||
|
return ColorMode.COLOR_TEMP
|
||||||
|
if ColorMode.BRIGHTNESS in supported and self.brightness is not None:
|
||||||
|
return ColorMode.BRIGHTNESS
|
||||||
|
if ColorMode.ONOFF in supported:
|
||||||
|
return ColorMode.ONOFF
|
||||||
|
return ColorMode.UNKNOWN
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Midea Light is on."""
|
||||||
|
return cast("bool", self._device.get_attribute(X13Attributes.power))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def brightness(self) -> int | None:
|
||||||
|
"""Midea Light brightness."""
|
||||||
|
return cast("int", self._device.get_attribute(X13Attributes.brightness))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def rgb_color(self) -> tuple[int, int, int] | None:
|
||||||
|
"""Midea Light rgb color."""
|
||||||
|
return cast("tuple", self._device.get_attribute(X13Attributes.rgb_color))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def color_temp(self) -> int | None:
|
||||||
|
"""Midea Light color temperature."""
|
||||||
|
if not self.color_temp_kelvin:
|
||||||
|
return None
|
||||||
|
return round(1000000 / self.color_temp_kelvin)
|
||||||
|
|
||||||
|
# https://developers.home-assistant.io/blog/2024/12/14/kelvin-preferred-color-temperature-unit
|
||||||
|
@property
|
||||||
|
def color_temp_kelvin(self) -> int | None:
|
||||||
|
"""Midea Light color temperature kelvin."""
|
||||||
|
return cast("int", self._device.get_attribute(X13Attributes.color_temperature))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_color_temp_kelvin(self) -> int:
|
||||||
|
"""Midea Light min color temperature kelvin."""
|
||||||
|
return self._device.color_temp_range[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_color_temp_kelvin(self) -> int:
|
||||||
|
"""Midea Light max color temperature kelvin."""
|
||||||
|
return self._device.color_temp_range[1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def effect_list(self) -> list[str] | None:
|
||||||
|
"""Midea Light effect list."""
|
||||||
|
return cast("list", self._device.effects)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def effect(self) -> str | None:
|
||||||
|
"""Midea Light effect."""
|
||||||
|
return cast("str", self._device.get_attribute(X13Attributes.effect))
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea Light turn on."""
|
||||||
|
if not self.is_on:
|
||||||
|
self._device.set_attribute(attr=X13Attributes.power, value=True)
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
if key == ATTR_BRIGHTNESS:
|
||||||
|
self._device.set_attribute(attr=X13Attributes.brightness, value=value)
|
||||||
|
if key == ATTR_COLOR_TEMP_KELVIN:
|
||||||
|
self._device.set_attribute(
|
||||||
|
attr=X13Attributes.color_temperature,
|
||||||
|
value=value,
|
||||||
|
)
|
||||||
|
if key == ATTR_EFFECT:
|
||||||
|
self._device.set_attribute(attr=X13Attributes.effect, value=value)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Light turn off."""
|
||||||
|
self._device.set_attribute(attr=X13Attributes.power, value=False)
|
||||||
|
|
||||||
|
def update_state(self, status: Any) -> None: # noqa: ANN401,ARG002
|
||||||
|
"""Midea Light update state."""
|
||||||
|
if not self.hass:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Light update_state skipped for %s [%s]: HASS is None",
|
||||||
|
self.name,
|
||||||
|
type(self),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
self.schedule_update_ha_state()
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
"""Lock entities for Midea Lan."""
|
||||||
|
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from homeassistant.components.lock import LockEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up entities for device."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
locks = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.LOCK and entity_key in extra_switches:
|
||||||
|
dev = MideaLock(device, entity_key)
|
||||||
|
locks.append(dev)
|
||||||
|
async_add_entities(locks)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaLock(MideaEntity, LockEntity):
|
||||||
|
"""Represent a Midea lock entity."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_locked(self) -> bool:
|
||||||
|
"""Return true if state is locked."""
|
||||||
|
return cast("bool", self._device.get_attribute(self._entity_key))
|
||||||
|
|
||||||
|
def lock(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Lock the lock."""
|
||||||
|
self._device.set_attribute(attr=self._entity_key, value=True)
|
||||||
|
|
||||||
|
def unlock(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Unlock the lock."""
|
||||||
|
self._device.set_attribute(attr=self._entity_key, value=False)
|
||||||
|
|
||||||
|
def open(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Open the lock."""
|
||||||
|
self.unlock()
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"domain": "midea_ac_lan",
|
||||||
|
"name": "Midea AC LAN",
|
||||||
|
"codeowners": ["@wuwentao", "@rokam", "@chemelli74", "@Necroneco"],
|
||||||
|
"config_flow": true,
|
||||||
|
"dependencies": [],
|
||||||
|
"documentation": "https://github.com/wuwentao/midea_ac_lan#readme",
|
||||||
|
"integration_type": "device",
|
||||||
|
"iot_class": "local_push",
|
||||||
|
"issue_tracker": "https://github.com/wuwentao/midea_ac_lan/issues",
|
||||||
|
"loggers": ["midealocal"],
|
||||||
|
"requirements": ["midea-local==6.6.0"],
|
||||||
|
"version": "v0.6.11"
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,144 @@
|
|||||||
|
"""Base entity for Midea Lan."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from homeassistant.const import MAJOR_VERSION, MINOR_VERSION
|
||||||
|
from homeassistant.core import callback
|
||||||
|
|
||||||
|
if (MAJOR_VERSION, MINOR_VERSION) >= (2023, 9):
|
||||||
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
|
else:
|
||||||
|
from homeassistant.helpers.entity import ( # type: ignore[attr-defined]
|
||||||
|
DeviceInfo,
|
||||||
|
)
|
||||||
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from midealocal.device import MideaDevice
|
||||||
|
|
||||||
|
from .const import DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaEntity(Entity):
|
||||||
|
"""Base Midea entity."""
|
||||||
|
|
||||||
|
def __init__(self, device: MideaDevice, entity_key: str) -> None:
|
||||||
|
"""Initialize Midea base entity."""
|
||||||
|
self._device = device
|
||||||
|
self._device.register_update(self.update_state)
|
||||||
|
self._config = cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[self._device.device_type]["entities"],
|
||||||
|
)[entity_key]
|
||||||
|
self._entity_key = entity_key
|
||||||
|
self._unique_id = f"{DOMAIN}.{self._device.device_id}_{entity_key}"
|
||||||
|
self.entity_id = self._unique_id
|
||||||
|
self._device_name = self._device.name
|
||||||
|
|
||||||
|
# HA language setting:
|
||||||
|
# 1. hass.config.language: Settings / System / General settings
|
||||||
|
# 2. user language setting in user profile setting
|
||||||
|
# Entity name translation based on hass.config.language
|
||||||
|
# add language in /config/configuration.yaml will disable web UI setting
|
||||||
|
# homeassistant:
|
||||||
|
# language: zh-Hans # noqa: ERA001
|
||||||
|
|
||||||
|
# Translating the name and attributes of entities:
|
||||||
|
# https://developers.home-assistant.io/blog/2023/03/27/entity_name_translations/#translating-entity-name
|
||||||
|
# https://developers.home-assistant.io/docs/internationalization/core
|
||||||
|
# translation_key: if defined, Home Assistant will try to find a
|
||||||
|
# translation in translations/<lang>.json.
|
||||||
|
# If translation exists -> UI shows the translated string.
|
||||||
|
# If translation not found -> fallback to "name" / device_class / entity_id.
|
||||||
|
self._attr_translation_key = self._config.get("translation_key")
|
||||||
|
|
||||||
|
# has_entity_name: MUST be True in modern HA (old False behavior is deprecated).
|
||||||
|
self._attr_has_entity_name = True
|
||||||
|
|
||||||
|
# Step 1: translation_key is defined
|
||||||
|
# - If translation is found in the current language:
|
||||||
|
# -> UI displays the translated string.
|
||||||
|
if self._attr_translation_key is not None:
|
||||||
|
# skip set attr_name and use translation_key
|
||||||
|
pass
|
||||||
|
# set attr_name to None will only show device name without translaion_key
|
||||||
|
# Step 2: No translation_key
|
||||||
|
# but english "name" is explicitly set in config:
|
||||||
|
# -> UI displays this name directly (highest priority).
|
||||||
|
elif self._config.get("name") is not None:
|
||||||
|
self._attr_name = self._config["name"]
|
||||||
|
# Step 3: No translation_key, no name,
|
||||||
|
# fallback to device_class default label.
|
||||||
|
# Example: device_class = temperature -> "Temperature".
|
||||||
|
elif "device_class" in self._config:
|
||||||
|
self._attr_name = None # Let HA generate from device_class
|
||||||
|
# Step 4: Nothing available,
|
||||||
|
else:
|
||||||
|
self._attr_name = (
|
||||||
|
f"{self._device_name} {self._config.get('name')}"
|
||||||
|
if "name" in self._config
|
||||||
|
else f"{self._device_name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device(self) -> MideaDevice:
|
||||||
|
"""Return device structure."""
|
||||||
|
return self._device
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_info(self) -> DeviceInfo:
|
||||||
|
"""Return device info."""
|
||||||
|
return {
|
||||||
|
"manufacturer": "Midea",
|
||||||
|
"model": f"{MIDEA_DEVICES[self._device.device_type]['name']} "
|
||||||
|
f"{self._device.model}"
|
||||||
|
f" ({self._device.subtype})",
|
||||||
|
"identifiers": {(DOMAIN, str(self._device.device_id))},
|
||||||
|
"name": self._device_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self) -> str:
|
||||||
|
"""Return entity unique id."""
|
||||||
|
return self._unique_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self) -> bool:
|
||||||
|
"""Return true is integration should poll."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return entity availability."""
|
||||||
|
return bool(self._device.available)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self) -> str:
|
||||||
|
"""Return entity icon."""
|
||||||
|
return cast("str", self._config.get("icon"))
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def update_state(self, status: Any) -> None: # noqa: ANN401
|
||||||
|
"""Update entity state."""
|
||||||
|
if not self.hass:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"MideaEntity update_state for %s [%s] with status %s: HASS is None",
|
||||||
|
self.name,
|
||||||
|
type(self),
|
||||||
|
status,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.hass.is_stopping:
|
||||||
|
_LOGGER.debug(
|
||||||
|
"MideaEntity update_state for %s [%s] with status %s: HASS is stopping",
|
||||||
|
self.name,
|
||||||
|
type(self),
|
||||||
|
status,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._entity_key in status or "available" in status:
|
||||||
|
self.schedule_update_ha_state()
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
"""Number for Midea Lan."""
|
||||||
|
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from homeassistant.components.number import NumberEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from midealocal.device import MideaDevice
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up numbers for device."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
numbers = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.NUMBER and entity_key in extra_switches:
|
||||||
|
dev = MideaNumber(device, entity_key)
|
||||||
|
numbers.append(dev)
|
||||||
|
async_add_entities(numbers)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaNumber(MideaEntity, NumberEntity):
|
||||||
|
"""Represent a Midea number sensor."""
|
||||||
|
|
||||||
|
def __init__(self, device: MideaDevice, entity_key: str) -> None:
|
||||||
|
"""Midea number sensor init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._max_value = self._config.get("max")
|
||||||
|
self._min_value = self._config.get("min")
|
||||||
|
self._step_value = self._config.get("step")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_min_value(self) -> float:
|
||||||
|
"""Return minimum value."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
(
|
||||||
|
self._min_value
|
||||||
|
if isinstance(self._min_value, int)
|
||||||
|
else (
|
||||||
|
self._device.get_attribute(attr=self._min_value)
|
||||||
|
if self._device.get_attribute(attr=self._min_value)
|
||||||
|
else getattr(self._device, self._min_value)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_max_value(self) -> float:
|
||||||
|
"""Return maximum value."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
(
|
||||||
|
self._max_value
|
||||||
|
if isinstance(self._max_value, int)
|
||||||
|
else (
|
||||||
|
self._device.get_attribute(attr=self._max_value)
|
||||||
|
if self._device.get_attribute(attr=self._max_value)
|
||||||
|
else getattr(self._device, self._max_value)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_step(self) -> float:
|
||||||
|
"""Return step value."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
(
|
||||||
|
self._step_value
|
||||||
|
if isinstance(self._step_value, int)
|
||||||
|
else (
|
||||||
|
self._device.get_attribute(attr=self._step_value)
|
||||||
|
if self._device.get_attribute(attr=self._step_value)
|
||||||
|
else getattr(self._device, self._step_value)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_value(self) -> float:
|
||||||
|
"""Return value."""
|
||||||
|
return cast("float", self._device.get_attribute(self._entity_key))
|
||||||
|
|
||||||
|
def set_native_value(self, value: Any) -> None: # noqa: ANN401
|
||||||
|
"""Set value."""
|
||||||
|
self._device.set_attribute(self._entity_key, value)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
"""Select for Midea Lan."""
|
||||||
|
|
||||||
|
from typing import cast
|
||||||
|
|
||||||
|
from homeassistant.components.select import SelectEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from midealocal.device import MideaDevice
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up selects for device."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
selects = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.SELECT and entity_key in extra_switches:
|
||||||
|
dev = MideaSelect(device, entity_key)
|
||||||
|
selects.append(dev)
|
||||||
|
async_add_entities(selects)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaSelect(MideaEntity, SelectEntity):
|
||||||
|
"""Represent a Midea select."""
|
||||||
|
|
||||||
|
def __init__(self, device: MideaDevice, entity_key: str) -> None:
|
||||||
|
"""Midea select init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._options_name = self._config.get("options")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def options(self) -> list[str]:
|
||||||
|
"""Return entity options."""
|
||||||
|
return cast("list", getattr(self._device, self._options_name))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_option(self) -> str:
|
||||||
|
"""Return entity current option."""
|
||||||
|
return cast("str", self._device.get_attribute(self._entity_key))
|
||||||
|
|
||||||
|
def select_option(self, option: str) -> None:
|
||||||
|
"""Select entity option."""
|
||||||
|
self._device.set_attribute(self._entity_key, option)
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
"""Sensor for Midea Lan."""
|
||||||
|
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorEntity,
|
||||||
|
SensorStateClass,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SENSORS, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up sensors for device."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_sensors = config_entry.options.get(CONF_SENSORS, [])
|
||||||
|
sensors = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.SENSOR and entity_key in extra_sensors:
|
||||||
|
sensor = MideaSensor(device, entity_key)
|
||||||
|
sensors.append(sensor)
|
||||||
|
async_add_entities(sensors)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaSensor(MideaEntity, SensorEntity):
|
||||||
|
"""Represent a Midea sensor."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_value(self) -> StateType:
|
||||||
|
"""Return entity value."""
|
||||||
|
return cast("StateType", self._device.get_attribute(self._entity_key))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_class(self) -> SensorDeviceClass:
|
||||||
|
"""Return device class."""
|
||||||
|
return cast("SensorDeviceClass", self._config.get("device_class"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state_class(self) -> SensorStateClass | None:
|
||||||
|
"""Return state state."""
|
||||||
|
return cast("SensorStateClass | None", self._config.get("state_class"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_unit_of_measurement(self) -> str | None:
|
||||||
|
"""Return unit of measurement."""
|
||||||
|
return cast("str | None", self._config.get("unit"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def capability_attributes(self) -> dict[str, Any] | None:
|
||||||
|
"""Return capabilities."""
|
||||||
|
return {"state_class": self.state_class} if self.state_class else {}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
set_attribute:
|
||||||
|
fields:
|
||||||
|
device_id:
|
||||||
|
example: "1234567890"
|
||||||
|
attribute:
|
||||||
|
example: "eco_mode"
|
||||||
|
value:
|
||||||
|
example: true
|
||||||
|
|
||||||
|
send_command:
|
||||||
|
fields:
|
||||||
|
device_id:
|
||||||
|
example: "1234567890"
|
||||||
|
cmd_type:
|
||||||
|
example: 2
|
||||||
|
cmd_body:
|
||||||
|
example: "B0FF01370E0000A500"
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
"""Switch for Midea Lan."""
|
||||||
|
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_DEVICE_ID, CONF_SWITCHES, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity import ToggleEntity
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up switches for device."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
switches = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.SWITCH and entity_key in extra_switches:
|
||||||
|
dev = MideaSwitch(device, entity_key)
|
||||||
|
switches.append(dev)
|
||||||
|
async_add_entities(switches)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaSwitch(MideaEntity, ToggleEntity):
|
||||||
|
"""Represent a Midea switch."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self) -> bool:
|
||||||
|
"""Return true if switch is on."""
|
||||||
|
return cast("bool", self._device.get_attribute(self._entity_key))
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Turn on switch."""
|
||||||
|
self._device.set_attribute(attr=self._entity_key, value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Turn off switch."""
|
||||||
|
self._device.set_attribute(attr=self._entity_key, value=False)
|
||||||
@@ -0,0 +1,715 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "Anmeldung mit voreingestelltem Konto fehlgeschlagen, bitte melden Sie dieses Problem",
|
||||||
|
"login_failed": "Anmeldung fehlgeschlagen, Konto oder Passwort ist falsch",
|
||||||
|
"no_devices": "Keine neuen verfügbaren Geräte im Netzwerk gefunden",
|
||||||
|
"device_exist": "Das Gerät ist bereits konfiguriert",
|
||||||
|
"config_incorrect": "Die Konfiguration ist falsch",
|
||||||
|
"connect_error": "Kann keine Verbindung zum Gerät herstellen",
|
||||||
|
"invalid_token": "Token oder Schlüssel hat ein falsches Format"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "Hinzufügen von Geräten"
|
||||||
|
},
|
||||||
|
"description": "Wählen Sie die Art des Hinzufügens eines Geräts",
|
||||||
|
"title": "Neues Gerät hinzufügen"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "Konto",
|
||||||
|
"password": "Passwort"
|
||||||
|
},
|
||||||
|
"description": "Melden Sie sich mit Ihrem Midea-Konto an. Ihr Konto wird nur verwendet, um die Geräteinformationen zu erhalten.\nSie können die Konfiguration entfernen, nachdem alle Geräte konfiguriert wurden.",
|
||||||
|
"title": "Login"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "IP-Adresse des Geräts, geben Sie \"auto\" ein, um es automatisch zu finden.\nSie können auch eine IP-Adresse verwenden, um innerhalb eines bestimmten Netzwerks zu suchen, z.B. \"192.168.1.255\".",
|
||||||
|
"title": "Suche",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP-Adresse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "Geräte"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "Geräte"
|
||||||
|
},
|
||||||
|
"description": "Wählen Sie ein Gerät zum Hinzufügen",
|
||||||
|
"title": "Neues Gerät gefunden"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "Name (z.B. Klimaanlage Wohnzimmer)",
|
||||||
|
"device_id": "Geräte-ID",
|
||||||
|
"type": "Typ",
|
||||||
|
"ip_address": "IP-Adresse",
|
||||||
|
"port": "Port",
|
||||||
|
"model": "Modell",
|
||||||
|
"subtype": "Untertyp",
|
||||||
|
"protocol": "Protokoll",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Schlüssel"
|
||||||
|
},
|
||||||
|
"description": "Konfiguration des Geräts",
|
||||||
|
"title": "Neues Gerät"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "Bar Door"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "Bar Door Overtime"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "Bathing Working Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "Bottom Compartment Cooling"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "Bottom Compartment Door"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "Bottom Compartment Preheating"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "Burning State"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "Compressor Status"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "Cooking"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "Filter Change Reminder"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "Filter Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "Finished"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "Flex Door"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "Flex Zone Door"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "Freezer Door"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "Freezer Door Overtime"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "Full of Dust"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "Heating Working Status"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "Keep Warm"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "Lid Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "Middle Compartment Cooling"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "Middle Compartment Door"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "Middle Compartment Preheating"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "Oil-cup Full"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "Protection"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "Refrigerator Door"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "Refrigerator Door Overtime"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "Rinse Aid Shortage"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "Salt Shortage"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "Seat Status"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "DHW status"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "Heating status"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "IBH status"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "TBH status"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "Tank Ejected"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "Tank status"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "Top Compartment Cooling"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "Top Compartment Door"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "Top Compartment Preheating"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "Water Change Reminder"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "Water Shortage"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "With Pressure"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "Zone1 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "Zone1 Water-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "Zone2 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_water_temp_mode": {
|
||||||
|
"name": "Zone2 Water-temperature Mode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "Zone1 Thermostat"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "Zone2 Thermostat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "Fresh Air"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Kindersicherung"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "Dry Level"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "Heating Level"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "Seat Temperature Level"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "Water Temperature Level"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "Detect Mode"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "Direction"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "Fan Speed"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "Oscillation Angle"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "Oscillation Mode"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "Silent Level"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "Tilting Angle"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "Water Level Setting"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "Bathing Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "Bottom Compartment Remaining"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "Bottom Compartment Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "Bottom Compartment Temperature"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "Bottom Temperature"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "Bright Level"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "Compressor Temperature"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "Condenser Temperature"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "Current Energy Consumption"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "Current Temperature"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "dehydration speed"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "dehydration time"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "detergent"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "Energy Consumption"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "Error Code"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "Fan level"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "Filter Life"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "Filter1 Verfügbare Tage"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "Filter1 Lebensdauer Level"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "Filter2 Verfügbare Tage"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "Filter2 Lebensdauer Level"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "Filter3 Verfügbare Tage"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "Filter3 Lebensdauer Level"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "Freezer Actual Temperature"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "Freezer Setting Temperature"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "Methanal"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "Heating Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "Heating Time Remaining"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "TDS-Wert rein"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "Indoor Humidity"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "Indoor Temperature"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "Keep Warm Remaining"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "Keep Warm Time"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "Middle Compartment Remaining"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "Middle Compartment Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "Middle Compartment Temperature"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "TDS-Wert raus"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "Outdoor Temperature"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "Program"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "Progress"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "Realtime Power"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "Refrigerator Actual Temperature"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "Refrigerator Setting Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "Right Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "Right Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "rinse level"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "Seat Temperature"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "soak time"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "softener"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "Softwater Level"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Status"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "Storage Remaining"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "Tank"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "Tank Actual Temperature"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "Target Temperature"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "Time Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "Top Compartment Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "Top Compartment Status"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "Top Compartment Temperature"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "Top Temperature"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "Total Energy Consumption"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "Total produced energy"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "TVOC"
|
||||||
|
},
|
||||||
|
"wash_level": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "wash strength"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "wash time"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "Wasserverbrauch"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "Water Temperature"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "Water Level"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "Working Time"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "Anion"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "Aux Heating"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "Boost Mode"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "Breezeless"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "Comfort Mode"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "DHW Power"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "Disinfect"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "Dry"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "ECO Mode"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "Fast DHW"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "Foam Shield"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "Frost Protect"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "Indirect Wind"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Licht"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "Link to AC"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "Main Light"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "Main Power"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "Natural Wind"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "Night Light"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "Oscillate"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "Strom"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "Powerful Purification"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "Prompt Tone"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "Screen Display Alternate"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "Sensor Light"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "Silent Mode"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "Sleep Mode"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "Smart Eye"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "Smart Volume"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "Geruchssensor"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "Standby"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "Start"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "Storage"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "swing"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "Swing Horizontal"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "Swing Vertical"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "Variable Heating"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "Lüftung"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "Whole Tank Heating"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "Zero Cold Water (Pulse)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "Zero Cold Water"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "Zone1 Curve"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "Zone1 Power"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "Zone2 Curve"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "Zone2 Power"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "Domestic hot water"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "Bathing"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP-Adresse",
|
||||||
|
"refresh_interval": "Aktualisierungsintervall (0 bedeutet, dass nicht aktiv aktualisiert wird)",
|
||||||
|
"sensors": "Zusätzliche Sensoren",
|
||||||
|
"switches": "Zusätzliche Schalter",
|
||||||
|
"customize": "Anpassen"
|
||||||
|
},
|
||||||
|
"title": "Konfiguration"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "Das Konto unterstützt diesen Vorgang nicht.\nKlicken Sie auf \"GERÄT HINZUFÜGEN\" um ein neues Gerät hinzuzufügen."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "Attribut setzen",
|
||||||
|
"description": "Einstellen des Attributwerts des Geräts",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Geräte-ID",
|
||||||
|
"description": "Die Geräte-ID des Geräts"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "Attribut",
|
||||||
|
"description": "Der Name des Attributs, das gesetzt werden soll"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "Wert",
|
||||||
|
"description": "Der Attributwert, der gesetzt werden soll"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "Befehl an Gerät senden",
|
||||||
|
"description": "Senden eines Befehls an das Gerät",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Geräte-ID",
|
||||||
|
"description": "Die Geräte-ID des Geräts"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "Befehlstyp",
|
||||||
|
"description": "Die Art des Befehls, sollte 3 (abfragen) oder 2 (setzen) sein"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "Befehl",
|
||||||
|
"description": "Der Hauptteil des Befehls (ohne den MSmart-Protokollkopf und die Prüfsumme am Ende)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,834 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "Failed to login with preset account, please report this issue",
|
||||||
|
"login_failed": "Failed to login, account or password was wrong",
|
||||||
|
"no_devices": "No new available appliances found on the network",
|
||||||
|
"device_exist": "Appliance is already configured",
|
||||||
|
"config_incorrect": "The configuration is incorrect",
|
||||||
|
"connect_error": "Can't connect to appliance",
|
||||||
|
"invalid_token": "Token or Key in an incorrect format"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "Adding appliances"
|
||||||
|
},
|
||||||
|
"description": "Choose the way to add a appliance",
|
||||||
|
"title": "Add new appliance"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "Account",
|
||||||
|
"password": "Password"
|
||||||
|
},
|
||||||
|
"description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.",
|
||||||
|
"title": "Login"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "IP address for device, enter \"auto\" to discover automatically\nYou can also use an IP address to search within a specified network, such as \"192.168.1.255\"",
|
||||||
|
"title": "Search",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "Appliances"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "Appliances"
|
||||||
|
},
|
||||||
|
"description": "Choose a appliance to add",
|
||||||
|
"title": "New appliance found"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "Name (e.g. Living room AC)",
|
||||||
|
"device_id": "Appliance code",
|
||||||
|
"type": "Type",
|
||||||
|
"ip_address": "IP address",
|
||||||
|
"port": "Port",
|
||||||
|
"model": "Model",
|
||||||
|
"subtype": "Subtype",
|
||||||
|
"protocol": "Protocol",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Key"
|
||||||
|
},
|
||||||
|
"description": "Configuration of appliance",
|
||||||
|
"title": "New appliance"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "Bar Door"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "Bar Door Overtime"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "Bathing Working Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "Bottom Compartment Cooling"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "Bottom Compartment Door"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "Bottom Compartment Preheating"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "Burning State"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "Compressor Status"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "Cooking"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "Filter Change Reminder"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "Filter Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "Finished"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "Flex Door"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "Flex Zone Door"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "Freezer Door"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "Freezer Door Overtime"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "Full of Dust"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "Heating Working Status"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "Keep Warm"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "Lid Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "Middle Compartment Cooling"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "Middle Compartment Door"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "Middle Compartment Preheating"
|
||||||
|
},
|
||||||
|
"top_elec_heat": {
|
||||||
|
"name": "Top Electric Heat"
|
||||||
|
},
|
||||||
|
"bottom_elec_heat": {
|
||||||
|
"name": "Bottom Electric Heat"
|
||||||
|
},
|
||||||
|
"mute_effect": {
|
||||||
|
"name": "Mute Effect"
|
||||||
|
},
|
||||||
|
"mute_status": {
|
||||||
|
"name": "Mute Status"
|
||||||
|
},
|
||||||
|
"multi_terminal": {
|
||||||
|
"name": "Multi Terminal"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "Oil-cup Full"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "Protection"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "Refrigerator Door"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "Refrigerator Door Overtime"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "Rinse Aid Shortage"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "Salt Shortage"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "Seat Status"
|
||||||
|
},
|
||||||
|
"smart_grid": {
|
||||||
|
"name": "Smart Grid"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "DHW status"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "Heating status"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "IBH status"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "TBH status"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "Tank Ejected"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "Tank status"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "Top Compartment Cooling"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "Top Compartment Door"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "Top Compartment Preheating"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "Water Change Reminder"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "Water Shortage"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "With Pressure"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "Zone1 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "Zone1 Water-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "Zone2 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"microcrystal_fresh": {
|
||||||
|
"name": "Microcrystal Fresh"
|
||||||
|
},
|
||||||
|
"electronic_smell": {
|
||||||
|
"name": "Deodorizing sterilizing"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "Zone1 Thermostat"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "Zone2 Thermostat"
|
||||||
|
},
|
||||||
|
"climate_key": {
|
||||||
|
"state_attributes": {
|
||||||
|
"fan_mode": {
|
||||||
|
"state": {
|
||||||
|
"silent": "Silent",
|
||||||
|
"full": "Full"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "Fresh Air"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Child Lock"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "Dry Level"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "Heating Level"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "Seat Temperature Level"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "Water Temperature Level"
|
||||||
|
},
|
||||||
|
"fan_speed_percent": {
|
||||||
|
"name": "Fan Speed Percent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "Detect Mode"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "Direction"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "Fan Speed"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "Oscillation Angle"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "Oscillation Mode"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "Silent Level"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "Tilting Angle"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "Water Level Setting"
|
||||||
|
},
|
||||||
|
"wind_lr_angle": {
|
||||||
|
"name": "Airflow Horizontal",
|
||||||
|
"state": {
|
||||||
|
"off": "Off",
|
||||||
|
"left": "Left",
|
||||||
|
"left-mid": "Left-Mid",
|
||||||
|
"middle": "Middle",
|
||||||
|
"right-mid": "Right-Mid",
|
||||||
|
"right": "Right"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wind_ud_angle": {
|
||||||
|
"name": "Airflow Vertical",
|
||||||
|
"state": {
|
||||||
|
"off": "Off",
|
||||||
|
"up": "Up",
|
||||||
|
"up-mid": "Up-Mid",
|
||||||
|
"middle": "Middle",
|
||||||
|
"down-mid": "Down-Mid",
|
||||||
|
"down": "Down"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "Bathing Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "Bottom Compartment Remaining"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "Bottom Compartment Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "Bottom Compartment Temperature"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "Bottom Temperature"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "Bright Level"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "Compressor Temperature"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "Condenser Temperature"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "Current Energy Consumption"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "Current Temperature"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "Dehydration speed"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "Dehydration time"
|
||||||
|
},
|
||||||
|
"dehydration_time_value": {
|
||||||
|
"name": "Dehydration time value"
|
||||||
|
},
|
||||||
|
"wash_time_value": {
|
||||||
|
"name": "Wash time value"
|
||||||
|
},
|
||||||
|
"stains": {
|
||||||
|
"name": "Stains"
|
||||||
|
},
|
||||||
|
"dirty_degree": {
|
||||||
|
"name": "Dirty degree"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "Detergent"
|
||||||
|
},
|
||||||
|
"intensity": {
|
||||||
|
"name": "Intensity"
|
||||||
|
},
|
||||||
|
"dryness_level": {
|
||||||
|
"name": "Dryness Level"
|
||||||
|
},
|
||||||
|
"dry_temperature": {
|
||||||
|
"name": "Dry Temperature"
|
||||||
|
},
|
||||||
|
"door_warn": {
|
||||||
|
"name": "Door Warn"
|
||||||
|
},
|
||||||
|
"ai_switch": {
|
||||||
|
"name": "AI Switch"
|
||||||
|
},
|
||||||
|
"material": {
|
||||||
|
"name": "Material"
|
||||||
|
},
|
||||||
|
"water_box": {
|
||||||
|
"name": "Water Box"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "Energy Consumption"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "Error Code"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "Fan level"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "Filter Life"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "Filter1 Available Days"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "Filter1 Life Level"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "Filter2 Available Days"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "Filter2 Life Level"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "Filter3 Available Days"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "Filter3 Life Level"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "Freezer Actual Temperature"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "Freezer Setting Temperature"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "Methanal"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "Heating Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "Heating Time Remaining"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "In TDS"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "Indoor Humidity"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "Indoor Temperature"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "Keep Warm Remaining"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "Keep Warm Time"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "Middle Compartment Remaining"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "Middle Compartment Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "Middle Compartment Temperature"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "Out TDS"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "Outdoor Temperature"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "Program"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "Progress"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "Realtime Power"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "Refrigerator Actual Temperature"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "Refrigerator Setting Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "Right Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "Right Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "Rinse count"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "Rinse level"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "Seat Temperature"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "Soak time"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "Softener"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "Softwater Level"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Status"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "Storage Remaining"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "Tank"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "Tank Actual Temperature"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "Target Temperature"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "Time Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "Top Compartment Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "Top Compartment Status"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "Top Compartment Temperature"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "Top Temperature"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "Total Energy Consumption"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "Total produced energy"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "TVOC"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "Wash strength"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "Wash time"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "Water Consumption"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "Water Temperature"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "Water Level"
|
||||||
|
},
|
||||||
|
"wind": {
|
||||||
|
"name": "Wind"
|
||||||
|
},
|
||||||
|
"typeinfo": {
|
||||||
|
"name": "Type Info"
|
||||||
|
},
|
||||||
|
"elec_heat": {
|
||||||
|
"name": "Electric Heat"
|
||||||
|
},
|
||||||
|
"water_pump": {
|
||||||
|
"name": "Water Pump"
|
||||||
|
},
|
||||||
|
"four_way": {
|
||||||
|
"name": "Four Way Valve"
|
||||||
|
},
|
||||||
|
"back_water": {
|
||||||
|
"name": "Back Water"
|
||||||
|
},
|
||||||
|
"sterilize": {
|
||||||
|
"name": "Sterilize"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "Working Time"
|
||||||
|
},
|
||||||
|
"humidity": {
|
||||||
|
"name": "Humidity"
|
||||||
|
},
|
||||||
|
"variable_mode": {
|
||||||
|
"name": "Variable Mode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "Anion"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "Aux Heating"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "Boost Mode"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "Breezeless"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "Comfort Mode"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "DHW Power"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "Disinfect"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "Dry"
|
||||||
|
},
|
||||||
|
"cold_water_single": {
|
||||||
|
"name": "Cold Water Single"
|
||||||
|
},
|
||||||
|
"cold_water_dot": {
|
||||||
|
"name": "Cold Water Dot"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "ECO Mode"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "Fast DHW"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "Foam Shield"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "Frost Protect"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "Indirect Wind"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Light"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "Link to AC"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "Main Light"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "Main Power"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "Natural Wind"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "Night Light"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "Oscillate"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "Power"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "Powerful Purification"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "Prompt Tone"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "Screen Display Alternate"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "Sensor Light"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "Silent Mode"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "Sleep Mode"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "Smart Eye"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "Smart Volume"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "Smelly Sensor"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "Standby"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "Start"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "Storage"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "Swing"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "Swing Horizontal"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "Swing Vertical"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "Variable Heating"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "Ventilation"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "Whole Tank Heating"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "Zero Cold Water (Pulse)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "Zero Cold Water"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "Zone1 Curve"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "Zone1 Power"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "Zone2 Curve"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "Zone2 Power"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "Domestic hot water"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "Bathing"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP address",
|
||||||
|
"refresh_interval": "Refresh interval (0 means not refreshing actively)",
|
||||||
|
"sensors": "Extra sensors",
|
||||||
|
"switches": "Extra controls",
|
||||||
|
"customize": "Customize"
|
||||||
|
},
|
||||||
|
"title": "Configure"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "The account does not supports this operation.\nClick \"ADD DEVICE\" to add a new device."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "Set attribute",
|
||||||
|
"description": "Set the attribute value of device",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Appliance code",
|
||||||
|
"description": "The appliance code (Device ID) of appliance"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "Attribute",
|
||||||
|
"description": "The attribute name want to set"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "Value",
|
||||||
|
"description": "The attribute value want to set"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "Customize command",
|
||||||
|
"description": "Send a customize command to device",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Appliance code",
|
||||||
|
"description": "The appliance code (Device ID) of appliance"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "Command type",
|
||||||
|
"description": "The type of command,should be 3(query) or 2(set)"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "Command body",
|
||||||
|
"description": "The body of command, (not include MSmart protocol head and checksum at the end)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,795 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "Fallo al iniciar sesión con la cuenta preestablecida, por favor reporte este problema",
|
||||||
|
"login_failed": "Fallo al iniciar sesión, la cuenta o la contraseña son incorrectas",
|
||||||
|
"no_devices": "No se encontraron nuevos electrodomésticos disponibles en la red",
|
||||||
|
"device_exist": "El electrodoméstico ya está configurado",
|
||||||
|
"config_incorrect": "La configuración es incorrecta",
|
||||||
|
"connect_error": "No se puede conectar con el electrodoméstico",
|
||||||
|
"invalid_token": "Identificador o clave en un formato incorrecto"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "Añadir electrodomésticos"
|
||||||
|
},
|
||||||
|
"description": "Elija la forma de añadir un electrodoméstico",
|
||||||
|
"title": "Añadir nuevo electrodoméstico"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "Cuenta",
|
||||||
|
"password": "Contraseña"
|
||||||
|
},
|
||||||
|
"description": "Inicie sesión y guarde su cuenta Midea solo para obtener la información del electrodoméstico.\nPuede eliminar esta configuración después de haber configurado todos los dispositivos.",
|
||||||
|
"title": "Iniciar sesión"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "Dirección IP del dispositivo, escriba \"auto\" para descubrir automáticamente.\nTambién puede usar una dirección IP para buscar dentro de una red específica, como \"192.168.1.255\"",
|
||||||
|
"title": "Buscar",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "Dirección IP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "Electrodomésticos"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "Electrodomésticos"
|
||||||
|
},
|
||||||
|
"description": "Elija un electrodoméstico para añadir",
|
||||||
|
"title": "Nuevo electrodoméstico encontrado"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "Nombre (ej. AA Salón)",
|
||||||
|
"device_id": "Código del electrodoméstico",
|
||||||
|
"type": "Tipo",
|
||||||
|
"ip_address": "Dirección IP",
|
||||||
|
"port": "Puerto",
|
||||||
|
"model": "Modelo",
|
||||||
|
"subtype": "Subtipo",
|
||||||
|
"protocol": "Protocolo",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Clave"
|
||||||
|
},
|
||||||
|
"description": "Configuración del electrodoméstico",
|
||||||
|
"title": "Nuevo electrodoméstico"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "Puerta del bar"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "Puerta del bar abierta demasiado tiempo"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "Estado de funcionamiento del baño"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "Enfriamiento del compartimento inferior"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "Puerta del compartimento inferior"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "Precalentamiento del compartimento inferior"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "Estado de combustión"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "Recordatorio de limpieza"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "Estado del compresor"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "Cocinando"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "Recordatorio de cambio de filtro"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "Recordatorio de limpieza de filtro"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "Terminado"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "Puerta de zona flexible"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "Puerta de zona flexible abierta demasiado tiempo"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "Puerta del congelador"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "Puerta del congelador abierta demasiado tiempo"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "Lleno de polvo"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Calentando"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "Estado de funcionamiento de calefacción"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "Mantener caliente"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "Estado de la tapa"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "Enfriamiento del compartimento medio"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "Puerta del compartimento medio"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "Precalentamiento del compartimento medio"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "Depósito de aceite lleno"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "Protección"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "Puerta del frigorífico"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "Puerta del frigorífico abierta demasiado tiempo"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "Escasez de abrillantador"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "Escasez de sal"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "Estado del asiento"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "Estado ACS"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "Estado calefacción"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "Estado IBH"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "Estado TBH"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "Depósito extraído"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "Estado del depósito"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "Enfriamiento del compartimento superior"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "Puerta del compartimento superior"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "Precalentamiento del compartimento superior"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "Recordatorio de cambio de agua"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "Escasez de agua"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "Con presión"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "Zona 1 Modo temperatura ambiente"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "Zona 1 Modo temperatura del agua"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "Zona 2 Modo temperatura ambiente"
|
||||||
|
},
|
||||||
|
"microcrystal_fresh": {
|
||||||
|
"name": "Frescura microcristalina"
|
||||||
|
},
|
||||||
|
"electronic_smell": {
|
||||||
|
"name": "Esterilización desodorizante"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "Termostato Zona 1"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "Termostato Zona 2"
|
||||||
|
},
|
||||||
|
"climate_key": {
|
||||||
|
"state_attributes": {
|
||||||
|
"fan_mode": {
|
||||||
|
"state": {
|
||||||
|
"silent": "Silencioso",
|
||||||
|
"full": "Máximo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "Aire fresco"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Bloqueo infantil"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "Nivel de secado"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "Nivel de calefacción"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "Nivel de temperatura del asiento"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "Nivel de temperatura del agua"
|
||||||
|
},
|
||||||
|
"fan_speed_percent": {
|
||||||
|
"name": "Porcentaje de velocidad del ventilador"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "Modo de detección"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "Dirección"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "Velocidad del ventilador"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Modo"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "Ángulo de oscilación"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "Modo de oscilación"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Visualización de pantalla"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "Nivel de silencio"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "Ángulo de inclinación"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "Ajuste de nivel de agua"
|
||||||
|
},
|
||||||
|
"wind_lr_angle": {
|
||||||
|
"name": "Flujo de aire horizontal",
|
||||||
|
"state": {
|
||||||
|
"off": "Apagado",
|
||||||
|
"left": "Izquierda",
|
||||||
|
"left-mid": "Izquierda-Medio",
|
||||||
|
"middle": "Medio",
|
||||||
|
"right-mid": "Derecha-Medio",
|
||||||
|
"right": "Derecha"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wind_ud_angle": {
|
||||||
|
"name": "Flujo de aire vertical",
|
||||||
|
"state": {
|
||||||
|
"off": "Apagado",
|
||||||
|
"up": "Arriba",
|
||||||
|
"up-mid": "Arriba-Medio",
|
||||||
|
"middle": "Medio",
|
||||||
|
"down-mid": "Abajo-Medio",
|
||||||
|
"down": "Abajo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "Temperatura de salida del agua de baño"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "Tiempo restante compartimento inferior"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "Estado del compartimento inferior"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "Temperatura del compartimento inferior"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "Temperatura inferior"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "Nivel de brillo"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "Temperatura del compresor"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "Temperatura del condensador"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "Consumo de energía actual"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "Temperatura actual"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "Velocidad de centrifugado"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "Tiempo de centrifugado"
|
||||||
|
},
|
||||||
|
"dehydration_time_value": {
|
||||||
|
"name": "Valor del tiempo de centrifugado"
|
||||||
|
},
|
||||||
|
"wash_time_value": {
|
||||||
|
"name": "Valor del tiempo de lavado"
|
||||||
|
},
|
||||||
|
"stains": {
|
||||||
|
"name": "Manchas"
|
||||||
|
},
|
||||||
|
"dirty_degree": {
|
||||||
|
"name": "Grado de suciedad"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "Detergente"
|
||||||
|
},
|
||||||
|
"intensity": {
|
||||||
|
"name": "Intensidad"
|
||||||
|
},
|
||||||
|
"dryness_level": {
|
||||||
|
"name": "Nivel de sequedad"
|
||||||
|
},
|
||||||
|
"dry_temperature": {
|
||||||
|
"name": "Temperatura de secado"
|
||||||
|
},
|
||||||
|
"door_warn": {
|
||||||
|
"name": "Advertencia de puerta"
|
||||||
|
},
|
||||||
|
"ai_switch": {
|
||||||
|
"name": "Interruptor IA"
|
||||||
|
},
|
||||||
|
"material": {
|
||||||
|
"name": "Material"
|
||||||
|
},
|
||||||
|
"water_box": {
|
||||||
|
"name": "Caja de agua"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "Consumo de energía"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "Código de error"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "Nivel del ventilador"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "Vida útil del filtro"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "Días disponibles Filtro 1"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "Nivel de vida Filtro 1"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "Días disponibles Filtro 2"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "Nivel de vida Filtro 2"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "Días disponibles Filtro 3"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "Nivel de vida Filtro 3"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "Temperatura real de zona flexible"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "Temperatura establecida de zona flexible"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "Temperatura real del congelador"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "Temperatura establecida del congelador"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "Formaldehído"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "Temperatura de salida del agua de calefacción"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Potencia de calefacción"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "Tiempo restante de calefacción"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "TDS de entrada"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "Humedad interior"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "Temperatura interior"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "Tiempo restante de mantener caliente"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "Tiempo de mantener caliente"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "Tiempo restante compartimento medio"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "Estado del compartimento medio"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "Temperatura del compartimento medio"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Modo"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "TDS de salida"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "Temperatura exterior"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "Programa"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "Progreso"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "Potencia en tiempo real"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "Temperatura real del frigorífico"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "Temperatura establecida del frigorífico"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "Temperatura real de zona flexible derecha"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "Temperatura establecida de zona flexible derecha"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "Recuento de aclarados"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "Nivel de aclarado"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "Temperatura del asiento"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "Tiempo de remojo"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "Suavizante"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "Nivel de agua blanda"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Estado"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "Almacenamiento restante"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "Depósito"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "Temperatura real del depósito"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "Temperatura objetivo"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "Tiempo restante"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "Tiempo restante compartimento superior"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "Estado del compartimento superior"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "Temperatura del compartimento superior"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "Temperatura superior"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "Consumo total de energía"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "Energía total producida"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "COVT"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "Potencia de lavado"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "Tiempo de lavado"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "Consumo de agua"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "Temperatura del agua"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "Nivel de agua"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "Tiempo de funcionamiento"
|
||||||
|
},
|
||||||
|
"humidity": {
|
||||||
|
"name": "Humedad"
|
||||||
|
},
|
||||||
|
"variable_mode": {
|
||||||
|
"name": "Modo variable"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "Anión"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "Calefacción auxiliar"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "Modo potente"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "Sin corrientes"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "Modo confort"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "Potencia ACS"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "Desinfectar"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "Secado"
|
||||||
|
},
|
||||||
|
"cold_water_single": {
|
||||||
|
"name": "Agua fría individual"
|
||||||
|
},
|
||||||
|
"cold_water_dot": {
|
||||||
|
"name": "Agua fría punto"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "Modo ECO"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "ACS Rápido"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "Escudo de espuma"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "Protección contra heladas"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Potencia de calefacción"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "Viento indirecto"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Luz"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "Vincular a AA"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "Luz principal"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "Alimentación principal"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "Viento natural"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "Luz nocturna"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "Oscilar"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "Encendido"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "Purificación potente"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "Tono de aviso"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Visualización de pantalla"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "Pantalla alterna"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "Luz con sensor"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "Modo silencioso"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "Modo sueño"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "Ojo inteligente"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "Volumen inteligente"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "Sensor de olores"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "En espera"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "Iniciar"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "Almacenamiento"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "Oscilación"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "Oscilación horizontal"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "Oscilación vertical"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "Calefacción variable"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "Ventilación"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "Calentamiento de tanque completo"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "Cero agua fría (Pulso)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "Cero agua fría"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "Curva Zona 1"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "Potencia Zona 1"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "Curva Zona 2"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "Potencia Zona 2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "Agua caliente sanitaria"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "Baño"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Calefacción"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "Dirección IP",
|
||||||
|
"refresh_interval": "Intervalo de actualización (0 significa no actualizar activamente)",
|
||||||
|
"sensors": "Sensores extra",
|
||||||
|
"switches": "Controles extra",
|
||||||
|
"customize": "Personalizar"
|
||||||
|
},
|
||||||
|
"title": "Configurar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "La cuenta no admite esta operación.\nHaga clic en \"AÑADIR DISPOSITIVO\" para agregar un nuevo dispositivo."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "Establecer atributo",
|
||||||
|
"description": "Establecer el valor del atributo del dispositivo",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Código del electrodoméstico",
|
||||||
|
"description": "El código (ID de dispositivo) del electrodoméstico"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "Atributo",
|
||||||
|
"description": "El nombre del atributo que desea establecer"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "Valor",
|
||||||
|
"description": "El valor del atributo que desea establecer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "Comando personalizado",
|
||||||
|
"description": "Enviar un comando personalizado al dispositivo",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Código del electrodoméstico",
|
||||||
|
"description": "El código (ID de dispositivo) del electrodoméstico"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "Tipo de comando",
|
||||||
|
"description": "El tipo de comando, debe ser 3 (consulta) o 2 (ajuste)"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "Cuerpo del comando",
|
||||||
|
"description": "El cuerpo del comando, (no incluye el encabezado del protocolo MSmart ni la suma de comprobación al final)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,715 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "Failed to login with preset account, please report this issue",
|
||||||
|
"login_failed": "Failed to login, account or password was wrong",
|
||||||
|
"no_devices": "Aucun nouvel apparel trouvé sur le réseau",
|
||||||
|
"device_exist": "L'appareil est déjà configurée",
|
||||||
|
"config_incorrect": "La configuration est incorrecte",
|
||||||
|
"connect_error": "Impossible de se connecter à l'appareil",
|
||||||
|
"invalid_token": "Token ou Key dans un format incorrect"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "Ajout d'appareil"
|
||||||
|
},
|
||||||
|
"description": "Choisissez comment ajouter des appareils",
|
||||||
|
"title": "Ajouter un nouvel apparel"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "Account",
|
||||||
|
"password": "Password"
|
||||||
|
},
|
||||||
|
"description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.",
|
||||||
|
"title": "Login"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "Saisissez l'address IP de l'appareil, entrez \"auto\" pour découvrir automatiquement.\nVous pouvez également utiliser une address IP pour rechercher dans un réseau spécifié, comme \"192.168.1.255\".",
|
||||||
|
"title": "Recherche",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "Address IP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "Apparel"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "Apparel"
|
||||||
|
},
|
||||||
|
"description": "Choisissez un apparel à ajouter",
|
||||||
|
"title": "Nouvel apparel trouvé"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "Nom (ex: Clim Salon)",
|
||||||
|
"device_id": "Code apparel",
|
||||||
|
"type": "Type",
|
||||||
|
"ip_address": "Address IP",
|
||||||
|
"port": "Port",
|
||||||
|
"model": "Modèle",
|
||||||
|
"subtype": "Soustype",
|
||||||
|
"protocol": "Protocole",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Key"
|
||||||
|
},
|
||||||
|
"description": "Configuration de l'appareil",
|
||||||
|
"title": "Nouvel apparel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "Bar Door"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "Bar Door Overtime"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "Bathing Working Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "Bottom Compartment Cooling"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "Bottom Compartment Door"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "Bottom Compartment Preheating"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "Burning State"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "Compressor Status"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "Cooking"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "Filter Change Reminder"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "Filter Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "Finished"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "Flex Door"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "Flex Zone Door"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "Freezer Door"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "Freezer Door Overtime"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "Full of Dust"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "Heating Working Status"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "Keep Warm"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "Lid Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "Middle Compartment Cooling"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "Middle Compartment Door"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "Middle Compartment Preheating"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "Oil-cup Full"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "Protection"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "Refrigerator Door"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "Refrigerator Door Overtime"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "Rinse Aid Shortage"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "Salt Shortage"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "Seat Status"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "DHW status"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "Heating status"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "IBH status"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "TBH status"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "Tank Ejected"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "Tank status"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "Top Compartment Cooling"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "Top Compartment Door"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "Top Compartment Preheating"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "Water Change Reminder"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "Water Shortage"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "With Pressure"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "Zone1 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "Zone1 Water-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "Zone2 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_water_temp_mode": {
|
||||||
|
"name": "Zone2 Water-temperature Mode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "Zone1 Thermostat"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "Zone2 Thermostat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "Fresh Air"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Child Lock"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "Dry Level"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "Heating Level"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "Seat Temperature Level"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "Water Temperature Level"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "Detect Mode"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "Direction"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "Fan Speed"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "Oscillation Angle"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "Oscillation Mode"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "Silent Level"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "Tilting Angle"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "Water Level Setting"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "Bathing Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "Bottom Compartment Remaining"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "Bottom Compartment Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "Bottom Compartment Temperature"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "Bottom Temperature"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "Bright Level"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "Compressor Temperature"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "Condenser Temperature"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "Current Energy Consumption"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "Current Temperature"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "dehydration speed"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "dehydration time"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "detergent"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "Energy Consumption"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "Error Code"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "Fan level"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "Filter Life"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "Filter1 Available Days"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "Filter1 Life Level"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "Filter2 Available Days"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "Filter2 Life Level"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "Filter3 Available Days"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "Filter3 Life Level"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "Freezer Actual Temperature"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "Freezer Setting Temperature"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "Methanal"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "Heating Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "Heating Time Remaining"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "In TDS"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "Indoor Humidity"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "Indoor Temperature"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "Keep Warm Remaining"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "Keep Warm Time"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "Middle Compartment Remaining"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "Middle Compartment Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "Middle Compartment Temperature"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "Out TDS"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "Outdoor Temperature"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "Program"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "Progress"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "Realtime Power"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "Refrigerator Actual Temperature"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "Refrigerator Setting Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "Right Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "Right Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "rinse level"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "Seat Temperature"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "soak time"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "softener"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "Softwater Level"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Status"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "Storage Remaining"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "Tank"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "Tank Actual Temperature"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "Target Temperature"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "Time Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "Top Compartment Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "Top Compartment Status"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "Top Compartment Temperature"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "Top Temperature"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "Total Energy Consumption"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "Total produced energy"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "TVOC"
|
||||||
|
},
|
||||||
|
"wash_level": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "wash strength"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "wash time"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "Water Consumption"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "Water Temperature"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "Water Level"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "Working Time"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "Anion"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "Aux Heating"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "Boost Mode"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "Breezeless"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "Comfort Mode"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "DHW Power"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "Disinfect"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "Dry"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "ECO Mode"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "Fast DHW"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "Foam Shield"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "Frost Protect"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "Indirect Wind"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Light"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "Link to AC"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "Main Light"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "Main Power"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "Natural Wind"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "Night Light"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "Oscillate"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "Power"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "Powerful Purification"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "Prompt Tone"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "Screen Display Alternate"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "Sensor Light"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "Silent Mode"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "Sleep Mode"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "Smart Eye"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "Smart Volume"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "Smelly Sensor"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "Standby"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "Start"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "Storage"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "swing"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "Swing Horizontal"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "Swing Vertical"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "Variable Heating"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "Ventilation"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "Whole Tank Heating"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "Zero Cold Water (Pulse)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "Zero Cold Water"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "Zone1 Curve"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "Zone1 Power"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "Zone2 Curve"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "Zone2 Power"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "Domestic hot water"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "Bathing"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "Address IP",
|
||||||
|
"refresh_interval": "Refresh interval (0 means not refreshing actively)",
|
||||||
|
"sensors": "Capteurs supplémentaire",
|
||||||
|
"switches": "Contrôles supplémentaire",
|
||||||
|
"customize": "Personnaliser"
|
||||||
|
},
|
||||||
|
"title": "Configurer"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "The account does not supports this operation.\nClick \"ADD DEVICE\" to add a new device."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "Définir l'attribut",
|
||||||
|
"description": "Définir la valeur d'attribut de l'appareil",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Code apparel",
|
||||||
|
"description": "Code de l'appareil (ID de l'appareil)"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "Attribute",
|
||||||
|
"description": "Nom de l'attribut que vous souhaitez définir"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "Valeur",
|
||||||
|
"description": "Valeur d'attribut que vous souhaitez définir"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "Customize command",
|
||||||
|
"description": "Send a customize command to device",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Code apparel",
|
||||||
|
"description": "Code de l'appareil (ID de l'appareil)"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "command type",
|
||||||
|
"description": "The type of command,should be 3(query) or 2(set)"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "command body",
|
||||||
|
"description": "The body of command, (not include MSmart protocol head and checksum at the end)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,715 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "Failed to login with preset account, please report this issue",
|
||||||
|
"login_failed": "Bejelentkezés sikertelen, a fiók vagy a jelszó helytelen",
|
||||||
|
"no_devices": "Nem találhatóak új eszközök a hálózaton",
|
||||||
|
"device_exist": "Az eszköz már be van állítva",
|
||||||
|
"config_incorrect": "A beállítások helytelenek",
|
||||||
|
"connect_error": "Nem sikerült csatlakozni az eszközhöz",
|
||||||
|
"invalid_token": "A Token vagy a Key formátuma helytelen"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "Eszközök hozzáadása"
|
||||||
|
},
|
||||||
|
"description": "Válassza ki az eszközök hozzáadásának módját",
|
||||||
|
"title": "Új eszköz hozzáadása"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "Fiók",
|
||||||
|
"password": "Jelszó"
|
||||||
|
},
|
||||||
|
"description": "Jelentkezzen be és tárolja el Midea-fiókját, kizárólag a készülékei információinak a megszerzéséhez.\nAz összes készülékének beállítása után eltávolíthatja ezt a konfigurációt.",
|
||||||
|
"title": "Bejelentkezés"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "Adja meg az eszköz IP címét vagy írja be az \"auto\" kifejezést az automatikus kereséshez.\nIP-címet is használhat egy megadott hálózaton belüli kereséshez, például \"192.168.1.255\".",
|
||||||
|
"title": "Keresés",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP cím"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "Eszközök"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "Eszközök"
|
||||||
|
},
|
||||||
|
"description": "Válassza ki a hozzáadandó eszközt",
|
||||||
|
"title": "Új eszköz található"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "Név (pl. Nappali légkondicionáló)",
|
||||||
|
"device_id": "Eszköz kód",
|
||||||
|
"type": "Típus",
|
||||||
|
"ip_address": "IP cím",
|
||||||
|
"port": "Port",
|
||||||
|
"model": "Model",
|
||||||
|
"subtype": "Altípus",
|
||||||
|
"protocol": "Protokoll",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Key"
|
||||||
|
},
|
||||||
|
"description": "Eszköz konfigurációja",
|
||||||
|
"title": "Új eszköz"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "Bar Door"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "Bar Door Overtime"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "Bathing Working Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "Bottom Compartment Cooling"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "Bottom Compartment Door"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "Bottom Compartment Preheating"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "Burning State"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "Compressor Status"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "Cooking"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "Filter Change Reminder"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "Filter Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "Finished"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "Flex Door"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "Flex Zone Door"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "Freezer Door"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "Freezer Door Overtime"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "Full of Dust"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "Heating Working Status"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "Keep Warm"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "Lid Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "Middle Compartment Cooling"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "Middle Compartment Door"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "Middle Compartment Preheating"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "Oil-cup Full"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "Protection"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "Refrigerator Door"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "Refrigerator Door Overtime"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "Rinse Aid Shortage"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "Salt Shortage"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "Seat Status"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "DHW status"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "Heating status"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "IBH status"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "TBH status"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "Tank Ejected"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "Tank status"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "Top Compartment Cooling"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "Top Compartment Door"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "Top Compartment Preheating"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "Water Change Reminder"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "Water Shortage"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "With Pressure"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "Zone1 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "Zone1 Water-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "Zone2 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_water_temp_mode": {
|
||||||
|
"name": "Zone2 Water-temperature Mode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "Zone1 Thermostat"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "Zone2 Thermostat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "Fresh Air"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Child Lock"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "Dry Level"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "Heating Level"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "Seat Temperature Level"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "Water Temperature Level"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "Detect Mode"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "Direction"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "Fan Speed"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "Oscillation Angle"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "Oscillation Mode"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "Silent Level"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "Tilting Angle"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "Water Level Setting"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "Bathing Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "Bottom Compartment Remaining"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "Bottom Compartment Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "Bottom Compartment Temperature"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "Bottom Temperature"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "Bright Level"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "Compressor Temperature"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "Condenser Temperature"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "Current Energy Consumption"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "Current Temperature"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "dehydration speed"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "dehydration time"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "detergent"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "Energy Consumption"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "Error Code"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "Fan level"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "Filter Life"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "Filter1 Available Days"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "Filter1 Life Level"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "Filter2 Available Days"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "Filter2 Life Level"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "Filter3 Available Days"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "Filter3 Life Level"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "Freezer Actual Temperature"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "Freezer Setting Temperature"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "Methanal"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "Heating Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "Heating Time Remaining"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "In TDS"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "Indoor Humidity"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "Indoor Temperature"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "Keep Warm Remaining"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "Keep Warm Time"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "Middle Compartment Remaining"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "Middle Compartment Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "Middle Compartment Temperature"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "Out TDS"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "Outdoor Temperature"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "Program"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "Progress"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "Realtime Power"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "Refrigerator Actual Temperature"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "Refrigerator Setting Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "Right Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "Right Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "rinse level"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "Seat Temperature"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "soak time"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "softener"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "Softwater Level"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Status"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "Storage Remaining"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "Tank"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "Tank Actual Temperature"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "Target Temperature"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "Time Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "Top Compartment Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "Top Compartment Status"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "Top Compartment Temperature"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "Top Temperature"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "Total Energy Consumption"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "Total produced energy"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "TVOC"
|
||||||
|
},
|
||||||
|
"wash_level": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "wash strength"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "wash time"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "Water Consumption"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "Water Temperature"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "Water Level"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "Working Time"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "Anion"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "Aux Heating"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "Boost Mode"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "Breezeless"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "Comfort Mode"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "DHW Power"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "Disinfect"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "Dry"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "ECO Mode"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "Fast DHW"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "Foam Shield"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "Frost Protect"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "Indirect Wind"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Light"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "Link to AC"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "Main Light"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "Main Power"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "Natural Wind"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "Night Light"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "Oscillate"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "Power"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "Powerful Purification"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "Prompt Tone"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "Screen Display Alternate"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "Sensor Light"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "Silent Mode"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "Sleep Mode"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "Smart Eye"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "Smart Volume"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "Smelly Sensor"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "Standby"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "Start"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "Storage"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "swing"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "Swing Horizontal"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "Swing Vertical"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "Variable Heating"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "Ventilation"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "Whole Tank Heating"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "Zero Cold Water (Pulse)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "Zero Cold Water"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "Zone1 Curve"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "Zone1 Power"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "Zone2 Curve"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "Zone2 Power"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "Domestic hot water"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "Bathing"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP cím",
|
||||||
|
"refresh_interval": "Frissítési intervallum (0 azt jelenti, hogy nincs aktív frissítés)",
|
||||||
|
"sensors": "Extra érzékelők",
|
||||||
|
"switches": "Extra vezérlők",
|
||||||
|
"customize": "Személyre szabás"
|
||||||
|
},
|
||||||
|
"title": "Konfigurálás"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "A fiók nem támogatja ezt a műveletet.\nKattintson az \"ESZKÖZ HOZZÁADÁSA\" gombra egy új eszköz hozzáadásához."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "Attribútum beállítása",
|
||||||
|
"description": "Állítsa be az eszköz attribútumának értékét",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Eszköz kód",
|
||||||
|
"description": "A készülék kódja (eszköz ID)"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "Attribútum",
|
||||||
|
"description": "A beállítandó attribútum neve"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "Érték",
|
||||||
|
"description": "A beállítandó attribútum értéke"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "Egyéni parancs",
|
||||||
|
"description": "Küldjön egy egyéni parancsot az eszköznek",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Eszköz kód",
|
||||||
|
"description": "A készülék kódja (Eszköz ID)"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "Parancs típusa",
|
||||||
|
"description": "A parancs típusa, lehet 3 (lekérdezés) vagy 2 (beállítás)"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "Parancs törzse",
|
||||||
|
"description": "A parancs törzse (nem tartalmazza az MSmart protokoll fejlécét és a végén lévő ellenőrző összeget)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,745 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "Failed to login with preset account, please report this issue",
|
||||||
|
"login_failed": "Не удалось авторизоваться, неверное имя аккаунта или пароль",
|
||||||
|
"no_devices": "Новые доступные устройства в локальной сети не найдены",
|
||||||
|
"device_exist": "Устройство уже настроено",
|
||||||
|
"config_incorrect": "Некорректная конфигурация",
|
||||||
|
"connect_error": "Не удается подключиться к устройству",
|
||||||
|
"invalid_token": "Некорректный формат Token или Key"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "Добавление устройства"
|
||||||
|
},
|
||||||
|
"description": "Выберите способ добавления устройств",
|
||||||
|
"title": "Добавить новое устройство"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "Аккаунт",
|
||||||
|
"password": "Пароль"
|
||||||
|
},
|
||||||
|
"description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.",
|
||||||
|
"title": "Login"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "Введите IP-адрес устройства или \"auto\", чтобы обнаружить устройства автоматически.\nВы также можете использовать IP-адрес для поиска в определенной сети, например, \"192.168.1.255\"",
|
||||||
|
"title": "Поиск",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP-адрес"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "Устройства"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "Устройства"
|
||||||
|
},
|
||||||
|
"description": "Выберите устройство для добавления",
|
||||||
|
"title": "Найдено новое устройство"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "Название (например, Кондиционер в гостиной)",
|
||||||
|
"device_id": "Идентификатор устройства",
|
||||||
|
"type": "Тип",
|
||||||
|
"ip_address": "IP-адрес",
|
||||||
|
"port": "Порт",
|
||||||
|
"model": "Модель",
|
||||||
|
"subtype": "Подтип",
|
||||||
|
"protocol": "Протокол",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Key"
|
||||||
|
},
|
||||||
|
"description": "Настройка устройства",
|
||||||
|
"title": "Новое устройство"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "Bar Door"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "Bar Door Overtime"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "Bathing Working Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "Bottom Compartment Cooling"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "Bottom Compartment Door"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "Bottom Compartment Preheating"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "Burning State"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "Требуется очистка"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "Статус компрессора"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "Приготовление"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "Требуется замена фильтра"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "Требуется очистка фильтра"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "Завершено"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "Flex Door"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "Flex Zone Door"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "Freezer Door"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "Freezer Door Overtime"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "Загрязнение"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Нагрев"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "Heating Working Status"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "Поддержание температуры"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "Крышка"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "Middle Compartment Cooling"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "Middle Compartment Door"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "Middle Compartment Preheating"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "Oil-cup Full"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "Защита"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "Refrigerator Door"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "Refrigerator Door Overtime"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "Нехватка ополаскивателя"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "Соль"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "Сиденье"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "DHW status"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "Подогрев"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "IBH status"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "TBH status"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "Tank Ejected"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "Tank status"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "Top Compartment Cooling"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "Top Compartment Door"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "Top Compartment Preheating"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "Water Change Reminder"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "Нехватка воды"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "With Pressure"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "Zone1 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "Zone1 Water-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "Zone2 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_water_temp_mode": {
|
||||||
|
"name": "Zone2 Water-temperature Mode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "Zone1 Thermostat"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "Zone2 Thermostat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "Fresh Air"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Блокировка"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "Dry Level"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "Heating Level"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "Seat Temperature Level"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "Water Temperature Level"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "Detect Mode"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "Направление"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "Скорость"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Режим"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "Oscillation Angle"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "Oscillation Mode"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "Silent Level"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "Угол поворота"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "Water Level Setting"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "Bathing Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "Bottom Compartment Remaining"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "Bottom Compartment Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "Bottom Compartment Temperature"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "Bottom Temperature"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "Bright Level"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "Compressor Temperature"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "Condenser Temperature"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "Current Energy Consumption"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "Текущая температура"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "Dehydration speed"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "Dehydration time"
|
||||||
|
},
|
||||||
|
"dehydration_time_value": {
|
||||||
|
"name": "Dehydration time value"
|
||||||
|
},
|
||||||
|
"wash_time_value": {
|
||||||
|
"name": "Wash time value"
|
||||||
|
},
|
||||||
|
"stains": {
|
||||||
|
"name": "Stains"
|
||||||
|
},
|
||||||
|
"dirty_degree": {
|
||||||
|
"name": "Dirty degree"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "Моющее средство"
|
||||||
|
},
|
||||||
|
"intensity": {
|
||||||
|
"name": "Интенсивность"
|
||||||
|
},
|
||||||
|
"dryness_level": {
|
||||||
|
"name": "Dryness Level"
|
||||||
|
},
|
||||||
|
"dry_temperature": {
|
||||||
|
"name": "Dry Temperature"
|
||||||
|
},
|
||||||
|
"door_warn": {
|
||||||
|
"name": "Door Warn"
|
||||||
|
},
|
||||||
|
"ai_switch": {
|
||||||
|
"name": "AI Switch"
|
||||||
|
},
|
||||||
|
"material": {
|
||||||
|
"name": "Материал"
|
||||||
|
},
|
||||||
|
"water_box": {
|
||||||
|
"name": "Water Box"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "Энергопотребление"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "Код ошибки"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "Fan level"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "Состояние фильтра"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "Filter1 Available Days"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "Filter1 Life Level"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "Filter2 Available Days"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "Filter2 Life Level"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "Filter3 Available Days"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "Filter3 Life Level"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "Freezer Actual Temperature"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "Freezer Setting Temperature"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "Формальдегид"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "Heating Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Мощность нагрева"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "Heating Time Remaining"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "In TDS"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "Indoor Humidity"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "Indoor Temperature"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "Keep Warm Remaining"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "Keep Warm Time"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "Middle Compartment Remaining"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "Middle Compartment Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "Middle Compartment Temperature"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Режим"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "Out TDS"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "Outdoor Temperature"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "Программа"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "Этап"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "Энергопотребление"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "Refrigerator Actual Temperature"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "Refrigerator Setting Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "Right Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "Right Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "Rinse count"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "Уровень ополаскивателя"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "Температура сиденья"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "Время замачивания"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "Умягчитель"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "Уровень умягчителя"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Статус"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "Storage Remaining"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "Tank"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "Tank Actual Temperature"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "Целевая температура"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "Время цикла"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "Top Compartment Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "Top Compartment Status"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "Top Compartment Temperature"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "Top Temperature"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "Общее энергопотребление"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "Total produced energy"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "TVOC"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "Wash strength"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "Время мойки"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "Water Consumption"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "Температура воды"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "Уровень воды"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "Время работы"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "Anion"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "Aux Heating"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "Boost Mode"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "Breezeless"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "Comfort Mode"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "DHW Power"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "Дезинфекция"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "Dry"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "Эко-режим"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "Fast DHW"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "Foam Shield"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "Защита от замерзания"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Нагреватель"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "Indirect Wind"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Свет"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "Link to AC"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "Main Light"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "Main Power"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "Natural Wind"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "Night Light"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "Режим поворота"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "Питание"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "Powerful Purification"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "Prompt Tone"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "Screen Display Alternate"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "Sensor Light"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "Silent Mode"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "Sleep Mode"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "Smart Eye"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "Smart Volume"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "Smelly Sensor"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "Ожидание"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "Старт"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "Storage"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "Swing"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "Swing Horizontal"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "Swing Vertical"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "Variable Heating"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "Вентиляция"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "Whole Tank Heating"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "Zero Cold Water (Pulse)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "Zero Cold Water"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "Zone1 Curve"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "Zone1 Power"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "Zone2 Curve"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "Zone2 Power"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "Domestic hot water"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "Bathing"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP-адрес",
|
||||||
|
"refresh_interval": "Интервал обновления (0 не выполняет активное обновление)",
|
||||||
|
"sensors": "Дополнительные сенсоры",
|
||||||
|
"switches": "Дополнительные элементы управления",
|
||||||
|
"customize": "Настроить"
|
||||||
|
},
|
||||||
|
"title": "Конфигурация"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "The account does not supports this operation.\nClick \"ADD DEVICE\" to add a new device."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "Установить атрибут",
|
||||||
|
"description": "Установить значение атрибута устройства",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Идентификатор устройства",
|
||||||
|
"description": "Код (Идентификатор) устройства"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "Атрибут",
|
||||||
|
"description": "Название атрибута для установки"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "Значение",
|
||||||
|
"description": "Значение атрибута для установки"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "Пользовательская команда",
|
||||||
|
"description": "Отправить пользовательскую команду на устройство",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Идентификатор устройства",
|
||||||
|
"description": "Код (Идентификатор) устройства"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "Тип команды",
|
||||||
|
"description": "Тип команды, может быть 3 (запрос) или 2 (установка значения)"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "Тело команды",
|
||||||
|
"description": "Тело команды (без заголовков протокола MSmart и контрольной суммы в конце)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,715 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "Failed to login with preset account, please report this issue",
|
||||||
|
"login_failed": "Failed to login, account or password was wrong",
|
||||||
|
"no_devices": "V sieti sa nenašli žiadne nové dostupné zariadenia",
|
||||||
|
"device_exist": "Spotrebič je už nakonfigurovaný",
|
||||||
|
"config_incorrect": "Konfigurácia je nesprávna",
|
||||||
|
"connect_error": "Nedá sa pripojiť k spotrebiču",
|
||||||
|
"invalid_token": "Token alebo Key v nesprávnom formáte"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "Pridávanie spotrebičov"
|
||||||
|
},
|
||||||
|
"description": "Vyberte spôsob pridávania zariadení",
|
||||||
|
"title": "Pridať nový spotrebič"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "Account",
|
||||||
|
"password": "Password"
|
||||||
|
},
|
||||||
|
"description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.",
|
||||||
|
"title": "Login"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "Zadajte IP adresu pre zariadenie, zadajte \"auto\" pre automatické vyhľadávanie.\nNa vyhľadávanie v rámci určitej siete môžete použiť aj IP adresu, napríklad \"192.168.1.255\".",
|
||||||
|
"title": "Hľadať",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP adresa"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "Spotrebiče"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "Spotrebiče"
|
||||||
|
},
|
||||||
|
"description": "Vyberte zariadenie, ktoré chcete pridať",
|
||||||
|
"title": "Našiel sa nový spotrebič"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "Názov (napr. AC obývačka)",
|
||||||
|
"device_id": "Kód spotrebiča",
|
||||||
|
"type": "Typ",
|
||||||
|
"ip_address": "IP adresa",
|
||||||
|
"port": "Port",
|
||||||
|
"model": "Model",
|
||||||
|
"subtype": "Podtyp",
|
||||||
|
"protocol": "Protokol",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Key"
|
||||||
|
},
|
||||||
|
"description": "Konfigurácia spotrebiča",
|
||||||
|
"title": "Nový spotrebič"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "Bar Door"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "Bar Door Overtime"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "Bathing Working Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "Bottom Compartment Cooling"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "Bottom Compartment Door"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "Bottom Compartment Preheating"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "Burning State"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "Compressor Status"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "Cooking"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "Filter Change Reminder"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "Filter Cleaning Reminder"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "Finished"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "Flex Door"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "Flex Zone Door"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "Freezer Door"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "Freezer Door Overtime"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "Full of Dust"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "Heating Working Status"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "Keep Warm"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "Lid Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "Middle Compartment Cooling"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "Middle Compartment Door"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "Middle Compartment Preheating"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "Oil-cup Full"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "Protection"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "Refrigerator Door"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "Refrigerator Door Overtime"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "Rinse Aid Shortage"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "Salt Shortage"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "Seat Status"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "DHW status"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "Heating status"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "IBH status"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "TBH status"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "Tank Ejected"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "Tank status"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "Top Compartment Cooling"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "Top Compartment Door"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "Top Compartment Preheating"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "Water Change Reminder"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "Water Shortage"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "With Pressure"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "Zone1 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "Zone1 Water-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "Zone2 Room-temperature Mode"
|
||||||
|
},
|
||||||
|
"zone2_water_temp_mode": {
|
||||||
|
"name": "Zone2 Water-temperature Mode"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "Zone1 Thermostat"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "Zone2 Thermostat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "Fresh Air"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Child Lock"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "Dry Level"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "Heating Level"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "Seat Temperature Level"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "Water Temperature Level"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "Detect Mode"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "Direction"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "Fan Speed"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "Oscillation Angle"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "Oscillation Mode"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "Silent Level"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "Tilting Angle"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "Water Level Setting"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "Bathing Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "Bottom Compartment Remaining"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "Bottom Compartment Status"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "Bottom Compartment Temperature"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "Bottom Temperature"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "Bright Level"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "Compressor Temperature"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "Condenser Temperature"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "Current Energy Consumption"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "Current Temperature"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "dehydration speed"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "dehydration time"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "detergent"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "Energy Consumption"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "Error Code"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "Fan level"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "Filter Life"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "Filter1 Available Days"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "Filter1 Life Level"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "Filter2 Available Days"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "Filter2 Life Level"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "Filter3 Available Days"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "Filter3 Life Level"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "Freezer Actual Temperature"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "Freezer Setting Temperature"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "Methanal"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "Heating Leaving Water Temperature"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "Heating Time Remaining"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "In TDS"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "Indoor Humidity"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "Indoor Temperature"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "Keep Warm Remaining"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "Keep Warm Time"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "Middle Compartment Remaining"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "Middle Compartment Status"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "Middle Compartment Temperature"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "Out TDS"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "Outdoor Temperature"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "Program"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "Progress"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "Realtime Power"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "Refrigerator Actual Temperature"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "Refrigerator Setting Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "Right Flex Zone Actual Temperature"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "Right Flex Zone Setting Temperature"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "rinse level"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "Seat Temperature"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "soak time"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "softener"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "Softwater Level"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Status"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "Storage Remaining"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "Tank"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "Tank Actual Temperature"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "Target Temperature"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "Time Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "Top Compartment Remaining"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "Top Compartment Status"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "Top Compartment Temperature"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "Top Temperature"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "Total Energy Consumption"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "Total produced energy"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "TVOC"
|
||||||
|
},
|
||||||
|
"wash_level": {
|
||||||
|
"name": "rinse count"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "wash strength"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "wash time"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "Water Consumption"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "Water Temperature"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "Water Level"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "Working Time"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "Anion"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "Aux Heating"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "Boost Mode"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "Breezeless"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "Comfort Mode"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "DHW Power"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "Disinfect"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "Dry"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "ECO Mode"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "Fast DHW"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "Foam Shield"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "Frost Protect"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "Heating Power"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "Indirect Wind"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Light"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "Link to AC"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "Main Light"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "Main Power"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "Natural Wind"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "Night Light"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "Oscillate"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "Power"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "Powerful Purification"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "Prompt Tone"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "Screen Display"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "Screen Display Alternate"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "Sensor Light"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "Silent Mode"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "Sleep Mode"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "Smart Eye"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "Smart Volume"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "Smelly Sensor"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "Standby"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "Start"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "Storage"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "swing"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "Swing Horizontal"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "Swing Vertical"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "Variable Heating"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "Ventilation"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "Whole Tank Heating"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "Zero Cold Water (Pulse)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "Zero Cold Water"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "Zone1 Curve"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "Zone1 Power"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "Zone2 Curve"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "Zone2 Power"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "Domestic hot water"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "Bathing"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "Heating"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP adresa",
|
||||||
|
"refresh_interval": "Refresh interval (0 means not refreshing actively)",
|
||||||
|
"sensors": "Extra Snímače",
|
||||||
|
"switches": "Extra Ovládacie prvky",
|
||||||
|
"customize": "Voliteľné"
|
||||||
|
},
|
||||||
|
"title": "Konfigurovať"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "The account does not supports this operation.\nClick \"ADD DEVICE\" to add a new device."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "Nastaviť atribút",
|
||||||
|
"description": "Nastavte hodnotu atribútu zariadenia",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Kód spotrebiča",
|
||||||
|
"description": "Kód spotrebiča (ID zariadenia) spotrebiča"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "Atribút",
|
||||||
|
"description": "Názov atribútu, ktorý chcete nastaviť"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "Hodnota",
|
||||||
|
"description": "Hodnota atribútu, ktorú chcete nastaviť"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "Prispôsobiť príkaz",
|
||||||
|
"description": "Pošlite do zariadenia príkaz na prispôsobenie",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "Kód spotrebiča",
|
||||||
|
"description": "Kód spotrebiča (ID zariadenia) spotrebiča"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "typ príkazu",
|
||||||
|
"description": "Typ príkazu by mal byť 3 (dopyt) alebo 2 (nastaviť)"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "obsah príkazu",
|
||||||
|
"description": "Obsah príkazu, (nezahŕňa hlavičku protokolu MSmart a kontrolný súčet na konci)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,802 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"error": {
|
||||||
|
"preset_account": "预置账户登录失败,请报告此问题",
|
||||||
|
"login_failed": "登录失败, 用户名或密码错",
|
||||||
|
"no_devices": "未在网络上发现可用新设备",
|
||||||
|
"device_exist": "设备已经存在, 请添加其它设备",
|
||||||
|
"config_incorrect": "配置信息不正确, 请检查后重新输入",
|
||||||
|
"connect_error": "无法连接到指定设备",
|
||||||
|
"invalid_token": "Token或Key格式不正确"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"way": "添加方式"
|
||||||
|
},
|
||||||
|
"description": "选择添加设备的方式",
|
||||||
|
"title": "添加新设备"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"data": {
|
||||||
|
"account": "账号",
|
||||||
|
"password": "密码"
|
||||||
|
},
|
||||||
|
"description": "登录并保存你的美的账户,仅用于获取添加设备时设备信息\n添加设备完成后,你可以删除该配置",
|
||||||
|
"title": "登录"
|
||||||
|
},
|
||||||
|
"discovery": {
|
||||||
|
"description": "输入设备的IP地址, 输入\"auto\"自动搜索设备\n你也可以使用IP地址在指定网络中搜索, 比如`192.168.1.255`",
|
||||||
|
"title": "搜索",
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP地址"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"description": "{table}",
|
||||||
|
"title": "设备"
|
||||||
|
},
|
||||||
|
"auto": {
|
||||||
|
"data": {
|
||||||
|
"device": "设备"
|
||||||
|
},
|
||||||
|
"description": "选择设备并添加",
|
||||||
|
"title": "发现新设备"
|
||||||
|
},
|
||||||
|
"manually": {
|
||||||
|
"data": {
|
||||||
|
"name": "名称(如客厅空调)",
|
||||||
|
"device_id": "设备编号",
|
||||||
|
"type": "设备类型",
|
||||||
|
"ip_address": "IP地址",
|
||||||
|
"port": "端口",
|
||||||
|
"model": "型号",
|
||||||
|
"subtype": "子型号",
|
||||||
|
"protocol": "协议版本",
|
||||||
|
"token": "Token",
|
||||||
|
"key": "Key"
|
||||||
|
},
|
||||||
|
"description": "配置设备参数",
|
||||||
|
"title": "新设备"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"bar_door": {
|
||||||
|
"name": "吧台门状态"
|
||||||
|
},
|
||||||
|
"bar_door_overtime": {
|
||||||
|
"name": "吧台门超时"
|
||||||
|
},
|
||||||
|
"bathing_working": {
|
||||||
|
"name": "淋浴工作状态"
|
||||||
|
},
|
||||||
|
"bottom_compartment_cooling": {
|
||||||
|
"name": "下层冷却"
|
||||||
|
},
|
||||||
|
"bottom_compartment_door": {
|
||||||
|
"name": "下层门状态"
|
||||||
|
},
|
||||||
|
"bottom_compartment_preheating": {
|
||||||
|
"name": "下层预热"
|
||||||
|
},
|
||||||
|
"burning_state": {
|
||||||
|
"name": "燃烧状态"
|
||||||
|
},
|
||||||
|
"cleaning_reminder": {
|
||||||
|
"name": "清洁提示"
|
||||||
|
},
|
||||||
|
"compressor_status": {
|
||||||
|
"name": "压缩机状态"
|
||||||
|
},
|
||||||
|
"cooking": {
|
||||||
|
"name": "烹饪中"
|
||||||
|
},
|
||||||
|
"filter_change_reminder": {
|
||||||
|
"name": "滤芯更换提醒"
|
||||||
|
},
|
||||||
|
"filter_cleaning_reminder": {
|
||||||
|
"name": "滤芯清洁提醒"
|
||||||
|
},
|
||||||
|
"finished": {
|
||||||
|
"name": "完成"
|
||||||
|
},
|
||||||
|
"flex_zone_door": {
|
||||||
|
"name": "变温区门状态"
|
||||||
|
},
|
||||||
|
"flex_zone_door_overtime": {
|
||||||
|
"name": "变温区门超时"
|
||||||
|
},
|
||||||
|
"freezer_door": {
|
||||||
|
"name": "冷冻室门状态"
|
||||||
|
},
|
||||||
|
"freezer_door_overtime": {
|
||||||
|
"name": "冷冻室门超时"
|
||||||
|
},
|
||||||
|
"full_dust": {
|
||||||
|
"name": "尘满"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "加热"
|
||||||
|
},
|
||||||
|
"heating_working": {
|
||||||
|
"name": "取暖工作状态"
|
||||||
|
},
|
||||||
|
"keep_warm": {
|
||||||
|
"name": "保温"
|
||||||
|
},
|
||||||
|
"lid_status": {
|
||||||
|
"name": "盖子状态"
|
||||||
|
},
|
||||||
|
"middle_compartment_cooling": {
|
||||||
|
"name": "中层冷却"
|
||||||
|
},
|
||||||
|
"middle_compartment_door": {
|
||||||
|
"name": "中层门状态"
|
||||||
|
},
|
||||||
|
"middle_compartment_preheating": {
|
||||||
|
"name": "中层预热"
|
||||||
|
},
|
||||||
|
"oilcup_full": {
|
||||||
|
"name": "油杯满提示"
|
||||||
|
},
|
||||||
|
"protection": {
|
||||||
|
"name": "安全防护"
|
||||||
|
},
|
||||||
|
"refrigerator_door": {
|
||||||
|
"name": "冷藏室门状态"
|
||||||
|
},
|
||||||
|
"refrigerator_door_overtime": {
|
||||||
|
"name": "冷藏室门超时"
|
||||||
|
},
|
||||||
|
"rinse_aid": {
|
||||||
|
"name": "漂洗剂不足"
|
||||||
|
},
|
||||||
|
"salt": {
|
||||||
|
"name": "软水盐不足"
|
||||||
|
},
|
||||||
|
"seat_status": {
|
||||||
|
"name": "入座状态"
|
||||||
|
},
|
||||||
|
"status_dhw": {
|
||||||
|
"name": "DHW状态"
|
||||||
|
},
|
||||||
|
"status_heating": {
|
||||||
|
"name": "加热状态"
|
||||||
|
},
|
||||||
|
"status_ibh": {
|
||||||
|
"name": "IBH状态"
|
||||||
|
},
|
||||||
|
"status_tbh": {
|
||||||
|
"name": "TBH状态"
|
||||||
|
},
|
||||||
|
"tank_ejected": {
|
||||||
|
"name": "水箱弹出"
|
||||||
|
},
|
||||||
|
"tank_full": {
|
||||||
|
"name": "水箱状态"
|
||||||
|
},
|
||||||
|
"top_compartment_cooling": {
|
||||||
|
"name": "上层冷却"
|
||||||
|
},
|
||||||
|
"top_compartment_door": {
|
||||||
|
"name": "上层门状态"
|
||||||
|
},
|
||||||
|
"top_compartment_preheating": {
|
||||||
|
"name": "上层预热"
|
||||||
|
},
|
||||||
|
"water_change_reminder": {
|
||||||
|
"name": "换水提醒"
|
||||||
|
},
|
||||||
|
"water_shortage": {
|
||||||
|
"name": "缺水"
|
||||||
|
},
|
||||||
|
"with_pressure": {
|
||||||
|
"name": "带压中"
|
||||||
|
},
|
||||||
|
"zone1_room_temp_mode": {
|
||||||
|
"name": "区域1室温模式"
|
||||||
|
},
|
||||||
|
"zone1_water_temp_mode": {
|
||||||
|
"name": "区域1水温模式"
|
||||||
|
},
|
||||||
|
"zone2_room_temp_mode": {
|
||||||
|
"name": "区域2室温模式"
|
||||||
|
},
|
||||||
|
"zone2_water_temp_mode": {
|
||||||
|
"name": "区域2水温模式"
|
||||||
|
},
|
||||||
|
"microcrystal_fresh": {
|
||||||
|
"name": "微晶一周鲜"
|
||||||
|
},
|
||||||
|
"electronic_smell": {
|
||||||
|
"name": "净味杀菌"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"climate": {
|
||||||
|
"climate_zone1": {
|
||||||
|
"name": "区域1恒温器"
|
||||||
|
},
|
||||||
|
"climate_zone2": {
|
||||||
|
"name": "区域2恒温器"
|
||||||
|
},
|
||||||
|
"climate_key": {
|
||||||
|
"state_attributes": {
|
||||||
|
"fan_mode": {
|
||||||
|
"state": {
|
||||||
|
"silent": "静音",
|
||||||
|
"full": "全速"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fan": {
|
||||||
|
"fresh_air": {
|
||||||
|
"name": "新风"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"child_lock": {
|
||||||
|
"name": "童锁"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"dry_level": {
|
||||||
|
"name": "烘干档位"
|
||||||
|
},
|
||||||
|
"heating_level": {
|
||||||
|
"name": "加热档位"
|
||||||
|
},
|
||||||
|
"seat_temp_level": {
|
||||||
|
"name": "座温档位"
|
||||||
|
},
|
||||||
|
"water_temp_level": {
|
||||||
|
"name": "水温档位"
|
||||||
|
},
|
||||||
|
"fan_speed_percent": {
|
||||||
|
"name": "风速百分比"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"detect_mode": {
|
||||||
|
"name": "检测模式"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"name": "摇摆方向"
|
||||||
|
},
|
||||||
|
"fan_speed": {
|
||||||
|
"name": "风速设定"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "模式"
|
||||||
|
},
|
||||||
|
"oscillation_angle": {
|
||||||
|
"name": "水平摆头角度"
|
||||||
|
},
|
||||||
|
"oscillation_mode": {
|
||||||
|
"name": "水平摆头模式"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "屏幕显示"
|
||||||
|
},
|
||||||
|
"silent_level": {
|
||||||
|
"name": "静音级别"
|
||||||
|
},
|
||||||
|
"tilting_angle": {
|
||||||
|
"name": "垂直摆头角度"
|
||||||
|
},
|
||||||
|
"water_level_set": {
|
||||||
|
"name": "水位设定"
|
||||||
|
},
|
||||||
|
"wind_lr_angle": {
|
||||||
|
"name": "水平出风",
|
||||||
|
"state": {
|
||||||
|
"off": "停止",
|
||||||
|
"left": "左方",
|
||||||
|
"left-mid": "左中",
|
||||||
|
"middle": "中部",
|
||||||
|
"right-mid": "右中",
|
||||||
|
"right": "右方"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wind_ud_angle": {
|
||||||
|
"name": "垂直出风",
|
||||||
|
"state": {
|
||||||
|
"off": "停止",
|
||||||
|
"up": "上方",
|
||||||
|
"up-mid": "中上",
|
||||||
|
"middle": "中部",
|
||||||
|
"down-mid": "中下",
|
||||||
|
"down": "下方"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"bathing_leaving_temperature": {
|
||||||
|
"name": "淋浴出水温度"
|
||||||
|
},
|
||||||
|
"bottom_compartment_remaining": {
|
||||||
|
"name": "下层剩余时间"
|
||||||
|
},
|
||||||
|
"bottom_compartment_status": {
|
||||||
|
"name": "下层状态"
|
||||||
|
},
|
||||||
|
"bottom_compartment_temperature": {
|
||||||
|
"name": "下层温度"
|
||||||
|
},
|
||||||
|
"bottom_temperature": {
|
||||||
|
"name": "底部温度"
|
||||||
|
},
|
||||||
|
"bright": {
|
||||||
|
"name": "亮碟剂档位"
|
||||||
|
},
|
||||||
|
"compressor_temperature": {
|
||||||
|
"name": "压缩机温度"
|
||||||
|
},
|
||||||
|
"condenser_temperature": {
|
||||||
|
"name": "冷凝器温度"
|
||||||
|
},
|
||||||
|
"current_energy_consumption": {
|
||||||
|
"name": "当前能耗"
|
||||||
|
},
|
||||||
|
"current_temperature": {
|
||||||
|
"name": "当前温度"
|
||||||
|
},
|
||||||
|
"dehydration_speed": {
|
||||||
|
"name": "脱水速度"
|
||||||
|
},
|
||||||
|
"dehydration_time": {
|
||||||
|
"name": "脱水时间档位"
|
||||||
|
},
|
||||||
|
"dehydration_time_value": {
|
||||||
|
"name": "脱水时间值"
|
||||||
|
},
|
||||||
|
"wash_time_value": {
|
||||||
|
"name": "洗涤时间值"
|
||||||
|
},
|
||||||
|
"stains": {
|
||||||
|
"name": "污渍"
|
||||||
|
},
|
||||||
|
"dirty_degree": {
|
||||||
|
"name": "脏度"
|
||||||
|
},
|
||||||
|
"intensity": {
|
||||||
|
"name": "强度"
|
||||||
|
},
|
||||||
|
"dryness_level": {
|
||||||
|
"name": "干燥档位"
|
||||||
|
},
|
||||||
|
"dry_temperature": {
|
||||||
|
"name": "干燥温度"
|
||||||
|
},
|
||||||
|
"door_warn": {
|
||||||
|
"name": "开门警告"
|
||||||
|
},
|
||||||
|
"ai_switch": {
|
||||||
|
"name": "AI开关"
|
||||||
|
},
|
||||||
|
"material": {
|
||||||
|
"name": "材质"
|
||||||
|
},
|
||||||
|
"water_box": {
|
||||||
|
"name": "水箱"
|
||||||
|
},
|
||||||
|
"energy_consumption": {
|
||||||
|
"name": "能耗"
|
||||||
|
},
|
||||||
|
"error_code": {
|
||||||
|
"name": "错误码"
|
||||||
|
},
|
||||||
|
"fan_level": {
|
||||||
|
"name": "当前风扇档位"
|
||||||
|
},
|
||||||
|
"filter_life": {
|
||||||
|
"name": "滤芯寿命"
|
||||||
|
},
|
||||||
|
"filter1_days": {
|
||||||
|
"name": "滤芯1可用天数"
|
||||||
|
},
|
||||||
|
"filter1_life": {
|
||||||
|
"name": "滤芯1剩余寿命"
|
||||||
|
},
|
||||||
|
"filter2_days": {
|
||||||
|
"name": "滤芯2可用天数"
|
||||||
|
},
|
||||||
|
"filter2_life": {
|
||||||
|
"name": "滤芯2剩余寿命"
|
||||||
|
},
|
||||||
|
"filter3_days": {
|
||||||
|
"name": "滤芯3可用天数"
|
||||||
|
},
|
||||||
|
"filter3_life": {
|
||||||
|
"name": "滤芯3剩余寿命"
|
||||||
|
},
|
||||||
|
"flex_zone_actual_temp": {
|
||||||
|
"name": "变温区实际温度"
|
||||||
|
},
|
||||||
|
"flex_zone_setting_temp": {
|
||||||
|
"name": "变温区设置温度"
|
||||||
|
},
|
||||||
|
"freezer_actual_temp": {
|
||||||
|
"name": "冷冻室实际温度"
|
||||||
|
},
|
||||||
|
"freezer_setting_temp": {
|
||||||
|
"name": "冷冻室设置温度"
|
||||||
|
},
|
||||||
|
"hcho": {
|
||||||
|
"name": "甲醛"
|
||||||
|
},
|
||||||
|
"heating_leaving_temperature": {
|
||||||
|
"name": "取暖出水温度"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "加热功率"
|
||||||
|
},
|
||||||
|
"heating_time_remaining": {
|
||||||
|
"name": "加热剩余时间"
|
||||||
|
},
|
||||||
|
"in_tds": {
|
||||||
|
"name": "进水TDS"
|
||||||
|
},
|
||||||
|
"indoor_humidity": {
|
||||||
|
"name": "室内湿度"
|
||||||
|
},
|
||||||
|
"indoor_temperature": {
|
||||||
|
"name": "室内温度"
|
||||||
|
},
|
||||||
|
"keep_warm_remaining": {
|
||||||
|
"name": "保温剩余时间"
|
||||||
|
},
|
||||||
|
"keep_warm_time": {
|
||||||
|
"name": "保温时间"
|
||||||
|
},
|
||||||
|
"middle_compartment_remaining": {
|
||||||
|
"name": "中层剩余时间"
|
||||||
|
},
|
||||||
|
"middle_compartment_status": {
|
||||||
|
"name": "中层状态"
|
||||||
|
},
|
||||||
|
"middle_compartment_temperature": {
|
||||||
|
"name": "中层温度"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"name": "模式"
|
||||||
|
},
|
||||||
|
"out_tds": {
|
||||||
|
"name": "出水TDS"
|
||||||
|
},
|
||||||
|
"outdoor_temperature": {
|
||||||
|
"name": "室外温度"
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"name": "程序"
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"name": "当前程序"
|
||||||
|
},
|
||||||
|
"realtime_power": {
|
||||||
|
"name": "实时功率"
|
||||||
|
},
|
||||||
|
"refrigerator_actual_temp": {
|
||||||
|
"name": "冷藏室实际温度"
|
||||||
|
},
|
||||||
|
"refrigerator_setting_temp": {
|
||||||
|
"name": "冷藏室设置温度"
|
||||||
|
},
|
||||||
|
"right_flex_zone_actual_temp": {
|
||||||
|
"name": "右变温区实际温度"
|
||||||
|
},
|
||||||
|
"right_flex_zone_setting_temp": {
|
||||||
|
"name": "右变温区设置温度"
|
||||||
|
},
|
||||||
|
"rinse_count": {
|
||||||
|
"name": "漂洗次数"
|
||||||
|
},
|
||||||
|
"rinse_level": {
|
||||||
|
"name": "漂洗档位"
|
||||||
|
},
|
||||||
|
"seat_temperature": {
|
||||||
|
"name": "当前座温"
|
||||||
|
},
|
||||||
|
"soak_time": {
|
||||||
|
"name": "浸泡时间"
|
||||||
|
},
|
||||||
|
"softener": {
|
||||||
|
"name": "柔顺剂"
|
||||||
|
},
|
||||||
|
"softwater": {
|
||||||
|
"name": "软水盐档位"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "状态"
|
||||||
|
},
|
||||||
|
"storage_remaining": {
|
||||||
|
"name": "保管剩余时间"
|
||||||
|
},
|
||||||
|
"tank": {
|
||||||
|
"name": "水箱水位"
|
||||||
|
},
|
||||||
|
"tank_actual_temperature": {
|
||||||
|
"name": "水箱实际温度"
|
||||||
|
},
|
||||||
|
"target_temperature": {
|
||||||
|
"name": "设定温度"
|
||||||
|
},
|
||||||
|
"time_remaining": {
|
||||||
|
"name": "剩余时间"
|
||||||
|
},
|
||||||
|
"top_compartment_remaining": {
|
||||||
|
"name": "上层剩余时间"
|
||||||
|
},
|
||||||
|
"top_compartment_status": {
|
||||||
|
"name": "上层状态"
|
||||||
|
},
|
||||||
|
"top_compartment_temperature": {
|
||||||
|
"name": "上层温度"
|
||||||
|
},
|
||||||
|
"top_temperature": {
|
||||||
|
"name": "顶部温度"
|
||||||
|
},
|
||||||
|
"total_energy_consumption": {
|
||||||
|
"name": "总能耗"
|
||||||
|
},
|
||||||
|
"total_produced_energy": {
|
||||||
|
"name": "总计产生能量"
|
||||||
|
},
|
||||||
|
"tvoc": {
|
||||||
|
"name": "TVOC"
|
||||||
|
},
|
||||||
|
"wash_level": {
|
||||||
|
"name": "洗涤档位"
|
||||||
|
},
|
||||||
|
"wash_strength": {
|
||||||
|
"name": "洗涤强度"
|
||||||
|
},
|
||||||
|
"wash_time": {
|
||||||
|
"name": "洗涤时间档位"
|
||||||
|
},
|
||||||
|
"detergent": {
|
||||||
|
"name": "洗涤剂"
|
||||||
|
},
|
||||||
|
"water_consumption": {
|
||||||
|
"name": "总耗水量"
|
||||||
|
},
|
||||||
|
"water_level": {
|
||||||
|
"name": "水位"
|
||||||
|
},
|
||||||
|
"water_temperature": {
|
||||||
|
"name": "水温"
|
||||||
|
},
|
||||||
|
"working_time": {
|
||||||
|
"name": "工作时间"
|
||||||
|
},
|
||||||
|
"humidity": {
|
||||||
|
"name": "湿度"
|
||||||
|
},
|
||||||
|
"variable_mode": {
|
||||||
|
"name": "变温区模式"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"anion": {
|
||||||
|
"name": "负离子开关"
|
||||||
|
},
|
||||||
|
"aux_heating": {
|
||||||
|
"name": "电辅热"
|
||||||
|
},
|
||||||
|
"boost_mode": {
|
||||||
|
"name": "强劲模式"
|
||||||
|
},
|
||||||
|
"breezeless": {
|
||||||
|
"name": "无风感"
|
||||||
|
},
|
||||||
|
"comfort_mode": {
|
||||||
|
"name": "舒省模式"
|
||||||
|
},
|
||||||
|
"cold_water_single": {
|
||||||
|
"name": "单次零冷水"
|
||||||
|
},
|
||||||
|
"cold_water_dot": {
|
||||||
|
"name": "点动零冷水"
|
||||||
|
},
|
||||||
|
"dhw_power": {
|
||||||
|
"name": "生活热水电源开关"
|
||||||
|
},
|
||||||
|
"disinfect": {
|
||||||
|
"name": "消毒"
|
||||||
|
},
|
||||||
|
"dry": {
|
||||||
|
"name": "干燥"
|
||||||
|
},
|
||||||
|
"eco_mode": {
|
||||||
|
"name": "ECO模式"
|
||||||
|
},
|
||||||
|
"fast_dhw": {
|
||||||
|
"name": "快速生活热水"
|
||||||
|
},
|
||||||
|
"foam_shield": {
|
||||||
|
"name": "泡沫盾"
|
||||||
|
},
|
||||||
|
"frost_protect": {
|
||||||
|
"name": "防霜冻"
|
||||||
|
},
|
||||||
|
"heating_power": {
|
||||||
|
"name": "加热",
|
||||||
|
"_comments": "E2 加热功率, E6 加热开关"
|
||||||
|
},
|
||||||
|
"indirect_wind": {
|
||||||
|
"name": "防直吹"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "灯光"
|
||||||
|
},
|
||||||
|
"link_to_ac": {
|
||||||
|
"name": "空调联动开关"
|
||||||
|
},
|
||||||
|
"main_light": {
|
||||||
|
"name": "主灯"
|
||||||
|
},
|
||||||
|
"main_power": {
|
||||||
|
"name": "主电源"
|
||||||
|
},
|
||||||
|
"natural_wind": {
|
||||||
|
"name": "自然风"
|
||||||
|
},
|
||||||
|
"night_light": {
|
||||||
|
"name": "夜灯"
|
||||||
|
},
|
||||||
|
"oscillate": {
|
||||||
|
"name": "摆头开关"
|
||||||
|
},
|
||||||
|
"power": {
|
||||||
|
"name": "电源开关"
|
||||||
|
},
|
||||||
|
"powerful_purify": {
|
||||||
|
"name": "强净开关"
|
||||||
|
},
|
||||||
|
"prompt_tone": {
|
||||||
|
"name": "提示音"
|
||||||
|
},
|
||||||
|
"screen_display": {
|
||||||
|
"name": "屏幕显示"
|
||||||
|
},
|
||||||
|
"screen_display_alternate": {
|
||||||
|
"name": "屏幕显示备用开关"
|
||||||
|
},
|
||||||
|
"sensor_light": {
|
||||||
|
"name": "感应夜灯"
|
||||||
|
},
|
||||||
|
"silent_mode": {
|
||||||
|
"name": "静音模式"
|
||||||
|
},
|
||||||
|
"sleep_mode": {
|
||||||
|
"name": "睡眠模式"
|
||||||
|
},
|
||||||
|
"smart_eye": {
|
||||||
|
"name": "智慧眼"
|
||||||
|
},
|
||||||
|
"smart_volume": {
|
||||||
|
"name": "智能变容"
|
||||||
|
},
|
||||||
|
"smelly_sensor": {
|
||||||
|
"name": "异味感应"
|
||||||
|
},
|
||||||
|
"standby": {
|
||||||
|
"name": "待机"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"name": "启动"
|
||||||
|
},
|
||||||
|
"storage": {
|
||||||
|
"name": "保管开关"
|
||||||
|
},
|
||||||
|
"swing": {
|
||||||
|
"name": "摆风开关"
|
||||||
|
},
|
||||||
|
"swing_horizontal": {
|
||||||
|
"name": "水平摆风"
|
||||||
|
},
|
||||||
|
"swing_vertical": {
|
||||||
|
"name": "垂直摆风"
|
||||||
|
},
|
||||||
|
"tbh": {
|
||||||
|
"name": "TBH"
|
||||||
|
},
|
||||||
|
"variable_heating": {
|
||||||
|
"name": "变频加热"
|
||||||
|
},
|
||||||
|
"ventilation": {
|
||||||
|
"name": "换气"
|
||||||
|
},
|
||||||
|
"whole_tank_heating": {
|
||||||
|
"name": "全胆速热"
|
||||||
|
},
|
||||||
|
"zero_cold_pulse": {
|
||||||
|
"name": "零冷水(点动)"
|
||||||
|
},
|
||||||
|
"zero_cold_water": {
|
||||||
|
"name": "零冷水"
|
||||||
|
},
|
||||||
|
"zone1_curve": {
|
||||||
|
"name": "区域1曲线"
|
||||||
|
},
|
||||||
|
"zone1_power": {
|
||||||
|
"name": "区域1恒温器开关"
|
||||||
|
},
|
||||||
|
"zone2_curve": {
|
||||||
|
"name": "区域2曲线"
|
||||||
|
},
|
||||||
|
"zone2_power": {
|
||||||
|
"name": "区域2恒温器开关"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"water_heater": {
|
||||||
|
"domestic_hot_water": {
|
||||||
|
"name": "生活热水"
|
||||||
|
},
|
||||||
|
"bathing": {
|
||||||
|
"name": "淋浴"
|
||||||
|
},
|
||||||
|
"heating": {
|
||||||
|
"name": "加热"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"init": {
|
||||||
|
"data": {
|
||||||
|
"ip_address": "IP地址",
|
||||||
|
"refresh_interval": "刷新间隔(设0为不进行主动刷新)",
|
||||||
|
"sensors": "扩展传感器",
|
||||||
|
"switches": "扩展控制",
|
||||||
|
"customize": "自定义"
|
||||||
|
},
|
||||||
|
"title": "配置"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"account_option": "账户配置不支持此操作.\n点击\"添加设备\"完成添加新设备的操作"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"set_attribute": {
|
||||||
|
"name": "设置属性",
|
||||||
|
"description": "设置设备的属性值",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "设备编码",
|
||||||
|
"description": "设备编码(Device ID)"
|
||||||
|
},
|
||||||
|
"attribute": {
|
||||||
|
"name": "属性",
|
||||||
|
"description": "要设置的属性名称"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "值",
|
||||||
|
"description": "要设置的属性值"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"send_command": {
|
||||||
|
"name": "自定义命令",
|
||||||
|
"description": "向设备发送一个自定义命令",
|
||||||
|
"fields": {
|
||||||
|
"device_id": {
|
||||||
|
"name": "设备编码",
|
||||||
|
"description": "设备编码(Device ID)"
|
||||||
|
},
|
||||||
|
"cmd_type": {
|
||||||
|
"name": "命令类型",
|
||||||
|
"description": "命令类型,可以为2(查询)或3(设置)"
|
||||||
|
},
|
||||||
|
"cmd_body": {
|
||||||
|
"name": "命令体",
|
||||||
|
"description": "命令的消息体(不包括前部的MSmart协议头及后部的校验码)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,455 @@
|
|||||||
|
"""Midea Water Heater entries."""
|
||||||
|
|
||||||
|
import functools as ft
|
||||||
|
import logging
|
||||||
|
from typing import Any, ClassVar, TypeAlias, cast
|
||||||
|
|
||||||
|
from homeassistant.components.water_heater import (
|
||||||
|
WaterHeaterEntity,
|
||||||
|
WaterHeaterEntityFeature,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_TEMPERATURE,
|
||||||
|
CONF_DEVICE_ID,
|
||||||
|
CONF_SWITCHES,
|
||||||
|
PRECISION_HALVES,
|
||||||
|
PRECISION_WHOLE,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
Platform,
|
||||||
|
UnitOfTemperature,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from midealocal.device import DeviceType
|
||||||
|
from midealocal.devices.c3 import DeviceAttributes as C3Attributes
|
||||||
|
from midealocal.devices.c3 import MideaC3Device
|
||||||
|
from midealocal.devices.cd import DeviceAttributes as CDAttributes
|
||||||
|
from midealocal.devices.cd import MideaCDDevice
|
||||||
|
from midealocal.devices.e2 import DeviceAttributes as E2Attributes
|
||||||
|
from midealocal.devices.e2 import MideaE2Device
|
||||||
|
from midealocal.devices.e3 import MideaE3Device
|
||||||
|
from midealocal.devices.e6 import DeviceAttributes as E6Attributes
|
||||||
|
from midealocal.devices.e6 import MideaE6Device
|
||||||
|
|
||||||
|
from .const import DEVICES, DOMAIN
|
||||||
|
from .midea_devices import MIDEA_DEVICES
|
||||||
|
from .midea_entity import MideaEntity
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
E2_TEMPERATURE_MAX = 75
|
||||||
|
E2_TEMPERATURE_MIN = 30
|
||||||
|
E3_TEMPERATURE_MAX = 65
|
||||||
|
E3_TEMPERATURE_MIN = 35
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up water heater entries."""
|
||||||
|
device_id = config_entry.data.get(CONF_DEVICE_ID)
|
||||||
|
device = hass.data[DOMAIN][DEVICES].get(device_id)
|
||||||
|
extra_switches = config_entry.options.get(CONF_SWITCHES, [])
|
||||||
|
devs: list[
|
||||||
|
MideaE2WaterHeater
|
||||||
|
| MideaE3WaterHeater
|
||||||
|
| MideaE6WaterHeater
|
||||||
|
| MideaC3WaterHeater
|
||||||
|
| MideaCDWaterHeater
|
||||||
|
] = []
|
||||||
|
for entity_key, config in cast(
|
||||||
|
"dict",
|
||||||
|
MIDEA_DEVICES[device.device_type]["entities"],
|
||||||
|
).items():
|
||||||
|
if config["type"] == Platform.WATER_HEATER and (
|
||||||
|
config.get("default") or entity_key in extra_switches
|
||||||
|
):
|
||||||
|
if device.device_type == DeviceType.E2:
|
||||||
|
devs.append(MideaE2WaterHeater(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.E3:
|
||||||
|
devs.append(MideaE3WaterHeater(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.E6:
|
||||||
|
devs.append(MideaE6WaterHeater(device, entity_key, config["use"]))
|
||||||
|
elif device.device_type == DeviceType.C3:
|
||||||
|
devs.append(MideaC3WaterHeater(device, entity_key))
|
||||||
|
elif device.device_type == DeviceType.CD:
|
||||||
|
devs.append(MideaCDWaterHeater(device, entity_key))
|
||||||
|
async_add_entities(devs)
|
||||||
|
|
||||||
|
|
||||||
|
MideaWaterHeaterDevice: TypeAlias = (
|
||||||
|
MideaE2Device | MideaE3Device | MideaC3Device | MideaE6Device | MideaCDDevice
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaWaterHeater(MideaEntity, WaterHeaterEntity):
|
||||||
|
"""Midea Water Heater Entries Base Class."""
|
||||||
|
|
||||||
|
_device: MideaWaterHeaterDevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaWaterHeaterDevice, entity_key: str) -> None:
|
||||||
|
"""Midea Water Heater entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._operations: list[str] = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> WaterHeaterEntityFeature:
|
||||||
|
"""Midea Water Heater supported features."""
|
||||||
|
return WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
|
"""Midea Water Heater extra state attributes."""
|
||||||
|
attrs: dict[str, Any] = self._device.attributes
|
||||||
|
if hasattr(self._device, "temperature_step"):
|
||||||
|
attrs["target_temperature_step"] = self._device.temperature_step
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea Water Heater min temperature."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea Water Heater max temperature."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def precision(self) -> float:
|
||||||
|
"""Midea Water Heater precision."""
|
||||||
|
return float(PRECISION_WHOLE)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def temperature_unit(self) -> UnitOfTemperature:
|
||||||
|
"""Midea Water Heater temperature unix."""
|
||||||
|
return UnitOfTemperature.CELSIUS
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_operation(self) -> str | None:
|
||||||
|
"""Midea Water Heater current operation."""
|
||||||
|
return cast(
|
||||||
|
"str",
|
||||||
|
(
|
||||||
|
self._device.get_attribute("mode")
|
||||||
|
if self._device.get_attribute("power")
|
||||||
|
else STATE_OFF
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self) -> float:
|
||||||
|
"""Midea Water Heater current temperature."""
|
||||||
|
return cast("float", self._device.get_attribute("current_temperature"))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature(self) -> float:
|
||||||
|
"""Midea Water Heater target temperature."""
|
||||||
|
return cast("float", self._device.get_attribute("target_temperature"))
|
||||||
|
|
||||||
|
def set_temperature(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea Water Heater set temperature."""
|
||||||
|
if ATTR_TEMPERATURE not in kwargs:
|
||||||
|
return
|
||||||
|
# input target_temperature should be float
|
||||||
|
temperature = float(kwargs[ATTR_TEMPERATURE])
|
||||||
|
self._device.set_attribute("target_temperature", temperature)
|
||||||
|
|
||||||
|
def set_operation_mode(self, operation_mode: str) -> None:
|
||||||
|
"""Midea Water Heater set operation mode."""
|
||||||
|
self._device.set_attribute(attr="mode", value=operation_mode)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def operation_list(self) -> list[str] | None:
|
||||||
|
"""Midea Water Heater operation list."""
|
||||||
|
if not hasattr(self._device, "preset_modes"):
|
||||||
|
return None
|
||||||
|
return cast("list", self._device.preset_modes)
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Water Heater turn on."""
|
||||||
|
self._device.set_attribute(attr="power", value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Water Heater turn off."""
|
||||||
|
self._device.set_attribute(attr="power", value=False)
|
||||||
|
|
||||||
|
async def async_turn_on(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea Water Heater async turn on."""
|
||||||
|
await self.hass.async_add_executor_job(ft.partial(self.turn_on, **kwargs))
|
||||||
|
|
||||||
|
async def async_turn_off(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea Water Heater async off."""
|
||||||
|
await self.hass.async_add_executor_job(ft.partial(self.turn_off, **kwargs))
|
||||||
|
|
||||||
|
def update_state(self, status: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea Water Heater update state."""
|
||||||
|
if not self.hass:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Water update_state skipped for %s [%s]: HASS is None",
|
||||||
|
self.name,
|
||||||
|
type(self),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
|
class MideaE2WaterHeater(MideaWaterHeater):
|
||||||
|
"""Midea E2 Water Heater Entries."""
|
||||||
|
|
||||||
|
_device: MideaE2Device
|
||||||
|
|
||||||
|
def __init__(self, device: MideaE2Device, entity_key: str) -> None:
|
||||||
|
"""Midea E2 Water Heater entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_operation(self) -> str:
|
||||||
|
"""Midea E2 Water Heater current operation."""
|
||||||
|
return str(
|
||||||
|
STATE_ON if self._device.get_attribute(E2Attributes.power) else STATE_OFF,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea E2 Water Heater min temperature."""
|
||||||
|
return E2_TEMPERATURE_MIN
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea E2 Water Heater max temperature."""
|
||||||
|
return E2_TEMPERATURE_MAX
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> WaterHeaterEntityFeature:
|
||||||
|
"""Midea E2 Water Heater supported features."""
|
||||||
|
return (
|
||||||
|
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||||
|
| WaterHeaterEntityFeature.ON_OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaE3WaterHeater(MideaWaterHeater):
|
||||||
|
"""Midea E3 Water Heater Entries."""
|
||||||
|
|
||||||
|
_device: MideaE3Device
|
||||||
|
|
||||||
|
def __init__(self, device: MideaE3Device, entity_key: str) -> None:
|
||||||
|
"""Midea E3 Water Heater entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea E3 Water Heater min temperature."""
|
||||||
|
return E3_TEMPERATURE_MIN
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea E3 Water Heater max temperature."""
|
||||||
|
return E3_TEMPERATURE_MAX
|
||||||
|
|
||||||
|
@property
|
||||||
|
def precision(self) -> float:
|
||||||
|
"""Midea E3 Water Heater precision."""
|
||||||
|
return float(
|
||||||
|
PRECISION_HALVES if self._device.precision_halves else PRECISION_WHOLE,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_operation(self) -> str:
|
||||||
|
"""Midea E3 Water Heater current operation."""
|
||||||
|
return str(
|
||||||
|
STATE_ON if self._device.get_attribute("power") else STATE_OFF,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaC3WaterHeater(MideaWaterHeater):
|
||||||
|
"""Midea C3 Water Heater Entries."""
|
||||||
|
|
||||||
|
_device: MideaC3Device
|
||||||
|
|
||||||
|
def __init__(self, device: MideaC3Device, entity_key: str) -> None:
|
||||||
|
"""Midea C3 Water Heater entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_operation(self) -> str:
|
||||||
|
"""Midea C3 Water Heater current operation."""
|
||||||
|
return str(
|
||||||
|
(
|
||||||
|
STATE_ON
|
||||||
|
if self._device.get_attribute(C3Attributes.dhw_power)
|
||||||
|
else STATE_OFF
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self) -> float:
|
||||||
|
"""Midea C3 Water Heater current temperature."""
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
self._device.get_attribute(C3Attributes.tank_actual_temperature),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature(self) -> float:
|
||||||
|
"""Midea C3 Water Heater target temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(C3Attributes.dhw_target_temp))
|
||||||
|
|
||||||
|
def set_temperature(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea C3 Water Heater set temperature."""
|
||||||
|
if ATTR_TEMPERATURE not in kwargs:
|
||||||
|
return
|
||||||
|
temperature = float(kwargs[ATTR_TEMPERATURE])
|
||||||
|
self._device.set_attribute(C3Attributes.dhw_target_temp, temperature)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea C3 Water Heater min temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(C3Attributes.dhw_temp_min))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea C3 Water Heater max temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(C3Attributes.dhw_temp_max))
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea C3 Water Heater turn on."""
|
||||||
|
self._device.set_attribute(attr=C3Attributes.dhw_power, value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea C3 Water Heater turn off."""
|
||||||
|
self._device.set_attribute(attr=C3Attributes.dhw_power, value=False)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaE6WaterHeater(MideaWaterHeater):
|
||||||
|
"""Midea E6 Water Heater Entries."""
|
||||||
|
|
||||||
|
_device: MideaE6Device
|
||||||
|
|
||||||
|
_powers: ClassVar[list[E6Attributes]] = [
|
||||||
|
E6Attributes.heating_power,
|
||||||
|
E6Attributes.main_power,
|
||||||
|
]
|
||||||
|
_current_temperatures: ClassVar[list[E6Attributes]] = [
|
||||||
|
E6Attributes.heating_leaving_temperature,
|
||||||
|
E6Attributes.bathing_leaving_temperature,
|
||||||
|
]
|
||||||
|
_target_temperatures: ClassVar[list[E6Attributes]] = [
|
||||||
|
E6Attributes.heating_temperature,
|
||||||
|
E6Attributes.bathing_temperature,
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, device: MideaE6Device, entity_key: str, use: int) -> None:
|
||||||
|
"""Midea E6 Water Heater entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
self._use = use
|
||||||
|
self._power_attr = MideaE6WaterHeater._powers[self._use]
|
||||||
|
self._current_temperature_attr = MideaE6WaterHeater._current_temperatures[
|
||||||
|
self._use
|
||||||
|
]
|
||||||
|
self._target_temperature_attr = MideaE6WaterHeater._target_temperatures[
|
||||||
|
self._use
|
||||||
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_operation(self) -> str:
|
||||||
|
"""Midea E6 Water Heater current operation."""
|
||||||
|
if self._use == 0: # for heating
|
||||||
|
return str(
|
||||||
|
(
|
||||||
|
STATE_ON
|
||||||
|
if self._device.get_attribute(E6Attributes.main_power)
|
||||||
|
and self._device.get_attribute(E6Attributes.heating_power)
|
||||||
|
else STATE_OFF
|
||||||
|
),
|
||||||
|
)
|
||||||
|
# for bathing
|
||||||
|
return str(
|
||||||
|
(
|
||||||
|
STATE_ON
|
||||||
|
if self._device.get_attribute(E6Attributes.main_power)
|
||||||
|
else STATE_OFF
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def current_temperature(self) -> float:
|
||||||
|
"""Midea E6 Water Heater current temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(self._current_temperature_attr))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_temperature(self) -> float:
|
||||||
|
"""Midea E6 Water Heater target temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(self._target_temperature_attr))
|
||||||
|
|
||||||
|
def set_temperature(self, **kwargs: Any) -> None: # noqa: ANN401
|
||||||
|
"""Midea E6 Water Heater set temperature."""
|
||||||
|
if ATTR_TEMPERATURE not in kwargs:
|
||||||
|
return
|
||||||
|
temperature = float(kwargs[ATTR_TEMPERATURE])
|
||||||
|
self._device.set_attribute(self._target_temperature_attr, temperature)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea E6 Water Heater min temperature."""
|
||||||
|
min_temperature = cast(
|
||||||
|
"list[str]",
|
||||||
|
self._device.get_attribute(E6Attributes.min_temperature),
|
||||||
|
)
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
min_temperature[self._use],
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea E6 Water Heater max temperature."""
|
||||||
|
max_temperature = cast(
|
||||||
|
"list[str]",
|
||||||
|
self._device.get_attribute(E6Attributes.max_temperature),
|
||||||
|
)
|
||||||
|
return cast(
|
||||||
|
"float",
|
||||||
|
max_temperature[self._use],
|
||||||
|
)
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea E6 Water Heater turn on."""
|
||||||
|
self._device.set_attribute(attr=self._power_attr, value=True)
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs: Any) -> None: # noqa: ANN401, ARG002
|
||||||
|
"""Midea E6 Water Heater turn off."""
|
||||||
|
self._device.set_attribute(attr=self._power_attr, value=False)
|
||||||
|
|
||||||
|
|
||||||
|
class MideaCDWaterHeater(MideaWaterHeater):
|
||||||
|
"""Midea CD Water Heater Entries."""
|
||||||
|
|
||||||
|
_device: MideaCDDevice
|
||||||
|
|
||||||
|
def __init__(self, device: MideaCDDevice, entity_key: str) -> None:
|
||||||
|
"""Midea CD Water Heater entity init."""
|
||||||
|
super().__init__(device, entity_key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> WaterHeaterEntityFeature:
|
||||||
|
"""Midea CD Water Heater supported features."""
|
||||||
|
return (
|
||||||
|
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||||
|
| WaterHeaterEntityFeature.OPERATION_MODE
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_temp(self) -> float:
|
||||||
|
"""Midea CD Water Heater min temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(CDAttributes.min_temperature))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_temp(self) -> float:
|
||||||
|
"""Midea CD Water Heater max temperature."""
|
||||||
|
return cast("float", self._device.get_attribute(CDAttributes.max_temperature))
|
||||||
Reference in New Issue
Block a user