Skip to content

Commit

Permalink
Merge pull request #10 from tijsverkoyen/more-data
Browse files Browse the repository at this point in the history
Station and Device entities
  • Loading branch information
tijsverkoyen authored Nov 9, 2022
2 parents 31eaa7e + 74e6805 commit 37a2880
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 21 deletions.
12 changes: 11 additions & 1 deletion custom_components/fusion_solar/fusion_solar/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
ATTR_SUCCESS = 'success'
ATTR_STATION_CODE = 'stationCode'
ATTR_STATION_NAME = 'stationName'
ATTR_STATION_ADDRESS = 'stationAddr'
ATTR_CAPACITY = 'capacity'
ATTR_BUILD_STATE = 'buildState'
ATTR_COMBINE_TYPE = 'combineType'
ATTR_AID_TYPE = 'aidType'
ATTR_STATION_CONTACT_PERSON = 'stationLinkman'
ATTR_CONTACT_PERSON_PHONE = 'linkmanPho'

ATTR_PARAMS = 'params'
ATTR_PARAMS_CURRENT_TIME = 'currentTime'
ATTR_DEVICE_ID = 'id'
Expand All @@ -16,6 +24,8 @@
ATTR_DEVICE_TYPE_ID = 'devTypeId'
ATTR_DEVICE_INVERTER_TYPE = 'invType'
ATTR_DEVICE_SOFTWARE_VERSION = 'softwareVersion'
ATTR_DEVICE_LATITUDE = 'latitude'
ATTR_DEVICE_LONGITUDE = 'longitude'

# Data attributes
ATTR_REALTIME_POWER = 'realTimePower'
Expand All @@ -38,4 +48,4 @@
PARAM_DEVICE_TYPE_ID_STRING_INVERTER = 1
PARAM_DEVICE_TYPE_ID_GRID_METER = 17
PARAM_DEVICE_TYPE_ID_RESIDENTIAL_INVERTER = 38
PARAM_DEVICE_TYPE_ID_POWER_SENSOR = 47
PARAM_DEVICE_TYPE_ID_POWER_SENSOR = 47
49 changes: 46 additions & 3 deletions custom_components/fusion_solar/fusion_solar/openapi/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,73 @@


class FusionSolarDevice:
def __init__(self, id: str, name: str, station_code: str, esn_code: str, type_id: str, inverter_type,
software_version: str):
def __init__(
self,
id: str,
name: str,
station_code: str,
esn_code: str,
type_id: str,
inverter_type,
software_version: str,
longitude: float,
latitude: float
):
self.device_id = id
self.name = name
self.station_code = station_code
self.esn_code = esn_code
self.type_id = type_id
self.inverter_type = inverter_type
self.software_version = software_version
self.longitude = longitude
self.latitude = latitude

@property
def model(self) -> str:
if self.type_id == 38:
return f'{self.device_type} {self.inverter_type}'

return self.device_type

@property
def device_type(self) -> str:
if self.type_id == 1:
return 'String inverter'
if self.type_id == 2:
return 'SmartLogger'
if self.type_id == 8:
return 'Transformer'
if self.type_id == 10:
return 'EMI'
if self.type_id == 13:
return 'Protocol converter'
if self.type_id == 16:
return 'General device'
if self.type_id == 17:
return 'Grid meter'
if self.type_id == 22:
return 'PID'
if self.type_id == 37:
return 'Pinnet data logger'
if self.type_id == 38:
return f'Residential inverter {self.inverter_type}'
return 'Residential inverter'
if self.type_id == 39:
return 'Battery'
if self.type_id == 40:
return 'Backup box'
if self.type_id == 45:
return 'PLC'
if self.type_id == 46:
return 'Optimizer'
if self.type_id == 47:
return 'Power Sensor'
if self.type_id == 62:
return 'Dongle'
if self.type_id == 63:
return 'Distributed SmartLogger'
if self.type_id == 70:
return 'Safety box'

return 'Unknown'

Expand Down
23 changes: 18 additions & 5 deletions custom_components/fusion_solar/fusion_solar/openapi/openapi_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

from requests import post

from ..const import ATTR_SUCCESS, ATTR_DATA, ATTR_FAIL_CODE, ATTR_MESSAGE, ATTR_STATION_CODE, \
ATTR_STATION_NAME, ATTR_PARAMS, ATTR_PARAMS_CURRENT_TIME, ATTR_DEVICE_ID, ATTR_DEVICE_NAME, \
ATTR_DEVICE_STATION_CODE, ATTR_DEVICE_ESN_CODE, ATTR_DEVICE_TYPE_ID, ATTR_DEVICE_INVERTER_TYPE, \
ATTR_DEVICE_SOFTWARE_VERSION
from ..const import ATTR_SUCCESS, ATTR_DATA, ATTR_FAIL_CODE, ATTR_MESSAGE, ATTR_STATION_CODE, ATTR_STATION_NAME, \
ATTR_PARAMS, ATTR_PARAMS_CURRENT_TIME, ATTR_DEVICE_ID, ATTR_DEVICE_NAME, ATTR_DEVICE_STATION_CODE, \
ATTR_DEVICE_ESN_CODE, ATTR_DEVICE_TYPE_ID, ATTR_DEVICE_INVERTER_TYPE, ATTR_DEVICE_SOFTWARE_VERSION, \
ATTR_DEVICE_LATITUDE, ATTR_DEVICE_LONGITUDE, ATTR_STATION_ADDRESS, ATTR_CAPACITY, ATTR_BUILD_STATE, \
ATTR_COMBINE_TYPE, ATTR_AID_TYPE, ATTR_STATION_CONTACT_PERSON, ATTR_CONTACT_PERSON_PHONE

