home-assistant / home-assistant.io

:blue_book: Home Assistant User documentation
https://www.home-assistant.io
Other
4.85k stars 7.23k forks source link

Unclear information for MQTT cover stop #17501

Closed florinmihut closed 3 years ago

florinmihut commented 3 years ago

Feedback

I am controlling outdoor blinds over MQTT using an ESP8266 and micropython. I don't have any control over the actual position of the blinds and I am just simulating the remote. Interesting is that I am trying to have nice transitions e.g. open command would trigger opening->open. The problem is with stop. The stop command allows me to stop the blinds somewhere in between open and close. Sending the command works but the UI buttons on stop remain in the initial state. E.g. the blinds are open, the buttons stop and close are active, open is disabled. I press close, the icon will update, I see the states updating over MQTT, then during the process, I press stop - well in this case I would expect at least the buttons open and close to be active but somehow only stop and close are active in the stopped state.

I tried to set the position to a fake value like 50 since I was hopping that this would activate both buttons but no change. Force refreshing the page does not solve the problem.

So either there is some information missing regarding the states or how the buttons are disabled in UI does not really take in consideration the state stopped.

URL

https://www.home-assistant.io/integrations/cover.mqtt/

Version

2021.4.4

probot-home-assistant[bot] commented 3 years ago

Hey there @emontnemery, mind taking a look at this feedback as its been labeled with an integration (mqtt) you are listed as a codeowner for? Thanks! (message by CodeOwnersMention)

florinmihut commented 3 years ago

Found the problem in mqtt/cover.py:

if payload == self._config[CONF_STATE_STOPPED]: if self._config.get(CONF_GET_POSITION_TOPIC) is not None: self._state = ( STATE_CLOSED if self._position == DEFAULT_POSITION_CLOSED else STATE_OPEN ) else: self._state = ( STATE_CLOSED if self._state == STATE_CLOSING else STATE_OPEN )

If I understand this correctly, if stopped is received as state, it will internally set the state to closed or open (depending on the position if available, if not available, it will look at the previous state (e.g. if closing then the state is closed). This is wrong, it should handle the stopped state as intermediate state between open and closed.

thecode commented 3 years ago

From reading @florinmihut comment, I am not sure the information is not clear, but that he does not agree with the implementation. If I also followed the first description correctly, I think you are using wrong MQTT topics.

Can you add yaml with your MQTT cover configuration and the exact MQTT messages you sent, what was displayed in the UI after each message and what did you expect to be shown there?

florinmihut commented 3 years ago

Hi @thecode,

I have my own implementation of remotes using micropython. The topic "~/config", in this example, cover/living_room/lr_smalldoor/config :

{
         "~": "cover/living_room/lr_smalldoor",
         "name": "lr_smalldoor",
         "unique_id": "lr_smalldoor",
         "device_class": "shade",
         "state_topic": "~/state",
         "command_topic" : "~/set"
         "position_topic": "~/position",
}

In yaml I don't have anything because everything is enabled by default (mqtt discovery for example). As soon as the topic config is visible in network HA will show me the entities and I can put them in the UI. Then, I am using Entities Card to display them and they loom like this : Screenshot from 2021-04-22 21-56-26 The buttons in the right will change according to the values of the state, the icons on the left too.

The only problem with this is that if the state changes to stopped, I would expect to have both buttons up and down enabled (not grayed out).

What happens is that (what I saw as well in the code above) if I press the button down, it will disable button down and enable button up. All good so far! Now, if I press stop during my shades are rolling down, I would expect from that position to be able to go either way up and down thus both buttons must be enabled. Instead I will see this: Screenshot from 2021-04-22 22-08-30 Which is wrong, stop button should be disabled and up and down should be active.

Maybe I am using the wrong UI controls to display the entities. Or maybe the device type is wrong in MQTT. I don't know, but the behavior right now seems to be wrong from my point of view (or better said ignoring the stop state as per the code above).

Sorry for the long post! :)

florinmihut commented 3 years ago

I forgot to mention that I am setting the position to 50 in the state = stopped but no change.

thecode commented 3 years ago

About stop button, HA always leaves stop button enabled, even if device is stopped. I guess this is a safety measures, I have tested it in other cover integrations and this button is always left enabled. About the grayed buttons, I was the one who added the "stopped" state to MQTT covers, but it was not to control which buttons will be enabled, but to allow working with cover types which can only report if they are moving in open direction, in closing direction or not moving. So that when they report they are not moving the state open or close is calculated either by position or by last move direction.

Note that HA cover entity (not related to MQTT) has only 4 states as explain in the first paragraph: "A cover entity can be in states (open, opening, closed or closing)."

In order for your cover to have all 3 buttons enabled you need to do one of the following:

  1. Set it to optimistic mode, in this mode you can still report one of the 4 states above and the icons will show status correctly, but all 3 buttons will left enabled. Position topic is not needed.
  2. Report position status (which you have tried and did not work for you). When position status is reported it will enable/disable the up/down buttons. If position is 100, up button will be disabled, if position is 0, down button will be disabled. otherwise both will be enabled.

