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:
Pawel 2018-11-21 15:48:44 +01:00 committed by Martin Hjelmare
parent 81cac33801
commit 92c0f9e4aa
2 changed files with 84 additions and 16 deletions

View file

@ -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

View file

@ -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, {