Yup!
I believe there was one more thing - device_info for night light. Without that, this entity will be detached from device, and hang as separate entity.
It’s in light.py file. Please check, there’s if-statement for night light and separate class for it.
Hello. I followed the instructions above. I downloaded the zip and extracted it under “custom_components”. I see it there, the folder is vesync_formatbce and the permissions are identical to other components and the contents look to be ok, but after doing a server restart from the configuration panel, I only see the plain VeSync integration, not the vesync_formatbce.
Any ideas what I’m missing?
I’ll leave this post, just in case it helps someone else, but the answer was a browser restart. It just was caching the old integrations list.
Kertz1954:
Could you share the lovelace code that created the cards (that you captured in your post) in your HA configuration? It would save us all a bit of time!
paulearley
No problem. Here’s the one for the Levoit Humidifier Classic 300S
type: vertical-stack
cards:
-
type: markdown
content: Levoit Humidifier Classic 300S
style: |
ha-card
{
background-color: transparent;
box-shadow: 0px 0px;
border-top: 1px solid yellow;
border-left: 1px solid yellow;
border-right: 1px solid yellow;
border-bottom: 0px solid yellow;
border-radius: 20px 20px 0px 0px;
color: white;
text-align: center;
font-size: 26px;
line-height: 1px;
padding-bottom: 10px;
margin-bottom: -10px;
} -
type: horizontal-stack
cards:-
type: button
tap_action:
action: call-service
service: humidifier.set_mode
service_data:
mode: auto
target:
entity_id: humidifier.humber
icon: mdi:air-humidifier
icon_height: 44px
name: Auto
entity: humidifier.humber
show_state: false
show_icon: true
style: |
:host {}
ha-card
{
background-color: transparent;
box-shadow: 0px 0px;
border-top: 1px solid white;
border-left: 1px solid yellow;
border-right: 1px solid white;
border-bottom: 1px solid white;color: {% if states("humidifier.humber") == "on" and state_attr("humidifier.humber","mode") == "auto"%} yellow {% else %} white {% endif %}; --paper-item-icon-active-color: {% if states("humidifier.humber") == "on" and state_attr("humidifier.humber","mode") == "auto"%} yellow {% else %} white {% endif %};
}
-
type: button
tap_action:
action: call-service
service: humidifier.set_mode
service_data:
mode: manual low
target:
entity_id: humidifier.humber
icon: mdi:air-humidifier
icon_height: 44px
name: Low
entity: humidifier.humber
show_state: false
style: |
:host {}
ha-card
{
background-color: transparent;
box-shadow: 0px 0px;
color: {% if state_attr(“humidifier.humber”,“mode”) == “manual low” and
states(“humidifier.humber”) == “on” %}
yellow {% else %} white {% endif %};
border: 1px solid white;
–paper-item-icon-active-color: {% if state_attr(“humidifier.humber”,“mode”) == “manual low” %}
yellow {% else %} white {% endif %};
} -
type: button
tap_action:
action: call-service
service: humidifier.set_mode
service_data:
mode: manual mid
target:
entity_id: humidifier.humber
icon: mdi:air-humidifier
icon_height: 44px
name: Mid
entity: humidifier.humber
show_state: false
style: |
:host {}
ha-card
{
background-color: transparent;
box-shadow: 0px 0px;
color: {% if state_attr(“humidifier.humber”,“mode”) == “manual mid” and
states(“humidifier.humber”) == “on” %}
yellow {% else %} white {% endif %};
border: 1px solid white;
–paper-item-icon-active-color: {% if state_attr(“humidifier.humber”,“mode”) == “manual mid” %}
yellow {% else %} white {% endif %};
} -
type: button
tap_action:
action: call-service
service: humidifier.set_mode
service_data:
mode: manual high
target:
entity_id: humidifier.humber
icon: mdi:air-humidifier
icon_height: 44px
name: High
entity: humidifier.humber
show_state: false
style: |
:host {}
ha-card
{
background-color: transparent;
box-shadow: 0px 0px;
color: {% if state_attr(“humidifier.humber”,“mode”) == “manual high” and
states(“humidifier.humber”) == “on” %}
yellow {% else %} white {% endif %};
border: 1px solid white;
–paper-item-icon-active-color: {% if state_attr(“humidifier.humber”,“mode”) == “manual high” %}
yellow {% else %} white {% endif %};
} -
type: button
entity: humidifier.humber
icon: mdi:air-humidifier-off
show_state: false
show_icon: true
hold_action:
action: more-info
icon_height: 44px
tap_action:
action: call-service
service: humidifier.turn_off
service_data: {}
target:
entity_id: humidifier.humber
name: ‘Off’
style: |
:host {}
ha-card {
background-color: transparent;
box-shadow: 0px 0px;
border-top: 1px solid white;
border-left: 1px solid white;
border-right: 1px solid yellow;
border-bottom: 1px solid white;color: {% if states("humidifier.humber") == "off" %} yellow {% else %} white {% endif %}; --secondary-text-color: {% if states('humidifier.humber') == "off" %} white {% else %} yellow {% endif %}; --paper-item-icon-active-color: {% if states("humidifier.humber") == "off" %} yellow {% else %} white {% endif %}; --paper-item-icon-color: {% if states("humidifier.humber") == "off" %} yellow {% else %} white {% endif %};
}
-
-
type: humidifier
entity: humidifier.humber
name: Target Humidity
style: |
ha-card {
background-color: transparent;
box-shadow: 0px 0px;
border-top: 0px solid white;
border-left: 1px solid yellow;
border-right: 1px solid yellow;
border-bottom: 0px solid white;color: {% if states('humidifier.humber') == "off" %} white {% else %} yellow {% endif %}; --primary-text-color: {% if states('humidifier.humber') == "off" %} white {% else %} yellow {% endif %}; --secondary-text-color: {% if states('humidifier.humber') == "off" %} white {% else %} yellow {% endif %}; animation: blink 0s linear infinite; background-image: {% if states('sensor.plug_ah_milliamps') | float(default=0) != 0 and states('humidifier.humber') != "off" %} url("/local/images/humidifier-on.gif") {% endif %}; background-repeat: no-repeat; background-size: 100% 100%; padding-top: 11px; margin-top: -11px;
}
-
type: entities
entities:-
icon: mdi:air-humidifier
name: Current Humidifier Humidity
state: ‘{{state_attr(“humidifier.humber”,“current_humidity”)}} %’
type: custom:template-entity-row -
icon: mdi:air-humidifier
name: Mode
state: >-
{% if state_attr(“humidifier.humber”,“mode”) == “manual low” %} Manual
Low {% elif state_attr(“humidifier.humber”,“mode”) == “manual mid” %}
Manual Medium {% elif state_attr(“humidifier.humber”,“mode”) ==
“manual high” %} Manual High{% elif state_attr(“humidifier.humber”,“mode”) == “auto” and
state_attr(“humidifier.humber”,“current_humidity”) <
state_attr(“humidifier.humber”,“humidity”) and
states(“humidifier.humber”) == “on” %} Auto {% else %} Auto
Standby {% endif %}
type: custom:template-entity-row -
icon: mdi:air-humidifier
name: Current Room Humidity
state: ‘{{states(“sensor.bme280_humidity”)| round(default=0) }} %’
type: custom:template-entity-row -
icon: mdi:air-humidifier
name: Refill Water Tank
state: ‘{{state_attr(“humidifier.humber”,“water_lacks”)}}’
type: custom:template-entity-row
style: |
:host {
–paper-item-icon-color: white;
}
#states > * {
margin: -9px 0px !important;
}
ha-card
{
background-color: transparent;
box-shadow: 0px 0px;
border-top: 0px solid yellow;
border-left: 1px solid yellow;
border-right: 1px solid yellow;
border-bottom: 1px solid yellow;
border-radius: 0px 0px 20px 20px;
color: white;
margin-top: -11px;
}
show_header_toggle: false -
I’ve been using your custom integration for a few weeks with the Classic 300S, and everything has been working great, humidity target, mode setting, display and light. I recently got the Dual 200S (which doesn’t have a light), and when the device was added to the HA integration, the light entity of the 300S disappeared. I tried deleting and rebooting HA with no luck. I still can control target level, mode and display on/off for both devices but not the light of the 300S.
I read that there’s still issues with the night light, but is there anything else I can try to get it working again?
Hi!
Logs would help greatly to identify exact issue. But on first glance it looks like lagging of API.
Hi! Thank you for replying so fast. Yeah after reading through this thread, it seems like it’s an API issue.
Here’s the log for the homeassistant.components.light, let me know if I can do anything else to help you with this project.
Logger: homeassistant.components.light
Source: custom_components/vesync_formatbce/light.py:50
Integration: Light (documentation, issues)
First occurred: 10:25:34 AM (1 occurrences)
Last logged: 10:25:34 AM
Error while setting up vesync_formatbce platform for light
Traceback (most recent call last): File “/usr/src/homeassistant/homeassistant/helpers/entity_platform.py”, line 249, in _async_setup_platform await asyncio.shield(task) File “/config/custom_components/vesync_formatbce/light.py”, line 40, in async_setup_entry _async_setup_entities(hass.data[DOMAIN][VS_LIGHTS], async_add_entities) File “/config/custom_components/vesync_formatbce/light.py”, line 50, in _async_setup_entities elif DEV_TYPE_TO_HA.get(dev.device_type) in (“bulb-tunable-white”): TypeError: 'in ’ requires string as left operand, not NoneType
Ok, it’s not the API.
It’s actually a bug.
I will fix it ASAP. Looks like it tries to add light for 200s.
Awesome! Thanks!
Please try latest code and check if it works.
Tried it, and everything is working including the night light of the 300S. I’ll report back in a week or so. Thanks again!
Perfect. Thanks for reporting!
Hmm, mine is in same place.
Maybe, some errors in logs after restarting HA?
Hi, 1st of all thanks for your work
i installed ur custom component but dont show any devices…
I have a Dual 200S humidifier, whats wrong?
Hello!
Could you please check HA logs related to integration?
Also, make sure that you have this device configured in VeSync application.
This is only i can see in logs
Logger: homeassistant.config_entries
Source: helpers/entity_component.py:172
First occurred: 17:49:07 (4 occurrences)
Last logged: 17:49:07
Error unloading entry *******@gmail.com for switch
Error unloading entry ********@gmail.com for fan
Error unloading entry *********@gmail.com for light
Error unloading entry *********@gmail.com for humidifier
Traceback (most recent call last):
File “/usr/src/homeassistant/homeassistant/config_entries.py”, line 466, in async_unload
result = await component.async_unload_entry(hass, self)
File “/usr/src/homeassistant/homeassistant/components/switch/init.py”, line 95, in async_unload_entry
return await component.async_unload_entry(entry)
File “/usr/src/homeassistant/homeassistant/helpers/entity_component.py”, line 172, in async_unload_entry
raise ValueError(“Config entry was never loaded!”)
ValueError: Config entry was never loaded!
I have my humidifier in the vesync App, Maybe not compatible? This is my model:
https://levoit.com/products/dual-200s-smart-top-fill-humidifier
Thanks
Logs showing, that you tried to delete integration, maybe?
Can you try to delete, restart HA and configure integration again?
Also pls make sure you have latest code.
Other that that, I can’t suggest, what’s going wrong.
There is the way to debug this on lower level: using pyvesync library on PC. If you’re getting desperate, please check it out.
I tried and nothing, only show This ok log
Logger: homeassistant.helpers.frame
Source: helpers/frame.py:103
First occurred: 18:28:19 (2 occurrences)
Last logged: 18:28:19
Detected integration that accessed discovery_info.contains(‘ssdp_location’) instead of discovery_info.upnp.contains(‘ssdp_location’) or discovery_info.ssdp_headers.contains(‘ssdp_location’); this will fail in version 2022.6. Please report issue for upnp using this method at homeassistant/components/upnp/device.py, line 78: if ssdp.ATTR_SSDP_LOCATION not in headers:
Detected integration that accessed discovery_info[‘ssdp_location’] instead of discovery_info.ssdp_location, discovery_info.upnp[‘ssdp_location’] or discovery_info.ssdp_headers[‘ssdp_location’]; this will fail in version 2022.6. Please report issue for upnp using this method at homeassistant/components/upnp/device.py, line 81: location = headers[ssdp.ATTR_SSDP_LOCATION]
Maybe not related with the humidifier.