When I was first new with HA, I set up my first config to include a bchydro custom component.
I’ve searched everywhere I can think of (and… don’t have it stored locally. sigh) and cannot find this… Help?
I don’t recall seeing it and I keep a close watch of new components. If it was a custom component, should you not see it in your custom component folder?
My first install wasn’t preserved, or at least I don’t think it was. I haven’t found a backup of it anywhere.
I feel like I dreamed it, but I’m really sure I remember the data, and it being a bit of a funky setup…
I FOUND IT!!! @RobDYI if you’re interested?
import logging
import xml.etree.ElementTree as ET
import homeassistant.helpers.config_validation as cv
import requests
import voluptuous as vol
from homeassistant.const import (
CONF_PASSWORD, CONF_USERNAME, CONF_TIMEOUT)
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
DOMAIN = 'bchydro'
DEFAULT_TIMEOUT = 10
CONF_ACCOUNT_NUMBER = 'account_number'
CONF_SLID = 'slid'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_ACCOUNT_NUMBER): cv.string,
vol.Optional(CONF_SLID): cv.string,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
})
}, extra=vol.ALLOW_EXTRA)
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the sensor platform."""
api = Api(config.get(CONF_USERNAME),
config.get(CONF_PASSWORD),
config.get(CONF_ACCOUNT_NUMBER),
config.get(CONF_SLID),
config.get(CONF_TIMEOUT))
add_devices([BCHydroUsageSensor(api)], True)
class BCHydroUsageSensor(Entity):
def __init__(self, api):
"""Initialize the sensor."""
self._api = api
self._state = None
@property
def name(self):
"""Return the name of the sensor."""
return 'BC Hydro Usage'
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def unit_of_measurement(self):
return 'kWh'
def update(self):
"""Fetch new state data for the sensor."""
self._state = self._api.latest_usage()
URL_LOGIN = "https://app.bchydro.com/sso/UI/Login"
URL_GET_USAGE = "https://app.bchydro.com/evportlet/SystemServices/main?system:runTemplate=html/indicators/AccountProfile.xml"
class Api:
def __init__(self, username, password, account_number, slid, timeout=10):
"""Initialize the sensor."""
self._username = username
self._password = password
self._account_number = account_number
self._slid = slid
self._timeout = timeout
def login(self):
r = self._call_api(
"post",
URL_LOGIN,
data={
"realm": "bch-ps",
'email': self._username,
'password': self._password,
}, allow_redirects=False)
return r.cookies
def latest_usage(self):
"""Fetch new state data for the sensor."""
auth_cookies = self.login()
r = self._call_api(
"post",
URL_GET_USAGE,
data={
"Slid": self._slid,
"Account": self._account_number,
"ValidityStart": '2015-09-03T00:00:00.000-07:00',
"ValidityEnd": '9999-12-31T00:00:00.000-08:00'
}, cookies=auth_cookies)
latest_usage = None
root = ET.fromstring(r.text)
for point in root.findall('Series')[0].findall('Point'):
if point.get('quality') != 'INVALID':
latest_usage = point.get('value')
return latest_usage
def _call_api(self, method, url, **kwargs):
payload = kwargs.get("params") or kwargs.get("data")
_LOGGER.debug("About to call %s with payload=%s", url, payload)
response = requests.request(method, url, timeout=self._timeout, **kwargs)
_LOGGER.debug("Received API response: %s, %s",
response.status_code,
response.content)
response.raise_for_status()
return response
Thanks, I copied it to /.homeassistant/custom_components/bchydro/bchydro.py and put in configuration.yaml
bchydro:
username: [email protected]
password: xxx
but I get
Configuration invalidCHECK CONFIG
Integration not found: bchydro
I tried /.homeassistant/custom_components/bchydro/sensor.py
with
sensor:
- platform: bchydro
username: xxx
password: xxx
but get
Integration bchydro not found when trying to verify its sensor platform.
I tried the two things you’ve described, and hosed my HA install, so you’re still doing better than me
Alright, I’ve got it working!
- platform: bchydro
scan_interval: 36
username: !secret bchydro_username
password: !secret bchydro_password
account_number: !secret bchydro_account_number
slid: !secret bchydro_slid
I need to look up how I found the slid again, but im excited it is working!!
Can you share what you put in your configuration.yaml and where you put the custom component?
Thank you
Where do you find the slid?
You can find it on your bill
I used HACS To install the custom component from my github: https://github.com/hdsheena/custom_components
And my config yaml entry is
- platform: bchydro
scan_interval: 36
username: !secret bchydro_username
password: !secret bchydro_password
account_number: !secret bchydro_account_number
slid: !secret bchydro_slid
I’d like to improve the way this gets data, I think it would be pretty easy to have it grab the hourly data rather than just the “Current usage” if anyone else is interested in this?
I’d definitely be interested in a “current usage” if someone can figure it out.
I think I’ve got the slid, does it look like this?
800000000XXXXXXX000023609000011578
I removed the extra spaces, and in the example I X’d out my account number
What information can you get from BC Hydro through this component? I know you can get daily consumption one day behind in your online account, and their smart speaker support function for Alexa and Google Home can tell you consumption to date this month and an approximate breakdown of power usage type. Is there any way to get real-time power usage, or is that data not communicated so often?
Hello all ,
Can someone please tell me where to find the SLID, I’ve tried what @cariboo mentioned but I’m getting this error
bchydro: Error on device update!
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 291, in _async_add_entity
await entity.async_device_update(warning=False)
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 419, in async_device_update
await self.hass.async_add_executor_job(self.update)
File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/config/custom_components/bchydro/sensor.py", line 62, in update
self._state = self._api.latest_usage()
File "/config/custom_components/bchydro/sensor.py", line 127, in latest_usage
for point in root.findall('Series')[0].findall('Point'):
IndexError: list index out of range
all my other credentials are correct. Any help would be appreciated
Thanks
This is just scraping from the web interface, and that’s not real-time, so this solution won’t offer real time tracking.
SLID:
Go to your bcHydro account page, and use “Inspect Element” in your browser.
Navigate to the detailed consupmtion page and go to “Network” in the inspector. Search “xml” to filter the list, and find consumption.xml
Look at the “Form Data” section in the headers tab for your SLID
IT WORKED!!! Using the SLID and “Account” from the xml file and my username and password.
Thank you so much
Hi, the BC hydro sensor was working perfectly! And then it broke…
Is this happening to anyone else?
Mine is just disappeared… maybe I need to make a change based on the newest updates?