From c3de8dafa9f5e38b2dc6f825794d36d6632f6fe0 Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Mon, 13 Dec 2021 13:11:06 -0500 Subject: [PATCH 1/8] include hacs.json --- hacs.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 hacs.json diff --git a/hacs.json b/hacs.json new file mode 100644 index 0000000..1fcf229 --- /dev/null +++ b/hacs.json @@ -0,0 +1,8 @@ +{ + "name": "Florida Power & Light", + "country": "US", + "domains": [ + "sensor" + ], + "homeassistant": "2021.12.0" +} \ No newline at end of file From 235c6d45c1404320e40f345a1399c79cdd4245fe Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Mon, 13 Dec 2021 13:19:33 -0500 Subject: [PATCH 2/8] include issue tracker in manifest --- custom_components/fpl/fplapi.py | 8 +++----- custom_components/fpl/manifest.json | 4 ++-- hacs.json | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/custom_components/fpl/fplapi.py b/custom_components/fpl/fplapi.py index 0e2b778..4c24f6a 100644 --- a/custom_components/fpl/fplapi.py +++ b/custom_components/fpl/fplapi.py @@ -1,7 +1,5 @@ -import asyncio import logging -import re -from datetime import timedelta, datetime, date as dt +from datetime import datetime import aiohttp import async_timeout @@ -9,7 +7,7 @@ import json import sys -from bs4 import BeautifulSoup +# from bs4 import BeautifulSoup STATUS_CATEGORY_OPEN = "OPEN" # Api login result @@ -57,7 +55,7 @@ class FplApi(object): async def login(self): _LOGGER.info("Logging in") - """login and get account information""" + # login and get account information result = LOGIN_RESULT_OK try: async with async_timeout.timeout(TIMEOUT): diff --git a/custom_components/fpl/manifest.json b/custom_components/fpl/manifest.json index 805319d..886666e 100644 --- a/custom_components/fpl/manifest.json +++ b/custom_components/fpl/manifest.json @@ -9,9 +9,9 @@ "@dotKrad" ], "requirements": [ - "bs4", "integrationhelper" ], "homeassistant": "0.96.0", - "version": "1.0.0" + "version": "1.0.0", + "issue_tracker": "https://github.com/dotKrad/hass-fpl/issues" } \ No newline at end of file diff --git a/hacs.json b/hacs.json index 1fcf229..c1a4266 100644 --- a/hacs.json +++ b/hacs.json @@ -1,5 +1,5 @@ { - "name": "Florida Power & Light", + "name": "FPL", "country": "US", "domains": [ "sensor" From 1c029314de67491e117b33107de73027590b9289 Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Mon, 13 Dec 2021 13:25:19 -0500 Subject: [PATCH 3/8] modified requirements files --- requirements.txt | 2 -- requirements_test.txt | 0 2 files changed, 2 deletions(-) create mode 100644 requirements_test.txt diff --git a/requirements.txt b/requirements.txt index 7019fc7..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +0,0 @@ -integrationhelper -sampleclient \ No newline at end of file diff --git a/requirements_test.txt b/requirements_test.txt new file mode 100644 index 0000000..e69de29 From c4623d8234ac756cf17599aced2ac0da1f2c2a31 Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Mon, 13 Dec 2021 11:59:28 -0500 Subject: [PATCH 4/8] removed some unused files --- custom_components/fpl/AverageDailySensor.py | 20 ----------- custom_components/fpl/DailyUsageSensor.py | 31 ---------------- custom_components/fpl/ProjectedBillSensor.py | 37 -------------------- custom_components/fpl/sensor.py | 3 -- custom_components/fpl/sensor_AllData.py | 24 ------------- 5 files changed, 115 deletions(-) delete mode 100644 custom_components/fpl/AverageDailySensor.py delete mode 100644 custom_components/fpl/DailyUsageSensor.py delete mode 100644 custom_components/fpl/ProjectedBillSensor.py delete mode 100644 custom_components/fpl/sensor_AllData.py diff --git a/custom_components/fpl/AverageDailySensor.py b/custom_components/fpl/AverageDailySensor.py deleted file mode 100644 index d0f4778..0000000 --- a/custom_components/fpl/AverageDailySensor.py +++ /dev/null @@ -1,20 +0,0 @@ -from .FplSensor import FplSensor - - -class FplAverageDailySensor(FplSensor): - def __init__(self, hass, config, account): - FplSensor.__init__(self, hass, config, account, "Average Daily") - - @property - def state(self): - try: - if "daily_avg" in self.data: - self._state = self.data["daily_avg"] - except: - pass - return self._state - - @property - def device_state_attributes(self): - """Return the state attributes.""" - return self.attr \ No newline at end of file diff --git a/custom_components/fpl/DailyUsageSensor.py b/custom_components/fpl/DailyUsageSensor.py deleted file mode 100644 index 255e0e7..0000000 --- a/custom_components/fpl/DailyUsageSensor.py +++ /dev/null @@ -1,31 +0,0 @@ -from .FplSensor import FplSensor - - -class FplDailyUsageSensor(FplSensor): - def __init__(self, hass, config, account): - FplSensor.__init__(self, hass, config, account, "Daily Usage") - - @property - def state(self): - try: - if "daily_usage" in self.data: - if len(self.data["daily_usage"]) > 0: - if "cost" in self.data["daily_usage"][-1]: - self._state = self.data["daily_usage"][-1]["cost"] - except: - pass - - return self._state - - @property - def device_state_attributes(self): - """Return the state attributes.""" - try: - if "daily_usage" in self.data: - if len(self.data["daily_usage"]) > 0: - if "date" in self.data["daily_usage"][-1]: - self.attr["date"] = self.data["daily_usage"][-1]["date"] - except: - pass - - return self.attr diff --git a/custom_components/fpl/ProjectedBillSensor.py b/custom_components/fpl/ProjectedBillSensor.py deleted file mode 100644 index bf14a32..0000000 --- a/custom_components/fpl/ProjectedBillSensor.py +++ /dev/null @@ -1,37 +0,0 @@ -from .FplSensor import FplSensor - - -class FplProjectedBillSensor(FplSensor): - def __init__(self, hass, config, account): - FplSensor.__init__(self, hass, config, account, "Projected Bill") - - @property - def state(self): - data = self.data - try: - if "budget_bill" in data.keys(): - if data["budget_bill"]: - if "budget_billing_projected_bill" in data.keys(): - self._state = data["budget_billing_projected_bill"] - else: - if "projected_bill" in data.keys(): - self._state = data["projected_bill"] - except: - pass - - return self._state - - @property - def device_state_attributes(self): - """Return the state attributes.""" - try: - if "budget_bill" in self.data.keys(): - self.attr["budget_bill"] = self.data["budget_bill"] - except: - pass - - return self.attr - - @property - def icon(self): - return "mdi:currency-usd" \ No newline at end of file diff --git a/custom_components/fpl/sensor.py b/custom_components/fpl/sensor.py index 616653c..ee64995 100644 --- a/custom_components/fpl/sensor.py +++ b/custom_components/fpl/sensor.py @@ -26,7 +26,6 @@ from .sensor_AverageDailySensor import ( from .sensor_DailyUsageSensor import FplDailyUsageKWHSensor, FplDailyUsageSensor from .const import DOMAIN -from .sensor_AllData import AllDataSensor from .TestSensor import TestSensor @@ -40,8 +39,6 @@ async def async_setup_entry(hass, entry, async_add_devices): for account in accounts: # Test Sensor # fpl_accounts.append(TestSensor(coordinator, entry, account)) - # All data sensor - # fpl_accounts.append(AllDataSensor(coordinator, entry, account)) # bill sensors fpl_accounts.append(FplProjectedBillSensor(coordinator, entry, account)) diff --git a/custom_components/fpl/sensor_AllData.py b/custom_components/fpl/sensor_AllData.py deleted file mode 100644 index 98044b3..0000000 --- a/custom_components/fpl/sensor_AllData.py +++ /dev/null @@ -1,24 +0,0 @@ -from .fplEntity import FplEntity - - -class AllDataSensor(FplEntity): - def __init__(self, coordinator, config, account): - super().__init__(coordinator, config, account, "") - - @property - def state(self): - budget = self.getData("budget_bill") - budget_billing_projected_bill = self.getData("budget_billing_projected_bill") - - if budget == True and budget_billing_projected_bill is not None: - return self.getData("budget_billing_projected_bill") - - return self.getData("projected_bill") - - def defineAttributes(self): - """Return the state attributes.""" - return self.coordinator.data.get(self.account) - - @property - def icon(self): - return "mdi:currency-usd" From ef2516ada4782124331c6bfed0d5f75e62682df2 Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Mon, 13 Dec 2021 12:02:39 -0500 Subject: [PATCH 5/8] sensors mini rework --- custom_components/fpl/fplEntity.py | 78 ++++++++++++++++++- .../fpl/sensor_AverageDailySensor.py | 20 +---- .../fpl/sensor_DailyUsageSensor.py | 14 +--- custom_components/fpl/sensor_DatesSensor.py | 32 ++------ custom_components/fpl/sensor_KWHSensor.py | 23 +++--- .../fpl/sensor_ProjectedBillSensor.py | 26 ++----- 6 files changed, 104 insertions(+), 89 deletions(-) diff --git a/custom_components/fpl/fplEntity.py b/custom_components/fpl/fplEntity.py index 7b30d27..1680931 100644 --- a/custom_components/fpl/fplEntity.py +++ b/custom_components/fpl/fplEntity.py @@ -1,10 +1,20 @@ """BlueprintEntity class""" +from homeassistant.components.sensor import SensorEntity, STATE_CLASS_MEASUREMENT from homeassistant.helpers.update_coordinator import CoordinatorEntity +from homeassistant.const import ( + CURRENCY_DOLLAR, + DEVICE_CLASS_ENERGY, + ENERGY_KILO_WATT_HOUR, + DEVICE_CLASS_MONETARY, + DEVICE_CLASS_TIMESTAMP, +) + +from datetime import datetime, timedelta from .const import DOMAIN, VERSION, ATTRIBUTION -class FplEntity(CoordinatorEntity): +class FplEntity(CoordinatorEntity, SensorEntity): def __init__(self, coordinator, config_entry, account, sensorName): super().__init__(coordinator) self.config_entry = config_entry @@ -47,3 +57,69 @@ class FplEntity(CoordinatorEntity): def getData(self, field): return self.coordinator.data.get(self.account).get(field) + + +class FplEnergyEntity(FplEntity): + def __init__(self, coordinator, config_entry, account, sensorName): + super().__init__(coordinator, config_entry, account, sensorName) + + @property + def state_class(self) -> str: + """Return the state class of this entity, from STATE_CLASSES, if any.""" + + return STATE_CLASS_MEASUREMENT + + @property + def last_reset(self) -> datetime: + """Return the time when the sensor was last reset, if any.""" + + today = datetime.today() + yesterday = today - timedelta(days=1) + return datetime.combine(yesterday, datetime.min.time()) + + @property + def device_class(self) -> str: + """Return the class of this device, from component DEVICE_CLASSES.""" + return DEVICE_CLASS_ENERGY + + @property + def unit_of_measurement(self) -> str: + """Return the unit of measurement of this entity, if any.""" + return ENERGY_KILO_WATT_HOUR + + @property + def icon(self): + return "mdi:flash" + + +class FplMoneyEntity(FplEntity): + def __init__(self, coordinator, config_entry, account, sensorName): + super().__init__(coordinator, config_entry, account, sensorName) + + @property + def icon(self): + return "mdi:currency-usd" + + @property + def device_class(self) -> str: + """Return the class of this device, from component DEVICE_CLASSES.""" + return DEVICE_CLASS_MONETARY + + @property + def unit_of_measurement(self) -> str: + """Return the unit of measurement of this entity, if any.""" + return CURRENCY_DOLLAR + + +class FplDateEntity(FplEntity): + def __init__(self, coordinator, config_entry, account, sensorName): + super().__init__(coordinator, config_entry, account, sensorName) + + # @property + # def device_class(self) -> str: + # """Return the class of this device, from component DEVICE_CLASSES.""" + # return DEVICE_CLASS_TIMESTAMP + + @property + def icon(self): + return "mdi:calendar" \ No newline at end of file diff --git a/custom_components/fpl/sensor_AverageDailySensor.py b/custom_components/fpl/sensor_AverageDailySensor.py index 66d25f1..3399ded 100644 --- a/custom_components/fpl/sensor_AverageDailySensor.py +++ b/custom_components/fpl/sensor_AverageDailySensor.py @@ -1,7 +1,7 @@ -from .fplEntity import FplEntity +from .fplEntity import FplMoneyEntity -class FplAverageDailySensor(FplEntity): +class FplAverageDailySensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Daily Average") @@ -15,12 +15,8 @@ class FplAverageDailySensor(FplEntity): return self.getData("daily_avg") - @property - def icon(self): - return "mdi:currency-usd" - -class BudgetDailyAverageSensor(FplEntity): +class BudgetDailyAverageSensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Budget Daily Average") @@ -28,19 +24,11 @@ class BudgetDailyAverageSensor(FplEntity): def state(self): return self.getData("budget_billing_daily_avg") - @property - def icon(self): - return "mdi:currency-usd" - -class ActualDailyAverageSensor(FplEntity): +class ActualDailyAverageSensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Actual Daily Average") @property def state(self): return self.getData("daily_avg") - - @property - def icon(self): - return "mdi:currency-usd" diff --git a/custom_components/fpl/sensor_DailyUsageSensor.py b/custom_components/fpl/sensor_DailyUsageSensor.py index 299188e..8bfa90e 100644 --- a/custom_components/fpl/sensor_DailyUsageSensor.py +++ b/custom_components/fpl/sensor_DailyUsageSensor.py @@ -1,7 +1,7 @@ -from .fplEntity import FplEntity +from .fplEntity import FplEnergyEntity, FplMoneyEntity -class FplDailyUsageSensor(FplEntity): +class FplDailyUsageSensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Daily Usage") @@ -23,12 +23,8 @@ class FplDailyUsageSensor(FplEntity): return {} - @property - def icon(self): - return "mdi:currency-usd" - -class FplDailyUsageKWHSensor(FplEntity): +class FplDailyUsageKWHSensor(FplEnergyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Daily Usage KWH") @@ -49,7 +45,3 @@ class FplDailyUsageKWHSensor(FplEntity): return {"date": data[-1]["date"]} return {} - - @property - def icon(self): - return "mdi:currency-usd" diff --git a/custom_components/fpl/sensor_DatesSensor.py b/custom_components/fpl/sensor_DatesSensor.py index b0414d7..b2f2fdb 100644 --- a/custom_components/fpl/sensor_DatesSensor.py +++ b/custom_components/fpl/sensor_DatesSensor.py @@ -1,7 +1,7 @@ -from .fplEntity import FplEntity +from .fplEntity import FplDateEntity -class CurrentBillDateSensor(FplEntity): +class CurrentBillDateSensor(FplDateEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Current Bill Date") @@ -9,12 +9,8 @@ class CurrentBillDateSensor(FplEntity): def state(self): return self.getData("current_bill_date") - @property - def icon(self): - return "mdi:calendar" - -class NextBillDateSensor(FplEntity): +class NextBillDateSensor(FplDateEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Next Bill Date") @@ -22,12 +18,8 @@ class NextBillDateSensor(FplEntity): def state(self): return self.getData("next_bill_date") - @property - def icon(self): - return "mdi:calendar" - -class ServiceDaysSensor(FplEntity): +class ServiceDaysSensor(FplDateEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Service Days") @@ -35,12 +27,8 @@ class ServiceDaysSensor(FplEntity): def state(self): return self.getData("service_days") - @property - def icon(self): - return "mdi:calendar" - -class AsOfDaysSensor(FplEntity): +class AsOfDaysSensor(FplDateEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "As Of Days") @@ -48,19 +36,11 @@ class AsOfDaysSensor(FplEntity): def state(self): return self.getData("as_of_days") - @property - def icon(self): - return "mdi:calendar" - -class RemainingDaysSensor(FplEntity): +class RemainingDaysSensor(FplDateEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Remaining Days") @property def state(self): return self.getData("remaining_days") - - @property - def icon(self): - return "mdi:calendar" diff --git a/custom_components/fpl/sensor_KWHSensor.py b/custom_components/fpl/sensor_KWHSensor.py index b360e4d..6b9ba6b 100644 --- a/custom_components/fpl/sensor_KWHSensor.py +++ b/custom_components/fpl/sensor_KWHSensor.py @@ -1,7 +1,8 @@ -from .fplEntity import FplEntity +from homeassistant.components.sensor import STATE_CLASS_TOTAL_INCREASING +from .fplEntity import FplEnergyEntity -class ProjectedKWHSensor(FplEntity): +class ProjectedKWHSensor(FplEnergyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Projected KWH") @@ -9,12 +10,8 @@ class ProjectedKWHSensor(FplEntity): def state(self): return self.getData("projectedKWH") - @property - def icon(self): - return "mdi:flash" - -class DailyAverageKWHSensor(FplEntity): +class DailyAverageKWHSensor(FplEnergyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Daily Average KWH") @@ -22,12 +19,8 @@ class DailyAverageKWHSensor(FplEntity): def state(self): return self.getData("dailyAverageKWH") - @property - def icon(self): - return "mdi:flash" - -class BillToDateKWHSensor(FplEntity): +class BillToDateKWHSensor(FplEnergyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Bill To Date KWH") @@ -36,5 +29,7 @@ class BillToDateKWHSensor(FplEntity): return self.getData("billToDateKWH") @property - def icon(self): - return "mdi:flash" + def state_class(self) -> str: + """Return the state class of this entity, from STATE_CLASSES, if any.""" + + return STATE_CLASS_TOTAL_INCREASING diff --git a/custom_components/fpl/sensor_ProjectedBillSensor.py b/custom_components/fpl/sensor_ProjectedBillSensor.py index acf7482..7f6a515 100644 --- a/custom_components/fpl/sensor_ProjectedBillSensor.py +++ b/custom_components/fpl/sensor_ProjectedBillSensor.py @@ -1,7 +1,7 @@ -from .fplEntity import FplEntity +from .fplEntity import FplMoneyEntity -class FplProjectedBillSensor(FplEntity): +class FplProjectedBillSensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Projected Bill") @@ -26,13 +26,9 @@ class FplProjectedBillSensor(FplEntity): return attributes - @property - def icon(self): - return "mdi:currency-usd" - # Defered Amount -class DeferedAmountSensor(FplEntity): +class DeferedAmountSensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Defered Amount") @@ -42,12 +38,8 @@ class DeferedAmountSensor(FplEntity): return self.getData("defered_amount") return 0 - @property - def icon(self): - return "mdi:currency-usd" - -class ProjectedBudgetBillSensor(FplEntity): +class ProjectedBudgetBillSensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Projected Budget Bill") @@ -55,19 +47,11 @@ class ProjectedBudgetBillSensor(FplEntity): def state(self): return self.getData("budget_billing_projected_bill") - @property - def icon(self): - return "mdi:currency-usd" - -class ProjectedActualBillSensor(FplEntity): +class ProjectedActualBillSensor(FplMoneyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Projected Actual Bill") @property def state(self): return self.getData("projected_bill") - - @property - def icon(self): - return "mdi:currency-usd" From 8cb703526d3d8168f72da90be0e7023856422183 Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Wed, 29 Dec 2021 14:27:25 -0500 Subject: [PATCH 6/8] replace FplEntity with FplEnergyEntity --- custom_components/fpl/sensor_KWHSensor.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_components/fpl/sensor_KWHSensor.py b/custom_components/fpl/sensor_KWHSensor.py index 71abae2..6d48d03 100644 --- a/custom_components/fpl/sensor_KWHSensor.py +++ b/custom_components/fpl/sensor_KWHSensor.py @@ -32,7 +32,8 @@ class BillToDateKWHSensor(FplEnergyEntity): def state_class(self) -> str: """Return the state class of this entity, from STATE_CLASSES, if any.""" -class NetReceivedKWHSensor(FplEntity): + +class NetReceivedKWHSensor(FplEnergyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Received Meter Reading KWH") @@ -44,7 +45,8 @@ class NetReceivedKWHSensor(FplEntity): def icon(self): return "mdi:flash" -class NetDeliveredKWHSensor(FplEntity): + +class NetDeliveredKWHSensor(FplEnergyEntity): def __init__(self, coordinator, config, account): super().__init__(coordinator, config, account, "Delivered Meter Reading KWH") From c6d2d56bbc44a29a5cb7dfd9f5c00234445f5dd8 Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Wed, 29 Dec 2021 14:27:39 -0500 Subject: [PATCH 7/8] include new sensors --- custom_components/fpl/sensor.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/custom_components/fpl/sensor.py b/custom_components/fpl/sensor.py index 31e53ce..64d651a 100644 --- a/custom_components/fpl/sensor.py +++ b/custom_components/fpl/sensor.py @@ -68,4 +68,7 @@ async def async_setup_entry(hass, entry, async_add_devices): fpl_accounts.append(DailyAverageKWHSensor(coordinator, entry, account)) fpl_accounts.append(BillToDateKWHSensor(coordinator, entry, account)) + fpl_accounts.append(NetReceivedKWHSensor(coordinator, entry, account)) + fpl_accounts.append(NetDeliveredKWHSensor(coordinator, entry, account)) + async_add_devices(fpl_accounts) From 0ad4336c60c40d85666af62003a6d9a89717a2f3 Mon Sep 17 00:00:00 2001 From: Yordan Suarez Date: Wed, 12 Jan 2022 19:33:41 -0500 Subject: [PATCH 8/8] remove homeassistant key from manifest --- custom_components/fpl/manifest.json | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/fpl/manifest.json b/custom_components/fpl/manifest.json index 886666e..0397962 100644 --- a/custom_components/fpl/manifest.json +++ b/custom_components/fpl/manifest.json @@ -11,7 +11,6 @@ "requirements": [ "integrationhelper" ], - "homeassistant": "0.96.0", "version": "1.0.0", "issue_tracker": "https://github.com/dotKrad/hass-fpl/issues" } \ No newline at end of file