tronikos / opower

A Python library for getting historical and forecasted usage/cost from utilities that use opower.com such as PG&E
Apache License 2.0
53 stars 49 forks source link

New Provider: Duquesne Light #68

Closed swartzd closed 5 months ago

swartzd commented 5 months ago

Adds support for Duquesne Light Company (DQE), the major provider in Pittsburgh, PA area.

Example successful output:

$ python src/demo.py --utility duquesnelight --username <redacted> --password <redacted> --aggregate_type day

Current bill forecast: Forecast(account=Account(customer=Customer(uuid='<redacted>'), uuid='<redacted>', utility_account_id='<redacted>', meter_type=<MeterType.ELEC: 'ELEC'>, read_resolution=None), start_date=datetime.date(2024, 1, 9), end_date=datetime.date(2024, 2, 7), current_date=datetime.date(2024, 1, 30), unit_of_measure=<UnitOfMeasure.KWH: 'KWH'>, usage_to_date=714.0, cost_to_date=146.0, forecasted_usage=1026.0, forecasted_cost=211.0, typical_usage=578.0, typical_cost=128.0)

Getting historical data: account= Account(customer=Customer(uuid='<redacted>'), uuid='<redacted>', utility_account_id='<redacted>', meter_type=<MeterType.ELEC: 'ELEC'>, read_resolution=<ReadResolution.HOUR: 'HOUR'>) aggregate_type= day start_date= 2024-01-23 19:02:08.742167 end_date= 2024-01-30 19:02:08.742188

start_time  end_time    consumption provided_cost   start_minus_prev_end    end_minus_prev_end

2024-01-23 00:00:00-05:00   2024-01-24 00:00:00-05:00   30.229  5.843719135 None    None

2024-01-24 00:00:00-05:00   2024-01-25 00:00:00-05:00   32.283  6.240788145 0:00:00 1 day, 0:00:00

2024-01-25 00:00:00-05:00   2024-01-26 00:00:00-05:00   18.499  3.576134185 0:00:00 1 day, 0:00:00

2024-01-26 00:00:00-05:00   2024-01-27 00:00:00-05:00   38.887  7.517440405 0:00:00 1 day, 0:00:00

2024-01-27 00:00:00-05:00   2024-01-28 00:00:00-05:00   51.582  9.97157433  0:00:00 1 day, 0:00:00

Example failed login:

$ python src/demo.py --utility duquesnelight --username test --password test --aggregate_type day

Traceback (most recent call last):

  File "/home/user/repos/opower/src/demo.py", line 170, in <module>

    asyncio.run(_main())

  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run

    return loop.run_until_complete(main)

  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete

    return future.result()

  File "/home/user/repos/opower/src/demo.py", line 86, in _main

    await opower.async_login()

  File "/home/user/repos/opower/src/opower/opower.py", line 194, in async_login

    self.access_token = await self.utility.async_login(

  File "/home/user/repos/opower/src/opower/utilities/duquesnelight.py", line 112, in async_login

    raise InvalidAuth("Login failed")

opower.exceptions.InvalidAuth: Login failed

pre-commit:


check for added large files..............................................Passed

check python ast.........................................................Passed

check builtin type constructor use.......................................Passed

check for case conflicts.................................................Passed

check docstring is first.................................................Passed

check that executables have shebangs.................(no files to check)Skipped

check json...............................................................Passed

check for merge conflicts................................................Passed

check that scripts with shebangs are executable..........................Passed

check for broken symlinks............................(no files to check)Skipped

check toml...............................................................Passed

check vcs permalinks.....................................................Passed

check xml............................................(no files to check)Skipped

check yaml...............................................................Passed

debug statements (python)................................................Passed

detect destroyed symlinks................................................Passed

detect private key.......................................................Passed

fix end of files.........................................................Passed

fix utf-8 byte order marker..............................................Passed

forbid submodules....................................(no files to check)Skipped

mixed line ending........................................................Passed

trim trailing whitespace.................................................Passed

isort....................................................................Passed

black....................................................................Passed

flake8...................................................................Passed

ruff.....................................................................Passed

mypy.....................................................................Passed

pyupgrade................................................................Passed

yamllint.................................................................Passed

markdownlint.............................................................Passed

codespell................................................................Passed
tronikos commented 5 months ago

I just published a new version. Please bump the version on home assistant core, update the home assistant documentation and add a virtual integration.

gazpachoking commented 3 months ago

Just wanted to say thank you @swartzd and @tronikos. I looked at adding this myself a few times but could never get the token in an automated way because of some sort of javascript obfuscation they were doing.