from .station import FusionSolarStation
from .device import FusionSolarDevice
Expand Down Expand Up @@ -55,7 +56,17 @@ def get_station_list(self):
data = []
for station in response[ATTR_DATA]:
data.append(
FusionSolarStation(station[ATTR_STATION_CODE], station[ATTR_STATION_NAME])
FusionSolarStation(
station[ATTR_STATION_CODE],
station[ATTR_STATION_NAME],
station[ATTR_STATION_ADDRESS],
station[ATTR_CAPACITY],
station[ATTR_BUILD_STATE],
station[ATTR_COMBINE_TYPE],
station[ATTR_AID_TYPE],
station[ATTR_STATION_CONTACT_PERSON],
station[ATTR_CONTACT_PERSON_PHONE]
)
)

return data
Expand Down Expand Up @@ -103,6 +114,8 @@ def get_dev_list(self, station_codes: list):
device[ATTR_DEVICE_TYPE_ID],
device[ATTR_DEVICE_INVERTER_TYPE],
device[ATTR_DEVICE_SOFTWARE_VERSION],
device[ATTR_DEVICE_LATITUDE],
device[ATTR_DEVICE_LONGITUDE],
)
)

Expand Down
20 changes: 19 additions & 1 deletion custom_components/fusion_solar/fusion_solar/openapi/station.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@


class FusionSolarStation:
def __init__(self, code: str, name: str):
def __init__(
self,
code: str,
name: str,
address: str = None,
capacity: float = None,
build_state: str = None,
combine_type: str = None,
aid_type: int = None,
contact_person: str = None,
contact_phone: str = None
):
self.code = code
self.name = name
self.address = address
self.capacity = capacity
self.build_state = build_state
self.combine_type = combine_type
self.aid_type = aid_type
self.contact_person = contact_person
self.contact_phone = contact_phone

def device_info(self):
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from homeassistant.helpers.entity import Entity, EntityCategory


class FusionSolarAttributeEntity(Entity):
"""Base class for all FusionSolarAttributeEntity entities."""

def __init__(
self,
unique_id,
name,
value,
device_info=None
):
"""Initialize the entity"""
self._unique_id = unique_id
self._name = name
self._value = value
self._device_info = device_info

@property
def unique_id(self) -> str:
return self._unique_id

@property
def name(self):
return self._name

@property
def state(self):
return self._value

@property
def device_info(self) -> dict:
return self._device_info

@property
def entity_category(self) -> str:
return EntityCategory.DIAGNOSTIC

@property
def should_poll(self) -> bool:
return False


class FusionSolarCapacityEntity(FusionSolarAttributeEntity):
_attr_icon = 'mdi:lightning-bolt'


class FusionSolarContactPersonEntity(FusionSolarAttributeEntity):
_attr_icon = 'mdi:account'


class FusionSolarContactPersonPhoneEntity(FusionSolarAttributeEntity):
_attr_icon = 'mdi:card-account-phone'


class FusionSolarAddressEntity(FusionSolarAttributeEntity):
_attr_icon = 'mdi:map-marker'


class FusionSolarLatitudeEntity(FusionSolarAttributeEntity):
_attr_icon = 'mdi:latitude'


class FusionSolarLongitudeEntity(FusionSolarAttributeEntity):
_attr_icon = 'mdi:longitude'
121 changes: 110 additions & 11 deletions custom_components/fusion_solar/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
FusionSolarEnergySensorTotalCurrentMonth, FusionSolarEnergySensorTotalCurrentYear, \
FusionSolarEnergySensorTotalLifetime
from .fusion_solar.power_entity import FusionSolarPowerEntityRealtime
from .fusion_solar.station_attribute_entity import FusionSolarAttributeEntity, FusionSolarAddressEntity, \
FusionSolarCapacityEntity, FusionSolarContactPersonEntity, FusionSolarContactPersonPhoneEntity, \
FusionSolarLatitudeEntity, FusionSolarLongitudeEntity

from .const import CONF_KIOSKS, CONF_OPENAPI_CREDENTIALS, DOMAIN, ID_REALTIME_POWER, NAME_REALTIME_POWER, \
ID_TOTAL_CURRENT_DAY_ENERGY, NAME_TOTAL_CURRENT_DAY_ENERGY, \
Expand Down Expand Up @@ -157,6 +160,43 @@ async def async_update_station_real_kpi_data():

