Skip to content

Instantly share code, notes, and snippets.

@gadgetmies
Last active November 18, 2022 22:47
Show Gist options
  • Save gadgetmies/4ba42bf63d91d787cf2328b31b06e72d to your computer and use it in GitHub Desktop.
Save gadgetmies/4ba42bf63d91d787cf2328b31b06e72d to your computer and use it in GitHub Desktop.
Fetch energy consumption from Helen with Puppeteer and push results to InfluxDB
// Put this file under src folder in the path where you put the run.sh
const puppeteer = require("puppeteer");
const http = require("node:http");
const influxOrg = ''
const influxBucket = ''
const influxHost = ''
const influxPort = 8086
const influxToken = ''
const helenUsername = ''
const helenPassword = ''
const substractOneDay = date => {
let d = new Date(date)
d.setDate(d.getDate() - 1)
return d
}
const addOneDay = date => {
let d = new Date(date)
d.setDate(d.getDate() + 1)
return d
}
const dateWithTime = (date, timeString) => {
let d = new Date(date)
return new Date(date.toISOString().substring(0, 10) + timeString)
}
const startTime = 'T22:00:00Z'
const endTime = 'T21:59:59Z'
;(async () => {
const yesterdayDate = substractOneDay(dateWithTime(new Date(), endTime))
const dayBeforeYesterdayDate = substractOneDay(dateWithTime(yesterdayDate, startTime))
const startDateString = (
process.env.START_DATE ?
new Date(process.env.START_DATE + startTime) :
process.env.END_DATE ?
substractOneDay(new Date(process.env.END_DATE + startTime)) :
dayBeforeYesterdayDate
).toISOString()
const endDateString = (process.env.END_DATE ? new Date(process.env.END_DATE + endTime) : yesterdayDate).toISOString()
console.log('Fetching electricity consumption for: ' + startDateString + ' - ' + endDateString)
const browser = await puppeteer.launch({
bindAddress: "0.0.0.0",
args: [
"--no-sandbox",
"--headless",
"--disable-gpu",
"--disable-dev-shm-usage",
"--remote-debugging-port=9222",
"--remote-debugging-address=0.0.0.0"
]
});
const page = await browser.newPage();
await page.goto("https://www.helen.fi/hcc/TupasLoginFrame?service=account&locale=fi", {
waitUntil: "networkidle2"
});
await page.waitForSelector('#username');
await page.type('#username', helenUsername);
await page.type('#password', helenPassword);
await page.click('.loginbutton input');
await page.waitForFunction('window.location.href === "https://web.omahelen.fi/personal"')
const electricity = await page.evaluate(async (startDateString, endDateString) => {
const bearer = window.localStorage.getItem('accessToken')
const res = await fetch(`https://api.omahelen.fi/v7/measurements/electricity?begin=${startDateString}&end=${endDateString}&resolution=hour&delivery_site_id=2438463&allow_transfer=true`, {headers: {'Authorization': 'Bearer ' + bearer }})
const measurements = await res.json()
let date = new Date(startDateString)
measurementLines = measurements.intervals.electricity[0].measurements.map(({value, status}) => {
const v = {value, timestamp: date.getTime(), valid: status === 'valid'}
date.setHours(date.getHours() + 1)
return v
}).filter(({valid}) => valid)
return measurementLines
}, startDateString, endDateString);
const lines = electricity.map(({value, timestamp}) => `kWh,domain=sensor,friendly_name=Helen\\ energy\\ consumption,source=Helen energy=${value} ${timestamp}`)
console.log('Sending data to InfluxDB:\n', lines.join('\n'))
const postReq = http.request({
host: influxHost,
port: influxPort,
path: `/api/v2/write?org=${influxOrg}&bucket=${influxBucket}&precision=ms`,
method: 'POST',
headers: {
Authorization: `Token ${influxToken}`,
'Content-Type': 'text/plain; charset=utf-8',
}
}, (res) => {
res.setEncoding('utf8')
res.on('data', (chunk) => console.log('Response: ' + chunk));
})
postReq.write(lines.join('\n'))
postReq.end()
console.log('Done')
await browser.close();
})();
docker container run --rm -u root -v ${PWD}/src:/usr/src/app/src -e START_DATE=$1 -e END_DATE=$2 --cap-add=SYS_ADMIN zenika/alpine-chrome:with-puppeteer node src/helen.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment