Fix mqtt cover inverted (#18456)
* Fixed state and position retrieval in inverted mode 100-0 * Always calculating find_percentage_in_range * Added usage of max/min functions.
This commit is contained in:
parent
81cac33801
commit
92c0f9e4aa
2 changed files with 84 additions and 16 deletions
|
@ -279,21 +279,19 @@ class MqttCover(MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo,
|
||||||
if self._template is not None:
|
if self._template is not None:
|
||||||
payload = self._template.async_render_with_possible_json_value(
|
payload = self._template.async_render_with_possible_json_value(
|
||||||
payload)
|
payload)
|
||||||
|
|
||||||
if payload.isnumeric():
|
if payload.isnumeric():
|
||||||
if 0 <= int(payload) <= 100:
|
percentage_payload = self.find_percentage_in_range(
|
||||||
percentage_payload = int(payload)
|
float(payload), COVER_PAYLOAD)
|
||||||
else:
|
self._position = percentage_payload
|
||||||
percentage_payload = self.find_percentage_in_range(
|
self._state = percentage_payload == DEFAULT_POSITION_CLOSED
|
||||||
float(payload), COVER_PAYLOAD)
|
|
||||||
if 0 <= percentage_payload <= 100:
|
|
||||||
self._position = percentage_payload
|
|
||||||
self._state = self._position == self._position_closed
|
|
||||||
else:
|
else:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Payload is not integer within range: %s",
|
"Payload is not integer within range: %s",
|
||||||
payload)
|
payload)
|
||||||
return
|
return
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
if self._get_position_topic:
|
if self._get_position_topic:
|
||||||
await mqtt.async_subscribe(
|
await mqtt.async_subscribe(
|
||||||
self.hass, self._get_position_topic,
|
self.hass, self._get_position_topic,
|
||||||
|
@ -374,7 +372,8 @@ class MqttCover(MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo,
|
||||||
# Optimistically assume that cover has changed state.
|
# Optimistically assume that cover has changed state.
|
||||||
self._state = False
|
self._state = False
|
||||||
if self._get_position_topic:
|
if self._get_position_topic:
|
||||||
self._position = self._position_open
|
self._position = self.find_percentage_in_range(
|
||||||
|
self._position_open, COVER_PAYLOAD)
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
async def async_close_cover(self, **kwargs):
|
async def async_close_cover(self, **kwargs):
|
||||||
|
@ -389,7 +388,8 @@ class MqttCover(MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo,
|
||||||
# Optimistically assume that cover has changed state.
|
# Optimistically assume that cover has changed state.
|
||||||
self._state = True
|
self._state = True
|
||||||
if self._get_position_topic:
|
if self._get_position_topic:
|
||||||
self._position = self._position_closed
|
self._position = self.find_percentage_in_range(
|
||||||
|
self._position_closed, COVER_PAYLOAD)
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
async def async_stop_cover(self, **kwargs):
|
async def async_stop_cover(self, **kwargs):
|
||||||
|
@ -469,6 +469,11 @@ class MqttCover(MqttAvailability, MqttDiscoveryUpdate, MqttEntityDeviceInfo,
|
||||||
offset_position = position - min_range
|
offset_position = position - min_range
|
||||||
position_percentage = round(
|
position_percentage = round(
|
||||||
float(offset_position) / current_range * 100.0)
|
float(offset_position) / current_range * 100.0)
|
||||||
|
|
||||||
|
max_percent = 100
|
||||||
|
min_percent = 0
|
||||||
|
position_percentage = min(max(position_percentage, min_percent),
|
||||||
|
max_percent)
|
||||||
if range_type == TILT_PAYLOAD and self._tilt_invert:
|
if range_type == TILT_PAYLOAD and self._tilt_invert:
|
||||||
return 100 - position_percentage
|
return 100 - position_percentage
|
||||||
return position_percentage
|
return position_percentage
|
||||||
|
|
|
@ -308,18 +308,81 @@ class TestCoverMQTT(unittest.TestCase):
|
||||||
'cover.test').attributes['current_position']
|
'cover.test').attributes['current_position']
|
||||||
assert 50 == current_cover_position
|
assert 50 == current_cover_position
|
||||||
|
|
||||||
fire_mqtt_message(self.hass, 'get-position-topic', '101')
|
|
||||||
self.hass.block_till_done()
|
|
||||||
current_cover_position = self.hass.states.get(
|
|
||||||
'cover.test').attributes['current_position']
|
|
||||||
assert 50 == current_cover_position
|
|
||||||
|
|
||||||
fire_mqtt_message(self.hass, 'get-position-topic', 'non-numeric')
|
fire_mqtt_message(self.hass, 'get-position-topic', 'non-numeric')
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
current_cover_position = self.hass.states.get(
|
current_cover_position = self.hass.states.get(
|
||||||
'cover.test').attributes['current_position']
|
'cover.test').attributes['current_position']
|
||||||
assert 50 == current_cover_position
|
assert 50 == current_cover_position
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'get-position-topic', '101')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
current_cover_position = self.hass.states.get(
|
||||||
|
'cover.test').attributes['current_position']
|
||||||
|
assert 100 == current_cover_position
|
||||||
|
|
||||||
|
def test_current_cover_position_inverted(self):
|
||||||
|
"""Test the current cover position."""
|
||||||
|
assert setup_component(self.hass, cover.DOMAIN, {
|
||||||
|
cover.DOMAIN: {
|
||||||
|
'platform': 'mqtt',
|
||||||
|
'name': 'test',
|
||||||
|
'position_topic': 'get-position-topic',
|
||||||
|
'command_topic': 'command-topic',
|
||||||
|
'position_open': 0,
|
||||||
|
'position_closed': 100,
|
||||||
|
'payload_open': 'OPEN',
|
||||||
|
'payload_close': 'CLOSE',
|
||||||
|
'payload_stop': 'STOP'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
state_attributes_dict = self.hass.states.get(
|
||||||
|
'cover.test').attributes
|
||||||
|
assert not ('current_position' in state_attributes_dict)
|
||||||
|
assert not ('current_tilt_position' in state_attributes_dict)
|
||||||
|
assert not (4 & self.hass.states.get(
|
||||||
|
'cover.test').attributes['supported_features'] == 4)
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'get-position-topic', '100')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
current_percentage_cover_position = self.hass.states.get(
|
||||||
|
'cover.test').attributes['current_position']
|
||||||
|
assert 0 == current_percentage_cover_position
|
||||||
|
assert STATE_CLOSED == self.hass.states.get(
|
||||||
|
'cover.test').state
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'get-position-topic', '0')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
current_percentage_cover_position = self.hass.states.get(
|
||||||
|
'cover.test').attributes['current_position']
|
||||||
|
assert 100 == current_percentage_cover_position
|
||||||
|
assert STATE_OPEN == self.hass.states.get(
|
||||||
|
'cover.test').state
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'get-position-topic', '50')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
current_percentage_cover_position = self.hass.states.get(
|
||||||
|
'cover.test').attributes['current_position']
|
||||||
|
assert 50 == current_percentage_cover_position
|
||||||
|
assert STATE_OPEN == self.hass.states.get(
|
||||||
|
'cover.test').state
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'get-position-topic', 'non-numeric')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
current_percentage_cover_position = self.hass.states.get(
|
||||||
|
'cover.test').attributes['current_position']
|
||||||
|
assert 50 == current_percentage_cover_position
|
||||||
|
assert STATE_OPEN == self.hass.states.get(
|
||||||
|
'cover.test').state
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'get-position-topic', '101')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
current_percentage_cover_position = self.hass.states.get(
|
||||||
|
'cover.test').attributes['current_position']
|
||||||
|
assert 0 == current_percentage_cover_position
|
||||||
|
assert STATE_CLOSED == self.hass.states.get(
|
||||||
|
'cover.test').state
|
||||||
|
|
||||||
def test_set_cover_position(self):
|
def test_set_cover_position(self):
|
||||||
"""Test setting cover position."""
|
"""Test setting cover position."""
|
||||||
assert setup_component(self.hass, cover.DOMAIN, {
|
assert setup_component(self.hass, cover.DOMAIN, {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue