Skip to content

Commit

Permalink
Merge pull request #46 from faanskit/dev
Browse files Browse the repository at this point in the history
Added support to push to CheckWattRank as an option
  • Loading branch information
faanskit authored Jan 3, 2024
2 parents f71e9d8 + a95e3b4 commit 8315d1e
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 9 deletions.
88 changes: 86 additions & 2 deletions custom_components/checkwatt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"""The CheckWatt integration."""
from __future__ import annotations

import asyncio
from datetime import time, timedelta
import logging
import random
from typing import TypedDict

import aiohttp
from pycheckwatt import CheckwattManager

from homeassistant.config_entries import ConfigEntry
Expand All @@ -17,6 +19,7 @@

from .const import (
CONF_DETAILED_SENSORS,
CONF_PUSH_CW_TO_RANK,
CONF_UPDATE_INTERVAL,
CONF_UPDATE_INTERVAL_FCRD,
DOMAIN,
Expand Down Expand Up @@ -111,6 +114,7 @@ def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
self.annual_revenue = None
self.annual_fees = None
self.last_annual_update = None
self.last_cw_rank_push = None
self.is_boot = True
self.energy_provider = None
self.random_offset = random.randint(0, 14)
Expand All @@ -128,6 +132,7 @@ async def _async_update_data(self) -> CheckwattResp:
username = self._entry.data.get(CONF_USERNAME)
password = self._entry.data.get(CONF_PASSWORD)
use_detailed_sensors = self._entry.options.get(CONF_DETAILED_SENSORS)
push_to_cw_rank = self._entry.options.get(CONF_PUSH_CW_TO_RANK)

async with CheckwattManager(username, password) as cw_inst:
if not await cw_inst.login():
Expand Down Expand Up @@ -183,14 +188,27 @@ async def _async_update_data(self) -> CheckwattResp:

self.update_monetary -= 1

# Price Zone is used both as Detailed Sensor and by Push to CheckWattRank
if push_to_cw_rank or use_detailed_sensors:
if not await cw_inst.get_price_zone():
raise UpdateFailed("Unknown error get_price_zone")
if use_detailed_sensors:
if not await cw_inst.get_power_data():
raise UpdateFailed("Unknown error get_power_data")
if not await cw_inst.get_price_zone():
raise UpdateFailed("Unknown error get_price_zone")
if not await cw_inst.get_spot_price():
raise UpdateFailed("Unknown error get_spot_price")

if push_to_cw_rank:
if self.last_cw_rank_push is None or (
dt_util.now().time()
>= time(8, self.random_offset) # Wait until 7am +- 15 min
and dt_util.start_of_local_day(dt_util.now())
!= dt_util.start_of_local_day(self.last_cw_rank_push)
):
_LOGGER.debug("Pushing to CheckWattRank")
if await self.push_to_checkwatt_rank(cw_inst):
self.last_cw_rank_push = dt_util.now()

resp: CheckwattResp = {
"id": cw_inst.customer_details["Id"],
"firstname": cw_inst.customer_details["FirstName"],
Expand Down Expand Up @@ -241,6 +259,72 @@ async def _async_update_data(self) -> CheckwattResp:
except CheckwattError as err:
raise UpdateFailed(str(err)) from err

async def push_to_checkwatt_rank(self, cw_inst):
"""Push data to CheckWattRank."""
if self.today_revenue is not None:
if (
"Meter" in cw_inst.customer_details
and len(cw_inst.customer_details["Meter"]) > 0
):
url = "https://checkwattrank.netlify.app/.netlify/functions/publishToSheet"
headers = {
"Content-Type": "application/json",
}
payload = {
"display_name": cw_inst.customer_details["Meter"][0]["DisplayName"],
# "display_name": "xxTESTxx",
"dso": cw_inst.battery_registration["Dso"],
"electricity_company": self.energy_provider,
"electricity_area": cw_inst.price_zone,
"installed_power": cw_inst.battery_charge_peak,
"today_gross_income": self.today_revenue,
"today_fee": self.today_fees,
"today_net_income": self.today_revenue - self.today_fees,
"reseller_id": cw_inst.customer_details["Meter"][0]["ResellerId"],
}

# Specify a timeout value (in seconds)
timeout_seconds = 10

async with aiohttp.ClientSession() as session:
try:
async with session.post(
url, headers=headers, json=payload, timeout=timeout_seconds
) as response:
response.raise_for_status() # Raise an exception for HTTP errors
content_type = response.headers.get(
"Content-Type", ""
).lower()
_LOGGER.debug(
"CheckWattRank Push Response Content-Type: %s",
content_type,
)

if "application/json" in content_type:
result = await response.json()
_LOGGER.debug("CheckWattRank Push Response: %s", result)
return True
elif "text/plain" in content_type:
result = await response.text()
_LOGGER.debug("CheckWattRank Push Response: %s", result)
return True
else:
_LOGGER.warning(
"Unexpected Content-Type: %s", content_type
)
result = await response.text()
_LOGGER.debug("CheckWattRank Push Response: %s", result)

except aiohttp.ClientError as e:
_LOGGER.error("Error pushing data to CheckWattRank: %s", e)
except asyncio.TimeoutError:
_LOGGER.error(
"Request to CheckWattRank timed out after %s seconds",
timeout_seconds,
)

return False


class CheckwattError(HomeAssistantError):
"""Base error."""
Expand Down
17 changes: 15 additions & 2 deletions custom_components/checkwatt/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
from homeassistant.data_entry_flow import FlowResult
from homeassistant.exceptions import HomeAssistantError

from .const import CONF_DETAILED_ATTRIBUTES, CONF_DETAILED_SENSORS, DOMAIN
from .const import (
CONF_DETAILED_ATTRIBUTES,
CONF_DETAILED_SENSORS,
CONF_PUSH_CW_TO_RANK,
DOMAIN,
)

CONF_TITLE = "CheckWatt"

Expand Down Expand Up @@ -69,7 +74,11 @@ async def async_step_user(
return self.async_create_entry(
title=CONF_TITLE,
data=self.data,
options={CONF_DETAILED_SENSORS: False, CONF_DETAILED_ATTRIBUTES: False},
options={
CONF_DETAILED_SENSORS: False,
CONF_DETAILED_ATTRIBUTES: False,
CONF_PUSH_CW_TO_RANK: False,
},
)

return self.async_show_form(
Expand Down Expand Up @@ -111,6 +120,10 @@ async def async_step_init(
CONF_DETAILED_ATTRIBUTES,
default=self.config_entry.options.get(CONF_DETAILED_ATTRIBUTES),
): bool,
vol.Required(
CONF_PUSH_CW_TO_RANK,
default=self.config_entry.options.get(CONF_PUSH_CW_TO_RANK),
): bool,
}
),
)
Expand Down
1 change: 1 addition & 0 deletions custom_components/checkwatt/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

CONF_DETAILED_SENSORS: Final = "show_details"
CONF_DETAILED_ATTRIBUTES: Final = "show_detailed_attributes"
CONF_PUSH_CW_TO_RANK: Final = "push_to_cw_rank"

# Misc
P_UNKNOWN = "Unknown"
Expand Down
4 changes: 2 additions & 2 deletions custom_components/checkwatt/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"homekit": {},
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/faanskit/ha-checkwatt/issues",
"requirements": ["pycheckwatt>=0.1.6"],
"requirements": ["pycheckwatt>=0.1.6", "aiohttp>=3.9.1"],
"ssdp": [],
"version": "0.1.3",
"version": "0.1.4",
"zeroconf": []
}
3 changes: 2 additions & 1 deletion custom_components/checkwatt/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"init": {
"data": {
"show_details": "Provide energy sensors",
"show_detailed_attributes": "Offer detailed attributes"
"show_detailed_attributes": "Offer detailed attributes",
"push_to_cw_rank": "Push data to CheckWattRank"
},
"description": "Select options",
"title": "CheckWatt"
Expand Down
3 changes: 2 additions & 1 deletion custom_components/checkwatt/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"init": {
"data": {
"show_details": "Provide energy sensors",
"show_detailed_attributes": "Offer detailed attributes"
"show_detailed_attributes": "Offer detailed attributes",
"push_to_cw_rank": "Push data to CheckWattRank"
},
"description": "Select options",
"title": "CheckWatt"
Expand Down
3 changes: 2 additions & 1 deletion custom_components/checkwatt/translations/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"init": {
"data": {
"show_details": "Skapa energisensorer",
"show_detailed_attributes": "Visa detaljerade attribut"
"show_detailed_attributes": "Visa detaljerade attribut",
"push_to_cw_rank": "Skicka data till CheckWattRank"
},
"description": "Dina val",
"title": "CheckWatt"
Expand Down

0 comments on commit 8315d1e

Please sign in to comment.