for station in stations:
async_add_entities([
FusionSolarAttributeEntity(
f'{DOMAIN}-{station.code}-station-code',
f'{station.name} ({station.code}) - Station Code',
station.code,
station.device_info()
),
FusionSolarAttributeEntity(
f'{DOMAIN}-{station.code}-station-name',
f'{station.name} ({station.code}) - Station Name',
station.name,
station.device_info()
),
FusionSolarAddressEntity(
f'{DOMAIN}-{station.code}-station-address',
f'{station.name} ({station.code}) - Station Address',
station.address,
station.device_info()
),
FusionSolarCapacityEntity(
f'{DOMAIN}-{station.code}-capacity',
f'{station.name} ({station.code}) - Capacity',
station.capacity,
station.device_info()
),
FusionSolarContactPersonEntity(
f'{DOMAIN}-{station.code}-contact-person',
f'{station.name} ({station.code}) - Contact Person',
station.contact_person,
station.device_info()
),
FusionSolarContactPersonPhoneEntity(
f'{DOMAIN}-{station.code}-contact-phone',
f'{station.name} ({station.code}) - Contact Phone',
station.contact_phone,
station.device_info()
),

FusionSolarEnergySensorTotalCurrentDay(
coordinator,
f'{DOMAIN}-{station.code}-{ID_TOTAL_CURRENT_DAY_ENERGY}',
Expand Down Expand Up @@ -267,21 +307,80 @@ async def async_update_device_real_kpi_data():
await coordinator.async_refresh()

for device in devices:
if device.type_id not in [PARAM_DEVICE_TYPE_ID_STRING_INVERTER, PARAM_DEVICE_TYPE_ID_GRID_METER,
PARAM_DEVICE_TYPE_ID_RESIDENTIAL_INVERTER, PARAM_DEVICE_TYPE_ID_POWER_SENSOR]:
continue

async_add_entities([
FusionSolarPowerEntityRealtime(
coordinator,
f'{DOMAIN}-{device.esn_code}-{ID_REALTIME_POWER}',
f'{device.name} ({device.esn_code}) - {NAME_REALTIME_POWER}',
ATTR_DEVICE_REAL_KPI_ACTIVE_POWER,
f'{DOMAIN}-{device.device_id}',
FusionSolarAttributeEntity(
f'{DOMAIN}-{device.esn_code}-device-id',
f'{device.name} ({device.esn_code}) - Device ID',
device.device_id,
device.device_info()
)
),
FusionSolarAttributeEntity(
f'{DOMAIN}-{device.esn_code}-device-name',
f'{device.name} ({device.esn_code}) - Device Name',
device.name,
device.device_info()
),
FusionSolarAttributeEntity(
f'{DOMAIN}-{device.esn_code}-station-code',
f'{device.name} ({device.esn_code}) - Station Code',
device.station_code,
device.device_info()
),
FusionSolarAttributeEntity(
f'{DOMAIN}-{device.esn_code}-esn-code',
f'{device.name} ({device.esn_code}) - Serial Number',
device.esn_code,
device.device_info()
),
FusionSolarAttributeEntity(
f'{DOMAIN}-{device.esn_code}-device-type-id',
f'{device.name} ({device.esn_code}) - Device Type ID',
device.type_id,
device.device_info()
),
FusionSolarAttributeEntity(
f'{DOMAIN}-{device.esn_code}-device-type',
f'{device.name} ({device.esn_code}) - Device Type',
device.device_type,
device.device_info()
),
FusionSolarLatitudeEntity(
f'{DOMAIN}-{device.esn_code}-latitude',
f'{device.name} ({device.esn_code}) - Latitude',
device.latitude,
device.device_info()
),
FusionSolarLongitudeEntity(
f'{DOMAIN}-{device.esn_code}-longitude',
f'{device.name} ({device.esn_code}) - Longitude',
device.longitude,
device.device_info()
),
])

if device.type_id in [PARAM_DEVICE_TYPE_ID_STRING_INVERTER, PARAM_DEVICE_TYPE_ID_GRID_METER,
PARAM_DEVICE_TYPE_ID_RESIDENTIAL_INVERTER, PARAM_DEVICE_TYPE_ID_POWER_SENSOR]:
async_add_entities([
FusionSolarPowerEntityRealtime(
coordinator,
f'{DOMAIN}-{device.esn_code}-{ID_REALTIME_POWER}',
f'{device.name} ({device.esn_code}) - {NAME_REALTIME_POWER}',
ATTR_DEVICE_REAL_KPI_ACTIVE_POWER,
f'{DOMAIN}-{device.device_id}',
device.device_info()
)
])

if device.type_id in [PARAM_DEVICE_TYPE_ID_STRING_INVERTER, PARAM_DEVICE_TYPE_ID_RESIDENTIAL_INVERTER]:
async_add_entities([
FusionSolarAttributeEntity(
f'{DOMAIN}-{device.esn_code}-inverter_type',
f'{device.name} ({device.esn_code}) - Inverter Type',
device.inverter_type,
device.device_info()
),
])


async def async_setup_entry(hass, config_entry, async_add_entities):
config = hass.data[DOMAIN][config_entry.entry_id]
Expand Down

0 comments on commit 37a2880

Please sign in to comment.