mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 10:47:10 +00:00
Update tesla_powerwall to 0.3.3 (#41482)
This commit is contained in:
parent
07d208f1bc
commit
734972f876
@ -4,7 +4,7 @@ from datetime import timedelta
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from tesla_powerwall import APIChangedError, Powerwall, PowerwallUnreachableError
|
from tesla_powerwall import MissingAttributeError, Powerwall, PowerwallUnreachableError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
@ -72,9 +72,7 @@ async def _migrate_old_unique_ids(hass, entry_id, powerwall_data):
|
|||||||
# The old unique_id ended with the nomianal_system_engery_kWh so we can use that
|
# The old unique_id ended with the nomianal_system_engery_kWh so we can use that
|
||||||
# to find the old base unique_id and extract the device_suffix.
|
# to find the old base unique_id and extract the device_suffix.
|
||||||
normalized_energy_index = (
|
normalized_energy_index = (
|
||||||
len(parts)
|
len(parts) - 1 - parts[::-1].index(str(site_info.nominal_system_energy))
|
||||||
- 1
|
|
||||||
- parts[::-1].index(str(site_info.nominal_system_energy_kWh))
|
|
||||||
)
|
)
|
||||||
device_suffix = parts[normalized_energy_index + 1 :]
|
device_suffix = parts[normalized_energy_index + 1 :]
|
||||||
|
|
||||||
@ -90,7 +88,9 @@ async def _migrate_old_unique_ids(hass, entry_id, powerwall_data):
|
|||||||
await entity_registry.async_migrate_entries(hass, entry_id, _async_migrator)
|
await entity_registry.async_migrate_entries(hass, entry_id, _async_migrator)
|
||||||
|
|
||||||
|
|
||||||
async def _async_handle_api_changed_error(hass: HomeAssistant, error: APIChangedError):
|
async def _async_handle_api_changed_error(
|
||||||
|
hass: HomeAssistant, error: MissingAttributeError
|
||||||
|
):
|
||||||
# The error might include some important information about what exactly changed.
|
# The error might include some important information about what exactly changed.
|
||||||
_LOGGER.error(str(error))
|
_LOGGER.error(str(error))
|
||||||
hass.components.persistent_notification.async_create(
|
hass.components.persistent_notification.async_create(
|
||||||
@ -116,7 +116,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
except PowerwallUnreachableError as err:
|
except PowerwallUnreachableError as err:
|
||||||
http_session.close()
|
http_session.close()
|
||||||
raise ConfigEntryNotReady from err
|
raise ConfigEntryNotReady from err
|
||||||
except APIChangedError as err:
|
except MissingAttributeError as err:
|
||||||
http_session.close()
|
http_session.close()
|
||||||
await _async_handle_api_changed_error(hass, err)
|
await _async_handle_api_changed_error(hass, err)
|
||||||
return False
|
return False
|
||||||
@ -135,7 +135,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
)
|
)
|
||||||
except PowerwallUnreachableError as err:
|
except PowerwallUnreachableError as err:
|
||||||
raise UpdateFailed("Unable to fetch data from powerwall") from err
|
raise UpdateFailed("Unable to fetch data from powerwall") from err
|
||||||
except APIChangedError as err:
|
except MissingAttributeError as err:
|
||||||
await _async_handle_api_changed_error(hass, err)
|
await _async_handle_api_changed_error(hass, err)
|
||||||
hass.data[DOMAIN][entry.entry_id][POWERWALL_API_CHANGED] = True
|
hass.data[DOMAIN][entry.entry_id][POWERWALL_API_CHANGED] = True
|
||||||
# Returns the cached data. This data can also be None
|
# Returns the cached data. This data can also be None
|
||||||
|
@ -19,7 +19,6 @@ from .const import (
|
|||||||
POWERWALL_API_SITE_INFO,
|
POWERWALL_API_SITE_INFO,
|
||||||
POWERWALL_API_SITEMASTER,
|
POWERWALL_API_SITEMASTER,
|
||||||
POWERWALL_API_STATUS,
|
POWERWALL_API_STATUS,
|
||||||
POWERWALL_BATTERY_METER,
|
|
||||||
POWERWALL_COORDINATOR,
|
POWERWALL_COORDINATOR,
|
||||||
)
|
)
|
||||||
from .entity import PowerWallEntity
|
from .entity import PowerWallEntity
|
||||||
@ -74,7 +73,7 @@ class PowerWallRunningSensor(PowerWallEntity, BinarySensorEntity):
|
|||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
"""Get the powerwall running state."""
|
"""Get the powerwall running state."""
|
||||||
return self.coordinator.data[POWERWALL_API_SITEMASTER].running
|
return self.coordinator.data[POWERWALL_API_SITEMASTER].is_running
|
||||||
|
|
||||||
|
|
||||||
class PowerWallConnectedSensor(PowerWallEntity, BinarySensorEntity):
|
class PowerWallConnectedSensor(PowerWallEntity, BinarySensorEntity):
|
||||||
@ -98,7 +97,7 @@ class PowerWallConnectedSensor(PowerWallEntity, BinarySensorEntity):
|
|||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
"""Get the powerwall connected to tesla state."""
|
"""Get the powerwall connected to tesla state."""
|
||||||
return self.coordinator.data[POWERWALL_API_SITEMASTER].connected_to_tesla
|
return self.coordinator.data[POWERWALL_API_SITEMASTER].is_connected_to_tesla
|
||||||
|
|
||||||
|
|
||||||
class PowerWallGridStatusSensor(PowerWallEntity, BinarySensorEntity):
|
class PowerWallGridStatusSensor(PowerWallEntity, BinarySensorEntity):
|
||||||
@ -147,6 +146,4 @@ class PowerWallChargingStatusSensor(PowerWallEntity, BinarySensorEntity):
|
|||||||
def is_on(self):
|
def is_on(self):
|
||||||
"""Powerwall is charging."""
|
"""Powerwall is charging."""
|
||||||
# is_sending_to returns true for values greater than 100 watts
|
# is_sending_to returns true for values greater than 100 watts
|
||||||
return self.coordinator.data[POWERWALL_API_METERS][
|
return self.coordinator.data[POWERWALL_API_METERS].battery.is_sending_to()
|
||||||
POWERWALL_BATTERY_METER
|
|
||||||
].is_sending_to()
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Config flow for Tesla Powerwall integration."""
|
"""Config flow for Tesla Powerwall integration."""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from tesla_powerwall import APIChangedError, Powerwall, PowerwallUnreachableError
|
from tesla_powerwall import MissingAttributeError, Powerwall, PowerwallUnreachableError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries, core, exceptions
|
from homeassistant import config_entries, core, exceptions
|
||||||
@ -27,7 +27,7 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
site_info = await hass.async_add_executor_job(power_wall.get_site_info)
|
site_info = await hass.async_add_executor_job(power_wall.get_site_info)
|
||||||
except PowerwallUnreachableError as err:
|
except PowerwallUnreachableError as err:
|
||||||
raise CannotConnect from err
|
raise CannotConnect from err
|
||||||
except APIChangedError as err:
|
except MissingAttributeError as err:
|
||||||
# Only log the exception without the traceback
|
# Only log the exception without the traceback
|
||||||
_LOGGER.error(str(err))
|
_LOGGER.error(str(err))
|
||||||
raise WrongVersion from err
|
raise WrongVersion from err
|
||||||
|
@ -29,8 +29,6 @@ POWERWALL_API_SERIAL_NUMBERS = "serial_numbers"
|
|||||||
|
|
||||||
POWERWALL_HTTP_SESSION = "http_session"
|
POWERWALL_HTTP_SESSION = "http_session"
|
||||||
|
|
||||||
POWERWALL_BATTERY_METER = "battery"
|
|
||||||
|
|
||||||
MODEL = "PowerWall 2"
|
MODEL = "PowerWall 2"
|
||||||
MANUFACTURER = "Tesla"
|
MANUFACTURER = "Tesla"
|
||||||
|
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
"name": "Tesla Powerwall",
|
"name": "Tesla Powerwall",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/powerwall",
|
"documentation": "https://www.home-assistant.io/integrations/powerwall",
|
||||||
"requirements": ["tesla-powerwall==0.2.12"],
|
"requirements": ["tesla-powerwall==0.3.3"],
|
||||||
"codeowners": ["@bdraco", "@jrester"]
|
"codeowners": ["@bdraco", "@jrester"]
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Support for August sensors."""
|
"""Support for August sensors."""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from tesla_powerwall import MeterType, convert_to_kw
|
from tesla_powerwall import MeterType
|
||||||
|
|
||||||
from homeassistant.const import DEVICE_CLASS_BATTERY, DEVICE_CLASS_POWER, PERCENTAGE
|
from homeassistant.const import DEVICE_CLASS_BATTERY, DEVICE_CLASS_POWER, PERCENTAGE
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ class PowerWallChargeSensor(PowerWallEntity):
|
|||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
"""Get the current value in percentage."""
|
"""Get the current value in percentage."""
|
||||||
return self.coordinator.data[POWERWALL_API_CHARGE]
|
return round(self.coordinator.data[POWERWALL_API_CHARGE])
|
||||||
|
|
||||||
|
|
||||||
class PowerWallEnergySensor(PowerWallEntity):
|
class PowerWallEnergySensor(PowerWallEntity):
|
||||||
@ -131,18 +131,18 @@ class PowerWallEnergySensor(PowerWallEntity):
|
|||||||
"""Get the current value in kW."""
|
"""Get the current value in kW."""
|
||||||
return (
|
return (
|
||||||
self.coordinator.data[POWERWALL_API_METERS]
|
self.coordinator.data[POWERWALL_API_METERS]
|
||||||
.get(self._meter)
|
.get_meter(self._meter)
|
||||||
.get_power(precision=3)
|
.get_power(precision=3)
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the device specific state attributes."""
|
"""Return the device specific state attributes."""
|
||||||
meter = self.coordinator.data[POWERWALL_API_METERS].get(self._meter)
|
meter = self.coordinator.data[POWERWALL_API_METERS].get_meter(self._meter)
|
||||||
return {
|
return {
|
||||||
ATTR_FREQUENCY: round(meter.frequency, 1),
|
ATTR_FREQUENCY: round(meter.frequency, 1),
|
||||||
ATTR_ENERGY_EXPORTED: convert_to_kw(meter.energy_exported),
|
ATTR_ENERGY_EXPORTED: meter.get_energy_exported(),
|
||||||
ATTR_ENERGY_IMPORTED: convert_to_kw(meter.energy_imported),
|
ATTR_ENERGY_IMPORTED: meter.get_energy_imported(),
|
||||||
ATTR_INSTANT_AVERAGE_VOLTAGE: round(meter.instant_average_voltage, 1),
|
ATTR_INSTANT_AVERAGE_VOLTAGE: round(meter.avarage_voltage, 1),
|
||||||
ATTR_IS_ACTIVE: meter.is_active(),
|
ATTR_IS_ACTIVE: meter.is_active(),
|
||||||
}
|
}
|
||||||
|
@ -2152,7 +2152,7 @@ temperusb==1.5.3
|
|||||||
# tensorflow==2.3.0
|
# tensorflow==2.3.0
|
||||||
|
|
||||||
# homeassistant.components.powerwall
|
# homeassistant.components.powerwall
|
||||||
tesla-powerwall==0.2.12
|
tesla-powerwall==0.3.3
|
||||||
|
|
||||||
# homeassistant.components.tesla
|
# homeassistant.components.tesla
|
||||||
teslajsonpy==0.10.4
|
teslajsonpy==0.10.4
|
||||||
|
@ -1005,7 +1005,7 @@ surepy==0.2.6
|
|||||||
tellduslive==0.10.11
|
tellduslive==0.10.11
|
||||||
|
|
||||||
# homeassistant.components.powerwall
|
# homeassistant.components.powerwall
|
||||||
tesla-powerwall==0.2.12
|
tesla-powerwall==0.3.3
|
||||||
|
|
||||||
# homeassistant.components.tesla
|
# homeassistant.components.tesla
|
||||||
teslajsonpy==0.10.4
|
teslajsonpy==0.10.4
|
||||||
|
@ -6,11 +6,11 @@ import os
|
|||||||
from tesla_powerwall import (
|
from tesla_powerwall import (
|
||||||
DeviceType,
|
DeviceType,
|
||||||
GridStatus,
|
GridStatus,
|
||||||
MetersAggregateResponse,
|
MetersAggregates,
|
||||||
Powerwall,
|
Powerwall,
|
||||||
PowerwallStatusResponse,
|
PowerwallStatus,
|
||||||
SiteInfoResponse,
|
SiteInfo,
|
||||||
SitemasterResponse,
|
SiteMaster,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components.powerwall.const import DOMAIN
|
from homeassistant.components.powerwall.const import DOMAIN
|
||||||
@ -29,12 +29,12 @@ async def _mock_powerwall_with_fixtures(hass):
|
|||||||
device_type = await _async_load_json_fixture(hass, "device_type.json")
|
device_type = await _async_load_json_fixture(hass, "device_type.json")
|
||||||
|
|
||||||
return _mock_powerwall_return_value(
|
return _mock_powerwall_return_value(
|
||||||
site_info=SiteInfoResponse(site_info),
|
site_info=SiteInfo(site_info),
|
||||||
charge=47,
|
charge=47.34587394586,
|
||||||
sitemaster=SitemasterResponse(sitemaster),
|
sitemaster=SiteMaster(sitemaster),
|
||||||
meters=MetersAggregateResponse(meters),
|
meters=MetersAggregates(meters),
|
||||||
grid_status=GridStatus.CONNECTED,
|
grid_status=GridStatus.CONNECTED,
|
||||||
status=PowerwallStatusResponse(status),
|
status=PowerwallStatus(status),
|
||||||
device_type=DeviceType(device_type["device_type"]),
|
device_type=DeviceType(device_type["device_type"]),
|
||||||
serial_numbers=["TG0123456789AB", "TG9876543210BA"],
|
serial_numbers=["TG0123456789AB", "TG9876543210BA"],
|
||||||
)
|
)
|
||||||
@ -66,10 +66,9 @@ def _mock_powerwall_return_value(
|
|||||||
async def _mock_powerwall_site_name(hass, site_name):
|
async def _mock_powerwall_site_name(hass, site_name):
|
||||||
powerwall_mock = MagicMock(Powerwall("1.2.3.4"))
|
powerwall_mock = MagicMock(Powerwall("1.2.3.4"))
|
||||||
|
|
||||||
site_info_resp = SiteInfoResponse(
|
site_info_resp = SiteInfo(await _async_load_json_fixture(hass, "site_info.json"))
|
||||||
await _async_load_json_fixture(hass, "site_info.json")
|
# Sets site_info_resp.site_name to return site_name
|
||||||
)
|
site_info_resp.response["site_name"] = site_name
|
||||||
site_info_resp.site_name = site_name
|
|
||||||
powerwall_mock.get_site_info = Mock(return_value=site_info_resp)
|
powerwall_mock.get_site_info = Mock(return_value=site_info_resp)
|
||||||
|
|
||||||
return powerwall_mock
|
return powerwall_mock
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Test the Powerwall config flow."""
|
"""Test the Powerwall config flow."""
|
||||||
|
|
||||||
from tesla_powerwall import APIChangedError, PowerwallUnreachableError
|
from tesla_powerwall import MissingAttributeError, PowerwallUnreachableError
|
||||||
|
|
||||||
from homeassistant import config_entries, setup
|
from homeassistant import config_entries, setup
|
||||||
from homeassistant.components.powerwall.const import DOMAIN
|
from homeassistant.components.powerwall.const import DOMAIN
|
||||||
@ -99,7 +99,9 @@ async def test_form_wrong_version(hass):
|
|||||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_powerwall = _mock_powerwall_side_effect(site_info=APIChangedError(object, {}))
|
mock_powerwall = _mock_powerwall_side_effect(
|
||||||
|
site_info=MissingAttributeError({}, "")
|
||||||
|
)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.powerwall.config_flow.Powerwall",
|
"homeassistant.components.powerwall.config_flow.Powerwall",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user