first commit

This commit is contained in:
vlebourl 2022-04-01 15:02:13 +02:00
commit 79938b9f19
106 changed files with 7408 additions and 0 deletions

1
Config/.HA_VERSION Normal file
View File

@ -0,0 +1 @@
2022.3.8

122
Config/.storage/auth Normal file
View File

@ -0,0 +1,122 @@
{
"version": 1,
"minor_version": 1,
"key": "auth",
"data": {
"users": [
{
"id": "563d33967d924c588c6ecbff5eb96ed8",
"group_ids": [
"system-read-only"
],
"is_owner": false,
"is_active": true,
"name": "Home Assistant Content",
"system_generated": true,
"local_only": false
},
{
"id": "7e27048212fd43d78e900bed6f4ac44c",
"group_ids": [
"system-admin"
],
"is_owner": true,
"is_active": true,
"name": "vlb",
"system_generated": false,
"local_only": false
}
],
"groups": [
{
"id": "system-admin",
"name": "Administrators"
},
{
"id": "system-users",
"name": "Users"
},
{
"id": "system-read-only",
"name": "Read Only"
}
],
"credentials": [
{
"id": "9beb9518028c4616948324f9e7e2d071",
"user_id": "7e27048212fd43d78e900bed6f4ac44c",
"auth_provider_type": "homeassistant",
"auth_provider_id": null,
"data": {
"username": "vlb"
}
}
],
"refresh_tokens": [
{
"id": "a3f4e8066389495ea030efd0bf0d5cd4",
"user_id": "563d33967d924c588c6ecbff5eb96ed8",
"client_id": null,
"client_name": null,
"client_icon": null,
"token_type": "system",
"created_at": "2022-04-01T07:45:31.978398+00:00",
"access_token_expiration": 1800.0,
"token": "e4059f19c8a74f70691dafb6f8f67c7dddc2f6389020cb6c7d9a5596a0eedee4e523e8ef00c56f2e06ebe8eda4c26a26f12764a9802cf24c876e2f8f09418a50",
"jwt_key": "38697b84f9313b5652b1f8d85022617e8cc7ef3c6299225cc28af8e519694818ef3634c106e53c1f6e5bda25c17079c61a06fd0ba661800a642cd7d9f350c29c",
"last_used_at": null,
"last_used_ip": null,
"credential_id": null,
"version": "2022.3.8"
},
{
"id": "58d1aab125b742f98856591680c886f8",
"user_id": "7e27048212fd43d78e900bed6f4ac44c",
"client_id": "https://test.tiarkaerell.com/",
"client_name": null,
"client_icon": null,
"token_type": "normal",
"created_at": "2022-04-01T08:04:48.046872+00:00",
"access_token_expiration": 1800.0,
"token": "149461688179de15bb59d25377c890569b12a53cd3607a132d80089cdaa8e4539bc51bfd2b26e93a4574517181c245dfdd8a4b7dbd9fa58b110a834f4ac07306",
"jwt_key": "4516dea1cd209768b3918cdb9023464f08778c3f853511dbf524328abbd70e232c5808fd60c05b59fa500e30cfeef24d5c4fafed357965ecdab9c4a3dbd8123d",
"last_used_at": "2022-04-01T08:04:48.047248+00:00",
"last_used_ip": "85.195.218.245",
"credential_id": "9beb9518028c4616948324f9e7e2d071",
"version": "2022.3.8"
},
{
"id": "e0c00138ce364f58af0fae84be751b11",
"user_id": "7e27048212fd43d78e900bed6f4ac44c",
"client_id": "https://test.tiarkaerell.com/",
"client_name": null,
"client_icon": null,
"token_type": "normal",
"created_at": "2022-04-01T08:11:29.188371+00:00",
"access_token_expiration": 1800.0,
"token": "f3098610d7491485f26994ffcd37e51b32cd46d5719b1a5beab3063c61ca67d0eeb5c6416f1c77d01a420ab16465491cd3703cb1139018277d48476ac7c623de",
"jwt_key": "b954d0236661f8bffcf6d25568c06ea906e6c141ea644eca94f50a382d5a84defb07526fca7e61558db216eb6d1d5039be8d1eb04db4ce1d36e50f9731745388",
"last_used_at": "2022-04-01T10:28:18.393196+00:00",
"last_used_ip": "85.195.218.245",
"credential_id": "9beb9518028c4616948324f9e7e2d071",
"version": "2022.3.8"
},
{
"id": "c4fbf4356edf49a888812de23ecc63b6",
"user_id": "7e27048212fd43d78e900bed6f4ac44c",
"client_id": "https://test.tiarkaerell.com/",
"client_name": null,
"client_icon": null,
"token_type": "normal",
"created_at": "2022-04-01T10:46:28.226111+00:00",
"access_token_expiration": 1800.0,
"token": "81f8a38953cc3f3ad6d4a1622baac99d94b1ba939b8388b27a6aff1da417538f67841ae07e23fed18674810b18b9eac1f539dbfae556b15df871a7c4ea7efd0e",
"jwt_key": "5053a085fa4621225e4d53c3e26a934d2c92b418c1f98167e614a572d42d4381c526fae86e21f508014686645eb65a0c68c0821ec6c8e1a47e8fc59fe6fedb32",
"last_used_at": "2022-04-01T10:46:28.227004+00:00",
"last_used_ip": "84.74.113.94",
"credential_id": "9beb9518028c4616948324f9e7e2d071",
"version": "2022.3.8"
}
]
}
}

View File

@ -0,0 +1,13 @@
{
"version": 1,
"minor_version": 1,
"key": "auth_provider.homeassistant",
"data": {
"users": [
{
"username": "vlb",
"password": "JDJiJDEyJEg4Mkg2VHU5aXRCUjZPdmczUDNYQS5vVHplYjJIaUFUVDkyMmIuU1F6QVgvcUs2LnJhaTBt"
}
]
}
}

View File

@ -0,0 +1,10 @@
{
"version": 1,
"minor_version": 1,
"key": "core.analytics",
"data": {
"preferences": {},
"onboarded": true,
"uuid": null
}
}

View File

@ -0,0 +1,24 @@
{
"version": 1,
"minor_version": 1,
"key": "core.area_registry",
"data": {
"areas": [
{
"name": "Salon",
"id": "salon",
"picture": null
},
{
"name": "Cuisine",
"id": "cuisine",
"picture": null
},
{
"name": "Chambre",
"id": "chambre",
"picture": null
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"version": 1,
"minor_version": 1,
"key": "core.config",
"data": {
"latitude": 52.3731339,
"longitude": 4.8903147,
"elevation": 0,
"unit_system": "metric",
"location_name": "Maison",
"time_zone": "UTC",
"external_url": null,
"internal_url": null,
"currency": "EUR"
}
}

View File

@ -0,0 +1,38 @@
{
"version": 1,
"minor_version": 1,
"key": "core.config_entries",
"data": {
"entries": [
{
"entry_id": "b869fb6b3dbead7e9a32f0712597fc22",
"version": 1,
"domain": "radio_browser",
"title": "Radio Browser",
"data": {},
"options": {},
"pref_disable_new_entities": false,
"pref_disable_polling": false,
"source": "onboarding",
"unique_id": null,
"disabled_by": null
},
{
"entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"version": 1,
"domain": "vesync",
"title": "vlebourl@gmail.com",
"data": {
"username": "vlebourl@gmail.com",
"password": "pVMMJG6NHTxFFC"
},
"options": {},
"pref_disable_new_entities": false,
"pref_disable_polling": false,
"source": "user",
"unique_id": "vlebourl@gmail.com-6838532",
"disabled_by": null
}
]
}
}

View File

@ -0,0 +1,34 @@
{
"version": 1,
"minor_version": 3,
"key": "core.device_registry",
"data": {
"devices": [
{
"config_entries": [
"0d5d11a7d4cf40ae0800a418ed940bb3"
],
"connections": [],
"identifiers": [
[
"vesync",
"vsaq8556ccd84d7298c822b9bf950366"
]
],
"manufacturer": "VeSync",
"model": "LUH-D301S-WEU",
"name": "Humidificateur",
"sw_version": null,
"hw_version": null,
"entry_type": null,
"id": "8fdadc0cedefbc28016545713ccc7f02",
"via_device_id": null,
"area_id": null,
"name_by_user": null,
"disabled_by": null,
"configuration_url": null
}
],
"deleted_devices": []
}
}

View File

@ -0,0 +1,264 @@
{
"version": 1,
"minor_version": 5,
"key": "core.entity_registry",
"data": {
"entities": [
{
"area_id": null,
"capabilities": null,
"config_entry_id": null,
"device_class": null,
"device_id": null,
"disabled_by": null,
"entity_category": null,
"entity_id": "person.vlb",
"icon": null,
"id": "cac156ee969a158d3d7f6eddc27a9f13",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "vlb",
"platform": "person",
"supported_features": 0,
"unique_id": "vlb",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": null,
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "config",
"entity_id": "switch.humidificateur_display",
"icon": null,
"id": "61be826e1b8d0a297882c0479e99e5e5",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur display",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-display",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": {
"state_class": "measurement"
},
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "diagnostic",
"entity_id": "sensor.humidificateur_current_humidity",
"icon": null,
"id": "99c7e35a8b96bd6b41db17687b94b693",
"name": null,
"options": {},
"original_device_class": "humidity",
"original_icon": null,
"original_name": "Humidificateur current humidity",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-humidity",
"unit_of_measurement": "%"
},
{
"area_id": null,
"capabilities": null,
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "diagnostic",
"entity_id": "binary_sensor.humidificateur_out_of_water",
"icon": null,
"id": "9444be2d2b974b2a8152532d74d88bad",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur out of water",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-out_of_water",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": {
"min": 1,
"max": 2,
"step": 1.0,
"mode": "auto"
},
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "config",
"entity_id": "number.humidificateur_mist_level",
"icon": null,
"id": "4eb8ff6f14afee99ced44a973c9aab40",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur mist level",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-mist-level",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": {
"min_humidity": 30,
"max_humidity": 80,
"available_modes": [
"auto",
"sleep",
"manual"
]
},
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": null,
"entity_id": "humidifier.humidificateur",
"icon": null,
"id": "d504532493c5e3835a04739c93a4fd0c",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur",
"platform": "vesync",
"supported_features": 1,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": null,
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "config",
"entity_id": "switch.humidificateur_automatic_stop",
"icon": null,
"id": "ab61f5de2c2aa2b85b587c4b157298f5",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur automatic stop",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-automatic-stop",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": null,
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "diagnostic",
"entity_id": "binary_sensor.humidificateur_water_tank_lifted",
"icon": null,
"id": "9d1b97a64b64cb1689a1a01b8df694fe",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur water tank lifted",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-water_tank_lifted",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": {
"min": 30,
"max": 80,
"step": 1.0,
"mode": "auto"
},
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "config",
"entity_id": "number.humidificateur_target_level",
"icon": null,
"id": "653aa2a575961a9d2677a83bc584a6ea",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur target level",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-target-level",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": null,
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "config",
"entity_id": "switch.humidificateur_auto_mode",
"icon": null,
"id": "8fcb923b00a0fe95b1ee0670eb1714aa",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur auto mode",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-auto-mode",
"unit_of_measurement": null
},
{
"area_id": null,
"capabilities": {
"supported_color_modes": [
"brightness"
]
},
"config_entry_id": "0d5d11a7d4cf40ae0800a418ed940bb3",
"device_class": null,
"device_id": "8fdadc0cedefbc28016545713ccc7f02",
"disabled_by": null,
"entity_category": "config",
"entity_id": "light.humidificateur_night_light",
"icon": null,
"id": "66bf16efc1261a19c9c99db424275026",
"name": null,
"options": {},
"original_device_class": null,
"original_icon": null,
"original_name": "Humidificateur night light",
"platform": "vesync",
"supported_features": 0,
"unique_id": "vsaq8556ccd84d7298c822b9bf950366-night-light",
"unit_of_measurement": null
}
]
}
}

View File

@ -0,0 +1,28 @@
{
"version": 1,
"minor_version": 1,
"key": "core.restore_state",
"data": [
{
"state": {
"entity_id": "person.vlb",
"state": "unknown",
"attributes": {
"editable": false,
"id": "vlb",
"user_id": "7e27048212fd43d78e900bed6f4ac44c",
"friendly_name": "vlb"
},
"last_changed": "2022-04-01T10:41:26.492401+00:00",
"last_updated": "2022-04-01T10:41:30.405583+00:00",
"context": {
"id": "4916b780086bb9d8250804141e852b6f",
"parent_id": null,
"user_id": null
}
},
"extra_data": null,
"last_seen": "2022-04-01T10:56:55.367958+00:00"
}
]
}

View File

@ -0,0 +1,8 @@
{
"version": 1,
"minor_version": 1,
"key": "core.uuid",
"data": {
"uuid": "3b5ed1182c11445a93dc24d7737bf468"
}
}

18
Config/.storage/http Normal file
View File

@ -0,0 +1,18 @@
{
"version": 1,
"minor_version": 1,
"key": "http",
"data": {
"server_port": 9443,
"use_x_forwarded_for": true,
"trusted_proxies": [
"192.168.1.194"
],
"ip_ban_enabled": true,
"cors_allowed_origins": [
"https://cast.home-assistant.io"
],
"login_attempts_threshold": -1,
"ssl_profile": "modern"
}
}

View File

@ -0,0 +1,8 @@
{
"version": 1,
"minor_version": 1,
"key": "http.auth",
"data": {
"content_user": "563d33967d924c588c6ecbff5eb96ed8"
}
}

View File

@ -0,0 +1,13 @@
{
"version": 4,
"minor_version": 1,
"key": "onboarding",
"data": {
"done": [
"user",
"core_config",
"analytics",
"integration"
]
}
}

15
Config/.storage/person Normal file
View File

@ -0,0 +1,15 @@
{
"version": 2,
"minor_version": 1,
"key": "person",
"data": {
"items": [
{
"name": "vlb",
"user_id": "7e27048212fd43d78e900bed6f4ac44c",
"device_trackers": [],
"id": "vlb"
}
]
}
}

View File

@ -0,0 +1,6 @@
{
"version": 1,
"minor_version": 1,
"key": "trace.saved_traces",
"data": {}
}

1
Config/automations.yaml Normal file
View File

@ -0,0 +1 @@
[]

View File

@ -0,0 +1,54 @@
blueprint:
name: Motion-activated Light
description: Turn on a light when motion is detected.
domain: automation
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml
input:
motion_entity:
name: Motion Sensor
selector:
entity:
domain: binary_sensor
device_class: motion
light_target:
name: Light
selector:
target:
entity:
domain: light
no_motion_wait:
name: Wait time
description: Time to leave the light on after last motion is detected.
default: 120
selector:
number:
min: 0
max: 3600
unit_of_measurement: seconds
# If motion is detected within the delay,
# we restart the script.
mode: restart
max_exceeded: silent
trigger:
platform: state
entity_id: !input motion_entity
from: "off"
to: "on"
action:
- alias: "Turn on the light"
service: light.turn_on
target: !input light_target
- alias: "Wait until there is no motion from device"
wait_for_trigger:
platform: state
entity_id: !input motion_entity
from: "on"
to: "off"
- alias: "Wait the number of seconds that has been set"
delay: !input no_motion_wait
- alias: "Turn off the light"
service: light.turn_off
target: !input light_target

View File

@ -0,0 +1,46 @@
blueprint:
name: Zone Notification
description: Send a notification to a device when a person leaves a specific zone.
domain: automation
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/notify_leaving_zone.yaml
input:
person_entity:
name: Person
selector:
entity:
domain: person
zone_entity:
name: Zone
selector:
entity:
domain: zone
notify_device:
name: Device to notify
description: Device needs to run the official Home Assistant app to receive notifications.
selector:
device:
integration: mobile_app
trigger:
platform: state
entity_id: !input person_entity
variables:
zone_entity: !input zone_entity
# This is the state of the person when it's in this zone.
zone_state: "{{ states[zone_entity].name }}"
person_entity: !input person_entity
person_name: "{{ states[person_entity].name }}"
condition:
condition: template
# The first case handles leaving the Home zone which has a special state when zoning called 'home'.
# The second case handles leaving all other zones.
value_template: "{{ zone_entity == 'zone.home' and trigger.from_state.state == 'home' and trigger.to_state.state != 'home' or trigger.from_state.state == zone_state and trigger.to_state.state != zone_state }}"
action:
- alias: "Notify that a person has left the zone"
domain: mobile_app
type: notify
device_id: !input notify_device
message: "{{ person_name }} has left {{ zone_state }}"

View File

@ -0,0 +1,84 @@
blueprint:
name: Confirmable Notification
description: >-
A script that sends an actionable notification with a confirmation before
running the specified action.
domain: script
source_url: https://github.com/home-assistant/core/blob/master/homeassistant/components/script/blueprints/confirmable_notification.yaml
input:
notify_device:
name: Device to notify
description: Device needs to run the official Home Assistant app to receive notifications.
selector:
device:
integration: mobile_app
title:
name: "Title"
description: "The title of the button shown in the notification."
default: ""
selector:
text:
message:
name: "Message"
description: "The message body"
selector:
text:
confirm_text:
name: "Confirmation Text"
description: "Text to show on the confirmation button"
default: "Confirm"
selector:
text:
confirm_action:
name: "Confirmation Action"
description: "Action to run when notification is confirmed"
default: []
selector:
action:
dismiss_text:
name: "Dismiss Text"
description: "Text to show on the dismiss button"
default: "Dismiss"
selector:
text:
dismiss_action:
name: "Dismiss Action"
description: "Action to run when notification is dismissed"
default: []
selector:
action:
mode: restart
sequence:
- alias: "Set up variables"
variables:
action_confirm: "{{ 'CONFIRM_' ~ context.id }}"
action_dismiss: "{{ 'DISMISS_' ~ context.id }}"
- alias: "Send notification"
domain: mobile_app
type: notify
device_id: !input notify_device
title: !input title
message: !input message
data:
actions:
- action: "{{ action_confirm }}"
title: !input confirm_text
- action: "{{ action_dismiss }}"
title: !input dismiss_text
- alias: "Awaiting response"
wait_for_trigger:
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_confirm }}"
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_dismiss }}"
- choose:
- conditions: "{{ wait.trigger.event.data.action == action_confirm }}"
sequence: !input confirm_action
- conditions: "{{ wait.trigger.event.data.action == action_dismiss }}"
sequence: !input dismiss_action

21
Config/configuration.yaml Normal file
View File

@ -0,0 +1,21 @@
# Configure a default setup of Home Assistant (frontend, api, etc)
default_config:
# Text to speech
tts:
- platform: google_translate
http:
server_port: 9443
use_x_forwarded_for: true
trusted_proxies:
- 192.168.1.194
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
logger:
default: info
logs:
custom_components.vesync: debug

1
Config/custom_components Symbolic link
View File

@ -0,0 +1 @@
../custom_components

443
Config/home-assistant.log Normal file
View File