Since I understand option 2 did not work for you, please provide the exact messages you published and might also be good to have an MQTT log of the received messages. You can enable MQTT logs and core states so you can see in the logs what happens after each MQTT message, add this to configuration.yaml and restart HA:

logger:
  default: info
  logs:
    homeassistant.core: debug
    homeassistant.components.mqtt: debug

I have tested a configuration similar to yours and it worked correctly (with position_topic or optimistic: true). You can use HA built in MQTT publish service to debug your cover, so you do not need a real device to see the correct status in HA.

Bellow is the example configuration I used:

cover:
  - platform: mqtt
    name: "MQTT Cover"
    command_topic: "home-assistant/cover/set"
    state_topic: "home-assistant/cover/state"
    position_topic: "home-assistant/cover/position"
    payload_open: "OPEN"
    payload_close: "CLOSE"
    payload_stop: "STOP"
    state_open: "open"
    state_opening: "opening"
    state_closed: "closed"
    state_closing: "closing"
    #optimistic: true

And this is an example of position publish via HA:

image

Hope this helps, if you still have problems, please post logs and MQTT messages.

florinmihut commented 3 years ago

Hi,

Thanks for the quit response!

Here is what I found out:

  1. Using the optimistic mode - yes this solves the problem, all the buttons as active all the time - problem solved, since this implies less messages involved I will probably use it.
  2. The second method - I definitively I send the position, here is a screen capture using MQTT explorer of the HA server. Position is set in stopped state (although it is not supported) to 50 so both buttons should be active.

Screenshot from 2021-04-23 18-16-23

I see the traces that the cover is discovered and it is discovered with the position topic: 2021-04-23 13:34:56 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on homeassistant/cover/florin_room/fr_window/config: b'{ "~": "homeassistant/cover/florin_room/fr_window", "name": "fr_window", "unique_id": "fr_window", "device_class": "shade", "state_topic": "~/state", "position_topic": "~/position", "optimistic": "false", "command_topic" : "~/set" }' 2021-04-23 13:34:56 DEBUG (MainThread) [homeassistant.components.mqtt.discovery] Process discovery payload {'name': 'fr_window', 'unique_id': 'fr_window', 'device_class': 'shade', 'state_topic': 'homeassistant/cover/florin_room/fr_window/state', 'position_topic': 'homeassistant/cover/florin_room/fr_window/position', 'optimistic': 'false', 'command_topic': 'homeassistant/cover/florin_room/fr_window/set', 'platform': 'mqtt'} 2021-04-23 13:34:56 INFO (MainThread) [homeassistant.components.mqtt.discovery] Component has already been discovered: cover florin_room fr_window, sending update 2021-04-23 13:34:56 INFO (MainThread) [homeassistant.components.mqtt.mixins] Got update for entity with hash: ('cover', 'florin_room fr_window') '{'name': 'fr_window', 'unique_id': 'fr_window', 'device_class': 'shade', 'state_topic': 'homeassistant/cover/florin_room/fr_window/state', 'position_topic': 'homeassistant/cover/florin_room/fr_window/position', 'optimistic': 'false', 'command_topic': 'homeassistant/cover/florin_room/fr_window/set', 'platform': 'mqtt'}' 2021-04-23 13:34:56 INFO (MainThread) [homeassistant.components.mqtt.mixins] Updating component: cover.fr_window 2021-04-23 13:34:56 DEBUG (MainThread) [homeassistant.components.mqtt.discovery] Pending discovery for ('cover', 'florin_room fr_window'): deque([]) 2021-04-23 13:34:56 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on homeassistant/cover/florin_room/fr_window/state: b'open'

I see the stop state update too: 2021-04-23 13:35:11 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=cover, service=stop_cover, service_data=entity_id=cover.fr_window> 2021-04-23 13:35:11 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=mqtt, service=publish, service_data=topic=homeassistant/cover/florin_room/fr_window/set, qos=0, retain=False, payload=STOP> 2021-04-23 13:35:11 DEBUG (MainThread) [homeassistant.components.mqtt] Transmitting message on homeassistant/cover/florin_room/fr_window/set: 'STOP', mid: 26 2021-04-23 13:35:12 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on homeassistant/cover/florin_room/fr_window/state: b'stopped'

But I don't see the position notification - can be that HA did not notify on it?!

It is clearly send, but not be found in the HA traces. Do I have a typo somewhere that I don't see? When do you notify on the position? It is when you get the config payload? Or do I have to have something in the yaml?

florinmihut commented 3 years ago

Or maybe since the state stopped is not supported you disregard any message in that state until the device will return to a known state? BTW I forced optimistic to false to be sure that we debug second option.

florinmihut commented 3 years ago

Nope, position is definitively disregarded, even if I go in state open when I press stop and set position to 50, no change. Position is not visible in the entity list (not sure if it is supposed to be, just sayin').

thecode commented 3 years ago

In your screenshot above the position topic is missing an i

florinmihut commented 3 years ago

OMG, embarrassing, didn't saw that, although I was checking for typos. :) Sorry for the waste of time.