diff --git a/homeassistant/components/daikin/sensor.py b/homeassistant/components/daikin/sensor.py index e3e2e6a0f27..2982abd261c 100644 --- a/homeassistant/components/daikin/sensor.py +++ b/homeassistant/components/daikin/sensor.py @@ -1,17 +1,11 @@ """Support for Daikin AC sensors.""" import logging -from homeassistant.const import CONF_ICON, CONF_NAME, CONF_TYPE +from homeassistant.const import CONF_ICON, CONF_NAME, TEMP_CELSIUS from homeassistant.helpers.entity import Entity -from homeassistant.util.unit_system import UnitSystem from . import DOMAIN as DAIKIN_DOMAIN -from .const import ( - ATTR_INSIDE_TEMPERATURE, - ATTR_OUTSIDE_TEMPERATURE, - SENSOR_TYPE_TEMPERATURE, - SENSOR_TYPES, -) +from .const import ATTR_INSIDE_TEMPERATURE, ATTR_OUTSIDE_TEMPERATURE, SENSOR_TYPES _LOGGER = logging.getLogger(__name__) @@ -31,30 +25,19 @@ async def async_setup_entry(hass, entry, async_add_entities): sensors = [ATTR_INSIDE_TEMPERATURE] if daikin_api.device.support_outside_temperature: sensors.append(ATTR_OUTSIDE_TEMPERATURE) - async_add_entities( - [ - DaikinClimateSensor(daikin_api, sensor, hass.config.units) - for sensor in sensors - ] - ) + async_add_entities([DaikinClimateSensor(daikin_api, sensor) for sensor in sensors]) class DaikinClimateSensor(Entity): """Representation of a Sensor.""" - def __init__(self, api, monitored_state, units: UnitSystem, name=None) -> None: + def __init__(self, api, monitored_state) -> None: """Initialize the sensor.""" self._api = api - self._sensor = SENSOR_TYPES.get(monitored_state) - if name is None: - name = f"{self._sensor[CONF_NAME]} {api.name}" - - self._name = f"{name} {monitored_state.replace('_', ' ')}" + self._sensor = SENSOR_TYPES[monitored_state] + self._name = f"{api.name} {self._sensor[CONF_NAME]}" self._device_attribute = monitored_state - if self._sensor[CONF_TYPE] == SENSOR_TYPE_TEMPERATURE: - self._unit_of_measurement = units.temperature_unit - @property def unique_id(self): """Return a unique ID.""" @@ -82,7 +65,7 @@ class DaikinClimateSensor(Entity): @property def unit_of_measurement(self): """Return the unit of measurement.""" - return self._unit_of_measurement + return TEMP_CELSIUS async def async_update(self): """Retrieve latest state.""" diff --git a/homeassistant/components/elkm1/__init__.py b/homeassistant/components/elkm1/__init__.py index 183897d306e..5c6fbf71738 100644 --- a/homeassistant/components/elkm1/__init__.py +++ b/homeassistant/components/elkm1/__init__.py @@ -39,7 +39,7 @@ from .const import ( ELK_ELEMENTS, ) -SYNC_TIMEOUT = 55 +SYNC_TIMEOUT = 120 _LOGGER = logging.getLogger(__name__) @@ -215,7 +215,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): if not await async_wait_for_elk_to_sync(elk, SYNC_TIMEOUT): _LOGGER.error( - "Timed out after %d seconds while trying to sync with ElkM1", SYNC_TIMEOUT, + "Timed out after %d seconds while trying to sync with ElkM1 at %s", + SYNC_TIMEOUT, + conf[CONF_HOST], ) elk.disconnect() raise ConfigEntryNotReady diff --git a/homeassistant/components/elkm1/config_flow.py b/homeassistant/components/elkm1/config_flow.py index cad3ecac42a..c96e6e549c0 100644 --- a/homeassistant/components/elkm1/config_flow.py +++ b/homeassistant/components/elkm1/config_flow.py @@ -64,8 +64,9 @@ async def validate_input(data): timed_out = False if not await async_wait_for_elk_to_sync(elk, VALIDATE_TIMEOUT): _LOGGER.error( - "Timed out after %d seconds while trying to sync with elkm1", + "Timed out after %d seconds while trying to sync with ElkM1 at %s", VALIDATE_TIMEOUT, + url, ) timed_out = True diff --git a/homeassistant/components/here_travel_time/sensor.py b/homeassistant/components/here_travel_time/sensor.py index c88aeb8e5a0..f73d3bccaa6 100644 --- a/homeassistant/components/here_travel_time/sensor.py +++ b/homeassistant/components/here_travel_time/sensor.py @@ -424,6 +424,9 @@ class HERETravelTimeData: if departure is not None: departure = convert_time_to_isodate(departure) + if departure is None and arrival is None: + departure = "now" + _LOGGER.debug( "Requesting route for origin: %s, destination: %s, route_mode: %s, mode: %s, traffic_mode: %s, arrival: %s, departure: %s", origin, diff --git a/homeassistant/components/intesishome/manifest.json b/homeassistant/components/intesishome/manifest.json index f1647f5d97e..e38e1a7dd3b 100644 --- a/homeassistant/components/intesishome/manifest.json +++ b/homeassistant/components/intesishome/manifest.json @@ -4,5 +4,5 @@ "documentation": "https://www.home-assistant.io/integrations/intesishome", "dependencies": [], "codeowners": ["@jnimmo"], - "requirements": ["pyintesishome==1.7.1"] + "requirements": ["pyintesishome==1.7.3"] } diff --git a/homeassistant/components/lutron_caseta/light.py b/homeassistant/components/lutron_caseta/light.py index ba4342ecfce..350c35fffa8 100644 --- a/homeassistant/components/lutron_caseta/light.py +++ b/homeassistant/components/lutron_caseta/light.py @@ -15,7 +15,7 @@ _LOGGER = logging.getLogger(__name__) def to_lutron_level(level): """Convert the given Home Assistant light level (0-255) to Lutron (0-100).""" - return int((level * 100) // 255) + return int(round((level * 100) / 255)) def to_hass_level(level): diff --git a/homeassistant/components/nexia/climate.py b/homeassistant/components/nexia/climate.py index 8af1be20b1e..d7e93e511fb 100644 --- a/homeassistant/components/nexia/climate.py +++ b/homeassistant/components/nexia/climate.py @@ -2,7 +2,6 @@ import logging from nexia.const import ( - FAN_MODES, OPERATION_MODE_AUTO, OPERATION_MODE_COOL, OPERATION_MODE_HEAT, @@ -192,7 +191,7 @@ class NexiaZone(NexiaThermostatZoneEntity, ClimateDevice): @property def fan_modes(self): """Return the list of available fan modes.""" - return FAN_MODES + return self._thermostat.get_fan_modes() @property def min_temp(self): diff --git a/homeassistant/components/nexia/manifest.json b/homeassistant/components/nexia/manifest.json index 2102a2a8225..a58330ad227 100644 --- a/homeassistant/components/nexia/manifest.json +++ b/homeassistant/components/nexia/manifest.json @@ -1,7 +1,7 @@ { "domain": "nexia", "name": "Nexia", - "requirements": ["nexia==0.8.2"], + "requirements": ["nexia==0.9.1"], "codeowners": ["@ryannazaretian", "@bdraco"], "documentation": "https://www.home-assistant.io/integrations/nexia", "config_flow": true diff --git a/homeassistant/components/nut/__init__.py b/homeassistant/components/nut/__init__.py index a990cdf94b8..b8561dde303 100644 --- a/homeassistant/components/nut/__init__.py +++ b/homeassistant/components/nut/__init__.py @@ -109,7 +109,7 @@ def _firmware_from_status(status): def _serial_from_status(status): """Find the best serialvalue from the status.""" serial = status.get("device.serial") or status.get("ups.serial") - if serial and serial == "unknown": + if serial and (serial.lower() == "unknown" or serial.count("0") == len(serial)): return None return serial diff --git a/homeassistant/components/sense/__init__.py b/homeassistant/components/sense/__init__.py index 80e75bce400..f295b0d926c 100644 --- a/homeassistant/components/sense/__init__.py +++ b/homeassistant/components/sense/__init__.py @@ -17,6 +17,7 @@ from homeassistant.exceptions import ConfigEntryNotReady import homeassistant.helpers.config_validation as cv from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_track_time_interval +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( ACTIVE_UPDATE_RATE, @@ -27,6 +28,7 @@ from .const import ( SENSE_DEVICES_DATA, SENSE_DISCOVERED_DEVICES_DATA, SENSE_TIMEOUT_EXCEPTIONS, + SENSE_TRENDS_COORDINATOR, ) _LOGGER = logging.getLogger(__name__) @@ -111,9 +113,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): except SENSE_TIMEOUT_EXCEPTIONS: raise ConfigEntryNotReady + trends_coordinator = DataUpdateCoordinator( + hass, + _LOGGER, + name=f"Sense Trends {email}", + update_method=gateway.update_trend_data, + update_interval=timedelta(seconds=300), + ) + + # This can take longer than 60s and we already know + # sense is online since get_discovered_device_data was + # successful so we do it later. + hass.loop.create_task(trends_coordinator.async_request_refresh()) + hass.data[DOMAIN][entry.entry_id] = { SENSE_DATA: gateway, SENSE_DEVICES_DATA: sense_devices_data, + SENSE_TRENDS_COORDINATOR: trends_coordinator, SENSE_DISCOVERED_DEVICES_DATA: sense_discovered_devices, } @@ -122,7 +138,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): hass.config_entries.async_forward_entry_setup(entry, component) ) - async def async_sense_update(now): + async def async_sense_update(_): """Retrieve latest state.""" try: await gateway.update_realtime() diff --git a/homeassistant/components/sense/binary_sensor.py b/homeassistant/components/sense/binary_sensor.py index 50fb3fd7dc7..af1b2f34b4a 100644 --- a/homeassistant/components/sense/binary_sensor.py +++ b/homeassistant/components/sense/binary_sensor.py @@ -71,7 +71,6 @@ class SenseDevice(BinarySensorDevice): self._unique_id = f"{sense_monitor_id}-{self._id}" self._icon = sense_to_mdi(device["icon"]) self._sense_devices_data = sense_devices_data - self._undo_dispatch_subscription = None self._state = None self._available = False @@ -117,17 +116,14 @@ class SenseDevice(BinarySensorDevice): async def async_added_to_hass(self): """Register callbacks.""" - self._undo_dispatch_subscription = async_dispatcher_connect( - self.hass, - f"{SENSE_DEVICE_UPDATE}-{self._sense_monitor_id}", - self._async_update_from_data, + self.async_on_remove( + async_dispatcher_connect( + self.hass, + f"{SENSE_DEVICE_UPDATE}-{self._sense_monitor_id}", + self._async_update_from_data, + ) ) - async def async_will_remove_from_hass(self): - """Undo subscription.""" - if self._undo_dispatch_subscription: - self._undo_dispatch_subscription() - @callback def _async_update_from_data(self): """Get the latest data, update state. Must not do I/O.""" diff --git a/homeassistant/components/sense/const.py b/homeassistant/components/sense/const.py index 882c3c9d79f..cd1d2bfcf4a 100644 --- a/homeassistant/components/sense/const.py +++ b/homeassistant/components/sense/const.py @@ -12,6 +12,7 @@ SENSE_DATA = "sense_data" SENSE_DEVICE_UPDATE = "sense_devices_update" SENSE_DEVICES_DATA = "sense_devices_data" SENSE_DISCOVERED_DEVICES_DATA = "sense_discovered_devices" +SENSE_TRENDS_COORDINATOR = "sense_trends_coorindator" ACTIVE_NAME = "Energy" ACTIVE_TYPE = "active" diff --git a/homeassistant/components/sense/sensor.py b/homeassistant/components/sense/sensor.py index 06cfb90d2b5..0c6bfd7ee1f 100644 --- a/homeassistant/components/sense/sensor.py +++ b/homeassistant/components/sense/sensor.py @@ -1,12 +1,10 @@ """Support for monitoring a Sense energy sensor.""" -from datetime import timedelta import logging from homeassistant.const import DEVICE_CLASS_POWER, ENERGY_KILO_WATT_HOUR, POWER_WATT from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity -from homeassistant.util import Throttle from .const import ( ACTIVE_NAME, @@ -22,12 +20,9 @@ from .const import ( SENSE_DEVICE_UPDATE, SENSE_DEVICES_DATA, SENSE_DISCOVERED_DEVICES_DATA, - SENSE_TIMEOUT_EXCEPTIONS, + SENSE_TRENDS_COORDINATOR, ) -MIN_TIME_BETWEEN_DAILY_UPDATES = timedelta(seconds=300) - - _LOGGER = logging.getLogger(__name__) @@ -64,17 +59,18 @@ async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the Sense sensor.""" data = hass.data[DOMAIN][config_entry.entry_id][SENSE_DATA] sense_devices_data = hass.data[DOMAIN][config_entry.entry_id][SENSE_DEVICES_DATA] + trends_coordinator = hass.data[DOMAIN][config_entry.entry_id][ + SENSE_TRENDS_COORDINATOR + ] - @Throttle(MIN_TIME_BETWEEN_DAILY_UPDATES) - async def update_trends(): - """Update the daily power usage.""" - await data.update_trend_data() + # Request only in case it takes longer + # than 60s + await trends_coordinator.async_request_refresh() sense_monitor_id = data.sense_monitor_id sense_devices = hass.data[DOMAIN][config_entry.entry_id][ SENSE_DISCOVERED_DEVICES_DATA ] - await data.update_trend_data() devices = [ SenseEnergyDevice(sense_devices_data, device, sense_monitor_id) @@ -108,8 +104,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): name, sensor_type, is_production, - update_trends, - var, + trends_coordinator, unique_id, ) ) @@ -140,7 +135,6 @@ class SenseActiveSensor(Entity): self._sensor_type = sensor_type self._is_production = is_production self._state = None - self._undo_dispatch_subscription = None @property def name(self): @@ -179,17 +173,14 @@ class SenseActiveSensor(Entity): async def async_added_to_hass(self): """Register callbacks.""" - self._undo_dispatch_subscription = async_dispatcher_connect( - self.hass, - f"{SENSE_DEVICE_UPDATE}-{self._sense_monitor_id}", - self._async_update_from_data, + self.async_on_remove( + async_dispatcher_connect( + self.hass, + f"{SENSE_DEVICE_UPDATE}-{self._sense_monitor_id}", + self._async_update_from_data, + ) ) - async def async_will_remove_from_hass(self): - """Undo subscription.""" - if self._undo_dispatch_subscription: - self._undo_dispatch_subscription() - @callback def _async_update_from_data(self): """Update the sensor from the data. Must not do I/O.""" @@ -206,7 +197,7 @@ class SenseTrendsSensor(Entity): """Implementation of a Sense energy sensor.""" def __init__( - self, data, name, sensor_type, is_production, update_call, sensor_id, unique_id + self, data, name, sensor_type, is_production, trends_coordinator, unique_id, ): """Initialize the Sense sensor.""" name_type = PRODUCTION_NAME if is_production else CONSUMPTION_NAME @@ -215,10 +206,11 @@ class SenseTrendsSensor(Entity): self._available = False self._data = data self._sensor_type = sensor_type - self.update_sensor = update_call + self._coordinator = trends_coordinator self._is_production = is_production self._state = None self._unit_of_measurement = ENERGY_KILO_WATT_HOUR + self._had_any_update = False @property def name(self): @@ -228,12 +220,12 @@ class SenseTrendsSensor(Entity): @property def state(self): """Return the state of the sensor.""" - return self._state + return round(self._data.get_trend(self._sensor_type, self._is_production), 1) @property def available(self): - """Return the availability of the sensor.""" - return self._available + """Return if entity is available.""" + return self._had_any_update and self._coordinator.last_update_success @property def unit_of_measurement(self): @@ -250,18 +242,27 @@ class SenseTrendsSensor(Entity): """Return the unique id.""" return self._unique_id + @property + def should_poll(self): + """No need to poll. Coordinator notifies entity of updates.""" + return False + + @callback + def _async_update(self): + """Track if we had an update so we do not report zero data.""" + self._had_any_update = True + self.async_write_ha_state() + async def async_update(self): - """Get the latest data, update state.""" + """Update the entity. - try: - await self.update_sensor() - except SENSE_TIMEOUT_EXCEPTIONS: - _LOGGER.error("Timeout retrieving data") - return + Only used by the generic entity update service. + """ + await self._coordinator.async_request_refresh() - state = self._data.get_trend(self._sensor_type, self._is_production) - self._state = round(state, 1) - self._available = True + async def async_added_to_hass(self): + """When entity is added to hass.""" + self.async_on_remove(self._coordinator.async_add_listener(self._async_update)) class SenseEnergyDevice(Entity): @@ -276,7 +277,6 @@ class SenseEnergyDevice(Entity): self._unique_id = f"{sense_monitor_id}-{self._id}-{CONSUMPTION_ID}" self._icon = sense_to_mdi(device["icon"]) self._sense_devices_data = sense_devices_data - self._undo_dispatch_subscription = None self._state = None @property @@ -321,17 +321,14 @@ class SenseEnergyDevice(Entity): async def async_added_to_hass(self): """Register callbacks.""" - self._undo_dispatch_subscription = async_dispatcher_connect( - self.hass, - f"{SENSE_DEVICE_UPDATE}-{self._sense_monitor_id}", - self._async_update_from_data, + self.async_on_remove( + async_dispatcher_connect( + self.hass, + f"{SENSE_DEVICE_UPDATE}-{self._sense_monitor_id}", + self._async_update_from_data, + ) ) - async def async_will_remove_from_hass(self): - """Undo subscription.""" - if self._undo_dispatch_subscription: - self._undo_dispatch_subscription() - @callback def _async_update_from_data(self): """Get the latest data, update state. Must not do I/O.""" diff --git a/homeassistant/components/slack/notify.py b/homeassistant/components/slack/notify.py index fe6f7ab0d26..8cfffc1722a 100644 --- a/homeassistant/components/slack/notify.py +++ b/homeassistant/components/slack/notify.py @@ -74,11 +74,7 @@ class SlackNotificationService(BaseNotificationService): self._default_channel = default_channel self._hass = hass self._icon = icon - - if username or self._icon: - self._as_user = False - else: - self._as_user = True + self._username = username async def _async_send_local_file_message(self, path, targets, message, title): """Upload a local file (with message) to Slack.""" @@ -108,11 +104,11 @@ class SlackNotificationService(BaseNotificationService): target: self._client.chat_postMessage( channel=target, text=message, - as_user=self._as_user, attachments=attachments, blocks=blocks, icon_emoji=self._icon, link_names=True, + username=self._username, ) for target in targets } diff --git a/homeassistant/components/unifi/sensor.py b/homeassistant/components/unifi/sensor.py index 1b6667f2e80..2e82ecb4f6f 100644 --- a/homeassistant/components/unifi/sensor.py +++ b/homeassistant/components/unifi/sensor.py @@ -2,7 +2,7 @@ import logging from homeassistant.components.unifi.config_flow import get_controller_from_config_entry -from homeassistant.const import DATA_BYTES +from homeassistant.const import DATA_MEGABYTES from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -116,7 +116,7 @@ class UniFiRxBandwidthSensor(UniFiClient): @property def unit_of_measurement(self): """Return the unit of measurement of this entity.""" - return DATA_BYTES + return DATA_MEGABYTES class UniFiTxBandwidthSensor(UniFiRxBandwidthSensor): diff --git a/homeassistant/components/zwave/light.py b/homeassistant/components/zwave/light.py index b32daf71f54..745400e5c44 100644 --- a/homeassistant/components/zwave/light.py +++ b/homeassistant/components/zwave/light.py @@ -104,7 +104,7 @@ def byte_to_zwave_brightness(value): `value` -- (int) Brightness byte value from 0-255. """ if value > 0: - return max(1, int((value / 255) * 99)) + return max(1, round((value / 255) * 99)) return 0 diff --git a/homeassistant/const.py b/homeassistant/const.py index 17af8a6e320..da6dd4bb24e 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1,7 +1,7 @@ """Constants used by Home Assistant components.""" MAJOR_VERSION = 0 MINOR_VERSION = 108 -PATCH_VERSION = "3" +PATCH_VERSION = "4" __short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__ = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER = (3, 7, 0) diff --git a/requirements_all.txt b/requirements_all.txt index 3d4d5ad1394..36c54eab31b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -922,7 +922,7 @@ netdisco==2.6.0 neurio==0.3.1 # homeassistant.components.nexia -nexia==0.8.2 +nexia==0.9.1 # homeassistant.components.nextcloud nextcloudmonitor==1.1.0 @@ -1330,7 +1330,7 @@ pyialarm==0.3 pyicloud==0.9.6.1 # homeassistant.components.intesishome -pyintesishome==1.7.1 +pyintesishome==1.7.3 # homeassistant.components.ipma pyipma==2.0.5 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 9e128f83ca1..531b2550dea 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -357,7 +357,7 @@ nessclient==0.9.15 netdisco==2.6.0 # homeassistant.components.nexia -nexia==0.8.2 +nexia==0.9.1 # homeassistant.components.nsw_fuel_station nsw-fuel-api-client==1.0.10 diff --git a/tests/components/here_travel_time/test_sensor.py b/tests/components/here_travel_time/test_sensor.py index 642b774f1e5..d399f5b67aa 100644 --- a/tests/components/here_travel_time/test_sensor.py +++ b/tests/components/here_travel_time/test_sensor.py @@ -80,6 +80,8 @@ def _build_mock_url(origin, destination, modes, api_key, departure=None, arrival parameters["arrival"] = arrival if departure is not None: parameters["departure"] = departure + if departure is None and arrival is None: + parameters["departure"] = "now" url = base_url + urllib.parse.urlencode(parameters) print(url) return url diff --git a/tests/components/nexia/test_climate.py b/tests/components/nexia/test_climate.py index 7f3ed900d3c..fe47ceeffe4 100644 --- a/tests/components/nexia/test_climate.py +++ b/tests/components/nexia/test_climate.py @@ -18,8 +18,8 @@ async def test_climate_zones(hass): "current_temperature": 22.8, "dehumidify_setpoint": 45.0, "dehumidify_supported": True, - "fan_mode": "auto", - "fan_modes": ["auto", "on", "circulate"], + "fan_mode": "Auto", + "fan_modes": ["Auto", "On", "Circulate"], "friendly_name": "Nick Office", "humidify_supported": False, "humidity": 45.0, @@ -53,8 +53,8 @@ async def test_climate_zones(hass): "current_temperature": 25.0, "dehumidify_setpoint": 50.0, "dehumidify_supported": True, - "fan_mode": "auto", - "fan_modes": ["auto", "on", "circulate"], + "fan_mode": "Auto", + "fan_modes": ["Auto", "On", "Circulate"], "friendly_name": "Kitchen", "humidify_supported": False, "humidity": 50.0, diff --git a/tests/components/zwave/test_light.py b/tests/components/zwave/test_light.py index 10efed24bf2..fc62ef880f6 100644 --- a/tests/components/zwave/test_light.py +++ b/tests/components/zwave/test_light.py @@ -100,13 +100,23 @@ def test_dimmer_turn_on(mock_openzwave): node.reset_mock() + device.turn_on(**{ATTR_BRIGHTNESS: 224}) + + assert node.set_dimmer.called + value_id, brightness = node.set_dimmer.mock_calls[0][1] + + assert value_id == value.value_id + assert brightness == 87 # round(224 / 255 * 99) + + node.reset_mock() + device.turn_on(**{ATTR_BRIGHTNESS: 120}) assert node.set_dimmer.called value_id, brightness = node.set_dimmer.mock_calls[0][1] assert value_id == value.value_id - assert brightness == 46 # int(120 / 255 * 99) + assert brightness == 47 # round(120 / 255 * 99) with patch.object(light, "_LOGGER", MagicMock()) as mock_logger: device.turn_on(**{ATTR_TRANSITION: 35}) diff --git a/tests/fixtures/nut/BACKUPSES600M1.json b/tests/fixtures/nut/BACKUPSES600M1.json new file mode 100644 index 00000000000..1acd0ef0444 --- /dev/null +++ b/tests/fixtures/nut/BACKUPSES600M1.json @@ -0,0 +1,47 @@ +{ + "ups.realpower.nominal" : "330", + "input.voltage" : "123.0", + "ups.mfr" : "American Power Conversion", + "driver.version" : "2.7.4", + "ups.test.result" : "No test initiated", + "input.voltage.nominal" : "120", + "input.transfer.low" : "92", + "driver.parameter.pollinterval" : "15", + "driver.version.data" : "APC HID 0.96", + "driver.parameter.pollfreq" : "30", + "battery.mfr.date" : "2017/04/01", + "ups.beeper.status" : "enabled", + "battery.date" : "2001/09/25", + "driver.name" : "usbhid-ups", + "battery.charge" : "100", + "ups.status" : "OL", + "ups.model" : "Back-UPS ES 600M1", + "battery.runtime.low" : "120", + "ups.firmware" : "928.a5 .D", + "ups.delay.shutdown" : "20", + "device.model" : "Back-UPS ES 600M1", + "device.serial" : "4B1713P32195 ", + "input.sensitivity" : "medium", + "ups.firmware.aux" : "a5 ", + "input.transfer.reason" : "input voltage out of range", + "ups.timer.reboot" : "0", + "battery.voltage.nominal" : "12.0", + "ups.vendorid" : "051d", + "input.transfer.high" : "139", + "battery.voltage" : "13.7", + "battery.charge.low" : "10", + "battery.type" : "PbAc", + "ups.mfr.date" : "2017/04/01", + "ups.timer.shutdown" : "-1", + "device.mfr" : "American Power Conversion", + "driver.parameter.port" : "auto", + "battery.charge.warning" : "50", + "device.type" : "ups", + "driver.parameter.vendorid" : "051d", + "ups.serial" : "4B1713P32195 ", + "ups.load" : "22", + "driver.version.internal" : "0.41", + "battery.runtime" : "1968", + "driver.parameter.synchronous" : "no", + "ups.productid" : "0002" +} diff --git a/tests/fixtures/nut/CP1500PFCLCD.json b/tests/fixtures/nut/CP1500PFCLCD.json new file mode 100644 index 00000000000..8f12ae96df6 --- /dev/null +++ b/tests/fixtures/nut/CP1500PFCLCD.json @@ -0,0 +1,43 @@ +{ + "battery.runtime.low" : "300", + "driver.parameter.port" : "auto", + "ups.delay.shutdown" : "20", + "driver.parameter.pollfreq" : "30", + "ups.beeper.status" : "disabled", + "input.voltage.nominal" : "120", + "device.serial" : "000000000000", + "ups.timer.shutdown" : "-60", + "input.voltage" : "122.0", + "ups.status" : "OL", + "ups.model" : "CP1500PFCLCD", + "device.mfr" : "CPS", + "device.model" : "CP1500PFCLCD", + "input.transfer.low" : "88", + "battery.mfr.date" : "CPS", + "driver.version" : "2.7.4", + "driver.version.data" : "CyberPower HID 0.4", + "driver.parameter.synchronous" : "no", + "ups.realpower.nominal" : "900", + "ups.productid" : "0501", + "ups.mfr" : "CPS", + "ups.vendorid" : "0764", + "driver.version.internal" : "0.41", + "output.voltage" : "138.0", + "battery.runtime" : "10530", + "device.type" : "ups", + "battery.charge.low" : "10", + "ups.timer.start" : "-60", + "driver.parameter.pollinterval" : "15", + "ups.load" : "0", + "ups.serial" : "000000000000", + "input.transfer.high" : "139", + "battery.charge.warning" : "20", + "battery.voltage.nominal" : "24", + "driver.parameter.vendorid" : "0764", + "driver.name" : "usbhid-ups", + "battery.type" : "PbAcid", + "ups.delay.start" : "30", + "battery.voltage" : "24.0", + "battery.charge" : "100", + "ups.test.result" : "No test initiated" +}