@ -0,0 +1,443 @@
2022-04-01 12:41:25 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration vesync which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain logger took 0.0 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up system_log
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain system_log took 0.0 seconds
2022-04-01 12:41:25 WARNING (Recorder) [homeassistant.components.recorder.util] The system could not validate that the sqlite3 database at //home/vlb/temp/HAcore/vesync-bpo/Config/home-assistant_v2.db was shutdown cleanly
2022-04-01 12:41:25 WARNING (Recorder) [homeassistant.components.recorder.util] Ended unfinished session (id=16 from 2022-04-01 10:28:05.941295)
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain recorder took 0.1 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.bootstrap] Setting up stage 1: {'ssdp', 'lovelace', 'webhook', 'http', 'websocket_api', 'device_automation', 'person', 'zeroconf', 'analytics', 'dhcp', 'cloud', 'onboarding', 'api', 'usb', 'diagnostics', 'network', 'search', 'config', 'frontend', 'auth', 'image', 'system_log'}
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up lovelace
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up http
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up device_automation
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain device_automation took 0.0 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up dhcp
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain dhcp took 0.0 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain lovelace took 0.1 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain http took 0.1 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up webhook
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain webhook took 0.0 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up websocket_api
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain websocket_api took 0.0 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up api
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain api took 0.0 seconds
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up diagnostics
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up config
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setting up auth
2022-04-01 12:41:25 INFO (MainThread) [homeassistant.setup] Setup of domain auth took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain diagnostics took 0.1 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain config took 0.1 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up image
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up search
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain search took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up analytics
2022-04-01 12:41:26 INFO (SyncWorker_2) [homeassistant.loader] Loaded google_assistant from homeassistant.components.google_assistant
2022-04-01 12:41:26 INFO (SyncWorker_3) [homeassistant.loader] Loaded alexa from homeassistant.components.alexa
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up usb
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain usb took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up network
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain network took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain image took 0.1 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain analytics took 0.0 seconds
2022-04-01 12:41:26 INFO (SyncWorker_0) [homeassistant.loader] Loaded camera from homeassistant.components.camera
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up person
2022-04-01 12:41:26 INFO (SyncWorker_4) [homeassistant.loader] Loaded media_player from homeassistant.components.media_player
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up zeroconf
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up ssdp
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain ssdp took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain zeroconf took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up cloud
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain cloud took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain person took 0.3 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up onboarding
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain onboarding took 0.0 seconds
2022-04-01 12:41:26 INFO (SyncWorker_0) [homeassistant.loader] Loaded hassio from homeassistant.components.hassio
2022-04-01 12:41:26 INFO (SyncWorker_4) [homeassistant.loader] Loaded device_tracker from homeassistant.components.device_tracker
2022-04-01 12:41:26 INFO (SyncWorker_3) [homeassistant.loader] Loaded group from homeassistant.components.group
2022-04-01 12:41:26 INFO (SyncWorker_2) [homeassistant.loader] Loaded panel_custom from homeassistant.components.panel_custom
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up frontend
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain frontend took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.bootstrap] Setting up stage 2: {'energy', 'input_button', 'input_boolean', 'input_datetime', 'media_source', 'vesync', 'trace', 'history', 'map', 'tts', 'my', 'default_config', 'blueprint', 'input_number', 'counter', 'tag', 'input_select', 'zone', 'logbook', 'scene', 'mobile_app', 'automation', 'timer', 'system_health', 'sun', 'radio_browser', 'script', 'input_text'}
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up input_button
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up input_boolean
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up input_datetime
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up media_source
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up vesync
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain vesync took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up trace
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain trace took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up history
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain history took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up map
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain map took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up my
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain my took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up blueprint
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain blueprint took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up input_number
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up counter
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up tag
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up input_select
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up zone
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up logbook
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up scene
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.components.scene] Setting up scene.homeassistant
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up timer
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up system_health
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up sun
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain sun took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up radio_browser
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain radio_browser took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up input_text
2022-04-01 12:41:26 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v1/user/login' api
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain media_source took 0.2 seconds
2022-04-01 12:41:26 INFO (SyncWorker_0) [homeassistant.loader] Loaded tado from homeassistant.components.tado
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain logbook took 0.1 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain scene took 0.1 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up automation
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain system_health took 0.1 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up script
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up energy
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain energy took 0.0 seconds
2022-04-01 12:41:26 INFO (SyncWorker_1) [homeassistant.loader] Loaded google_translate from homeassistant.components.google_translate
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain automation took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain script took 0.0 seconds
2022-04-01 12:41:26 INFO (SyncWorker_5) [homeassistant.loader] Loaded sensor from homeassistant.components.sensor
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up tts
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain input_button took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain tag took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain input_datetime took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain input_boolean took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain input_number took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.components.http] Now listening on port 9443
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setting up sensor
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain sensor took 0.0 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain counter took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain input_select took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.energy
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain zone took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain timer took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain input_text took 0.2 seconds
2022-04-01 12:41:26 INFO (MainThread) [homeassistant.setup] Setup of domain tts took 0.1 seconds
2022-04-01 12:41:26 INFO (SyncWorker_5) [homeassistant.loader] Loaded notify from homeassistant.components.notify
2022-04-01 12:41:27 INFO (MainThread) [homeassistant.setup] Setting up mobile_app
2022-04-01 12:41:27 INFO (MainThread) [homeassistant.setup] Setup of domain mobile_app took 0.0 seconds
2022-04-01 12:41:27 INFO (MainThread) [homeassistant.setup] Setting up notify
2022-04-01 12:41:27 INFO (MainThread) [homeassistant.setup] Setup of domain notify took 0.0 seconds
2022-04-01 12:41:27 INFO (MainThread) [homeassistant.setup] Setting up default_config
2022-04-01 12:41:27 INFO (MainThread) [homeassistant.setup] Setup of domain default_config took 0.0 seconds
2022-04-01 12:41:27 INFO (MainThread) [homeassistant.components.notify] Setting up notify.mobile_app
2022-04-01 12:41:27 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v1/deviceManaged/devices' api
2022-04-01 12:41:27 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.vesync] New device list initialized
2022-04-01 12:41:27 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:28 INFO (MainThread) [custom_components.vesync.common] 1 VeSync fans found
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.vesync
2022-04-01 12:41:28 INFO (SyncWorker_1) [homeassistant.loader] Loaded switch from homeassistant.components.switch
2022-04-01 12:41:28 INFO (SyncWorker_5) [homeassistant.loader] Loaded fan from homeassistant.components.fan
2022-04-01 12:41:28 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:28 INFO (SyncWorker_3) [homeassistant.loader] Loaded light from homeassistant.components.light
2022-04-01 12:41:28 INFO (SyncWorker_2) [homeassistant.loader] Loaded number from homeassistant.components.number
2022-04-01 12:41:28 INFO (SyncWorker_1) [homeassistant.loader] Loaded binary_sensor from homeassistant.components.binary_sensor
2022-04-01 12:41:28 INFO (SyncWorker_0) [homeassistant.loader] Loaded humidifier from homeassistant.components.humidifier
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setting up switch
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setup of domain switch took 0.0 seconds
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setting up fan
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setup of domain fan took 0.0 seconds
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setting up light
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setting up number
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setup of domain number took 0.0 seconds
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setting up binary_sensor
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setup of domain binary_sensor took 0.0 seconds
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setting up humidifier
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setup of domain humidifier took 0.0 seconds
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.components.switch] Setting up switch.vesync
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.components.fan] Setting up fan.vesync
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.setup] Setup of domain light took 0.0 seconds
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.components.number] Setting up number.vesync
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.components.binary_sensor] Setting up binary_sensor.vesync
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.components.humidifier] Setting up humidifier.vesync
2022-04-01 12:41:28 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:28 INFO (MainThread) [homeassistant.components.light] Setting up light.vesync
2022-04-01 12:41:28 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:28 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:28 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:29 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:29 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:29 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:29 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:30 INFO (MainThread) [homeassistant.bootstrap] Home Assistant initialized in 5.01s
2022-04-01 12:41:30 INFO (MainThread) [homeassistant.core] Starting Home Assistant
2022-04-01 12:41:30 INFO (MainThread) [homeassistant.core] Timer:starting
2022-04-01 12:41:30 INFO (MainThread) [homeassistant.components.zeroconf] Starting Zeroconf broadcast
2022-04-01 12:41:30 INFO (SyncWorker_3) [homeassistant.loader] Loaded overkiz from homeassistant.components.overkiz
2022-04-01 12:41:30 INFO (SyncWorker_1) [homeassistant.loader] Loaded hue from homeassistant.components.hue
2022-04-01 12:41:31 INFO (SyncWorker_4) [homeassistant.loader] Loaded somfy from homeassistant.components.somfy
2022-04-01 12:41:31 INFO (SyncWorker_4) [homeassistant.loader] Loaded upnp from homeassistant.components.upnp
2022-04-01 12:41:31 INFO (SyncWorker_5) [homeassistant.loader] Loaded cast from homeassistant.components.cast
2022-04-01 12:41:31 INFO (SyncWorker_1) [homeassistant.loader] Loaded plex from homeassistant.components.plex
2022-04-01 12:41:31 INFO (SyncWorker_0) [homeassistant.loader] Loaded homekit_controller from homeassistant.components.homekit_controller
2022-04-01 12:41:32 INFO (SyncWorker_3) [homeassistant.loader] Loaded netatmo from homeassistant.components.netatmo
2022-04-01 12:41:32 INFO (SyncWorker_2) [homeassistant.loader] Loaded ipp from homeassistant.components.ipp
2022-04-01 12:41:32 INFO (SyncWorker_4) [homeassistant.loader] Loaded esphome from homeassistant.components.esphome
2022-04-01 12:41:32 INFO (SyncWorker_5) [homeassistant.loader] Loaded harmony from homeassistant.components.harmony
2022-04-01 12:41:32 INFO (SyncWorker_1) [homeassistant.loader] Loaded remote from homeassistant.components.remote
2022-04-01 12:41:32 INFO (MainThread) [homeassistant.setup] Setting up remote
2022-04-01 12:41:32 INFO (MainThread) [homeassistant.setup] Setup of domain remote took 0.0 seconds
2022-04-01 12:41:32 INFO (SyncWorker_3) [homeassistant.loader] Loaded dlna_dms from homeassistant.components.dlna_dms
2022-04-01 12:41:32 INFO (SyncWorker_2) [homeassistant.loader] Loaded devolo_home_control from homeassistant.components.devolo_home_control
2022-04-01 12:41:32 INFO (SyncWorker_4) [homeassistant.loader] Loaded devolo_home_network from homeassistant.components.devolo_home_network
2022-04-01 12:41:59 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:59 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:00 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:00 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:01 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:29 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:29 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:29 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:30 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:31 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:31 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:59 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:42:59 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:00 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:01 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:01 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:29 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:29 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:29 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:30 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:30 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:31 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:31 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:59 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:43:59 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:00 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:01 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:01 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:29 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:29 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:29 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:30 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:30 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:31 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:31 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:59 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:44:59 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:00 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:00 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:01 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:29 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:29 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:29 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:30 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:30 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:59 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:45:59 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:00 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:00 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:01 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:01 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:29 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:29 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:30 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:30 DEBUG (SyncWorker_9) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:30 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:30 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:31 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:31 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:46:59 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:00 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:00 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:00 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:00 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:01 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:02 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:29 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:29 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:30 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:30 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:30 DEBUG (SyncWorker_9) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:31 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:47:59 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:00 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:00 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:00 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:01 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:29 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:29 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:30 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:30 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:30 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:31 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:48:59 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:00 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:00 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:00 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:01 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:01 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:29 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:29 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:30 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:30 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:30 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:31 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:49:59 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:00 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:01 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:01 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:29 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:29 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:30 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:30 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:30 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:30 DEBUG (SyncWorker_9) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:31 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:50:59 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:00 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:00 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:00 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:01 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:29 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:29 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:30 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:30 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:30 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:31 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:51:59 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:00 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:00 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:01 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:01 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:01 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:29 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:29 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:30 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:30 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:30 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:31 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:52:59 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:00 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:00 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:01 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:01 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:29 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:29 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:30 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:30 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:30 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:30 DEBUG (SyncWorker_9) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:31 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:53:59 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:00 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:00 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:00 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:01 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:01 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:29 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:29 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:30 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:30 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:30 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:30 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:30 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:31 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:54:59 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:00 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:00 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:00 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:01 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:01 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:29 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:29 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:30 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:30 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:30 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:30 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:31 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:55:59 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:00 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:00 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:00 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:00 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:00 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:01 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:01 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:29 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:29 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:30 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:30 DEBUG (SyncWorker_7) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:30 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:30 DEBUG (SyncWorker_9) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:30 DEBUG (SyncWorker_10) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:31 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:31 DEBUG (SyncWorker_8) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:56:55 INFO (Recorder) [homeassistant.components.recorder.pool.RecorderPool] Pool recreating

457
Config/home-assistant.log.1 Normal file
View File

@ -0,0 +1,457 @@
2022-04-01 12:28:05 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration vesync which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-04-01 12:28:05 INFO (MainThread) [homeassistant.setup] Setup of domain logger took 0.0 seconds
2022-04-01 12:28:05 INFO (MainThread) [homeassistant.setup] Setting up recorder
2022-04-01 12:28:05 INFO (MainThread) [homeassistant.setup] Setting up system_log
2022-04-01 12:28:05 INFO (MainThread) [homeassistant.setup] Setup of domain system_log took 0.0 seconds
2022-04-01 12:28:05 WARNING (Recorder) [homeassistant.components.recorder.util] The system could not validate that the sqlite3 database at //home/vlb/temp/HAcore/vesync-bpo/Config/home-assistant_v2.db was shutdown cleanly
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain recorder took 0.1 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.bootstrap] Setting up stage 1: {'lovelace', 'analytics', 'diagnostics', 'image', 'api', 'http', 'websocket_api', 'search', 'config', 'system_log', 'device_automation', 'zeroconf', 'frontend', 'auth', 'dhcp', 'onboarding', 'person', 'webhook', 'ssdp', 'network', 'usb', 'cloud'}
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up lovelace
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up http
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up device_automation
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain device_automation took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up dhcp
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain dhcp took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain lovelace took 0.1 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain http took 0.1 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up diagnostics
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up api
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain api took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up websocket_api
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain websocket_api took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up config
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up auth
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain auth took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up webhook
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain webhook took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain diagnostics took 0.1 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up image
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain config took 0.1 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up analytics
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up search
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain search took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain image took 0.1 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up network
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain network took 0.0 seconds
2022-04-01 12:28:06 INFO (SyncWorker_4) [homeassistant.loader] Loaded google_assistant from homeassistant.components.google_assistant
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up person
2022-04-01 12:28:06 INFO (SyncWorker_1) [homeassistant.loader] Loaded alexa from homeassistant.components.alexa
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up usb
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain usb took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain analytics took 0.0 seconds
2022-04-01 12:28:06 INFO (SyncWorker_0) [homeassistant.loader] Loaded camera from homeassistant.components.camera
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up zeroconf
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up ssdp
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain ssdp took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain zeroconf took 0.0 seconds
2022-04-01 12:28:06 INFO (SyncWorker_4) [homeassistant.loader] Loaded media_player from homeassistant.components.media_player
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up cloud
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain cloud took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain person took 0.3 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up onboarding
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain onboarding took 0.0 seconds
2022-04-01 12:28:06 INFO (SyncWorker_0) [homeassistant.loader] Loaded hassio from homeassistant.components.hassio
2022-04-01 12:28:06 INFO (SyncWorker_3) [homeassistant.loader] Loaded device_tracker from homeassistant.components.device_tracker
2022-04-01 12:28:06 INFO (SyncWorker_1) [homeassistant.loader] Loaded tado from homeassistant.components.tado
2022-04-01 12:28:06 INFO (SyncWorker_2) [homeassistant.loader] Loaded group from homeassistant.components.group
2022-04-01 12:28:06 INFO (SyncWorker_0) [homeassistant.loader] Loaded panel_custom from homeassistant.components.panel_custom
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up frontend
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain frontend took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.bootstrap] Setting up stage 2: {'logbook', 'input_datetime', 'counter', 'zone', 'script', 'history', 'my', 'mobile_app', 'default_config', 'timer', 'tag', 'media_source', 'input_boolean', 'input_button', 'blueprint', 'system_health', 'automation', 'tts', 'energy', 'vesync', 'map', 'scene', 'input_text', 'radio_browser', 'sun', 'trace', 'input_number', 'input_select'}
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up logbook
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up input_datetime
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up counter
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up zone
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up history
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain history took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up my
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain my took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up timer
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up tag
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up media_source
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up input_boolean
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up input_button
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up blueprint
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain blueprint took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up system_health
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up vesync
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain vesync took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up map
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain map took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up scene
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.components.scene] Setting up scene.homeassistant
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up input_text
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up radio_browser
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain radio_browser took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up sun
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain sun took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up trace
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain trace took 0.0 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up input_number
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setting up input_select
2022-04-01 12:28:06 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v1/user/login' api
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain logbook took 0.2 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain media_source took 0.2 seconds
2022-04-01 12:28:06 INFO (MainThread) [homeassistant.setup] Setup of domain system_health took 0.2 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up energy
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain energy took 0.0 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain scene took 0.2 seconds
2022-04-01 12:28:07 INFO (SyncWorker_0) [homeassistant.loader] Loaded google_translate from homeassistant.components.google_translate
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up script
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up automation
2022-04-01 12:28:07 INFO (SyncWorker_3) [homeassistant.loader] Loaded sensor from homeassistant.components.sensor
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up tts
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain script took 0.0 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain automation took 0.0 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain input_datetime took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain counter took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain tag took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain timer took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up sensor
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain sensor took 0.0 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.components.http] Now listening on port 9443
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain zone took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain input_boolean took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain input_button took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain input_text took 0.3 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.energy
2022-04-01 12:28:07 INFO (SyncWorker_0) [homeassistant.loader] Loaded notify from homeassistant.components.notify
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain input_number took 0.2 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain input_select took 0.2 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up mobile_app
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain tts took 0.1 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain mobile_app took 0.1 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up notify
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain notify took 0.0 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setting up default_config
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.setup] Setup of domain default_config took 0.0 seconds
2022-04-01 12:28:07 INFO (MainThread) [homeassistant.components.notify] Setting up notify.mobile_app
2022-04-01 12:28:07 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v1/deviceManaged/devices' api
2022-04-01 12:28:07 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.vesync] New device list initialized
2022-04-01 12:28:07 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:08 INFO (MainThread) [custom_components.vesync.common] 1 VeSync fans found
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.vesync
2022-04-01 12:28:08 INFO (SyncWorker_1) [homeassistant.loader] Loaded humidifier from homeassistant.components.humidifier
2022-04-01 12:28:08 INFO (SyncWorker_5) [homeassistant.loader] Loaded fan from homeassistant.components.fan
2022-04-01 12:28:08 INFO (SyncWorker_4) [homeassistant.loader] Loaded light from homeassistant.components.light
2022-04-01 12:28:08 INFO (SyncWorker_3) [homeassistant.loader] Loaded switch from homeassistant.components.switch
2022-04-01 12:28:08 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:08 INFO (SyncWorker_0) [homeassistant.loader] Loaded number from homeassistant.components.number
2022-04-01 12:28:08 INFO (SyncWorker_2) [homeassistant.loader] Loaded binary_sensor from homeassistant.components.binary_sensor
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setting up humidifier
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setup of domain humidifier took 0.0 seconds
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setting up fan
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setup of domain fan took 0.0 seconds
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setting up light
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setting up switch
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setup of domain switch took 0.0 seconds
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setting up number
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setup of domain number took 0.0 seconds
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setting up binary_sensor
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setup of domain binary_sensor took 0.0 seconds
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.components.humidifier] Setting up humidifier.vesync
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.components.fan] Setting up fan.vesync
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.components.switch] Setting up switch.vesync
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.setup] Setup of domain light took 0.0 seconds
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.components.number] Setting up number.vesync
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.components.binary_sensor] Setting up binary_sensor.vesync
2022-04-01 12:28:08 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:08 INFO (MainThread) [homeassistant.components.light] Setting up light.vesync
2022-04-01 12:28:08 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:08 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:08 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:09 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:09 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:09 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:10 INFO (MainThread) [homeassistant.bootstrap] Home Assistant initialized in 5.20s
2022-04-01 12:28:10 INFO (MainThread) [homeassistant.core] Starting Home Assistant
2022-04-01 12:28:10 INFO (MainThread) [homeassistant.core] Timer:starting
2022-04-01 12:28:10 INFO (MainThread) [homeassistant.components.zeroconf] Starting Zeroconf broadcast
2022-04-01 12:28:10 INFO (SyncWorker_5) [homeassistant.loader] Loaded somfy from homeassistant.components.somfy
2022-04-01 12:28:10 INFO (SyncWorker_0) [homeassistant.loader] Loaded overkiz from homeassistant.components.overkiz
2022-04-01 12:28:11 INFO (SyncWorker_5) [homeassistant.loader] Loaded homekit_controller from homeassistant.components.homekit_controller
2022-04-01 12:28:11 INFO (SyncWorker_2) [homeassistant.loader] Loaded cast from homeassistant.components.cast
2022-04-01 12:28:11 INFO (SyncWorker_3) [homeassistant.loader] Loaded plex from homeassistant.components.plex
2022-04-01 12:28:11 INFO (SyncWorker_3) [homeassistant.loader] Loaded hue from homeassistant.components.hue
2022-04-01 12:28:12 INFO (SyncWorker_6) [homeassistant.loader] Loaded netatmo from homeassistant.components.netatmo
2022-04-01 12:28:12 INFO (SyncWorker_2) [homeassistant.loader] Loaded ipp from homeassistant.components.ipp
2022-04-01 12:28:12 INFO (SyncWorker_3) [homeassistant.loader] Loaded harmony from homeassistant.components.harmony
2022-04-01 12:28:12 INFO (SyncWorker_6) [homeassistant.loader] Loaded remote from homeassistant.components.remote
2022-04-01 12:28:12 INFO (MainThread) [homeassistant.setup] Setting up remote
2022-04-01 12:28:12 INFO (MainThread) [homeassistant.setup] Setup of domain remote took 0.0 seconds
2022-04-01 12:28:12 INFO (SyncWorker_0) [homeassistant.loader] Loaded upnp from homeassistant.components.upnp
2022-04-01 12:28:13 INFO (SyncWorker_2) [homeassistant.loader] Loaded dlna_dms from homeassistant.components.dlna_dms
2022-04-01 12:28:13 INFO (SyncWorker_4) [homeassistant.loader] Loaded devolo_home_network from homeassistant.components.devolo_home_network
2022-04-01 12:28:13 INFO (SyncWorker_3) [homeassistant.loader] Loaded devolo_home_control from homeassistant.components.devolo_home_control
2022-04-01 12:28:13 INFO (SyncWorker_5) [homeassistant.loader] Loaded esphome from homeassistant.components.esphome
2022-04-01 12:28:36 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Running websocket_api script
2022-04-01 12:28:36 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Executing step call service
2022-04-01 12:28:36 INFO (MainThread) [custom_components.vesync.common] 1 VeSync fans found
2022-04-01 12:28:36 WARNING (MainThread) [custom_components.vesync.fan] Humidificateur - Unknown device type - LUH-D301S-WEU
2022-04-01 12:28:36 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:36 INFO (MainThread) [homeassistant.helpers.entity_registry] Registered new light.vesync entity: light.humidificateur_night_light
2022-04-01 12:28:36 ERROR (MainThread) [homeassistant.components.light] Error adding entities for domain light with platform vesync
Traceback (most recent call last):
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity_platform.py", line 382, in async_add_entities
await asyncio.gather(*tasks)
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity_platform.py", line 614, in _async_add_entity
await entity.add_to_platform_finish()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 801, in add_to_platform_finish
self.async_write_ha_state()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 553, in async_write_ha_state
self._async_write_ha_state()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state
state = self._stringify_state()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 559, in _stringify_state
if (state := self.state) is None:
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 988, in state
if (is_on := self.is_on) is None:
File "/home/vlb/temp/HAcore/vesync-bpo/Config/custom_components/vesync/light.py", line 234, in is_on
return self.smarthumidifier.details["night_light_brightness"] > 0
KeyError: 'night_light_brightness'
2022-04-01 12:28:36 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity_platform.py", line 382, in async_add_entities
await asyncio.gather(*tasks)
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity_platform.py", line 614, in _async_add_entity
await entity.add_to_platform_finish()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 801, in add_to_platform_finish
self.async_write_ha_state()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 553, in async_write_ha_state
self._async_write_ha_state()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 590, in _async_write_ha_state
state = self._stringify_state()
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 559, in _stringify_state
if (state := self.state) is None:
File "/home/vlb/temp/HAcore/vesync-bpo/.venv/lib/python3.9/site-packages/homeassistant/helpers/entity.py", line 988, in state
if (is_on := self.is_on) is None:
File "/home/vlb/temp/HAcore/vesync-bpo/Config/custom_components/vesync/light.py", line 234, in is_on
return self.smarthumidifier.details["night_light_brightness"] > 0
KeyError: 'night_light_brightness'
2022-04-01 12:28:39 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:40 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:40 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:41 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:28:42 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:07 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Running websocket_api script
2022-04-01 12:29:07 INFO (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Executing step call service
2022-04-01 12:29:07 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v1/deviceManaged/devices' api
2022-04-01 12:29:08 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:09 INFO (MainThread) [custom_components.vesync.common] 1 VeSync fans found
2022-04-01 12:29:09 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:09 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:10 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:11 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:12 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:39 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:40 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:41 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:29:42 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:09 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:09 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:10 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:10 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:11 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:12 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:39 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:40 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:41 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:30:42 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:09 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:09 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:10 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:12 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:39 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:40 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:40 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:41 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:31:42 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:09 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:09 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:10 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:11 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:12 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:39 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:41 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:32:41 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:09 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:09 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:10 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:12 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:39 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:40 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:40 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:41 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:33:42 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:09 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:09 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:10 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:11 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:39 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:40 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:41 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:34:42 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:09 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:09 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:10 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:12 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:39 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:40 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:41 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:35:41 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:09 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:09 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:10 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:11 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:12 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:39 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:40 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:40 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:41 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:36:42 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:09 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:09 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:10 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:12 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:39 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:41 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:37:42 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:09 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:09 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:10 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:11 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:39 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:41 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:41 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:38:41 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:09 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:09 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:10 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:10 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:11 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:12 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:39 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:40 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:40 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:41 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:41 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:39:42 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:09 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:09 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:10 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:11 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:11 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:12 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:39 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:40 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:40 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:40 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:40 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:40 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:41 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:40:41 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:09 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:09 DEBUG (SyncWorker_2) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:10 DEBUG (SyncWorker_0) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:10 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:10 DEBUG (SyncWorker_6) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:10 DEBUG (SyncWorker_4) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:10 DEBUG (SyncWorker_3) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:11 DEBUG (SyncWorker_1) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api
2022-04-01 12:41:11 DEBUG (SyncWorker_5) [custom_components.vesync.pyvesync.helpers] [post] calling '/cloud/v2/deviceManaged/bypassV2' api

BIN
Config/home-assistant_v2.db Normal file

Binary file not shown.

0
Config/scenes.yaml Normal file
View File

0
Config/scripts.yaml Normal file
View File

4
Config/secrets.yaml Normal file
View File

@ -0,0 +1,4 @@
# Use this file to store secrets like usernames and passwords.
# Learn more at https://www.home-assistant.io/docs/configuration/secrets/
some_password: welcome

36
README.md Normal file
View File

@ -0,0 +1,36 @@
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg)](https://github.com/custom-components/hacs)
[![GitHub release](https://img.shields.io/github/release/iMicknl/ha-tahoma.svg)](https://GitHub.com/vlebourl/vesync-bpo/releases/)
# VeSync custom component for Home Assistant
Custom component for Home Assistant to interact with smart devices via the VeSync platform.
## Installation
You can install this integration via [HACS](#hacs) or [manually](#manual).
This integration will override the core VeSync integration.
### HACS
This integration can be installed by adding this repository to HACS, then searching for `VeSync` and choosing install. Reboot Home Assistant and configure the 'VeSync' integration via the integrations page or press the blue button below.
[![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=vesync)
### Manual
Copy the `custom_components/vesync` to your `custom_components` folder. Reboot Home Assistant and configure the 'Overkiz (by Somfy)' integration via the integrations page or press the blue button below.
[![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=vesync)
### Enable debug logging
The [logger](https://www.home-assistant.io/integrations/logger/) integration lets you define the level of logging activities in Home Assistant. Turning on debug mode will show more information about unsupported devices in your logbook.
```yaml
logger:
default: error
logs:
custom_components.vesync: debug
```
This integration is heavily based on [VeSync_bpo](https://github.com/borpin/vesync-bpo) and [pyvesync](https://pypi.org/project/pyvesync/)

View File

@ -0,0 +1,106 @@
"""VeSync integration."""
import logging
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_send
from .common import async_process_devices
from .const import (
DOMAIN,
SERVICE_UPDATE_DEVS,
VS_BINARY_SENSORS,
VS_DISCOVERY,
VS_FANS,
VS_HUMIDIFIERS,
VS_LIGHTS,
VS_MANAGER,
VS_NUMBERS,
VS_SENSORS,
VS_SWITCHES,
)
from .pyvesync.vesync import VeSync
PLATFORMS = {
Platform.SWITCH: VS_SWITCHES,
Platform.FAN: VS_FANS,
Platform.LIGHT: VS_LIGHTS,
Platform.SENSOR: VS_SENSORS,
Platform.HUMIDIFIER: VS_HUMIDIFIERS,
Platform.NUMBER: VS_NUMBERS,
Platform.BINARY_SENSOR: VS_BINARY_SENSORS,
}
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
"""Set up Vesync as config entry."""
username = config_entry.data[CONF_USERNAME]
password = config_entry.data[CONF_PASSWORD]
time_zone = str(hass.config.time_zone)
manager = VeSync(username, password, time_zone)
login = await hass.async_add_executor_job(manager.login)
if not login:
_LOGGER.error("Unable to login to the VeSync server")
return False
device_dict = await async_process_devices(hass, manager)
forward_setup = hass.config_entries.async_forward_entry_setup
hass.data[DOMAIN] = {config_entry.entry_id: {}}
hass.data[DOMAIN][config_entry.entry_id][VS_MANAGER] = manager
for p, vs_p in PLATFORMS.items():
hass.data[DOMAIN][config_entry.entry_id][vs_p] = []
if device_dict[VS_SWITCHES]:
hass.data[DOMAIN][config_entry.entry_id][vs_p].extend(device_dict[vs_p])
hass.async_create_task(forward_setup(config_entry, p))
async def async_new_device_discovery(service: ServiceCall) -> None:
"""Discover if new devices should be added."""
manager = hass.data[DOMAIN][config_entry.entry_id][VS_MANAGER]
dev_dict = await async_process_devices(hass, manager)
def _add_new_devices(platform: str) -> None:
"""Add new devices to hass."""
old_devices = hass.data[DOMAIN][config_entry.entry_id][PLATFORMS[platform]]
if new_devices := list(
set(dev_dict.get(VS_SWITCHES, [])).difference(old_devices)
):
old_devices.extend(new_devices)
if old_devices:
async_dispatcher_send(
hass, VS_DISCOVERY.format(PLATFORMS[platform]), new_devices
)
else:
hass.async_create_task(forward_setup(config_entry, platform))
for k, v in PLATFORMS.items():
_add_new_devices(k)
hass.services.async_register(
DOMAIN, SERVICE_UPDATE_DEVS, async_new_device_discovery
)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(
entry, list(PLATFORMS.keys())
)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok

View File

@ -0,0 +1,103 @@
"""Support for power & energy sensors for VeSync outlets."""
import logging
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncBaseEntity, is_humidifier
from .const import DOMAIN, VS_BINARY_SENSORS, VS_DISCOVERY
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up binary sensors."""
@callback
def discover(devices):
"""Add new devices to platform."""
_setup_entities(devices, async_add_entities)
config_entry.async_on_unload(
async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_BINARY_SENSORS), discover)
)
_setup_entities(
hass.data[DOMAIN][config_entry.entry_id][VS_BINARY_SENSORS], async_add_entities
)
@callback
def _setup_entities(devices, async_add_entities):
"""Check if device is online and add entity."""
entities = []
for dev in devices:
if is_humidifier(dev.device_type):
entities.append(VeSyncOutOfWaterSensor(dev))
entities.append(VeSyncWaterTankLiftedSensor(dev))
else:
_LOGGER.warning(
"%s - Unknown device type - %s", dev.device_name, dev.device_type
)
async_add_entities(entities, update_before_add=True)
class VeSyncHumidifierBinarySensorEntity(VeSyncBaseEntity, BinarySensorEntity):
"""Representation of a binary sensor describing diagnostics of a VeSync humidifier."""
def __init__(self, humidifier):
"""Initialize the VeSync humidifier device."""
super().__init__(humidifier)
self.smarthumidifier = humidifier
@property
def entity_category(self):
"""Return the diagnostic entity category."""
return EntityCategory.DIAGNOSTIC
class VeSyncOutOfWaterSensor(VeSyncHumidifierBinarySensorEntity):
"""Out of Water Sensor."""
@property
def unique_id(self):
"""Return unique ID for out of water sensor on device."""
return f"{super().unique_id}-out_of_water"
@property
def name(self):
"""Return sensor name."""
return f"{super().name} out of water"
@property
def is_on(self) -> bool:
"""Return a value indicating whether the Humidifier is out of water."""
return self.smarthumidifier.details["water_lacks"]
class VeSyncWaterTankLiftedSensor(VeSyncHumidifierBinarySensorEntity):
"""Tank Lifted Sensor."""
@property
def unique_id(self):
"""Return unique ID for water tank lifted sensor on device."""
return f"{super().unique_id}-water_tank_lifted"
@property
def name(self):
"""Return sensor name."""
return f"{super().name} water tank lifted"
@property
def is_on(self) -> bool:
"""Return a value indicating whether the Humidifier's water tank is lifted."""
return self.smarthumidifier.details["water_tank_lifted"]

View File

@ -0,0 +1,140 @@
"""Common utilities for VeSync Component."""
import logging
from homeassistant.helpers.entity import Entity, ToggleEntity
from .const import (
DOMAIN,
VS_BINARY_SENSORS,
VS_FANS,
VS_HUMIDIFIERS,
VS_LIGHTS,
VS_NUMBERS,
VS_SENSORS,
VS_SWITCHES,
)
from .pyvesync.vesyncfan import model_features
_LOGGER = logging.getLogger(__name__)
def is_humidifier(device_type: str) -> bool:
"""Return true if the device type is a humidifier."""
return model_features(device_type)["module"].find("VeSyncHumid") > -1
async def async_process_devices(hass, manager):
"""Assign devices to proper component."""
devices = {
VS_SWITCHES: [],
VS_FANS: [],
VS_LIGHTS: [],
VS_SENSORS: [],
VS_HUMIDIFIERS: [],
VS_NUMBERS: [],
VS_BINARY_SENSORS: [],
}
await hass.async_add_executor_job(manager.update)
if manager.fans:
for fan in manager.fans:
# VeSync classifies humidifiers as fans
if is_humidifier(fan.device_type):
devices[VS_HUMIDIFIERS].append(fan)
devices[VS_NUMBERS].append(fan) # for night light and mist level
devices[VS_SWITCHES].append(fan) # for automatic stop and display
devices[VS_SENSORS].append(fan) # for humidity sensor
devices[VS_BINARY_SENSORS].append(
fan
) # for out of water and water tank lifted sensors
if fan.night_light:
devices[VS_LIGHTS].append(fan) # for night light
else:
devices[VS_FANS].append(fan)
_LOGGER.info("%d VeSync fans found", len(manager.fans))
if manager.bulbs:
devices[VS_LIGHTS].extend(manager.bulbs)
_LOGGER.info("%d VeSync lights found", len(manager.bulbs))
if manager.outlets:
devices[VS_SWITCHES].extend(manager.outlets)
# Expose outlets' power & energy usage as separate sensors
devices[VS_SENSORS].extend(manager.outlets)
_LOGGER.info("%d VeSync outlets found", len(manager.outlets))
if manager.switches:
for switch in manager.switches:
if not switch.is_dimmable():
devices[VS_SWITCHES].append(switch)
else:
devices[VS_LIGHTS].append(switch)
_LOGGER.info("%d VeSync switches found", len(manager.switches))
return devices
class VeSyncBaseEntity(Entity):
"""Base class for VeSync Entity Representations."""
def __init__(self, device):
"""Initialize the VeSync device."""
self.device = device
@property
def base_unique_id(self):
"""Return the ID of this device."""
if isinstance(self.device.sub_device_no, int):
return f"{self.device.cid}{str(self.device.sub_device_no)}"
return self.device.cid
@property
def unique_id(self):
"""Return the ID of this device."""
# The unique_id property may be overridden in subclasses, such as in sensors. Maintaining base_unique_id allows
# us to group related entities under a single device.
return self.base_unique_id
@property
def base_name(self):
"""Return the name of the device."""
return self.device.device_name
@property
def name(self):
"""Return the name of the entity (may be overridden)."""
return self.base_name
@property
def available(self) -> bool:
"""Return True if device is available."""
return self.device.connection_status == "online"
@property
def device_info(self):
"""Return device information."""
return {
"identifiers": {(DOMAIN, self.base_unique_id)},
"name": self.base_name,
"model": self.device.device_type,
"default_manufacturer": "VeSync",
"sw_version": self.device.current_firm_version,
}
def update(self):
"""Update vesync device."""
self.device.update()
class VeSyncDevice(VeSyncBaseEntity, ToggleEntity):
"""Base class for VeSync Device Representations."""
@property
def is_on(self):
"""Return True if device is on."""
return self.device.device_status == "on"
def turn_off(self, **kwargs):
"""Turn the device off."""
self.device.turn_off()

View File

@ -0,0 +1,58 @@
"""Config flow utilities."""
from collections import OrderedDict
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import callback
from .const import DOMAIN
from .pyvesync.vesync import VeSync
class VeSyncFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow."""
VERSION = 1
def __init__(self):
"""Instantiate config flow."""
self._username = None
self._password = None
self.data_schema = OrderedDict()
self.data_schema[vol.Required(CONF_USERNAME)] = str
self.data_schema[vol.Required(CONF_PASSWORD)] = str
@callback
def _show_form(self, errors=None):
"""Show form to the user."""
return self.async_show_form(
step_id="user",
data_schema=vol.Schema(self.data_schema),
errors=errors or {},
)
async def async_step_user(self, user_input=None):
"""Handle a flow start."""
if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")
if not user_input:
return self._show_form()
self._username = user_input[CONF_USERNAME]
self._password = user_input[CONF_PASSWORD]
manager = VeSync(self._username, self._password)
login = await self.hass.async_add_executor_job(manager.login)
await self.async_set_unique_id(f"{self._username}-{manager.account_id}")
self._abort_if_unique_id_configured()
if not login:
return self._show_form(errors={"base": "invalid_auth"})
return self.async_create_entry(
title=self._username,
data={CONF_USERNAME: self._username, CONF_PASSWORD: self._password},
)

View File

@ -0,0 +1,33 @@
"""Constants for VeSync Component."""
DOMAIN = "vesync"
VS_DISCOVERY = "vesync_discovery_{}"
SERVICE_UPDATE_DEVS = "update_devices"
VS_SWITCHES = "switches"
VS_FANS = "fans"
VS_LIGHTS = "lights"
VS_SENSORS = "sensors"
VS_HUMIDIFIERS = "humidifiers"
VS_NUMBERS = "numbers"
VS_BINARY_SENSORS = "binary_sensors"
VS_MANAGER = "manager"
DEV_TYPE_TO_HA = {
"LV-PUR131S": "fan",
"Core200S": "fan",
"Core300S": "fan",
"Core400S": "fan",
"Classic300S": "humidifier",
"ESD16": "walldimmer",
"ESWD16": "walldimmer",
"ESL100": "bulb-dimmable",
"ESL100CW": "bulb-tunable-white",
"wifi-switch-1.3": "outlet",
"ESW03-USA": "outlet",
"ESW01-EU": "outlet",
"ESW15-USA": "outlet",
"ESWL01": "switch",
"ESWL03": "switch",
"ESO15-TB": "outlet",
}

View File

@ -0,0 +1,188 @@
"""Support for VeSync fans."""
import logging
import math
from homeassistant.components.fan import SUPPORT_SET_SPEED, FanEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.percentage import (
int_states_in_range,
percentage_to_ranged_value,
ranged_value_to_percentage,
)
from .common import VeSyncDevice
from .const import DEV_TYPE_TO_HA, DOMAIN, VS_DISCOVERY, VS_FANS
_LOGGER = logging.getLogger(__name__)
FAN_MODE_AUTO = "auto"
FAN_MODE_SLEEP = "sleep"
# Fixme add other models
PRESET_MODES = {
"Core200S": [FAN_MODE_SLEEP],
"Core300S": [FAN_MODE_AUTO, FAN_MODE_SLEEP],
"Core400S": [FAN_MODE_AUTO, FAN_MODE_SLEEP],
"LV-PUR131S": [FAN_MODE_AUTO, FAN_MODE_SLEEP],
}
SPEED_RANGE = (1, 3) # off is not included
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the VeSync fan platform."""
@callback
def discover(devices):
"""Add new devices to platform."""
_setup_entities(devices, async_add_entities)
config_entry.async_on_unload(
async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_FANS), discover)
)
_setup_entities(
hass.data[DOMAIN][config_entry.entry_id][VS_FANS], async_add_entities
)
@callback
def _setup_entities(devices, async_add_entities):
"""Check if device is online and add entity."""
entities = []
for dev in devices:
if DEV_TYPE_TO_HA.get(dev.device_type) == "fan":
entities.append(VeSyncFanHA(dev))
else:
_LOGGER.warning(
"%s - Unknown device type - %s", dev.device_name, dev.device_type
)
continue
async_add_entities(entities, update_before_add=True)
class VeSyncFanHA(VeSyncDevice, FanEntity):
"""Representation of a VeSync fan."""
def __init__(self, fan):
"""Initialize the VeSync fan device."""
super().__init__(fan)
self.smartfan = fan
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_SET_SPEED
@property
def percentage(self):
"""Return the current speed."""
if (
self.smartfan.mode == "manual"
and (current_level := self.smartfan.fan_level) is not None
):
return ranged_value_to_percentage(SPEED_RANGE, current_level)
return None
@property
def speed_count(self) -> int:
"""Return the number of speeds the fan supports."""
return int_states_in_range(SPEED_RANGE)
@property
def preset_modes(self):
"""Get the list of available preset modes."""
return PRESET_MODES[self.device.device_type]
@property
def preset_mode(self):
"""Get the current preset mode."""
if self.smartfan.mode in (FAN_MODE_AUTO, FAN_MODE_SLEEP):
return self.smartfan.mode
return None
@property
def unique_info(self):
"""Return the ID of this fan."""
return self.smartfan.uuid
@property
def extra_state_attributes(self):
"""Return the state attributes of the fan."""
attr = {}
if hasattr(self.smartfan, "active_time"):
attr["active_time"] = self.smartfan.active_time
if hasattr(self.smartfan, "screen_status"):
attr["screen_status"] = self.smartfan.screen_status
if hasattr(self.smartfan, "child_lock"):
attr["child_lock"] = self.smartfan.child_lock
if hasattr(self.smartfan, "night_light"):
attr["night_light"] = self.smartfan.night_light
if hasattr(self.smartfan, "air_quality"):
attr["air_quality"] = self.smartfan.air_quality
if hasattr(self.smartfan, "mode"):
attr["mode"] = self.smartfan.mode
if hasattr(self.smartfan, "filter_life"):
attr["filter_life"] = self.smartfan.filter_life
return attr
def set_percentage(self, percentage):
"""Set the speed of the device."""
if percentage == 0:
self.smartfan.turn_off()
return
if not self.smartfan.is_on:
self.smartfan.turn_on()
self.smartfan.manual_mode()
self.smartfan.change_fan_speed(
math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
)
self.schedule_update_ha_state()
def set_preset_mode(self, preset_mode):
"""Set the preset mode of device."""
if preset_mode not in self.preset_modes:
raise ValueError(
"{preset_mode} is not one of the valid preset modes: {self.preset_modes}"
)
if not self.smartfan.is_on:
self.smartfan.turn_on()
if preset_mode == FAN_MODE_AUTO:
self.smartfan.auto_mode()
elif preset_mode == FAN_MODE_SLEEP:
self.smartfan.sleep_mode()
self.schedule_update_ha_state()
def turn_on(
self,
speed: str = None,
percentage: int = None,
preset_mode: str = None,
**kwargs,
) -> None:
"""Turn the device on."""
if preset_mode:
self.set_preset_mode(preset_mode)
return
if percentage is None:
percentage = 50
self.set_percentage(percentage)

View File

@ -0,0 +1,154 @@
"""Support for VeSync humidifiers."""
import logging
from homeassistant.components.humidifier import HumidifierEntity
from homeassistant.components.humidifier.const import SUPPORT_MODES
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncDevice, is_humidifier
from .const import DOMAIN, VS_DISCOVERY, VS_HUMIDIFIERS
_LOGGER = logging.getLogger(__name__)
MAX_HUMIDITY = 80
MIN_HUMIDITY = 30
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the VeSync humidifier platform."""
@callback
def discover(devices):
"""Add new devices to platform."""
_setup_entities(devices, async_add_entities)
config_entry.async_on_unload(
async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_HUMIDIFIERS), discover)
)
_setup_entities(
hass.data[DOMAIN][config_entry.entry_id][VS_HUMIDIFIERS], async_add_entities
)
@callback
def _setup_entities(devices, async_add_entities):
"""Check if device is online and add entity."""
entities = []
for dev in devices:
if is_humidifier(dev.device_type):
entities.append(VeSyncHumidifierHA(dev))
else:
_LOGGER.warning(
"%s - Unknown device type - %s", dev.device_name, dev.device_type
)
continue
async_add_entities(entities, update_before_add=True)
class VeSyncHumidifierHA(VeSyncDevice, HumidifierEntity):
"""Representation of a VeSync humidifier."""
_attr_max_humidity = MAX_HUMIDITY
_attr_min_humidity = MIN_HUMIDITY
def __init__(self, humidifier):
"""Initialize the VeSync humidifier device."""
super().__init__(humidifier)
self.smarthumidifier = humidifier
@property
def available_modes(self):
"""Return the available mist modes."""
return self.device.config_dict["mist_modes"]
@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_MODES
@property
def target_humidity(self):
"""Return the humidity we try to reach."""
return self.smarthumidifier.config["auto_target_humidity"]
@property
def mode(self):
"""Get the current preset mode."""
if self.smarthumidifier.details["mode"] in self.available_modes:
return self.smarthumidifier.details["mode"]
return None
@property
def is_on(self):
"""Return True if humidifier is on."""
return self.smarthumidifier.enabled # device_status is always on
@property
def unique_info(self):
"""Return the ID of this humidifier."""
return self.smarthumidifier.uuid
@property
def extra_state_attributes(self):
"""Return the state attributes of the humidifier."""
attr = {}
if "water_lacks" in self.smarthumidifier.details:
attr["water_lacks"] = self.smarthumidifier.details["water_lacks"]
if "humidity_high" in self.smarthumidifier.details:
attr["humidity_high"] = self.smarthumidifier.details["humidity_high"]
if "water_tank_lifted" in self.smarthumidifier.details:
attr["water_tank_lifted"] = self.smarthumidifier.details[
"water_tank_lifted"
]
if "automatic_stop_reach_target" in self.smarthumidifier.details:
attr["automatic_stop_reach_target"] = self.smarthumidifier.details[
"automatic_stop_reach_target"
]
if "mist_level" in self.smarthumidifier.details:
attr["mist_level"] = self.smarthumidifier.details["mist_level"]
return attr
def set_humidity(self, humidity):
"""Set the target humidity of the device."""
if humidity not in range(self.min_humidity, self.max_humidity + 1):
raise ValueError(
"{humidity} is not between {self.min_humidity} and {self.max_humidity} (inclusive)"
)
self.smarthumidifier.set_humidity(humidity)
self.schedule_update_ha_state()
def set_mode(self, mode):
"""Set the mode of the device."""
if mode not in self.available_modes:
raise ValueError(
"{mode} is not one of the valid available modes: {self.available_modes}"
)
if mode == "manual":
self.smarthumidifier.set_mist_level(
self.smarthumidifier.details["mist_level"]
)
else:
self.smarthumidifier.set_humidity_mode(mode)
self.schedule_update_ha_state()
def turn_on(
self,
**kwargs,
) -> None:
"""Turn the device on."""
self.smarthumidifier.turn_on()

View File

@ -0,0 +1,251 @@
"""Support for VeSync bulbs and wall dimmers."""
import logging
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
COLOR_MODE_BRIGHTNESS,
COLOR_MODE_COLOR_TEMP,
LightEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncDevice, is_humidifier
from .const import DEV_TYPE_TO_HA, DOMAIN, VS_DISCOVERY, VS_LIGHTS
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up lights."""
@callback
def discover(devices):
"""Add new devices to platform."""
_setup_entities(devices, async_add_entities)
config_entry.async_on_unload(
async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_LIGHTS), discover)
)
_setup_entities(
hass.data[DOMAIN][config_entry.entry_id][VS_LIGHTS], async_add_entities
)
@callback
def _setup_entities(devices, async_add_entities):
"""Check if device is online and add entity."""
entities = []
for dev in devices:
if DEV_TYPE_TO_HA.get(dev.device_type) in ("walldimmer", "bulb-dimmable"):
entities.append(VeSyncDimmableLightHA(dev))
elif DEV_TYPE_TO_HA.get(dev.device_type) in ("bulb-tunable-white",):
entities.append(VeSyncTunableWhiteLightHA(dev))
elif is_humidifier(dev.device_type):
entities.append(VeSyncHumidifierNightLightHA(dev))
else:
_LOGGER.debug(
"%s - Unknown device type - %s", dev.device_name, dev.device_type
)
continue
async_add_entities(entities, update_before_add=True)
def _vesync_brightness_to_ha(vesync_brightness):
try:
# check for validity of brightness value received
brightness_value = int(vesync_brightness)
except ValueError:
# deal if any unexpected/non numeric value
_LOGGER.debug(
"VeSync - received unexpected 'brightness' value from pyvesync api: %s",
vesync_brightness,
)
return 0
# convert percent brightness to ha expected range
return round((max(1, brightness_value) / 100) * 255)
def _ha_brightness_to_vesync(ha_brightness):
# get brightness from HA data
brightness = int(ha_brightness)
# ensure value between 1-255
brightness = max(1, min(brightness, 255))
# convert to percent that vesync api expects
brightness = round((brightness / 255) * 100)
# ensure value between 1-100
brightness = max(1, min(brightness, 100))
return brightness
class VeSyncBaseLight(VeSyncDevice, LightEntity):
"""Base class for VeSync Light Devices Representations."""
@property
def brightness(self):
"""Get light brightness."""
# get value from pyvesync library api,
return _vesync_brightness_to_ha(self.device.brightness)
def turn_on(self, **kwargs):
"""Turn the device on."""
attribute_adjustment_only = False
# set white temperature
if self.color_mode in (COLOR_MODE_COLOR_TEMP,) and ATTR_COLOR_TEMP in kwargs:
# get white temperature from HA data
color_temp = int(kwargs[ATTR_COLOR_TEMP])
# ensure value between min-max supported Mireds
color_temp = max(self.min_mireds, min(color_temp, self.max_mireds))
# convert Mireds to Percent value that api expects
color_temp = round(
((color_temp - self.min_mireds) / (self.max_mireds - self.min_mireds))
* 100
)
# flip cold/warm to what pyvesync api expects
color_temp = 100 - color_temp
# ensure value between 0-100
color_temp = max(0, min(color_temp, 100))
# call pyvesync library api method to set color_temp
self.device.set_color_temp(color_temp)
# flag attribute_adjustment_only, so it doesn't turn_on the device redundantly
attribute_adjustment_only = True
# set brightness level
if (
self.color_mode in (COLOR_MODE_BRIGHTNESS, COLOR_MODE_COLOR_TEMP)
and ATTR_BRIGHTNESS in kwargs
):
# get brightness from HA data
brightness = _ha_brightness_to_vesync(kwargs[ATTR_BRIGHTNESS])
self.device.set_brightness(brightness)
# flag attribute_adjustment_only, so it doesn't turn_on the device redundantly
attribute_adjustment_only = True
# check flag if should skip sending the turn_on command
if attribute_adjustment_only:
return
# send turn_on command to pyvesync api
self.device.turn_on()
class VeSyncDimmableLightHA(VeSyncBaseLight, LightEntity):
"""Representation of a VeSync dimmable light device."""
@property
def color_mode(self):
"""Set color mode for this entity."""
return COLOR_MODE_BRIGHTNESS
@property
def supported_color_modes(self):
"""Flag supported color_modes (in an array format)."""
return [COLOR_MODE_BRIGHTNESS]
class VeSyncTunableWhiteLightHA(VeSyncBaseLight, LightEntity):
"""Representation of a VeSync Tunable White Light device."""
@property
def color_temp(self):
"""Get device white temperature."""
# get value from pyvesync library api,
result = self.device.color_temp_pct
try:
# check for validity of brightness value received
color_temp_value = int(result)
except ValueError:
# deal if any unexpected/non numeric value
_LOGGER.debug(
"VeSync - received unexpected 'color_temp_pct' value from pyvesync api: %s",
result,
)
return 0
# flip cold/warm
color_temp_value = 100 - color_temp_value
# ensure value between 0-100
color_temp_value = max(0, min(color_temp_value, 100))
# convert percent value to Mireds
color_temp_value = round(
self.min_mireds
+ ((self.max_mireds - self.min_mireds) / 100 * color_temp_value)
)
# ensure value between minimum and maximum Mireds
return max(self.min_mireds, min(color_temp_value, self.max_mireds))
@property
def min_mireds(self):
"""Set device coldest white temperature."""
return 154 # 154 Mireds ( 1,000,000 divided by 6500 Kelvin = 154 Mireds)
@property
def max_mireds(self):
"""Set device warmest white temperature."""
return 370 # 370 Mireds ( 1,000,000 divided by 2700 Kelvin = 370 Mireds)
@property
def color_mode(self):
"""Set color mode for this entity."""
return COLOR_MODE_COLOR_TEMP
@property
def supported_color_modes(self):
"""Flag supported color_modes (in an array format)."""
return [COLOR_MODE_COLOR_TEMP]
class VeSyncHumidifierNightLightHA(VeSyncDimmableLightHA):
"""Representation of the night light on a VeSync humidifier."""
def __init__(self, humidifier):
"""Initialize the VeSync humidifier device."""
super().__init__(humidifier)
self.smarthumidifier = humidifier
@property
def unique_id(self):
"""Return the ID of this device."""
return f"{super().unique_id}-night-light"
@property
def name(self):
"""Return the name of the device."""
return f"{super().name} night light"
@property
def brightness(self):
"""Get night light brightness."""
# get value from pyvesync library api,
return _vesync_brightness_to_ha(
self.smarthumidifier.details["night_light_brightness"]
)
@property
def is_on(self):
"""Return True if night light is on."""
return self.smarthumidifier.details["night_light_brightness"] > 0
@property
def entity_category(self):
"""Return the configuration entity category."""
return EntityCategory.CONFIG
def turn_on(self, **kwargs):
"""Turn the night light on."""
if ATTR_BRIGHTNESS in kwargs:
brightness = _ha_brightness_to_vesync(kwargs[ATTR_BRIGHTNESS])
self.smarthumidifier.set_night_light_brightness(brightness)
else:
self.smarthumidifier.set_night_light_brightness(100)
def turn_off(self, **kwargs):
"""Turn the night light off."""
self.smarthumidifier.set_night_light_brightness(0)

View File

@ -0,0 +1,10 @@
{
"domain": "vesync",
"name": "VeSync",
"documentation": "https://www.home-assistant.io/integrations/vesync",
"codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey"],
"config_flow": true,
"iot_class": "cloud_polling",
"version": "0.1.2",
"issue_tracker": "https://github.com/vlebourl/vesync-bpo"
}

View File

@ -0,0 +1,155 @@
"""Support for number settings on VeSync devices."""
import logging
from homeassistant.components.number import NumberEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncBaseEntity, is_humidifier
from .const import DOMAIN, VS_DISCOVERY, VS_NUMBERS
MAX_HUMIDITY = 80
MIN_HUMIDITY = 30
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up numbers."""
@callback
def discover(devices):
"""Add new devices to platform."""
_setup_entities(devices, async_add_entities)
config_entry.async_on_unload(
async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_NUMBERS), discover)
)
_setup_entities(
hass.data[DOMAIN][config_entry.entry_id][VS_NUMBERS], async_add_entities
)
@callback
def _setup_entities(devices, async_add_entities):
"""Check if device is online and add entity."""
entities = []
for dev in devices:
if is_humidifier(dev.device_type):
entities.extend(
(
VeSyncHumidifierMistLevelHA(dev),
VeSyncHumidifierTargetLevelHA(dev),
)
)
else:
_LOGGER.debug(
"%s - Unknown device type - %s", dev.device_name, dev.device_type
)
continue
async_add_entities(entities, update_before_add=True)
class VeSyncHumidifierNumberEntity(VeSyncBaseEntity, NumberEntity):
"""Representation of a number for configuring a VeSync humidifier."""
def __init__(self, humidifier):
"""Initialize the VeSync humidifier device."""
super().__init__(humidifier)
self.smarthumidifier = humidifier
@property
def entity_category(self):
"""Return the diagnostic entity category."""
return EntityCategory.CONFIG
class VeSyncHumidifierMistLevelHA(VeSyncHumidifierNumberEntity):
"""Representation of the mist level of a VeSync humidifier."""
@property
def unique_id(self):
"""Return the ID of this device."""
return f"{super().unique_id}-mist-level"
@property
def name(self):
"""Return the name of the device."""
return f"{super().name} mist level"
@property
def value(self):
"""Return the mist level."""
return self.device.details["mist_virtual_level"]
@property
def min_value(self) -> float:
"""Return the minimum mist level."""
return self.device.config_dict["mist_levels"][0]
@property
def max_value(self) -> float:
"""Return the maximum mist level."""
return self.device.config_dict["mist_levels"][-1]
@property
def step(self) -> float:
"""Return the steps for the mist level."""
return 1.0
@property
def extra_state_attributes(self):
"""Return the state attributes of the humidifier."""
return {"mist levels": self.device.config_dict["mist_levels"]}
def set_value(self, value):
"""Set the mist level."""
self.device.set_mist_level(int(value))
class VeSyncHumidifierTargetLevelHA(VeSyncHumidifierNumberEntity):
"""Representation of the target humidity level of a VeSync humidifier."""
@property
def unique_id(self):
"""Return the ID of this device."""
return f"{super().unique_id}-target-level"
@property
def name(self):
"""Return the name of the device."""
return f"{super().name} target level"
@property
def value(self):
"""Return the current target humidity level."""
return self.device.config["auto_target_humidity"]
@property
def min_value(self) -> float:
"""Return the minimum humidity level."""
return MIN_HUMIDITY
@property
def max_value(self) -> float:
"""Return the maximum humidity level."""
return MAX_HUMIDITY
@property
def step(self) -> float:
"""Return the humidity change step."""
return 1.0
def set_value(self, value):
"""Set the target humidity level."""
self.device.set_humidity(int(value))

View File

@ -0,0 +1,6 @@
"""VeSync API Library."""
import logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)5s - %(message)s"
)

View File

@ -0,0 +1,241 @@
"""Helper functions for VeSync API."""
import hashlib
import logging
import time
import requests
logger = logging.getLogger(__name__)
API_BASE_URL = "https://smartapi.vesync.com"
API_RATE_LIMIT = 30
API_TIMEOUT = 5
DEFAULT_TZ = "America/New_York"
DEFAULT_REGION = "US"
APP_VERSION = "2.8.6"
PHONE_BRAND = "SM N9005"
PHONE_OS = "Android"
MOBILE_ID = "1234567890123456"
USER_TYPE = "1"
BYPASS_APP_V = "VeSync 3.0.51"
class Helpers:
"""VeSync Helper Functions."""
@staticmethod
def req_headers(manager) -> dict:
"""Build header for api requests."""
return {
"accept-language": "en",
"accountId": manager.account_id,
"appVersion": APP_VERSION,
"content-type": "application/json",
"tk": manager.token,
"tz": manager.time_zone,
}
@staticmethod
def req_body_base(manager) -> dict:
"""Return universal keys for body of api requests."""
return {"timeZone": manager.time_zone, "acceptLanguage": "en"}
@staticmethod
def req_body_auth(manager) -> dict:
"""Keys for authenticating api requests."""
return {"accountID": manager.account_id, "token": manager.token}
@staticmethod
def req_body_details() -> dict:
"""Detail keys for api requests."""
return {
"appVersion": APP_VERSION,
"phoneBrand": PHONE_BRAND,
"phoneOS": PHONE_OS,
"traceId": str(int(time.time())),
}
@classmethod
def req_body(cls, manager, type_) -> dict:
"""Builder for body of api requests."""
body = {}
if type_ == "login":
body = {**cls.req_body_base(manager), **cls.req_body_details()}
body["email"] = manager.username
body["password"] = cls.hash_password(manager.password)
body["devToken"] = ""
body["userType"] = USER_TYPE
body["method"] = "login"
elif type_ == "devicedetail":
body = {
**cls.req_body_base(manager),
**cls.req_body_auth(manager),
**cls.req_body_details(),
}
body["method"] = "devicedetail"
body["mobileId"] = MOBILE_ID
elif type_ == "devicelist":
body = {
**cls.req_body_base(manager),
**cls.req_body_auth(manager),
**cls.req_body_details(),
}
body["method"] = "devices"
body["pageNo"] = "1"
body["pageSize"] = "100"
elif type_ == "devicestatus":
body = {**cls.req_body_base(manager), **cls.req_body_auth(manager)}
elif type_ == "energy_week":
body = {
**cls.req_body_base(manager),
**cls.req_body_auth(manager),
**cls.req_body_details(),
}
body["method"] = "energyweek"
body["mobileId"] = MOBILE_ID
elif type_ == "energy_month":
body = {
**cls.req_body_base(manager),
**cls.req_body_auth(manager),
**cls.req_body_details(),
}
body["method"] = "energymonth"
body["mobileId"] = MOBILE_ID
elif type_ == "energy_year":
body = {
**cls.req_body_base(manager),
**cls.req_body_auth(manager),
**cls.req_body_details(),
}
body["method"] = "energyyear"
body["mobileId"] = MOBILE_ID
elif type_ == "bypass":
body = {
**cls.req_body_base(manager),
**cls.req_body_auth(manager),
**cls.req_body_details(),
}
body["method"] = "bypass"
elif type_ == "bypass_config":
body = {
**cls.req_body_base(manager),
**cls.req_body_auth(manager),
**cls.req_body_details(),
}
body["method"] = "firmwareUpdateInfo"
return body
@staticmethod
def calculate_hex(hex_string) -> float:
"""Credit for conversion to itsnotlupus/vesync_wsproxy."""
hex_conv = hex_string.split(":")
return (int(hex_conv[0], 16) + int(hex_conv[1], 16)) / 8192
@staticmethod
def hash_password(string) -> str:
"""Encode password."""
return hashlib.md5(string.encode("utf-8")).hexdigest()
@staticmethod
def call_api(
api: str, method: str, json: dict = None, headers: dict = None
) -> tuple:
"""Make API calls by passing endpoint, header and body."""
response = None
status_code = None
try:
logger.debug("[%s] calling '%s' api", method, api)
if method.lower() == "get":
r = requests.get(
API_BASE_URL + api, json=json, headers=headers, timeout=API_TIMEOUT
)
elif method.lower() == "post":
r = requests.post(
API_BASE_URL + api, json=json, headers=headers, timeout=API_TIMEOUT
)
elif method.lower() == "put":
r = requests.put(
API_BASE_URL + api, json=json, headers=headers, timeout=API_TIMEOUT
)
except requests.exceptions.RequestException as e:
logger.debug(e)
except Exception as e:
logger.debug(e)
else:
if r.status_code == 200:
status_code = 200
if r.content:
response = r.json()
else:
logger.debug("Unable to fetch %s%s", API_BASE_URL, api)
return response, status_code
@staticmethod
def code_check(r: dict) -> bool:
"""Test if code == 0 for successful API call."""
return isinstance(r, dict) and r.get("code") == 0
@staticmethod
def build_details_dict(r: dict) -> dict:
"""Build details dictionary from API response."""
return {
"active_time": r.get("activeTime", 0),
"energy": r.get("energy", 0),
"night_light_status": r.get("nightLightStatus", None),
"night_light_brightness": r.get("nightLightBrightness", None),
"night_light_automode": r.get("nightLightAutomode", None),
"power": r.get("power", 0),
"voltage": r.get("voltage", 0),
}
@staticmethod
def build_energy_dict(r: dict) -> dict:
"""Build energy dictionary from API response."""
return {
"energy_consumption_of_today": r.get("energyConsumptionOfToday", 0),
"cost_per_kwh": r.get("costPerKWH", 0),
"max_energy": r.get("maxEnergy", 0),
"total_energy": r.get("totalEnergy", 0),
"currency": r.get("currency", 0),
"data": r.get("data", 0),
}
@staticmethod
def build_config_dict(r: dict) -> dict:
"""Build configuration dictionary from API response."""
if r.get("threshold") is not None:
threshold = r.get("threshold")
else:
threshold = r.get("thresHold")
return {
"current_firmware_version": r.get("currentFirmVersion"),
"latest_firmware_version": r.get("latestFirmVersion"),
"maxPower": r.get("maxPower"),
"threshold": threshold,
"power_protection": r.get("powerProtectionStatus"),
"energy_saving_status": r.get("energySavingStatus"),
}
@classmethod
def bypass_body_v2(cls, manager):
"""Build body dict for bypass calls."""
bdy = {}
bdy.update(**cls.req_body(manager, "bypass"))
bdy["method"] = "bypassV2"
bdy["debugMode"] = False
bdy["deviceRegion"] = DEFAULT_REGION
return bdy
@staticmethod
def bypass_header():
"""Build bypass header dict."""
return {
"Content-Type": "application/json; charset=UTF-8",
"User-Agent": "okhttp/3.12.1",
}

View File

@ -0,0 +1,302 @@
"""VeSync API Device Library."""
from itertools import chain
import logging
import re
import time
from typing import Tuple
from . import (
vesyncbulb as bulb_mods,
vesyncfan as fan_mods,
vesyncoutlet as outlet_mods,
vesyncswitch as switch_mods,
)
from .helpers import Helpers
from .vesyncbasedevice import VeSyncBaseDevice
logger = logging.getLogger(__name__)
API_RATE_LIMIT: int = 30
DEFAULT_TZ: str = "America/New_York"
DEFAULT_ENER_UP_INT: int = 21600
def object_factory(dev_type, config, manager) -> Tuple[str, VeSyncBaseDevice]:
"""Get device type and instantiate class."""
def fans(dev_type, config, manager):
fan_cls = fan_mods.fan_modules[dev_type]
fan_obj = getattr(fan_mods, fan_cls)
return "fans", fan_obj(config, manager)
def outlets(dev_type, config, manager):
outlet_cls = outlet_mods.outlet_modules[dev_type]
outlet_obj = getattr(outlet_mods, outlet_cls)
return "outlets", outlet_obj(config, manager)
def switches(dev_type, config, manager):
switch_cls = switch_mods.switch_modules[dev_type]
switch_obj = getattr(switch_mods, switch_cls)
return "switches", switch_obj(config, manager)
def bulbs(dev_type, config, manager):
bulb_cls = bulb_mods.bulb_modules[dev_type]
bulb_obj = getattr(bulb_mods, bulb_cls)
return "bulbs", bulb_obj(config, manager)
if dev_type in fan_mods.fan_modules:
type_str, dev_obj = fans(dev_type, config, manager)
elif dev_type in outlet_mods.outlet_modules:
type_str, dev_obj = outlets(dev_type, config, manager)
elif dev_type in switch_mods.switch_modules:
type_str, dev_obj = switches(dev_type, config, manager)
elif dev_type in bulb_mods.bulb_modules:
type_str, dev_obj = bulbs(dev_type, config, manager)
else:
logger.debug(
"Unknown device named %s model %s",
config.get("deviceName", ""),
config.get("deviceType", ""),
)
type_str = "unknown"
dev_obj = None
return type_str, dev_obj
class VeSync:
"""VeSync API functions."""
def __init__(self, username, password, time_zone=DEFAULT_TZ, debug=False):
"""Initialize VeSync class with username, password and time zone."""
self.debug = debug
if debug:
logger.setLevel(logging.DEBUG)
self.username = username
self.password = password
self.token = None
self.account_id = None
self.devices = None
self.enabled = False
self.update_interval = API_RATE_LIMIT
self.last_update_ts = None
self.in_process = False
self._energy_update_interval = DEFAULT_ENER_UP_INT
self._energy_check = True
self._dev_list = {}
self.outlets = []
self.switches = []
self.fans = []
self.bulbs = []
self.scales = []
self._dev_list = {
"fans": self.fans,
"outlets": self.outlets,
"switches": self.switches,
"bulbs": self.bulbs,
}
if isinstance(time_zone, str) and time_zone:
reg_test = r"[^a-zA-Z/_]"
if bool(re.search(reg_test, time_zone)):
self.time_zone = DEFAULT_TZ
logger.debug("Invalid characters in time zone - %s", time_zone)
else:
self.time_zone = time_zone
else:
self.time_zone = DEFAULT_TZ
logger.debug("Time zone is not a string")
@property
def energy_update_interval(self) -> int:
"""Return energy update interval."""
return self._energy_update_interval
@energy_update_interval.setter
def energy_update_interval(self, new_energy_update: int) -> None:
"""Set energy update interval in seconds."""
if new_energy_update > 0:
self._energy_update_interval = new_energy_update
@staticmethod
def remove_dev_test(device, new_list: list) -> bool:
"""Test if device should be removed - False = Remove."""
if isinstance(new_list, list) and device.cid:
for item in new_list:
device_found = False
if "cid" in item:
if device.cid == item["cid"]:
device_found = True
break
else:
logger.debug("No cid found in - %s", str(item))
if not device_found:
logger.debug(
"Device removed - %s - %s", device.device_name, device.device_type
)
return False
return True
def add_dev_test(self, new_dev: dict) -> bool:
"""Test if new device should be added - True = Add."""
if "cid" in new_dev:
for _, v in self._dev_list.items():
for dev in v:
if (
dev.cid == new_dev.get("cid")
and new_dev.get("subDeviceNo", 0) == dev.sub_device_no
):
return False
return True
def remove_old_devices(self, devices: list) -> bool:
"""Remove devices not found in device list return."""
for k, v in self._dev_list.items():
before = len(v)
v[:] = [x for x in v if self.remove_dev_test(x, devices)]
after = len(v)
if before != after:
logger.debug("%s %s removed", str(before - after), k)
return True
@staticmethod
def set_dev_id(devices: list) -> list:
"""Correct devices without cid or uuid."""
dev_rem = []
for dev_num, dev in enumerate(devices):
if dev.get("cid") is None:
if dev.get("macID") is not None:
dev["cid"] = dev["macID"]
elif dev.get("uuid") is not None:
dev["cid"] = dev["uuid"]
else:
dev_rem.append(dev_num)
logger.warning("Device with no ID - %s", dev.get("deviceName"))
if dev_rem:
devices = [i for j, i in enumerate(devices) if j not in dev_rem]
return devices
def process_devices(self, dev_list: list) -> bool:
"""Instantiate Device Objects."""
devices = VeSync.set_dev_id(dev_list)
num_devices = sum(
len(v) if isinstance(v, list) else 1 for _, v in self._dev_list.items()
)
if not devices:
logger.warning("No devices found in api return")
return False
if num_devices == 0:
logger.debug("New device list initialized")
else:
self.remove_old_devices(devices)
devices[:] = [x for x in devices if self.add_dev_test(x)]
detail_keys = ["deviceType", "deviceName", "deviceStatus"]
for dev in devices:
if any(k not in dev for k in detail_keys):
logger.debug("Error adding device")
continue
dev_type = dev.get("deviceType")
try:
device_str, device_obj = object_factory(dev_type, dev, self)
device_list = getattr(self, device_str)
device_list.append(device_obj)
except AttributeError as err:
logger.debug("Error - %s", err)
logger.debug("%s device not added", dev_type)
continue
return True
def get_devices(self) -> bool:
"""Return tuple listing outlets, switches, and fans of devices."""
if not self.enabled:
return False
self.in_process = True
proc_return = False
response, _ = Helpers.call_api(
"/cloud/v1/deviceManaged/devices",
"post",
headers=Helpers.req_headers(self),
json=Helpers.req_body(self, "devicelist"),
)
if response and Helpers.code_check(response):
if "result" in response and "list" in response["result"]:
device_list = response["result"]["list"]
if self.debug:
logger.debug(str(device_list))
proc_return = self.process_devices(device_list)
else:
logger.error("Device list in response not found")
else:
logger.warning("Error retrieving device list")
self.in_process = False
return proc_return
def login(self) -> bool:
"""Return True if log in request succeeds."""
user_check = isinstance(self.username, str) and len(self.username) > 0
pass_check = isinstance(self.password, str) and len(self.password) > 0
if not user_check:
logger.error("Username invalid")
return False
if not pass_check:
logger.error("Password invalid")
return False
response, _ = Helpers.call_api(
"/cloud/v1/user/login", "post", json=Helpers.req_body(self, "login")
)
if Helpers.code_check(response) and "result" in response:
self.token = response.get("result").get("token")
self.account_id = response.get("result").get("accountID")
self.enabled = True
return True
logger.error("Error logging in with username and password")
return False
def device_time_check(self) -> bool:
"""Test if update interval has been exceeded."""
return (
self.last_update_ts is None
or (time.time() - self.last_update_ts) > self.update_interval
)
def update(self) -> None:
"""Fetch updated information about devices."""
if self.device_time_check():
if not self.enabled:
logger.error("Not logged in to VeSync")
return
self.get_devices()
devices = list(self._dev_list.values())
for device in chain(*devices):
device.update()
self.last_update_ts = time.time()
def update_energy(self, bypass_check=False) -> None:
"""Fetch updated energy information about devices."""
if self.outlets:
for outlet in self.outlets:
outlet.update_energy(bypass_check)
def update_all_devices(self) -> None:
"""Run get_details() for each device."""
devices = list(self._dev_list.keys())
for dev in chain(*devices):
dev.get_details()

View File

@ -0,0 +1,117 @@
"""Base class for all VeSync devices."""
import collections
import json
import logging
from typing import Optional, Union
logger = logging.getLogger(__name__)
class VeSyncBaseDevice:
"""Properties shared across all VeSync devices."""
def __init__(self, details: dict, manager):
"""Initialize VeSync device base class."""
self.manager = manager
if "cid" in details and details["cid"] is not None:
self.device_name: str = details.get("deviceName", None)
self.device_image: Optional[str] = details.get("deviceImg", None)
self.cid: str = details.get("cid", None)
self.connection_status: str = details.get("connectionStatus", None)
self.connection_type: Optional[str] = details.get("connectionType", None)
self.device_type: str = details.get("deviceType", None)
self.type: str = details.get("type", None)
self.uuid: Optional[str] = details.get("uuid", None)
self.config_module: str = details.get("configModule", None)
self.mac_id: Optional[str] = details.get("macID", None)
self.mode: Optional[str] = details.get("mode", None)
self.speed: Union[str, int, None] = details.get("speed", None)
self.extension = details.get("extension", None)
self.current_firm_version = details.get("currentFirmVersion", None)
self.sub_device_no = details.get("subDeviceNo", 0)
self.config: dict = {}
if isinstance(details.get("extension"), dict):
ext = details["extension"]
self.speed = ext.get("fanSpeedLevel")
self.mode = ext.get("mode")
if self.connection_status != "online":
self.device_status = "off"
else:
self.device_status = details.get("deviceStatus", None)
else:
logger.error("No cid found for %s", self.__class__.__name__)
def __eq__(self, other):
"""Use device CID and subdevice number to test equality."""
return bool(other.cid == self.cid and other.sub_device_no == self.sub_device_no)
def __hash__(self):
"""Use CID and sub-device number to make device hash."""
if isinstance(self.sub_device_no, int) and self.sub_device_no > 0:
return hash(self.cid + str(self.sub_device_no))
return hash(self.cid)
def __str__(self):
"""Use device info for string represtation of class."""
return f"Device Name: {self.device_name}, \
Device Type: {self.device_type},\
SubDevice No.: {self.sub_device_no},\
Status: {self.device_status}"
def __repr__(self):
"""Representation of device details."""
return f"DevClass: {self.__class__.__name__},\
Name:{self.device_name}, Device No: {self.sub_device_no},\
DevStatus: {self.device_status}, CID: {self.cid}"
@property
def is_on(self) -> bool:
"""Return true if device is on."""
if self.device_status == "on":
return True
return False
@property
def firmware_update(self) -> bool:
"""Return True if firmware update available."""
cfv = self.config.get("current_firmware_version")
lfv = self.config.get("latest_firmware_version")
if cfv is not None and lfv is not None:
if cfv != lfv:
return True
else:
logger.debug("Call device.get_config() to get firmware versions")
return False
def display(self) -> None:
"""Print formatted device info to stdout."""
disp = [
("Device Name:", self.device_name),
("Model: ", self.device_type),
("Subdevice No: ", str(self.sub_device_no)),
("Status: ", self.device_status),
("Online: ", self.connection_status),
("Type: ", self.type),
("CID: ", self.cid),
]
if self.uuid is not None:
disp.append(("UUID: ", self.uuid))
disp1 = collections.OrderedDict(disp)
for k, v in disp1.items():
print(f"{k:.<15} {v:<15}")
def displayJSON(self) -> str:
"""JSON API for device details."""
return json.dumps(
{
"Device Name": self.device_name,
"Model": self.device_type,
"Subdevice No": str(self.sub_device_no),
"Status": self.device_status,
"Online": self.connection_status,
"Type": self.type,
"CID": self.cid,
}
)

View File

@ -0,0 +1,378 @@
"""Etekcity Smart Light Bulb."""
from abc import ABCMeta, abstractmethod
import json
import logging
from typing import Dict, Union
from .helpers import Helpers as helpers
from .vesyncbasedevice import VeSyncBaseDevice
logger = logging.getLogger(__name__)
# Possible features - dimmable, color_temp, rgb_shift
feature_dict: dict = {
"ESL100": {"module": "VeSyncBulbESL100", "features": ["dimmable"]},
"ESL100CW": {
"module": "VeSyncBulbESL100CW",
"features": ["dimmable", "color_temp"],
},
}
bulb_modules: dict = {k: v["module"] for k, v in feature_dict.items()}
__all__: list = list(bulb_modules.values()) + ["bulb_modules"]
def pct_to_kelvin(pct: float, max_k: int = 6500, min_k: int = 2700) -> float:
"""Convert percent to kelvin."""
return ((max_k - min_k) * pct / 100) + min_k
class VeSyncBulb(VeSyncBaseDevice):
"""Base class for VeSync Bulbs."""
__metaclass__ = ABCMeta
def __init__(self, details: Dict[str, Union[str, list]], manager):
"""Initialize VeSync smart bulb base class."""
super().__init__(details, manager)
self._brightness = 0
self._color_temp = 0
self.features = feature_dict.get(self.device_type, {}).get("features")
if self.features is None:
logger.error("No configuration set for - %s", self.device_name)
raise RuntimeError(f"No configuration set for - {self.device_name}")
@property
def brightness(self) -> int:
"""Return brightness of vesync bulb."""
if self.dimmable_feature and self._brightness is not None:
return self._brightness
return 0
@property
def color_temp_kelvin(self) -> int:
"""Return Color Temp of bulb if supported in Kelvin."""
if self.color_temp_feature and self._color_temp is not None:
return int(pct_to_kelvin(self._color_temp))
return 0
@property
def color_temp_pct(self) -> int:
"""Return color temperature of bulb in percent."""
if self.color_temp_feature and self._color_temp is not None:
return int(self._color_temp)
return 0
@property
def dimmable_feature(self) -> bool:
"""Return true if dimmable bulb."""
return "dimmable" in self.features
@property
def color_temp_feature(self) -> bool:
"""Return true if bulb supports color temperature changes."""
return "color_temp" in feature_dict[self.device_type]
@property
def rgb_shift_feature(self) -> bool:
"""Return True if bulb supports changing color."""
return "rgb_shift" in feature_dict[self.device_type]
@abstractmethod
def get_details(self) -> None:
"""Get vesync bulb details."""
@abstractmethod
def toggle(self, status: str) -> bool:
"""Toggle vesync lightbulb."""
@abstractmethod
def get_config(self) -> None:
"""Call api to get configuration details and firmware."""
def turn_on(self) -> bool:
"""Turn on vesync bulbs."""
return self._toggle("on")
def turn_off(self) -> bool:
"""Turn off vesync bulbs."""
return self._toggle("off")
def _toggle(self, state: str, warning: str):
if self.toggle(state):
self.device_status = state
return True
logger.warning("Error turning %s %s", self.device_name, state)
return False
def update(self) -> None:
"""Update bulb details."""
self.get_details()
def display(self) -> None:
"""Return formatted bulb info to stdout."""
super().display()
if self.connection_status == "online" and self.dimmable_feature:
disp1 = [("Brightness: ", self.brightness, "%")]
for line in disp1:
print(f"{line[0]:.<17} {line[1]} {line[2]}")
def displayJSON(self) -> str:
"""Return bulb device info in JSON format."""
sup = super().displayJSON()
sup_val = json.loads(sup)
if self.connection_status == "online":
if self.dimmable_feature:
sup_val.update({"Brightness": str(self.brightness)})
if self.color_temp_feature:
sup_val.update({"Kelvin": str(self.color_temp_kelvin)})
return sup_val
class VeSyncBulbESL100(VeSyncBulb):
"""Object to hold VeSync ESL100 light bulb."""
def __init__(self, details, manager):
"""Initialize Etekcity ESL100 Dimmable Bulb."""
super().__init__(details, manager)
self.details: dict = {}
def get_details(self) -> None:
"""Get details of dimmable bulb."""
body = helpers.req_body(self.manager, "devicedetail")
body["uuid"] = self.uuid
r, _ = helpers.call_api(
"/SmartBulb/v1/device/devicedetail",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self.connection_status = r.get("connectionStatus")
self.device_status = r.get("deviceStatus")
if self.dimmable_feature:
self._brightness = int(r.get("brightNess"))
else:
logger.debug("Error getting %s details", self.device_name)
def get_config(self) -> None:
"""Get configuration of dimmable bulb."""
body = helpers.req_body(self.manager, "devicedetail")
body["method"] = "configurations"
body["uuid"] = self.uuid
r, _ = helpers.call_api(
"/SmartBulb/v1/device/configurations",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self.config = helpers.build_config_dict(r)
else:
logger.warning("Error getting %s config info", self.device_name)
def toggle(self, status) -> bool:
"""Toggle dimmable bulb."""
body = self._get_body(status)
r, _ = helpers.call_api(
"/SmartBulb/v1/device/devicestatus",
"put",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self.device_status = status
return True
return False
def set_brightness(self, brightness: int) -> bool:
"""Set brightness of dimmable bulb."""
if not self.dimmable_feature:
logger.debug("%s is not dimmable", self.device_name)
return False
if isinstance(brightness, int) and (brightness <= 0 or brightness > 100):
logger.warning("Invalid brightness")
return False
body = self._get_body("on")
body["brightNess"] = str(brightness)
r, _ = helpers.call_api(
"/SmartBulb/v1/device/updateBrightness",
"put",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self._brightness = brightness
return True
logger.debug("Error setting brightness for %s", self.device_name)
return False
def _get_body(self, status: str):
body = helpers.req_body(self.manager, "devicestatus")
body["uuid"] = self.uuid
body["status"] = status
return body
class VeSyncBulbESL100CW(VeSyncBulb):
"""VeSync Tunable and Dimmable White Bulb."""
def __init__(self, details, manager):
"""Initialize Etekcity Tunable white bulb."""
super().__init__(details, manager)
def get_details(self) -> None:
"""Get details of tunable bulb."""
body = helpers.req_body(self.manager, "bypass")
body["cid"] = self.cid
body["jsonCmd"] = {"getLightStatus": "get"}
body["configModule"] = self.config_module
r, _ = helpers.call_api(
"/cloud/v1/deviceManaged/bypass",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if not isinstance(r, dict) or not helpers.code_check(r):
logger.debug("Error calling %s", self.device_name)
return
response = r
if response.get("result", {}).get("light") is not None:
light = response.get("result", {}).get("light")
self.connection_status = "online"
self.device_status = light.get("action", "off")
if self.dimmable_feature:
self._brightness = light.get("brightness")
if self.color_temp_feature:
self._color_temp = light.get("colorTempe")
elif response.get("code") == -11300027:
logger.debug("%s device offline", self.device_name)
self.connection_status = "offline"
self.device_status = "off"
else:
logger.debug(
"%s - Unknown return code - %d with message %s",
self.device_name,
response.get("code"),
response.get("msg"),
)
def get_config(self) -> None:
"""Get configuration and firmware info of tunable bulb."""
body = helpers.req_body(self.manager, "bypass_config")
body["uuid"] = self.uuid
r, _ = helpers.call_api(
"/cloud/v1/deviceManaged/configurations",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self.config = helpers.build_config_dict(r)
else:
logger.debug("Error getting %s config info", self.device_name)
def toggle(self, status) -> bool:
"""Toggle tunable bulb."""
body = helpers.req_body(self.manager, "bypass")
body["cid"] = self.cid
body["configModule"] = self.config_module
body["jsonCmd"] = {"light": {"action": status}}
r, _ = helpers.call_api(
"/cloud/v1/deviceManaged/bypass",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r) == 0:
self.device_status = status
return True
logger.debug("%s offline", self.device_name)
self.device_status = "off"
self.connection_status = "offline"
return False
def set_brightness(self, brightness: int) -> bool:
"""Set brightness of tunable bulb."""
if not self.dimmable_feature:
logger.debug("%s is not dimmable", self.device_name)
return False
if brightness <= 0 or brightness > 100:
logger.debug("Invalid brightness")
return False
body = helpers.req_body(self.manager, "bypass")
body["cid"] = self.cid
body["configModule"] = self.config_module
if self.device_status == "off":
light_dict = {"action": "on", "brightness": brightness}
else:
light_dict = {"brightness": brightness}
body["jsonCmd"] = {"light": light_dict}
r, _ = helpers.call_api(
"/cloud/v1/deviceManaged/bypass",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self._brightness = brightness
return True
self.device_status = "off"
self.connection_status = "offline"
logger.debug("%s offline", self.device_name)
return False
def set_color_temp(self, color_temp: int) -> bool:
"""Set Color Temperature of Bulb in pct (1 - 100)."""
if color_temp < 0 or color_temp > 100:
logger.debug("Invalid color temperature - only between 0 and 100")
return False
body = helpers.req_body(self.manager, "bypass")
body["cid"] = self.cid
body["jsonCmd"] = {"light": {}}
if self.device_status == "off":
light_dict = {"action": "on", "colorTempe": color_temp}
else:
light_dict = {"colorTempe": color_temp}
body["jsonCmd"]["light"] = light_dict
r, _ = helpers.call_api(
"/cloud/v1/deviceManaged/bypass",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if not helpers.code_check(r):
return False
if r.get("code") == -11300027:
logger.debug("%s device offline", self.device_name)
self.connection_status = "offline"
self.device_status = "off"
return False
if r.get("code") == 0:
self.device_status = "on"
self._color_temp = color_temp
return True
logger.debug(
"%s - Unknown return code - %d with message %s",
self.device_name,
r.get("code"),
r.get("msg"),
)
return False

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,703 @@
"""Etekcity Outlets."""
from abc import ABCMeta, abstractmethod
import json
import logging
import time
from .helpers import Helpers
from .vesyncbasedevice import VeSyncBaseDevice
logger = logging.getLogger(__name__)
outlet_config = {
"wifi-switch-1.3": {"module": "VeSyncOutlet7A"},
"ESW03-USA": {"module": "VeSyncOutlet10A"},
"ESW01-EU": {"module": "VeSyncOutlet10A"},
"ESW15-USA": {"module": "VeSyncOutlet15A"},
"ESO15-TB": {"module": "VeSyncOutdoorPlug"},
}
outlet_modules = {k: v["module"] for k, v in outlet_config.items()}
__all__ = list(outlet_modules.values()) + ["outlet_modules"]
class VeSyncOutlet(VeSyncBaseDevice):
"""Base class for Etekcity Outlets."""
__metaclass__ = ABCMeta
def __init__(self, details, manager):
"""Initialize VeSync Outlet base class."""
super().__init__(details, manager)
self.details = {}
self.energy = {}
self.update_energy_ts = None
self._energy_update_interval = manager.energy_update_interval
@property
def update_time_check(self) -> bool:
"""Test if energy update interval has been exceeded."""
if self.update_energy_ts is None:
return True
if (time.time() - self.update_energy_ts) > self._energy_update_interval:
return True
return False
@abstractmethod
def turn_on(self) -> bool:
"""Return True if device has beeeen turned on."""
@abstractmethod
def turn_off(self) -> bool:
"""Return True if device has beeeen turned off."""
@abstractmethod
def get_details(self) -> None:
"""Build details dictionary."""
@abstractmethod
def get_weekly_energy(self) -> None:
"""Build weekly energy history dictionary."""
@abstractmethod
def get_monthly_energy(self) -> None:
"""Build Monthly Energy History Dictionary."""
@abstractmethod
def get_yearly_energy(self):
"""Build Yearly Energy Dictionary."""
@abstractmethod
def get_config(self):
"""Get configuration and firmware details."""
def update(self):
"""Get Device Energy and Status."""
self.get_details()
def update_energy(self, bypass_check: bool = False):
"""Build weekly, monthly and yearly dictionaries."""
if bypass_check or self.update_time_check:
self.update_energy_ts = time.time()
self.get_weekly_energy()
if "week" in self.energy:
self.get_monthly_energy()
self.get_yearly_energy()
if not bypass_check:
self.update_energy_ts = time.time()
@property
def active_time(self) -> int:
"""Return active time of a device in minutes."""
return self.details.get("active_time", 0)
@property
def energy_today(self) -> float:
"""Return energy."""
return self.details.get("energy", 0)
@property
def power(self) -> float:
"""Return current power in watts."""
return float(self.details.get("power", 0))
@property
def voltage(self) -> float:
"""Return current voltage."""
return float(self.details.get("voltage", 0))
@property
def monthly_energy_total(self) -> float:
"""Return total energy usage over the month."""
return self.energy.get("month", {}).get("total_energy", 0)
@property
def weekly_energy_total(self) -> float:
"""Return total energy usage over the week."""
return self.energy.get("week", {}).get("total_energy", 0)
@property
def yearly_energy_total(self) -> float:
"""Return total energy usage over the year."""
return self.energy.get("year", {}).get("total_energy", 0)
def display(self):
"""Return formatted device info to stdout."""
super().display()
disp1 = [
("Active Time : ", self.active_time, " minutes"),
("Energy: ", self.energy_today, " kWh"),
("Power: ", self.power, " Watts"),
("Voltage: ", self.voltage, " Volts"),
("Energy Week: ", self.weekly_energy_total, " kWh"),
("Energy Month: ", self.monthly_energy_total, " kWh"),
("Energy Year: ", self.yearly_energy_total, " kWh"),
]
for line in disp1:
print(f"{line[0]:.<15} {line[1]} {line[2]}")
def displayJSON(self):
"""Return JSON details for outlet."""
sup = super().displayJSON()
sup_val = json.loads(sup)
sup_val.update(
{
"Active Time": str(self.active_time),
"Energy": str(self.energy_today),
"Power": str(self.power),
"Voltage": str(self.voltage),
"Energy Week": str(self.weekly_energy_total),
"Energy Month": str(self.monthly_energy_total),
"Energy Year": str(self.yearly_energy_total),
}
)
return sup_val
class VeSyncOutlet7A(VeSyncOutlet):
"""Etekcity 7A Round Outlet Class."""
def __init__(self, details, manager):
"""Initialize Etekcity 7A round outlet class."""
super().__init__(details, manager)
self.det_keys = ["deviceStatus", "activeTime", "energy", "power", "voltage"]
self.energy_keys = ["energyConsumptionOfToday", "maxEnergy", "totalEnergy"]
def get_details(self) -> None:
"""Get 7A outlet details."""
r, _ = Helpers.call_api(
f"/v1/device/{self.cid}/detail",
"get",
headers=Helpers.req_headers(self.manager),
)
if r is not None and all(x in r for x in self.det_keys):
self.device_status = r.get("deviceStatus", self.device_status)
self.details["active_time"] = r.get("activeTime", 0)
self.details["energy"] = r.get("energy", 0)
power = r.get("power", "0:0")
power = round(float(Helpers.calculate_hex(power)), 2)
self.details["power"] = power
voltage = r.get("voltage", "0:0")
voltage = round(float(Helpers.calculate_hex(voltage)), 2)
self.details["voltage"] = voltage
else:
logger.debug("Unable to get %s details", self.device_name)
def get_weekly_energy(self) -> None:
"""Get 7A outlet weekly energy info and build weekly energy dict."""
r, _ = Helpers.call_api(
f"/v1/device/{self.cid}/energy/week",
"get",
headers=Helpers.req_headers(self.manager),
)
if r is not None and all(x in r for x in self.energy_keys):
self.energy["week"] = Helpers.build_energy_dict(r)
else:
logger.debug("Unable to get %s weekly data", self.device_name)
def get_monthly_energy(self) -> None:
"""Get 7A outlet monthly energy info and build monthly energy dict."""
r, _ = Helpers.call_api(
f"/v1/device/{self.cid}/energy/month",
"get",
headers=Helpers.req_headers(self.manager),
)
if r is not None and all(x in r for x in self.energy_keys):
self.energy["month"] = Helpers.build_energy_dict(r)
else:
logger.warning("Unable to get %s monthly data", self.device_name)
def get_yearly_energy(self) -> None:
"""Get 7A outlet yearly energy info and build yearly energy dict."""
r, _ = Helpers.call_api(
f"/v1/device/{self.cid}/energy/year",
"get",
headers=Helpers.req_headers(self.manager),
)
if r is not None and all(x in r for x in self.energy_keys):
self.energy["year"] = Helpers.build_energy_dict(r)
else:
logger.debug("Unable to get %s yearly data", self.device_name)
def turn_on(self) -> bool:
"""Turn 7A outlet on - return True if successful."""
return self._toggle("on")
def turn_off(self) -> bool:
"""Turn 7A outlet off - return True if successful."""
return self._toggle("off")
def _toggle(self, state):
_, status_code = Helpers.call_api(
f"/v1/wifi-switch-1.3/{self.cid}/status/{state}",
"put",
headers=Helpers.req_headers(self.manager),
)
if status_code is not None and status_code == 200:
self.device_status = state
return True
logger.warning("Error turning %s %s", self.device_name, state)
return False
def get_config(self) -> None:
"""Get 7A outlet configuration info."""
r, _ = Helpers.call_api(
f"/v1/device/{self.cid}/configurations",
"get",
headers=Helpers.req_headers(self.manager),
)
if "currentFirmVersion" in r:
self.config = Helpers.build_config_dict(r)
else:
logger.debug("Error getting configuration info for %s", self.device_name)
class VeSyncOutlet10A(VeSyncOutlet):
"""Etekcity 10A Round Outlets."""
def __init__(self, details, manager):
"""Initialize 10A outlet class."""
super().__init__(details, manager)
def get_details(self) -> None:
"""Get 10A outlet details."""
body = Helpers.req_body(self.manager, "devicedetail")
body["uuid"] = self.uuid
r, _ = Helpers.call_api(
"/10a/v1/device/devicedetail",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(r):
self.device_status = r.get("deviceStatus", self.device_status)
self.connection_status = r.get("connectionStatus", self.connection_status)
self.details = Helpers.build_details_dict(r)
else:
logger.debug("Unable to get %s details", self.device_name)
def get_config(self) -> None:
"""Get 10A outlet configuration info."""
body = Helpers.req_body(self.manager, "devicedetail")
body["method"] = "configurations"
body["uuid"] = self.uuid
r, _ = Helpers.call_api(
"/10a/v1/device/configurations",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(r):
self.config = Helpers.build_config_dict(r)
else:
logger.debug("Error getting %s config info", self.device_name)
def get_weekly_energy(self) -> None:
"""Get 10A outlet weekly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_week")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/10a/v1/device/energyweek",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["week"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s weekly data", self.device_name)
def get_monthly_energy(self) -> None:
"""Get 10A outlet monthly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_month")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/10a/v1/device/energymonth",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["month"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s monthly data", self.device_name)
def get_yearly_energy(self) -> None:
"""Get 10A outlet yearly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_year")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/10a/v1/device/energyyear",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["year"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s yearly data", self.device_name)
def turn_on(self) -> bool:
"""Turn 10A outlet on - return True if successful."""
body = Helpers.req_body(self.manager, "devicestatus")
body["uuid"] = self.uuid
body["status"] = "on"
response, _ = Helpers.call_api(
"/10a/v1/device/devicestatus",
"put",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.device_status = "on"
return True
logger.warning("Error turning %s on", self.device_name)
return False
def turn_off(self) -> bool:
"""Turn 10A outlet off - return True if successful."""
body = Helpers.req_body(self.manager, "devicestatus")
body["uuid"] = self.uuid
body["status"] = "off"
response, _ = Helpers.call_api(
"/10a/v1/device/devicestatus",
"put",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.device_status = "off"
return True
logger.warning("Error turning %s off", self.device_name)
return False
class VeSyncOutlet15A(VeSyncOutlet):
"""Class for Etekcity 15A Rectangular Outlets."""
def __init__(self, details, manager):
"""Initialize 15A rectangular outlets."""
super().__init__(details, manager)
self.nightlight_status = "off"
self.nightlight_brightness = 0
def get_details(self) -> None:
"""Get 15A outlet details."""
body = Helpers.req_body(self.manager, "devicedetail")
body["uuid"] = self.uuid
r, _ = Helpers.call_api(
"/15a/v1/device/devicedetail",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
attr_list = (
"deviceStatus",
"activeTime",
"energy",
"power",
"voltage",
"nightLightStatus",
"nightLightAutomode",
"nightLightBrightness",
)
if Helpers.code_check(r) and all(k in r for k in attr_list):
self.device_status = r.get("deviceStatus")
self.connection_status = r.get("connectionStatus")
self.nightlight_status = r.get("nightLightStatus")
self.nightlight_brightness = r.get("nightLightBrightness")
self.details = Helpers.build_details_dict(r)
else:
logger.debug("Unable to get %s details", self.device_name)
def get_config(self) -> None:
"""Get 15A outlet configuration info."""
body = Helpers.req_body(self.manager, "devicedetail")
body["method"] = "configurations"
body["uuid"] = self.uuid
r, _ = Helpers.call_api(
"/15a/v1/device/configurations",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(r):
self.config = Helpers.build_config_dict(r)
else:
logger.debug("Unable to get %s config info", self.device_name)
def get_weekly_energy(self) -> None:
"""Get 15A outlet weekly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_week")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/15a/v1/device/energyweek",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["week"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s weekly data", self.device_name)
def get_monthly_energy(self) -> None:
"""Get 15A outlet monthly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_month")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/15a/v1/device/energymonth",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["month"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s monthly data", self.device_name)
def get_yearly_energy(self) -> None:
"""Get 15A outlet yearly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_year")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/15a/v1/device/energyyear",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["year"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s yearly data", self.device_name)
def turn_on(self) -> bool:
"""Turn 15A outlet on - return True if successful."""
body = Helpers.req_body(self.manager, "devicestatus")
body["uuid"] = self.uuid
body["status"] = "on"
response, _ = Helpers.call_api(
"/15a/v1/device/devicestatus",
"put",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.device_status = "on"
return True
logger.warning("Error turning %s on", self.device_name)
return False
def turn_off(self) -> bool:
"""Turn 15A outlet off - return True if successful."""
body = Helpers.req_body(self.manager, "devicestatus")
body["uuid"] = self.uuid
body["status"] = "off"
response, _ = Helpers.call_api(
"/15a/v1/device/devicestatus",
"put",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.device_status = "off"
return True
logger.warning("Error turning %s off", self.device_name)
return False
def turn_on_nightlight(self) -> bool:
"""Turn on nightlight."""
return self._extracted_from_turn_off_nightlight_3("auto")
def turn_off_nightlight(self) -> bool:
"""Turn Off Nightlight."""
return self._extracted_from_turn_off_nightlight_3("manual")
def _extracted_from_turn_off_nightlight_3(self, mode):
body = Helpers.req_body(self.manager, "devicestatus")
body["uuid"] = self.uuid
body["mode"] = mode
response, _ = Helpers.call_api(
"/15a/v1/device/nightlightstatus",
"put",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
return True
logger.debug(
"Error turning %s %s nightlight",
"on" if mode == "auto" else "off",
self.device_name,
)
return False
class VeSyncOutdoorPlug(VeSyncOutlet):
"""Class to hold Etekcity outdoor outlets."""
def __init__(self, details, manager):
"""Initialize Etekcity Outdoor Plug class."""
super().__init__(details, manager)
def get_details(self) -> None:
"""Get details for outdoor outlet."""
body = Helpers.req_body(self.manager, "devicedetail")
body["uuid"] = self.uuid
r, _ = Helpers.call_api(
"/outdoorsocket15a/v1/device/devicedetail",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(r):
self.details = Helpers.build_details_dict(r)
self.connection_status = r.get("connectionStatus")
dev_no = self.sub_device_no
sub_device_list = r.get("subDevices")
if sub_device_list and dev_no <= len(sub_device_list):
self.device_status = sub_device_list[(dev_no + -1)].get(
"subDeviceStatus"
)
return
logger.debug("Unable to get %s details", self.device_name)
def get_config(self) -> None:
"""Get configuration info for outdoor outlet."""
body = Helpers.req_body(self.manager, "devicedetail")
body["method"] = "configurations"
body["uuid"] = self.uuid
r, _ = Helpers.call_api(
"/outdoorsocket15a/v1/device/configurations",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(r):
self.config = Helpers.build_config_dict(r)
logger.debug("Error getting %s config info", self.device_name)
def get_weekly_energy(self) -> None:
"""Get outdoor outlet weekly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_week")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/outdoorsocket15a/v1/device/energyweek",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["week"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s weekly data", self.device_name)
def get_monthly_energy(self) -> None:
"""Get outdoor outlet monthly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_month")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/outdoorsocket15a/v1/device/energymonth",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["month"] = Helpers.build_energy_dict(response)
logger.debug("Unable to get %s monthly data", self.device_name)
def get_yearly_energy(self) -> None:
"""Get outdoor outlet yearly energy info and populate energy dict."""
body = Helpers.req_body(self.manager, "energy_year")
body["uuid"] = self.uuid
response, _ = Helpers.call_api(
"/outdoorsocket15a/v1/device/energyyear",
"post",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.energy["year"] = Helpers.build_energy_dict(response)
else:
logger.debug("Unable to get %s yearly data", self.device_name)
def toggle(self, status) -> bool:
"""Toggle power for outdoor outlet."""
body = Helpers.req_body(self.manager, "devicestatus")
body["uuid"] = self.uuid
body["status"] = status
body["switchNo"] = self.sub_device_no
response, _ = Helpers.call_api(
"/outdoorsocket15a/v1/device/devicestatus",
"put",
headers=Helpers.req_headers(self.manager),
json=body,
)
if Helpers.code_check(response):
self.device_status = status
return True
logger.warning("Error turning %s %s", self.device_name, status)
return False
def turn_on(self) -> bool:
"""Turn outdoor outlet on and return True if successful."""
return bool(self.toggle("on"))
def turn_off(self) -> bool:
"""Turn outdoor outlet off and return True if successful."""
return bool(self.toggle("off"))

View File

@ -0,0 +1,347 @@
"""Classes for VeSync Switch Devices."""
from abc import ABCMeta, abstractmethod
import json
import logging
from typing import Dict, Union
from .helpers import Helpers as helpers
from .vesyncbasedevice import VeSyncBaseDevice
logger = logging.getLogger(__name__)
feature_dict: Dict[str, Dict[str, Union[list, str]]] = {
"ESWL01": {"module": "VeSyncWallSwitch", "features": []},
"ESWD16": {"module": "VeSyncDimmerSwitch", "features": ["dimmable"]},
"ESWL03": {"module": "VeSyncWallSwitch", "features": []},
}
switch_modules: dict = {k: v["module"] for k, v in feature_dict.items()}
__all__: list = list(switch_modules.values()) + ["switch_modules"]
class VeSyncSwitch(VeSyncBaseDevice):
"""Etekcity Switch Base Class."""
__metaclasss__ = ABCMeta
def __init__(self, details, manager):
"""Initialize Switch Base Class."""
super().__init__(details, manager)
self.features = feature_dict.get(self.device_type, {}).get("features")
if self.features is None:
logger.error("No configuration set for - %s", self.device_name)
raise RuntimeError(f"No configuration set for - {self.device_name}")
self.details = {}
def is_dimmable(self) -> bool:
"""Return True if switch is dimmable."""
return bool("dimmable" in self.features)
@abstractmethod
def get_details(self) -> None:
"""Get Device Details."""
@abstractmethod
def turn_on(self) -> bool:
"""Turn Switch On."""
@abstractmethod
def turn_off(self) -> bool:
"""Turn switch off."""
@abstractmethod
def get_config(self) -> None:
"""Get configuration and firmware deatils."""
@property
def active_time(self) -> int:
"""Get active time of switch."""
return self.details.get("active_time", 0)
def update(self) -> None:
"""Update device details."""
self.get_details()
class VeSyncWallSwitch(VeSyncSwitch):
"""Etekcity standard wall switch class."""
def __init__(self, details, manager):
"""Initialize standard etekcity wall switch class."""
super().__init__(details, manager)
def get_details(self) -> None:
"""Get switch device details."""
body = helpers.req_body(self.manager, "devicedetail")
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
r, _ = helpers.call_api(
"/inwallswitch/v1/device/devicedetail", "post", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self.device_status = r.get("deviceStatus", self.device_status)
self.details["active_time"] = r.get("activeTime", 0)
self.connection_status = r.get("connectionStatus", self.connection_status)
else:
logger.debug("Error getting %s details", self.device_name)
def get_config(self) -> None:
"""Get switch device configuration info."""
body = helpers.req_body(self.manager, "devicedetail")
body["method"] = "configurations"
body["uuid"] = self.uuid
r, _ = helpers.call_api(
"/inwallswitch/v1/device/configurations",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self.config = helpers.build_config_dict(r)
else:
logger.warning("Unable to get %s config info", self.device_name)
def turn_off(self) -> bool:
"""Turn off switch device."""
body = helpers.req_body(self.manager, "devicestatus")
body["status"] = "off"
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
r, _ = helpers.call_api(
"/inwallswitch/v1/device/devicestatus", "put", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self.device_status = "off"
return True
logger.warning("Error turning %s off", self.device_name)
return False
def turn_on(self) -> bool:
"""Turn on switch device."""
body = helpers.req_body(self.manager, "devicestatus")
body["status"] = "on"
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
r, _ = helpers.call_api(
"/inwallswitch/v1/device/devicestatus", "put", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self.device_status = "on"
return True
logger.warning("Error turning %s on", self.device_name)
return False
class VeSyncDimmerSwitch(VeSyncSwitch):
"""Vesync Dimmer Switch Class with RGB Faceplate."""
def __init__(self, details, manager):
"""Initialize dimmer switch class."""
super().__init__(details, manager)
self._brightness = 0
self._rgb_value = {"red": 0, "blue": 0, "green": 0}
self._rgb_status = "unknown"
self._indicator_light = "unknown"
def get_details(self) -> None:
"""Get dimmer switch details."""
body = helpers.req_body(self.manager, "devicedetail")
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
r, _ = helpers.call_api(
"/dimmer/v1/device/devicedetail", "post", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self.device_status = r.get("deviceStatus", self.device_status)
self.details["active_time"] = r.get("activeTime", 0)
self.connection_status = r.get("connectionStatus", self.connection_status)
self._brightness = r.get("brightness")
self._rgb_status = r.get("rgbStatus")
self._rgb_value = r.get("rgbValue")
self._indicator_light = r.get("indicatorlightStatus")
else:
logger.debug("Error getting %s details", self.device_name)
@property
def brightness(self) -> float:
"""Return brightness in percent."""
return self._brightness
@property
def indicator_light_status(self) -> str:
"""Faceplate brightness light status."""
return self._indicator_light
@property
def rgb_light_status(self) -> str:
"""RGB Faceplate light status."""
return self._rgb_status
@property
def rgb_light_value(self) -> dict:
"""RGB Light Values."""
return self._rgb_value
def switch_toggle(self, status: str) -> bool:
"""Toggle switch status."""
if status not in ["on", "off"]:
logger.debug("Invalid status passed to wall switch")
return False
body = helpers.req_body(self.manager, "devicestatus")
body["status"] = status
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
r, _ = helpers.call_api(
"/dimmer/v1/device/devicestatus", "put", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self.device_status = status
return True
logger.warning("Error turning %s %s", self.device_name, status)
return False
def turn_on(self) -> bool:
"""Turn switch on."""
return self.switch_toggle("on")
def turn_off(self) -> bool:
"""Turn switch off."""
return self.switch_toggle("off")
def indicator_light_toggle(self, status: str) -> bool:
"""Toggle indicator light."""
if status not in ["on", "off"]:
logger.debug("Invalid status for wall switch")
return False
body = helpers.req_body(self.manager, "devicestatus")
body["status"] = status
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
r, _ = helpers.call_api(
"/dimmer/v1/device/indicatorlightstatus", "put", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self.device_status = status
return True
logger.warning("Error turning %s indicator light %s", self.device_name, status)
return False
def indicator_light_on(self) -> bool:
"""Turn Indicator light on."""
return self.indicator_light_toggle("on")
def indicator_light_off(self) -> bool:
"""Turn indicator light off."""
return self.indicator_light_toggle("off")
def rgb_color_status(
self, status: str, red: int = None, blue: int = None, green: int = None
) -> bool:
"""Set faceplate RGB color."""
body = helpers.req_body(self.manager, "devicestatus")
body["status"] = status
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
if red is not None and blue is not None and green is not None:
body["rgbValue"] = {"red": red, "blue": blue, "green": green}
r, _ = helpers.call_api(
"/dimmer/v1/device/devicergbstatus", "put", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self._rgb_status = status
if body.get("rgbValue") is not None:
self._rgb_value = {"red": red, "blue": blue, "green": green}
return True
logger.warning("Error turning %s off", self.device_name)
return False
def rgb_color_off(self) -> bool:
"""Turn RGB Color Off."""
return self.rgb_color_status("off")
def rgb_color_on(self) -> bool:
"""Turn RGB Color Off."""
return self.rgb_color_status("on")
def rgb_color_set(self, red: int, green: int, blue: int) -> bool:
"""Set RGB color of faceplate."""
if isinstance(red, int) and isinstance(green, int) and isinstance(blue, int):
for color in [red, green, blue]:
if color < 0 or color > 255:
logger.warning("Invalid RGB value")
return False
return bool(self.rgb_color_status("on", red, green, blue))
return False
def set_brightness(self, brightness: int) -> bool:
"""Set brightness of dimmer - 1 - 100."""
if isinstance(brightness, int) and (brightness > 0 or brightness <= 100):
body = helpers.req_body(self.manager, "devicestatus")
body["brightness"] = brightness
body["uuid"] = self.uuid
head = helpers.req_headers(self.manager)
r, _ = helpers.call_api(
"/dimmer/v1/device/updatebrightness", "put", headers=head, json=body
)
if r is not None and helpers.code_check(r):
self._brightness = brightness
return True
logger.warning("Error setting %s brightness", self.device_name)
else:
logger.warning("Invalid brightness")
return False
def displayJSON(self) -> str:
"""JSON API for dimmer switch."""
sup_val = json.loads(super().displayJSON())
if self.is_dimmable:
sup_val.update(
{
"Indicator Light": str(self.active_time),
"Brightness": str(self._brightness),
"RGB Light": str(self._rgb_status),
}
)
return sup_val
def get_config(self) -> None:
"""Get dimmable switch device configuration info."""
body = helpers.req_body(self.manager, "devicedetail")
body["method"] = "configurations"
body["uuid"] = self.uuid
r, _ = helpers.call_api(
"/dimmer/v1/device/configurations",
"post",
headers=helpers.req_headers(self.manager),
json=body,
)
if helpers.code_check(r):
self.config = helpers.build_config_dict(r)
else:
logger.warning("Unable to get %s config info", self.device_name)

View File

@ -0,0 +1,202 @@
"""Support for power & energy sensors for VeSync outlets."""
import logging
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ENERGY_KILO_WATT_HOUR, PERCENTAGE, POWER_WATT
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncBaseEntity, is_humidifier
from .const import DEV_TYPE_TO_HA, DOMAIN, VS_DISCOVERY, VS_SENSORS
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up switches."""
@callback
def discover(devices):
"""Add new devices to platform."""
_setup_entities(devices, async_add_entities)
config_entry.async_on_unload(
async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_SENSORS), discover)
)
_setup_entities(
hass.data[DOMAIN][config_entry.entry_id][VS_SENSORS], async_add_entities
)
@callback
def _setup_entities(devices, async_add_entities):
"""Check if device is online and add entity."""
entities = []
for dev in devices:
if DEV_TYPE_TO_HA.get(dev.device_type) == "outlet":
entities.extend((VeSyncPowerSensor(dev), VeSyncEnergySensor(dev)))
elif is_humidifier(dev.device_type):
entities.append(VeSyncHumiditySensor(dev))
else:
_LOGGER.warning(
"%s - Unknown device type - %s", dev.device_name, dev.device_type
)
async_add_entities(entities, update_before_add=True)
class VeSyncOutletSensorEntity(VeSyncBaseEntity, SensorEntity):
"""Representation of a sensor describing diagnostics of a VeSync outlet."""
def __init__(self, plug):
"""Initialize the VeSync outlet device."""
super().__init__(plug)
self.smartplug = plug
@property
def entity_category(self):
"""Return the diagnostic entity category."""
return EntityCategory.DIAGNOSTIC
class VeSyncPowerSensor(VeSyncOutletSensorEntity):
"""Representation of current power use for a VeSync outlet."""
@property
def unique_id(self):
"""Return unique ID for power sensor on device."""
return f"{super().unique_id}-power"
@property
def name(self):
"""Return sensor name."""
return f"{super().name} current power"
@property
def device_class(self):
"""Return the power device class."""
return SensorDeviceClass.POWER
@property
def native_value(self):
"""Return the current power usage in W."""
return self.smartplug.power
@property
def native_unit_of_measurement(self):
"""Return the Watt unit of measurement."""
return POWER_WATT
@property
def state_class(self):
"""Return the measurement state class."""
return SensorStateClass.MEASUREMENT
def update(self):
"""Update outlet details and energy usage."""
self.smartplug.update()
self.smartplug.update_energy()
class VeSyncEnergySensor(VeSyncOutletSensorEntity):
"""Representation of current day's energy use for a VeSync outlet."""
def __init__(self, plug):
"""Initialize the VeSync outlet device."""
super().__init__(plug)
self.smartplug = plug
@property
def unique_id(self):
"""Return unique ID for power sensor on device."""
return f"{super().unique_id}-energy"
@property
def name(self):
"""Return sensor name."""
return f"{super().name} energy use today"
@property
def device_class(self):
"""Return the energy device class."""
return SensorDeviceClass.ENERGY
@property
def native_value(self):
"""Return the today total energy usage in kWh."""
return self.smartplug.energy_today
@property
def native_unit_of_measurement(self):
"""Return the kWh unit of measurement."""
return ENERGY_KILO_WATT_HOUR
@property
def state_class(self):
"""Return the total_increasing state class."""
return SensorStateClass.TOTAL_INCREASING
def update(self):
"""Update outlet details and energy usage."""
self.smartplug.update()
self.smartplug.update_energy()
class VeSyncHumidifierSensorEntity(VeSyncBaseEntity, SensorEntity):
"""Representation of a sensor describing diagnostics of a VeSync humidifier."""
def __init__(self, humidifier):
"""Initialize the VeSync humidifier device."""
super().__init__(humidifier)
self.smarthumidifier = humidifier
@property
def entity_category(self):
"""Return the diagnostic entity category."""
return EntityCategory.DIAGNOSTIC
class VeSyncHumiditySensor(VeSyncHumidifierSensorEntity):
"""Representation of current humidity for a VeSync humidifier."""
@property
def unique_id(self):
"""Return unique ID for humidity sensor on device."""
return f"{super().unique_id}-humidity"
@property
def name(self):
"""Return sensor name."""
return f"{super().name} current humidity"
@property
def device_class(self):
"""Return the humidity device class."""
return SensorDeviceClass.HUMIDITY
@property
def native_value(self):
"""Return the current humidity in percent."""
return self.smarthumidifier.details["humidity"]
@property
def native_unit_of_measurement(self):
"""Return the % unit of measurement."""
return PERCENTAGE
@property
def state_class(self):
"""Return the measurement state class."""
return SensorStateClass.MEASUREMENT

View File

@ -0,0 +1,3 @@
update_devices:
name: Update devices
description: Add new VeSync devices to Home Assistant

View File

@ -0,0 +1,19 @@
{
"config": {
"step": {
"user": {
"title": "Enter Username and Password",
"data": {
"username": "[%key:common::config_flow::data::email%]",
"password": "[%key:common::config_flow::data::password%]"
}
}
},
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
},
"abort": {
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
}
}
}

View File

@ -0,0 +1,203 @@
"""Support for VeSync switches."""
import logging
from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncBaseEntity, VeSyncDevice, is_humidifier
from .const import DEV_TYPE_TO_HA, DOMAIN, VS_DISCOVERY, VS_SWITCHES
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up switches."""
@callback
def discover(devices):
"""Add new devices to platform."""
_setup_entities(devices, async_add_entities)
config_entry.async_on_unload(
async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_SWITCHES), discover)
)
_setup_entities(
hass.data[DOMAIN][config_entry.entry_id][VS_SWITCHES], async_add_entities
)
@callback
def _setup_entities(devices, async_add_entities):
"""Check if device is online and add entity."""
entities = []
for dev in devices:
if DEV_TYPE_TO_HA.get(dev.device_type) == "outlet":
entities.append(VeSyncSwitchHA(dev))
elif DEV_TYPE_TO_HA.get(dev.device_type) == "switch":
entities.append(VeSyncLightSwitch(dev))
elif is_humidifier(dev.device_type):
entities.extend(
(
VeSyncHumidifierDisplayHA(dev),
VeSyncHumidifierAutomaticStopHA(dev),
VeSyncHumidifierAutoOnHA(dev),
)
)
else:
_LOGGER.warning(
"%s - Unknown device type - %s", dev.device_name, dev.device_type
)
continue
async_add_entities(entities, update_before_add=True)
class VeSyncBaseSwitch(VeSyncDevice, SwitchEntity):
"""Base class for VeSync switch Device Representations."""
def turn_on(self, **kwargs):
"""Turn the device on."""
self.device.turn_on()
class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity):
"""Representation of a VeSync switch."""
def __init__(self, plug):
"""Initialize the VeSync switch device."""
super().__init__(plug)
self.smartplug = plug
@property
def extra_state_attributes(self):
"""Return the state attributes of the device."""
return (
{
"voltage": self.smartplug.voltage,
"weekly_energy_total": self.smartplug.weekly_energy_total,
"monthly_energy_total": self.smartplug.monthly_energy_total,
"yearly_energy_total": self.smartplug.yearly_energy_total,
}
if hasattr(self.smartplug, "weekly_energy_total")
else {}
)
def update(self):
"""Update outlet details and energy usage."""
self.smartplug.update()
self.smartplug.update_energy()
class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity):
"""Handle representation of VeSync Light Switch."""
def __init__(self, switch):
"""Initialize Light Switch device class."""
super().__init__(switch)
self.switch = switch
class VeSyncHumidifierSwitchEntity(VeSyncBaseEntity, SwitchEntity):
"""Representation of a switch for configuring a VeSync humidifier."""
def __init__(self, humidifier):
"""Initialize the VeSync humidifier device."""
super().__init__(humidifier)
self.smarthumidifier = humidifier
@property
def entity_category(self):
"""Return the configuration entity category."""
return EntityCategory.CONFIG
class VeSyncHumidifierDisplayHA(VeSyncHumidifierSwitchEntity):
"""Representation of the display on a VeSync humidifier."""
@property
def unique_id(self):
"""Return the ID of this display."""
return f"{super().unique_id}-display"
@property
def name(self):
"""Return the name of the display."""
return f"{super().name} display"
@property
def is_on(self):
"""Return True if display is on."""
return self.device.details["display"]
def turn_on(self, **kwargs):
"""Turn the display on."""
self.device.turn_on_display()
def turn_off(self, **kwargs):
"""Turn the display off."""
self.device.turn_off_display()
class VeSyncHumidifierAutomaticStopHA(VeSyncHumidifierSwitchEntity):
"""Representation of the automatic stop toggle on a VeSync humidifier."""
@property
def unique_id(self):
"""Return the ID of this device."""
return f"{super().unique_id}-automatic-stop"
@property
def name(self):
"""Return the name of the device."""
return f"{super().name} automatic stop"
@property
def is_on(self):
"""Return True if automatic stop is on."""
return self.device.config["automatic_stop"]
def turn_on(self, **kwargs):
"""Turn the automatic stop on."""
self.device.automatic_stop_on()
def turn_off(self, **kwargs):
"""Turn the automatic stop off."""
self.device.automatic_stop_off()
class VeSyncHumidifierAutoOnHA(VeSyncHumidifierSwitchEntity):
"""Provide switch to turn off auto mode and set manual mist level 1 on a VeSync humidifier."""
@property
def unique_id(self):
"""Return the ID of this device."""
return f"{super().unique_id}-auto-mode"
@property
def name(self):
"""Return the name of the device."""
return f"{super().name} auto mode"
@property
def is_on(self):
"""Return True if in auto mode."""
return self.device.details["mode"] == "auto"
def turn_on(self, **kwargs):
"""Turn auto mode on."""
self.device.set_auto_mode()
def turn_off(self, **kwargs):
"""Turn auto off by setting manual and mist level 1."""
self.device.set_manual_mode()
self.device.set_mist_level(1)

View File

@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "\u041f\u0430\u0440\u043e\u043b\u0430",
"username": "E-mail \u0430\u0434\u0440\u0435\u0441"
},
"title": "\u0412\u044a\u0432\u0435\u0434\u0435\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e \u0438\u043c\u0435 \u0438 \u043f\u0430\u0440\u043e\u043b\u0430"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Ja configurat. Nom\u00e9s \u00e9s possible una sola configuraci\u00f3."
},
"error": {
"invalid_auth": "Autenticaci\u00f3 inv\u00e0lida"
},
"step": {
"user": {
"data": {
"password": "Contrasenya",
"username": "Correu electr\u00f2nic"
},
"title": "Introdueix el nom d'usuari i contrasenya"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Ji\u017e nastaveno. Je mo\u017en\u00e1 pouze jedin\u00e1 konfigurace."
},
"error": {
"invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed"
},
"step": {
"user": {
"data": {
"password": "Heslo",
"username": "E-mail"
},
"title": "Zadejte u\u017eivatelsk\u00e9 jm\u00e9no a heslo"
}
}
}
}

View File

@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "Adgangskode",
"username": "Emailadresse"
},
"title": "Indtast brugernavn og adgangskode"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Bereits konfiguriert. Nur eine einzige Konfiguration m\u00f6glich."
},
"error": {
"invalid_auth": "Ung\u00fcltige Authentifizierung"
},
"step": {
"user": {
"data": {
"password": "Passwort",
"username": "E-Mail"
},
"title": "Benutzername und Passwort eingeben"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "\u0388\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03c1\u03c5\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af. \u039c\u03cc\u03bd\u03bf \u03bc\u03af\u03b1 \u03b4\u03b9\u03b1\u03bc\u03cc\u03c1\u03c6\u03c9\u03c3\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae."
},
"error": {
"invalid_auth": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf\u03c2 \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2"
},
"step": {
"user": {
"data": {
"password": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2",
"username": "Email"
},
"title": "\u0395\u03b9\u03c3\u03ac\u03b3\u03b5\u03c4\u03b5 \u03cc\u03bd\u03bf\u03bc\u03b1 \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7 \u03ba\u03b1\u03b9 \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Already configured. Only a single configuration possible."
},
"error": {
"invalid_auth": "Invalid authentication"
},
"step": {
"user": {
"data": {
"password": "Password",
"username": "Email"
},
"title": "Enter Username and Password"
}
}
}
}

View File

@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "Contrase\u00f1a",
"username": "Direcci\u00f3n de correo electr\u00f3nico"
},
"title": "Ingrese nombre de usuario y contrase\u00f1a"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Ya est\u00e1 configurado. Solo es posible una \u00fanica configuraci\u00f3n."
},
"error": {
"invalid_auth": "Autenticaci\u00f3n no v\u00e1lida"
},
"step": {
"user": {
"data": {
"password": "Contrase\u00f1a",
"username": "Correo electr\u00f3nico"
},
"title": "Introduzca el nombre de usuario y la contrase\u00f1a"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Juba seadistatud. V\u00f5imalik on ainult \u00fcks seadistamine."
},
"error": {
"invalid_auth": "Tuvastamise viga"
},
"step": {
"user": {
"data": {
"password": "Salas\u00f5na",
"username": "E-post"
},
"title": "Sisesta kasutajanimi ja salas\u00f5na"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "D\u00e9j\u00e0 configur\u00e9. Une seule configuration possible."
},
"error": {
"invalid_auth": "Authentification invalide"
},
"step": {
"user": {
"data": {
"password": "Mot de passe",
"username": "Email"
},
"title": "Entrez vos identifiants"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "\u05ea\u05e6\u05d5\u05e8\u05ea\u05d5 \u05db\u05d1\u05e8 \u05e0\u05e7\u05d1\u05e2\u05d4. \u05e8\u05e7 \u05ea\u05e6\u05d5\u05e8\u05d4 \u05d0\u05d7\u05ea \u05d0\u05e4\u05e9\u05e8\u05d9\u05ea."
},
"error": {
"invalid_auth": "\u05d0\u05d9\u05de\u05d5\u05ea \u05dc\u05d0 \u05d7\u05d5\u05e7\u05d9"
},
"step": {
"user": {
"data": {
"password": "\u05e1\u05d9\u05e1\u05de\u05d4",
"username": "\u05d3\u05d5\u05d0\"\u05dc"
},
"title": "\u05d4\u05d6\u05df \u05e9\u05dd \u05de\u05e9\u05ea\u05de\u05e9 \u05d5\u05e1\u05d9\u05e1\u05de\u05d4"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "M\u00e1r konfigur\u00e1lva van. Csak egy konfigur\u00e1ci\u00f3 lehets\u00e9ges."
},
"error": {
"invalid_auth": "\u00c9rv\u00e9nytelen hiteles\u00edt\u00e9s"
},
"step": {
"user": {
"data": {
"password": "Jelsz\u00f3",
"username": "E-mail"
},
"title": "\u00cdrja be a felhaszn\u00e1l\u00f3nevet \u00e9s a jelsz\u00f3t"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Sudah dikonfigurasi. Hanya satu konfigurasi yang diizinkan."
},
"error": {
"invalid_auth": "Autentikasi tidak valid"
},
"step": {
"user": {
"data": {
"password": "Kata Sandi",
"username": "Email"
},
"title": "Masukkan Nama Pengguna dan Kata Sandi"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Gi\u00e0 configurato. \u00c8 possibile una sola configurazione."
},
"error": {
"invalid_auth": "Autenticazione non valida"
},
"step": {
"user": {
"data": {
"password": "Password",
"username": "Email"
},
"title": "Immettere nome utente e password"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "\u3059\u3067\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u5358\u4e00\u306e\u8a2d\u5b9a\u3057\u304b\u3067\u304d\u307e\u305b\u3093\u3002"
},
"error": {
"invalid_auth": "\u7121\u52b9\u306a\u8a8d\u8a3c"
},
"step": {
"user": {
"data": {
"password": "\u30d1\u30b9\u30ef\u30fc\u30c9",
"username": "E\u30e1\u30fc\u30eb"
},
"title": "\u30e6\u30fc\u30b6\u30fc\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "\uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ud558\ub098\uc758 \uc778\uc2a4\ud134\uc2a4\ub9cc \uad6c\uc131\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4."
},
"error": {
"invalid_auth": "\uc778\uc99d\uc774 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"password": "\ube44\ubc00\ubc88\ud638",
"username": "\uc774\uba54\uc77c"
},
"title": "\uc0ac\uc6a9\uc790 \uc774\ub984\uacfc \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud574\uc8fc\uc138\uc694"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Scho konfigur\u00e9iert. N\u00ebmmen eng eenzeg Konfiguratioun m\u00e9iglech."
},
"error": {
"invalid_auth": "Ong\u00eblteg Authentifikatioun"
},
"step": {
"user": {
"data": {
"password": "Passwuert",
"username": "E-Mail"
},
"title": "Benotzernumm a Passwuert aginn"
}
}
}
}

View File

@ -0,0 +1,12 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "Parole",
"username": "E-pasta adrese"
}
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Al geconfigureerd. Slecht \u00e9\u00e9n configuratie mogelijk."
},
"error": {
"invalid_auth": "Ongeldige authenticatie"
},
"step": {
"user": {
"data": {
"password": "Wachtwoord",
"username": "E-mail"
},
"title": "Voer gebruikersnaam en wachtwoord in"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Allerede konfigurert. Bare \u00e9n enkelt konfigurasjon er mulig."
},
"error": {
"invalid_auth": "Ugyldig godkjenning"
},
"step": {
"user": {
"data": {
"password": "Passord",
"username": "E-post"
},
"title": "Fyll inn brukernavn og passord"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Ju\u017c skonfigurowano. Mo\u017cliwa jest tylko jedna konfiguracja."
},
"error": {
"invalid_auth": "Niepoprawne uwierzytelnienie"
},
"step": {
"user": {
"data": {
"password": "Has\u0142o",
"username": "Adres e-mail"
},
"title": "Wprowad\u017a nazw\u0119 u\u017cytkownika i has\u0142o."
}
}
}
}

View File

@ -0,0 +1,12 @@
{
"config": {
"error": {
"invalid_auth": "Autentica\u00e7\u00e3o invalida"
},
"step": {
"user": {
"title": "Digite o nome de usu\u00e1rio e a senha"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "J\u00e1 configurado. Apenas uma \u00fanica configura\u00e7\u00e3o \u00e9 poss\u00edvel."
},
"error": {
"invalid_auth": "Autentica\u00e7\u00e3o inv\u00e1lida"
},
"step": {
"user": {
"data": {
"password": "Palavra-passe",
"username": "Endere\u00e7o de email"
},
"title": "Introduza o nome de utilizador e a palavra-passe"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e."
},
"error": {
"invalid_auth": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438."
},
"step": {
"user": {
"data": {
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"username": "\u0410\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b"
},
"title": "VeSync"
}
}
}
}

View File

@ -0,0 +1,14 @@
{
"config": {
"error": {
"invalid_auth": "Neplatn\u00e9 overenie"
},
"step": {
"user": {
"data": {
"username": "Email"
}
}
}
}
}

View File

@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "Geslo",
"username": "E-po\u0161tni naslov"
},
"title": "Vnesite uporabni\u0161ko Ime in Geslo"
}
}
}
}

View File

@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "L\u00f6senord",
"username": "E-postadress"
},
"title": "Ange anv\u00e4ndarnamn och l\u00f6senord"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "Zaten yap\u0131land\u0131r\u0131lm\u0131\u015f. Yaln\u0131zca tek bir konfig\u00fcrasyon m\u00fcmk\u00fcnd\u00fcr."
},
"error": {
"invalid_auth": "Ge\u00e7ersiz kimlik do\u011frulama"
},
"step": {
"user": {
"data": {
"password": "Parola",
"username": "E-posta"
},
"title": "Kullan\u0131c\u0131 Ad\u0131 ve \u015eifre Girin"
}
}
}
}

View File

@ -0,0 +1,19 @@
{
"config": {
"abort": {
"single_instance_allowed": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0436\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e. \u041c\u043e\u0436\u043d\u0430 \u0434\u043e\u0434\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u043e\u0434\u043d\u0443 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044e."
},
"error": {
"invalid_auth": "\u041d\u0435\u0432\u0456\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f."
},
"step": {
"user": {
"data": {
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"username": "\u0410\u0434\u0440\u0435\u0441\u0430 \u0435\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0457 \u043f\u043e\u0448\u0442\u0438"
},
"title": "VeSync"
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More