Code Monkey home page Code Monkey logo

hass-bchydro's Introduction

Home Assistant BCHydro Sensor

๐Ÿšง In development, but you can copy sensor.py down to your HASS install: just copy-paste sensor.py into a file name the same inside your HASS custom_components/bchydro directory. Edit bchydro_username and bchydro_password to match your BCHydro account.

Installation

Place these files inside a directory in your custom_components directory:

cd config/custom_components
git clone [email protected]:emcniece/hass-bchydro.git

Then edit your configuration.yml to include this under sensors:

sensors:
  - platform: bchydro
    username: !secret bchydro_username
    password: !secret bchydro_password

Then edit your secrets.yml to include your BCHydro account details:

bchydro_username: [email protected]
bchydro_password: mypassword

Then restart your HASS installation and configure your new entites!

BCHydro Data Formats

Several calls are made to the BCHydro website for varying purposes.

Account Data

The URL_ACCT_INFO URL is used to obtain the user account slid which is later used for fetching usage data. This endpoint has a lot of other info that might be useful for consumption at a later time - here's a sample of the JSON response:

{
  "accountType": "residential",
  "evpSlid": "0001111111",
  "evpAccount": "000011111111",
  "evpAccountId": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "evpProfileId": "bchusername",
  "evpRateCategory": "BCRSE1101",
  "evpBillingClass": "Residential",
  "evpRateGroup": "RES1",
  "evpReadRoute": "BAAAAAAA",
  "evpBillingStart": "2020-06-06T00:00:00-07:00",
  "evpBillingEnd": "2020-08-06T00:00:00-07:00",
  "evpBilledStart": "2020-04-07T00:00:00-07:00",
  "evpBilledEnd": "2020-06-05T00:00:00-07:00",
  "evpValidityStart": "2020-06-29T00:00:00-07:00",
  "evpValidityEnd": "9999-12-31T00:00:00-08:00",
  "evpEnablementDate": "2012-12-23T23:00:00-08:00",
  "evpHeatingType": "N",
  "evpPremiseType": "10",
  "evpPostalCode": "V1V 1V1",
  "evpBillingArea": "99",
  "evpConsToDate": "584kWh",
  "evpCostToDate": "$67",
  "yesterdayPercentage": "97",
  "evpStepThreshold": "1375.89",
  "evpDaysInBillingPeriod": "62",
  "evpStepThresholdDate": "",
  "evpEstConsCurPeriod": "594",
  "evpEstCostCurPeriod": "68",
  "evpCurrentDateTime": "2020-08-06T23:30:46-07:00",
  "evpRole": "user",
  "evpCsrId": "bchusername",
  "evpComLastBillingPeakDemand": "",
  "evpComLastBillingPowerFactor": "",
  "enableSMSAlerts": "true",
  "nonWan": "False",
  "timezone": "GMT",
  "isEnDateinCBP": "True"
}

Usage Data

Points may be one of INVALID, ACTUAL, ESTIMATED(?). While evidence of ESTIMATED has been captured it seems to occur infrequently. This is something to plan for in the future and is noted in the ToDo.

After logging in, the usage URL_GET_USAGE URL returns data like this:

<Data>
  <Rates rateGroup="RES1" bpStart="Jun 6" bpEnd="Aug 6, 2020" daysSince="61" cons2date="584kWh" cost2date="$67" estCons="594" estCost="68"/>
  <Series name="Consumption data" step2Value="1375.89" isEnDateinCBP="true" evpCurrentDateTime="2020-08-06T22:41:06-07:00" blockStatus="0" nonWan="false">
    <Point type="SMI" quality="ACTUAL" dateTime="2020-07-30T00:00:00-07:00" endTime="2020-07-30T00:00:00-07:00" value="16.88" cost="0.00"/>
    <Point type="SMI" quality="ACTUAL" dateTime="2020-07-31T00:00:00-07:00" endTime="2020-07-31T00:00:00-07:00" value="12.36" cost="0.00"/>
    <Point type="SMI" quality="ACTUAL" dateTime="2020-08-01T00:00:00-07:00" endTime="2020-08-01T00:00:00-07:00" value="18.31" cost="0.00"/>
    <Point type="SMI" quality="ACTUAL" dateTime="2020-08-02T00:00:00-07:00" endTime="2020-08-02T00:00:00-07:00" value="16.27" cost="0.00"/>
    <Point type="SMI" quality="ACTUAL" dateTime="2020-08-03T00:00:00-07:00" endTime="2020-08-03T00:00:00-07:00" value="12.46" cost="0.00"/>
    <Point type="SMI" quality="ACTUAL" dateTime="2020-08-04T00:00:00-07:00" endTime="2020-08-04T00:00:00-07:00" value="14.66" cost="0.00"/>
    <Point type="SMI" quality="ACTUAL" dateTime="2020-08-05T00:00:00-07:00" endTime="2020-08-05T00:00:00-07:00" value="16.31" cost="0.00"/>
  </Series>
</Data>

In the sensor API, each of these <Point /> elements is processed like so:

for point in root.findall('Series')[0].findall('Point'):
    print(point.items())
    # [
    #   ('type', 'SMI'),
    #   ('quality', 'ACTUAL'),
    #   ('dateTime', '2020-07-30T00:00:00-07:00'),
    #   ('endTime', '2020-07-30T00:00:00-07:00'),
    #   ('value', '16.88'),
    #   ('cost', '0.00')
    # ]

ToDo

  • Unit tests + CI
  • Figure out how to read secrets
  • Implement HASS config flow for browser-based entry of secrets
  • Hass.io, integration, Supervisor, HACS compatibility
  • Add more sensors for days_since_billing, consumption_to_date, cost_to_date, estimated_consumption, estimated_cost
  • Handle ESTIMATED datapoints
    • Parse dates and only take latest_usage from days matching the current timestamp?

References

hass-bchydro's People

Contributors

emcniece avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

hass-bchydro's Issues

Is this still working

Is this still working/in development? I tried installing the custom component tonight but the sensors are just showing as unavailable.

No 'version' key in the manifest file

2021-03-07 15:34:46 WARNING (MainThread) [homeassistant.loader] No 'version' key in the manifest file for custom integration 'bchydro'. This will not be allowed in a future version of Home Assistant. Please report this to the maintainer of 'bchydro'

should probably fix that

Error using Sensor

Hi @emcniece, I'm getting the below error when I trying using the BC Hydro Home Assistant Senor. The sensor value is stuck at "Unavailable". My credentials in my Home Assistant Config match the credentials I'm using to log in to the BC Hydro website. I've tried wrapping the credentials in single quotes, double quotes and no quotes, without any luck. Do you have any ideas what's causing this?

Thank you,
Jack

2020-08-10 13:58:17 ERROR (SyncWorker_1) [custom_components.bchydro.sensor] SLID/Account Number parse error: Expecting value: line 1 column 1 (char 0)
2020-08-10 13:58:17 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.latest_usage fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 272, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 465, in async_device_update
await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/config/custom_components/bchydro/sensor.py", line 125, in update
self._api.login()
File "/config/custom_components/bchydro/sensor.py", line 182, in login
json = request.json()
File "/usr/local/lib/python3.8/site-packages/requests/models.py", line 898, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/local/lib/python3.8/site-packages/simplejson/init.py", line 525, in loads
return _default_decoder.decode(s)
File "/usr/local/lib/python3.8/site-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/local/lib/python3.8/site-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
2020-08-10 13:58:17 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.consumption_to_date fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 272, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 465, in async_device_update
await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/config/custom_components/bchydro/sensor.py", line 125, in update
self._api.login()
File "/config/custom_components/bchydro/sensor.py", line 155, in login
request = self.call_api(
File "/config/custom_components/bchydro/sensor.py", line 151, in call_api
response.raise_for_status()
File "/usr/local/lib/python3.8/site-packages/requests/models.py", line 941, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://app.bchydro.com/sso/UI/Login
2020-08-10 13:58:17 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.cost_to_date fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 272, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 465, in async_device_update
await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/config/custom_components/bchydro/sensor.py", line 125, in update
self._api.login()
File "/config/custom_components/bchydro/sensor.py", line 155, in login
request = self.call_api(
File "/config/custom_components/bchydro/sensor.py", line 151, in call_api
response.raise_for_status()
File "/usr/local/lib/python3.8/site-packages/requests/models.py", line 941, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://app.bchydro.com/sso/UI/Login
2020-08-10 13:58:18 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.next_billing_period fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 272, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 465, in async_device_update
await self.hass.async_add_executor_job(
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/config/custom_components/bchydro/sensor.py", line 125, in update
self._api.login()
File "/config/custom_components/bchydro/sensor.py", line 155, in login
request = self.call_api(
File "/config/custom_components/bchydro/sensor.py", line 151, in call_api
response.raise_for_status()
File "/usr/local/lib/python3.8/site-packages/requests/models.py", line 941, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://app.bchydro.com/sso/UI/Login

Unable to parse XML from string: no element found: line 1, column 0

Found after the sensor had been performing well for a few hours:

Logger: custom_components.bchydro.sensor
Source: custom_components/bchydro/sensor.py:54
Integration: bchydro (documentation)
First occurred: 1:46:18 PM (2 occurrences)
Last logged: 1:49:19 PM

Unable to parse XML from string: no element found: line 1, column 0

The UI element is reporting an unknown state:

Screen Shot 2020-08-07 at 1 53 02 PM

Is there a way to have the sensor fail and keep its prior state?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.