11from __future__ import annotations
22
33import asyncio
4- from aiohttp import client_exceptions
5- from homeassistant import config_entries
64
5+ import homeassistant .helpers .config_validation as cv
76import voluptuous as vol
8-
7+ from aiohttp import client_exceptions
8+ from APsystemsEZ1 import APsystemsEZ1M
9+ from homeassistant import config_entries
910from homeassistant .components .sensor import (
11+ PLATFORM_SCHEMA ,
1012 SensorDeviceClass ,
1113 SensorEntity ,
1214 SensorStateClass ,
13- PLATFORM_SCHEMA
1415)
15- import homeassistant .helpers .config_validation as cv
16- from homeassistant .const import UnitOfPower , UnitOfEnergy
17- from homeassistant .const import CONF_IP_ADDRESS , CONF_NAME
16+ from homeassistant .const import CONF_IP_ADDRESS , CONF_NAME , UnitOfEnergy , UnitOfPower
1817from homeassistant .core import HomeAssistant
18+ from homeassistant .helpers .device_registry import DeviceInfo
1919from homeassistant .helpers .entity_platform import AddEntitiesCallback
20- from homeassistant .helpers .typing import ConfigType , DiscoveryInfoType
21- from APsystemsEZ1 import APsystemsEZ1M
20+ from homeassistant .helpers .typing import DiscoveryInfoType
21+
2222from .const import DOMAIN
23- from homeassistant .helpers .device_registry import DeviceInfo
2423
25- PLATFORM_SCHEMA = PLATFORM_SCHEMA .extend ({
26- vol .Required (CONF_IP_ADDRESS ): cv .string ,
27- vol .Optional (CONF_NAME , default = "solar" ): cv .string
28- })
24+ PLATFORM_SCHEMA = PLATFORM_SCHEMA .extend (
25+ {
26+ vol .Required (CONF_IP_ADDRESS ): cv .string ,
27+ vol .Optional (CONF_NAME , default = "solar" ): cv .string ,
28+ }
29+ )
2930
3031
3132async def async_setup_entry (
32- hass : HomeAssistant ,
33- config_entry : config_entries .ConfigEntry ,
34- add_entities : AddEntitiesCallback ,
35- discovery_info : DiscoveryInfoType | None = None
33+ hass : HomeAssistant ,
34+ config_entry : config_entries .ConfigEntry ,
35+ add_entities : AddEntitiesCallback ,
36+ discovery_info : DiscoveryInfoType | None = None ,
3637) -> None :
3738 """Set up the sensor platform."""
3839 config = hass .data [DOMAIN ][config_entry .entry_id ]
3940 api = APsystemsEZ1M (ip_address = config [CONF_IP_ADDRESS ])
4041
4142 sensors = [
42- PowerSensorTotal (api , device_name = config [CONF_NAME ], sensor_name = "Total Power" , sensor_id = "total_power" ),
43- LifetimeEnergy (api , device_name = config [CONF_NAME ], sensor_name = "Lifetime Production" ,
44- sensor_id = "lifetime_production" ),
45- TodayEnergy (api , device_name = config [CONF_NAME ], sensor_name = "Today Production" ,
46- sensor_id = "today_production" )]
43+ PowerSensorTotal (
44+ api ,
45+ device_name = config [CONF_NAME ],
46+ sensor_name = "Total Power" ,
47+ sensor_id = "total_power" ,
48+ ),
49+ PowerSensorTotalP1 (
50+ api ,
51+ device_name = config [CONF_NAME ],
52+ sensor_name = "Total Power P1" ,
53+ sensor_id = "total_power_p1" ,
54+ ),
55+ PowerSensorTotalP2 (
56+ api ,
57+ device_name = config [CONF_NAME ],
58+ sensor_name = "Total Power P2" ,
59+ sensor_id = "total_power_p2" ,
60+ ),
61+ LifetimeEnergy (
62+ api ,
63+ device_name = config [CONF_NAME ],
64+ sensor_name = "Lifetime Production" ,
65+ sensor_id = "lifetime_production" ,
66+ ),
67+ LifetimeEnergyP1 (
68+ api ,
69+ device_name = config [CONF_NAME ],
70+ sensor_name = "Lifetime Production P1" ,
71+ sensor_id = "lifetime_production_p1" ,
72+ ),
73+ LifetimeEnergyP2 (
74+ api ,
75+ device_name = config [CONF_NAME ],
76+ sensor_name = "Lifetime Production P2" ,
77+ sensor_id = "lifetime_production_p2" ,
78+ ),
79+ TodayEnergy (
80+ api ,
81+ device_name = config [CONF_NAME ],
82+ sensor_name = "Today Production" ,
83+ sensor_id = "today_production" ,
84+ ),
85+ TodayEnergyP1 (
86+ api ,
87+ device_name = config [CONF_NAME ],
88+ sensor_name = "Today Production P1" ,
89+ sensor_id = "today_production_p1" ,
90+ ),
91+ TodayEnergyP2 (
92+ api ,
93+ device_name = config [CONF_NAME ],
94+ sensor_name = "Today Production_p2" ,
95+ sensor_id = "today_production_p2" ,
96+ ),
97+ ]
4798
4899 add_entities (sensors , True )
49100
50101
51102class BaseSensor (SensorEntity ):
52103 """Representation of an APsystem sensor."""
104+
53105 _attr_available = True
54- _attributes = {}
55106
56- def __init__ (self , api : APsystemsEZ1M , device_name : str , sensor_name : str , sensor_id : str ):
107+ def __init__ (
108+ self , api : APsystemsEZ1M , device_name : str , sensor_name : str , sensor_id : str
109+ ):
57110 """Initialize the sensor."""
58111 self ._api = api
59112 self ._state = None
@@ -78,18 +131,22 @@ def unique_id(self) -> str | None:
78131 @property
79132 def device_info (self ) -> DeviceInfo :
80133 return DeviceInfo (
81- identifiers = {
82- ("apsystemsapi_local" , self ._device_name )
83- },
134+ identifiers = {("apsystemsapi_local" , self ._device_name )},
84135 name = self ._device_name ,
85136 manufacturer = "APsystems" ,
86137 model = "EZ1-M" ,
87138 )
88139
89- @property
90- def extra_state_attributes (self ):
91- """Return entity specific state attributes."""
92- return self ._attributes
140+ async def async_update_data (self ):
141+ try :
142+ data = await self ._api .get_output_data ()
143+ self .update_state (data )
144+ self ._attr_available = True
145+ except (client_exceptions .ClientConnectionError , asyncio .TimeoutError ):
146+ self ._attr_available = False
147+
148+ def update_state (self , data ):
149+ raise NotImplementedError ("Must be implemented by subclasses." )
93150
94151
95152class BasePowerSensor (BaseSensor ):
@@ -100,14 +157,27 @@ class BasePowerSensor(BaseSensor):
100157
101158
102159class PowerSensorTotal (BasePowerSensor ):
160+ def update_state (self , data ):
161+ self ._state = data .p1 + data .p2
162+
103163 async def async_update (self ):
104- try :
105- data = await self ._api .get_output_data ()
106- self ._attributes = {"p1" : data .p1 , "p2" : data .p2 }
107- self ._state = data .p1 + data .p2
108- self ._attr_available = True
109- except (client_exceptions .ClientConnectionError , asyncio .TimeoutError ):
110- self ._attr_available = False
164+ await self .async_update_data ()
165+
166+
167+ class PowerSensorTotalP1 (BasePowerSensor ):
168+ def update_state (self , data ):
169+ self ._state = data .p1
170+
171+ async def async_update (self ):
172+ await self .async_update_data ()
173+
174+
175+ class PowerSensorTotalP2 (BasePowerSensor ):
176+ def update_state (self , data ):
177+ self ._state = data .p2
178+
179+ async def async_update (self ):
180+ await self .async_update_data ()
111181
112182
113183class BaseEnergySensor (BaseSensor ):
@@ -119,24 +189,58 @@ class BaseEnergySensor(BaseSensor):
119189class LifetimeEnergy (BaseEnergySensor ):
120190 _attr_state_class = SensorStateClass .TOTAL
121191
192+ def update_state (self , data ):
193+ self ._state = data .te1 + data .te2
194+
122195 async def async_update (self ):
123- try :
124- data = await self ._api .get_output_data ()
125- self ._attributes = {"p1" : data .te1 , "p2" : data .te2 }
126- self ._state = data .te1 + data .te2
127- self ._attr_available = True
128- except (client_exceptions .ClientConnectionError , asyncio .TimeoutError ):
129- self ._attr_available = False
196+ await self .async_update_data ()
197+
198+
199+ class LifetimeEnergyP1 (BaseEnergySensor ):
200+ _attr_state_class = SensorStateClass .TOTAL
201+
202+ def update_state (self , data ):
203+ self ._state = data .te1
204+
205+ async def async_update (self ):
206+ await self .async_update_data ()
207+
208+
209+ class LifetimeEnergyP2 (BaseEnergySensor ):
210+ _attr_state_class = SensorStateClass .TOTAL
211+
212+ def update_state (self , data ):
213+ self ._state = data .te2
214+
215+ async def async_update (self ):
216+ await self .async_update_data ()
130217
131218
132219class TodayEnergy (BaseEnergySensor ):
133220 _attr_state_class = SensorStateClass .TOTAL_INCREASING
134221
222+ def update_state (self , data ):
223+ self ._state = data .e1 + data .e2
224+
135225 async def async_update (self ):
136- try :
137- data = await self ._api .get_output_data ()
138- self ._attributes = {"p1" : data .e1 , "p2" : data .e2 }
139- self ._state = data .e1 + data .e2
140- self ._attr_available = True
141- except (client_exceptions .ClientConnectionError , asyncio .TimeoutError ):
142- self ._attr_available = False
226+ await self .async_update_data ()
227+
228+
229+ class TodayEnergyP1 (BaseEnergySensor ):
230+ _attr_state_class = SensorStateClass .TOTAL_INCREASING
231+
232+ def update_state (self , data ):
233+ self ._state = data .e1
234+
235+ async def async_update (self ):
236+ await self .async_update_data ()
237+
238+
239+ class TodayEnergyP2 (BaseEnergySensor ):
240+ _attr_state_class = SensorStateClass .TOTAL_INCREASING
241+
242+ def update_state (self , data ):
243+ self ._state = data .e2
244+
245+ async def async_update (self ):
246+ await self .async_update_data ()
0 commit comments