Bump hatasmota to 0.0.29 (#43013)
This commit is contained in:
parent
621a0a5dd2
commit
8cc7069323
7 changed files with 266 additions and 13 deletions
|
@ -3,7 +3,7 @@
|
||||||
"name": "Tasmota (beta)",
|
"name": "Tasmota (beta)",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/tasmota",
|
"documentation": "https://www.home-assistant.io/integrations/tasmota",
|
||||||
"requirements": ["hatasmota==0.0.27"],
|
"requirements": ["hatasmota==0.0.29"],
|
||||||
"dependencies": ["mqtt"],
|
"dependencies": ["mqtt"],
|
||||||
"mqtt": ["tasmota/discovery/#"],
|
"mqtt": ["tasmota/discovery/#"],
|
||||||
"codeowners": ["@emontnemery"]
|
"codeowners": ["@emontnemery"]
|
||||||
|
|
|
@ -95,8 +95,7 @@ class TasmotaAvailability(TasmotaEntity):
|
||||||
@callback
|
@callback
|
||||||
def availability_updated(self, available: bool) -> None:
|
def availability_updated(self, available: bool) -> None:
|
||||||
"""Handle updated availability."""
|
"""Handle updated availability."""
|
||||||
if available and not self._available:
|
self._tasmota_entity.poll_status()
|
||||||
self._tasmota_entity.poll_status()
|
|
||||||
self._available = available
|
self._available = available
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,19 @@ from typing import Optional
|
||||||
|
|
||||||
from hatasmota import status_sensor
|
from hatasmota import status_sensor
|
||||||
from hatasmota.const import (
|
from hatasmota.const import (
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER as TASMOTA_CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_PARTS_PER_BILLION as TASMOTA_CONCENTRATION_PARTS_PER_BILLION,
|
||||||
|
CONCENTRATION_PARTS_PER_MILLION as TASMOTA_CONCENTRATION_PARTS_PER_MILLION,
|
||||||
|
ELECTRICAL_CURRENT_AMPERE as TASMOTA_ELECTRICAL_CURRENT_AMPERE,
|
||||||
|
ELECTRICAL_VOLT_AMPERE as TASMOTA_ELECTRICAL_VOLT_AMPERE,
|
||||||
|
ENERGY_KILO_WATT_HOUR as TASMOTA_ENERGY_KILO_WATT_HOUR,
|
||||||
|
FREQUENCY_HERTZ as TASMOTA_FREQUENCY_HERTZ,
|
||||||
|
LENGTH_CENTIMETERS as TASMOTA_LENGTH_CENTIMETERS,
|
||||||
|
LIGHT_LUX as TASMOTA_LIGHT_LUX,
|
||||||
|
MASS_KILOGRAMS as TASMOTA_MASS_KILOGRAMS,
|
||||||
|
PERCENTAGE as TASMOTA_PERCENTAGE,
|
||||||
|
POWER_WATT as TASMOTA_POWER_WATT,
|
||||||
|
PRESSURE_HPA as TASMOTA_PRESSURE_HPA,
|
||||||
SENSOR_AMBIENT,
|
SENSOR_AMBIENT,
|
||||||
SENSOR_APPARENT_POWERUSAGE,
|
SENSOR_APPARENT_POWERUSAGE,
|
||||||
SENSOR_BATTERY,
|
SENSOR_BATTERY,
|
||||||
|
@ -35,12 +48,13 @@ from hatasmota.const import (
|
||||||
SENSOR_PROXIMITY,
|
SENSOR_PROXIMITY,
|
||||||
SENSOR_REACTIVE_POWERUSAGE,
|
SENSOR_REACTIVE_POWERUSAGE,
|
||||||
SENSOR_STATUS_IP,
|
SENSOR_STATUS_IP,
|
||||||
|
SENSOR_STATUS_LAST_RESTART_TIME,
|
||||||
SENSOR_STATUS_LINK_COUNT,
|
SENSOR_STATUS_LINK_COUNT,
|
||||||
SENSOR_STATUS_MQTT_COUNT,
|
SENSOR_STATUS_MQTT_COUNT,
|
||||||
SENSOR_STATUS_RESTART,
|
SENSOR_STATUS_RESTART_REASON,
|
||||||
SENSOR_STATUS_RSSI,
|
SENSOR_STATUS_RSSI,
|
||||||
SENSOR_STATUS_SIGNAL,
|
SENSOR_STATUS_SIGNAL,
|
||||||
SENSOR_STATUS_UPTIME,
|
SENSOR_STATUS_SSID,
|
||||||
SENSOR_TEMPERATURE,
|
SENSOR_TEMPERATURE,
|
||||||
SENSOR_TODAY,
|
SENSOR_TODAY,
|
||||||
SENSOR_TOTAL,
|
SENSOR_TOTAL,
|
||||||
|
@ -49,10 +63,21 @@ from hatasmota.const import (
|
||||||
SENSOR_VOLTAGE,
|
SENSOR_VOLTAGE,
|
||||||
SENSOR_WEIGHT,
|
SENSOR_WEIGHT,
|
||||||
SENSOR_YESTERDAY,
|
SENSOR_YESTERDAY,
|
||||||
|
SIGNAL_STRENGTH_DECIBELS as TASMOTA_SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR as TASMOTA_SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_METERS_PER_SECOND as TASMOTA_SPEED_METERS_PER_SECOND,
|
||||||
|
SPEED_MILES_PER_HOUR as TASMOTA_SPEED_MILES_PER_HOUR,
|
||||||
|
TEMP_CELSIUS as TASMOTA_TEMP_CELSIUS,
|
||||||
|
TEMP_FAHRENHEIT as TASMOTA_TEMP_FAHRENHEIT,
|
||||||
|
TEMP_KELVIN as TASMOTA_TEMP_KELVIN,
|
||||||
|
VOLT as TASMOTA_VOLT,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components import sensor
|
from homeassistant.components import sensor
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_PARTS_PER_BILLION,
|
||||||
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
DEVICE_CLASS_BATTERY,
|
DEVICE_CLASS_BATTERY,
|
||||||
DEVICE_CLASS_HUMIDITY,
|
DEVICE_CLASS_HUMIDITY,
|
||||||
DEVICE_CLASS_ILLUMINANCE,
|
DEVICE_CLASS_ILLUMINANCE,
|
||||||
|
@ -60,6 +85,25 @@ from homeassistant.const import (
|
||||||
DEVICE_CLASS_PRESSURE,
|
DEVICE_CLASS_PRESSURE,
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
DEVICE_CLASS_TEMPERATURE,
|
DEVICE_CLASS_TEMPERATURE,
|
||||||
|
DEVICE_CLASS_TIMESTAMP,
|
||||||
|
ELECTRICAL_CURRENT_AMPERE,
|
||||||
|
ELECTRICAL_VOLT_AMPERE,
|
||||||
|
ENERGY_KILO_WATT_HOUR,
|
||||||
|
FREQUENCY_HERTZ,
|
||||||
|
LENGTH_CENTIMETERS,
|
||||||
|
LIGHT_LUX,
|
||||||
|
MASS_KILOGRAMS,
|
||||||
|
PERCENTAGE,
|
||||||
|
POWER_WATT,
|
||||||
|
PRESSURE_HPA,
|
||||||
|
SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_METERS_PER_SECOND,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
|
TEMP_CELSIUS,
|
||||||
|
TEMP_FAHRENHEIT,
|
||||||
|
TEMP_KELVIN,
|
||||||
|
VOLT,
|
||||||
)
|
)
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
@ -108,10 +152,11 @@ SENSOR_DEVICE_CLASS_ICON_MAP = {
|
||||||
SENSOR_PRESSUREATSEALEVEL: {DEVICE_CLASS: DEVICE_CLASS_PRESSURE},
|
SENSOR_PRESSUREATSEALEVEL: {DEVICE_CLASS: DEVICE_CLASS_PRESSURE},
|
||||||
SENSOR_PROXIMITY: {ICON: "mdi:ruler"},
|
SENSOR_PROXIMITY: {ICON: "mdi:ruler"},
|
||||||
SENSOR_REACTIVE_POWERUSAGE: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
SENSOR_REACTIVE_POWERUSAGE: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
||||||
SENSOR_STATUS_RESTART: {ICON: "mdi:information-outline"},
|
SENSOR_STATUS_LAST_RESTART_TIME: {DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP},
|
||||||
|
SENSOR_STATUS_RESTART_REASON: {ICON: "mdi:information-outline"},
|
||||||
SENSOR_STATUS_SIGNAL: {DEVICE_CLASS: DEVICE_CLASS_SIGNAL_STRENGTH},
|
SENSOR_STATUS_SIGNAL: {DEVICE_CLASS: DEVICE_CLASS_SIGNAL_STRENGTH},
|
||||||
SENSOR_STATUS_RSSI: {ICON: "mdi:access-point"},
|
SENSOR_STATUS_RSSI: {ICON: "mdi:access-point"},
|
||||||
SENSOR_STATUS_UPTIME: {ICON: "mdi:progress-clock"},
|
SENSOR_STATUS_SSID: {ICON: "mdi:access-point-network"},
|
||||||
SENSOR_TEMPERATURE: {DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE},
|
SENSOR_TEMPERATURE: {DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE},
|
||||||
SENSOR_TODAY: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
SENSOR_TODAY: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
||||||
SENSOR_TOTAL: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
SENSOR_TOTAL: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
||||||
|
@ -122,6 +167,30 @@ SENSOR_DEVICE_CLASS_ICON_MAP = {
|
||||||
SENSOR_YESTERDAY: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
SENSOR_YESTERDAY: {DEVICE_CLASS: DEVICE_CLASS_POWER},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SENSOR_UNIT_MAP = {
|
||||||
|
TASMOTA_CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
TASMOTA_CONCENTRATION_PARTS_PER_BILLION: CONCENTRATION_PARTS_PER_BILLION,
|
||||||
|
TASMOTA_CONCENTRATION_PARTS_PER_MILLION: CONCENTRATION_PARTS_PER_MILLION,
|
||||||
|
TASMOTA_ELECTRICAL_CURRENT_AMPERE: ELECTRICAL_CURRENT_AMPERE,
|
||||||
|
TASMOTA_ELECTRICAL_VOLT_AMPERE: ELECTRICAL_VOLT_AMPERE,
|
||||||
|
TASMOTA_ENERGY_KILO_WATT_HOUR: ENERGY_KILO_WATT_HOUR,
|
||||||
|
TASMOTA_FREQUENCY_HERTZ: FREQUENCY_HERTZ,
|
||||||
|
TASMOTA_LENGTH_CENTIMETERS: LENGTH_CENTIMETERS,
|
||||||
|
TASMOTA_LIGHT_LUX: LIGHT_LUX,
|
||||||
|
TASMOTA_MASS_KILOGRAMS: MASS_KILOGRAMS,
|
||||||
|
TASMOTA_PERCENTAGE: PERCENTAGE,
|
||||||
|
TASMOTA_POWER_WATT: POWER_WATT,
|
||||||
|
TASMOTA_PRESSURE_HPA: PRESSURE_HPA,
|
||||||
|
TASMOTA_SIGNAL_STRENGTH_DECIBELS: SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
TASMOTA_SPEED_KILOMETERS_PER_HOUR: SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
TASMOTA_SPEED_METERS_PER_SECOND: SPEED_METERS_PER_SECOND,
|
||||||
|
TASMOTA_SPEED_MILES_PER_HOUR: SPEED_MILES_PER_HOUR,
|
||||||
|
TASMOTA_TEMP_CELSIUS: TEMP_CELSIUS,
|
||||||
|
TASMOTA_TEMP_FAHRENHEIT: TEMP_FAHRENHEIT,
|
||||||
|
TASMOTA_TEMP_KELVIN: TEMP_KELVIN,
|
||||||
|
TASMOTA_VOLT: VOLT,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Set up Tasmota sensor dynamically through discovery."""
|
"""Set up Tasmota sensor dynamically through discovery."""
|
||||||
|
@ -190,9 +259,11 @@ class TasmotaSensor(TasmotaAvailability, TasmotaDiscoveryUpdate, Entity):
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
"""Return the state of the entity."""
|
"""Return the state of the entity."""
|
||||||
|
if self._state and self.device_class == DEVICE_CLASS_TIMESTAMP:
|
||||||
|
return self._state.isoformat()
|
||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unit_of_measurement(self):
|
def unit_of_measurement(self):
|
||||||
"""Return the unit this state is expressed in."""
|
"""Return the unit this state is expressed in."""
|
||||||
return self._tasmota_entity.unit
|
return SENSOR_UNIT_MAP.get(self._tasmota_entity.unit, self._tasmota_entity.unit)
|
||||||
|
|
|
@ -741,7 +741,7 @@ hass-nabucasa==0.37.1
|
||||||
hass_splunk==0.1.1
|
hass_splunk==0.1.1
|
||||||
|
|
||||||
# homeassistant.components.tasmota
|
# homeassistant.components.tasmota
|
||||||
hatasmota==0.0.27
|
hatasmota==0.0.29
|
||||||
|
|
||||||
# homeassistant.components.jewish_calendar
|
# homeassistant.components.jewish_calendar
|
||||||
hdate==0.9.12
|
hdate==0.9.12
|
||||||
|
|
|
@ -376,7 +376,7 @@ hangups==0.4.11
|
||||||
hass-nabucasa==0.37.1
|
hass-nabucasa==0.37.1
|
||||||
|
|
||||||
# homeassistant.components.tasmota
|
# homeassistant.components.tasmota
|
||||||
hatasmota==0.0.27
|
hatasmota==0.0.29
|
||||||
|
|
||||||
# homeassistant.components.jewish_calendar
|
# homeassistant.components.jewish_calendar
|
||||||
hdate==0.9.12
|
hdate==0.9.12
|
||||||
|
|
|
@ -96,6 +96,54 @@ async def test_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota):
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
|
async def test_pushon_controlling_state_via_mqtt(hass, mqtt_mock, setup_tasmota):
|
||||||
|
"""Test state update via MQTT."""
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||||
|
config["swc"][0] = 13
|
||||||
|
mac = config["mac"]
|
||||||
|
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
f"{DEFAULT_PREFIX}/{mac}/config",
|
||||||
|
json.dumps(config),
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.test")
|
||||||
|
assert state.state == "unavailable"
|
||||||
|
assert not state.attributes.get(ATTR_ASSUMED_STATE)
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
|
||||||
|
state = hass.states.get("binary_sensor.test")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert not state.attributes.get(ATTR_ASSUMED_STATE)
|
||||||
|
|
||||||
|
# Test normal state update
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"ON"}}'
|
||||||
|
)
|
||||||
|
state = hass.states.get("binary_sensor.test")
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass, "tasmota_49A3BC/stat/RESULT", '{"Switch1":{"Action":"OFF"}}'
|
||||||
|
)
|
||||||
|
state = hass.states.get("binary_sensor.test")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
# Test periodic state update is ignored
|
||||||
|
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/SENSOR", '{"Switch1":"ON"}')
|
||||||
|
state = hass.states.get("binary_sensor.test")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
# Test polled state update is ignored
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass, "tasmota_49A3BC/stat/STATUS10", '{"StatusSNS":{"Switch1":"ON"}}'
|
||||||
|
)
|
||||||
|
state = hass.states.get("binary_sensor.test")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
async def test_friendly_names(hass, mqtt_mock, setup_tasmota):
|
async def test_friendly_names(hass, mqtt_mock, setup_tasmota):
|
||||||
"""Test state update via MQTT."""
|
"""Test state update via MQTT."""
|
||||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
"""The tests for the Tasmota sensor platform."""
|
"""The tests for the Tasmota sensor platform."""
|
||||||
import copy
|
import copy
|
||||||
|
import datetime
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
import hatasmota
|
||||||
from hatasmota.utils import (
|
from hatasmota.utils import (
|
||||||
get_topic_stat_status,
|
get_topic_stat_status,
|
||||||
get_topic_tele_sensor,
|
get_topic_tele_sensor,
|
||||||
|
@ -29,7 +31,7 @@ from .test_common import (
|
||||||
help_test_entity_id_update_subscriptions,
|
help_test_entity_id_update_subscriptions,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.async_mock import patch
|
from tests.async_mock import Mock, patch
|
||||||
from tests.common import async_fire_mqtt_message, async_fire_time_changed
|
from tests.common import async_fire_mqtt_message, async_fire_time_changed
|
||||||
|
|
||||||
DEFAULT_SENSOR_CONFIG = {
|
DEFAULT_SENSOR_CONFIG = {
|
||||||
|
@ -259,6 +261,7 @@ async def test_status_sensor_state_via_mqtt(hass, mqtt_mock, setup_tasmota):
|
||||||
async_fire_mqtt_message(
|
async_fire_mqtt_message(
|
||||||
hass, "tasmota_49A3BC/tele/STATE", '{"Wifi":{"Signal":20.5}}'
|
hass, "tasmota_49A3BC/tele/STATE", '{"Wifi":{"Signal":20.5}}'
|
||||||
)
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get("sensor.tasmota_status")
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
assert state.state == "20.5"
|
assert state.state == "20.5"
|
||||||
|
|
||||||
|
@ -268,10 +271,142 @@ async def test_status_sensor_state_via_mqtt(hass, mqtt_mock, setup_tasmota):
|
||||||
"tasmota_49A3BC/stat/STATUS11",
|
"tasmota_49A3BC/stat/STATUS11",
|
||||||
'{"StatusSTS":{"Wifi":{"Signal":20.0}}}',
|
'{"StatusSTS":{"Wifi":{"Signal":20.0}}}',
|
||||||
)
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get("sensor.tasmota_status")
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
assert state.state == "20.0"
|
assert state.state == "20.0"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("status_sensor_disabled", [False])
|
||||||
|
async def test_single_shot_status_sensor_state_via_mqtt(hass, mqtt_mock, setup_tasmota):
|
||||||
|
"""Test state update via MQTT."""
|
||||||
|
entity_reg = await hass.helpers.entity_registry.async_get_registry()
|
||||||
|
|
||||||
|
# Pre-enable the status sensor
|
||||||
|
entity_reg.async_get_or_create(
|
||||||
|
sensor.DOMAIN,
|
||||||
|
"tasmota",
|
||||||
|
"00000049A3BC_status_sensor_status_sensor_status_restart_reason",
|
||||||
|
suggested_object_id="tasmota_status",
|
||||||
|
disabled_by=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||||
|
mac = config["mac"]
|
||||||
|
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
f"{DEFAULT_PREFIX}/{mac}/config",
|
||||||
|
json.dumps(config),
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "unavailable"
|
||||||
|
assert not state.attributes.get(ATTR_ASSUMED_STATE)
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == STATE_UNKNOWN
|
||||||
|
assert not state.attributes.get(ATTR_ASSUMED_STATE)
|
||||||
|
|
||||||
|
# Test polled state update
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
"tasmota_49A3BC/stat/STATUS1",
|
||||||
|
'{"StatusPRM":{"RestartReason":"Some reason"}}',
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "Some reason"
|
||||||
|
|
||||||
|
# Test polled state update is ignored
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
"tasmota_49A3BC/stat/STATUS1",
|
||||||
|
'{"StatusPRM":{"RestartReason":"Another reason"}}',
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "Some reason"
|
||||||
|
|
||||||
|
# Device signals online again
|
||||||
|
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "Some reason"
|
||||||
|
|
||||||
|
# Test polled state update
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
"tasmota_49A3BC/stat/STATUS1",
|
||||||
|
'{"StatusPRM":{"RestartReason":"Another reason"}}',
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "Another reason"
|
||||||
|
|
||||||
|
# Test polled state update is ignored
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
"tasmota_49A3BC/stat/STATUS1",
|
||||||
|
'{"StatusPRM":{"RestartReason":"Third reason"}}',
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "Another reason"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("status_sensor_disabled", [False])
|
||||||
|
@patch.object(hatasmota.status_sensor, "datetime", Mock(wraps=datetime.datetime))
|
||||||
|
async def test_restart_time_status_sensor_state_via_mqtt(
|
||||||
|
hass, mqtt_mock, setup_tasmota
|
||||||
|
):
|
||||||
|
"""Test state update via MQTT."""
|
||||||
|
entity_reg = await hass.helpers.entity_registry.async_get_registry()
|
||||||
|
|
||||||
|
# Pre-enable the status sensor
|
||||||
|
entity_reg.async_get_or_create(
|
||||||
|
sensor.DOMAIN,
|
||||||
|
"tasmota",
|
||||||
|
"00000049A3BC_status_sensor_status_sensor_last_restart_time",
|
||||||
|
suggested_object_id="tasmota_status",
|
||||||
|
disabled_by=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||||
|
mac = config["mac"]
|
||||||
|
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
f"{DEFAULT_PREFIX}/{mac}/config",
|
||||||
|
json.dumps(config),
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "unavailable"
|
||||||
|
assert not state.attributes.get(ATTR_ASSUMED_STATE)
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, "tasmota_49A3BC/tele/LWT", "Online")
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == STATE_UNKNOWN
|
||||||
|
assert not state.attributes.get(ATTR_ASSUMED_STATE)
|
||||||
|
|
||||||
|
# Test polled state update
|
||||||
|
utc_now = datetime.datetime(2020, 11, 11, 8, 0, 0, tzinfo=dt.UTC)
|
||||||
|
hatasmota.status_sensor.datetime.now.return_value = utc_now
|
||||||
|
async_fire_mqtt_message(
|
||||||
|
hass,
|
||||||
|
"tasmota_49A3BC/stat/STATUS11",
|
||||||
|
'{"StatusSTS":{"UptimeSec":"3600"}}',
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
state = hass.states.get("sensor.tasmota_status")
|
||||||
|
assert state.state == "2020-11-11T07:00:00+00:00"
|
||||||
|
|
||||||
|
|
||||||
async def test_attributes(hass, mqtt_mock, setup_tasmota):
|
async def test_attributes(hass, mqtt_mock, setup_tasmota):
|
||||||
"""Test correct attributes for sensors."""
|
"""Test correct attributes for sensors."""
|
||||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||||
|
@ -301,7 +436,7 @@ async def test_attributes(hass, mqtt_mock, setup_tasmota):
|
||||||
assert state.attributes.get("device_class") == "temperature"
|
assert state.attributes.get("device_class") == "temperature"
|
||||||
assert state.attributes.get("friendly_name") == "Tasmota DHT11 Temperature"
|
assert state.attributes.get("friendly_name") == "Tasmota DHT11 Temperature"
|
||||||
assert state.attributes.get("icon") is None
|
assert state.attributes.get("icon") is None
|
||||||
assert state.attributes.get("unit_of_measurement") == "C"
|
assert state.attributes.get("unit_of_measurement") == "°C"
|
||||||
|
|
||||||
state = hass.states.get("sensor.tasmota_beer_CarbonDioxide")
|
state = hass.states.get("sensor.tasmota_beer_CarbonDioxide")
|
||||||
assert state.attributes.get("device_class") is None
|
assert state.attributes.get("device_class") is None
|
||||||
|
@ -371,7 +506,7 @@ async def test_indexed_sensor_attributes(hass, mqtt_mock, setup_tasmota):
|
||||||
assert state.attributes.get("device_class") == "temperature"
|
assert state.attributes.get("device_class") == "temperature"
|
||||||
assert state.attributes.get("friendly_name") == "Tasmota Dummy1 Temperature 0"
|
assert state.attributes.get("friendly_name") == "Tasmota Dummy1 Temperature 0"
|
||||||
assert state.attributes.get("icon") is None
|
assert state.attributes.get("icon") is None
|
||||||
assert state.attributes.get("unit_of_measurement") == "C"
|
assert state.attributes.get("unit_of_measurement") == "°C"
|
||||||
|
|
||||||
state = hass.states.get("sensor.tasmota_dummy2_carbondioxide_1")
|
state = hass.states.get("sensor.tasmota_dummy2_carbondioxide_1")
|
||||||
assert state.attributes.get("device_class") is None
|
assert state.attributes.get("device_class") is None
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue