I have written down-loaders for Python, and NodeRED (based on node.js) but I currently only maintain the latter. In essence your script will need to do a bunch of GETs which then return the JSON data that you need to parse, and one POST upfront to establish your login credentials. This script will also need to roll forward any session cookies as these are used to maintain the session context and authentication. I retro-engineered the request chain using a browser and web-tools window (typically Cntl+-Shift+I). (Hint: if you have two displays, then detach the debug window and move it to the second display, to keep things simple. Also set the "Persist logs" option to be able to track everything. Below is the result of my latest analysis, which was a useful exercise since OVO have updated their framework. My NodeRED flow looks like this and I've posted the JS code as a Gist: NodeRED Function to Download OVO Smart-meter Readings.
The first two request are to https://my.ovoenergy.com to initiate the authorized session context.
- GET https://my.ovoenergy.com/login to initiate logon. On a real browser this downloads bunch of JS scripts that display the logon page and process the "Log in" button. These can all be ignores except the session cookies.
- POST https://my.ovoenergy.com/api/v2/auth/login. Post content is a JSON object with items; username, password, rememberme (boolean).
Once authorized, the remaining request are https://smartpaymapi.ovoenergy.com.
- GET /first-login/api/bootstrap/v2/. This JSON object lists off the accounts used by the user (typically one). So either parse this or just use your known ACCOUNT. For a standard log on, the welcome page also generates a whole load of non-usage related requests, but the key one is:
- GET /orex/api/contracts/ACCOUNT. This JSON object lists off details of your contracts both electric and gas. Note that my smart meter is classed as ineligible for SMETS1 ot SMETS2 but is classed as "already smart"; I am not sure what this means but this could effect the format of the following requests for your analysis.
You can now loop through requesting daily or half-hourly data:
- GET /usage/api/daily/ACCOUNT?date=YYYY-MM. This returns a JSON object with electricity.data[i] containing the values for day i+1 of the given month. The consumption cost, and rates can be used to calculate the standing charge, peak and off-peak use and cost. (If are up to solving a simultaneous equation. 🤣) This will work for any ACCOUNT that you've logged onto with the session.
- GET /usage?datePeriod=daily&date=YYYY-MM-DD&unit=kwh. This returns a JSON object with electricity.data[i] where i = 0..47 being the energy reading for that half hour slot. Note that for can only get energy and not cost data on a half-hourly basis. You can also use the next and prev parameters to chain fetches for a date range. In this case, the account context is maintain in a session cookie rather than a request parameter. I need to check whether this is set by the daily breakdown request.
I assume that you can also do gas readings the same way.
Edited by TerryE
I forgot to publish this sorry