@runnane/node-red-contrib-easee 0.7.6
Module for streaming Easee data. Based on node-red-contrib-signalrcore
@runnane/node-red-contrib-easee npm module
Node-Red module for streaming Easee charger data.
Features
- SignalR streaming client
- Pre-defined list of REST API GET/POST commands
- Custom commands through REST API
Howto
npm i @runnane/node-red-contrib-easee
Add the easee Charger Streaming Client node
Configure the node with username/password and the Charger ID.
Streaming node
Configure the node with username/password and a Charger ID ("EH000000").
Streaming telemetry from the signalR enpoint will be available in the fourth output,
the ProductUpdate one.
REST node
Use the easee REST Client node
Configure the node with an account username/password.
The REST node will not authenticate on its own, so you will need to authenticate/renew tokens.
However, if you use the easee Charger Streaming Client node,
you do not need to authenticate additionally with the REST node, as the signalR socket
will authenticate and renew automatically.
There are two ways of sending commands:
Sending predefined commands by topic
Send the your selected command as the topic into the node.
You can set the charger, site and/or circuit variables directly in the node, or send them as
msg.charger, msg.site and msg.circuit to override.
Implemented commands that may be sent as topic, are:
loginrefresh_tokenchargercharger_detailscharger_state(see the note below — Easee changed the underlying endpoint)charger_sitecharger_configcharger_session_latestcharger_session_ongoingstop_chargingstart_chargingpause_chargingresume_chargingtoggle_chargingdynamic_current(Without msg.payload.body for reading (GET), and with msg.payload.body for setting (POST).)reboot
Example, get charger details:
node.send({
topic: "charger_details",
charger: "EH000000",
});
Note on charger_state
Easee retired GET /api/chargers/{id}/state on 1 September 2026; it now returns
404. Since then charger_state reads the same values from the replacement
observations endpoint instead.
Your flows do not need to change. The payload is still an object keyed by the same
field names as before (msg.payload.totalPower.value, msg.payload.chargerOpMode.value
and so on), and each value is still a parsed observation. Each one now also carries a
timestamp.
Two differences worth knowing about:
- Six fields are gone.
connectedToCloud,fatalErrorCode,isOnline,voltage,latestPulseanderrorswere derived cloud-side by the old endpoint rather than being device observations, and the replacement cannot return them. A field the charger has not reported is omitted from the payload rather than sent asnull, so check with"fieldName" in msg.payloadif you need to distinguish the two. - The endpoint is rate limited to 100 requests per 5 minutes. If you drive
charger_statefrom an inject node, keep the interval at 3 seconds or slower. For continuous updates prefer the streaming client node, which pushes changes instead of polling.
Sending custom commands
Send the full path as msg.command, and optionally the POST body as msg.payload. See get_api-chargers for full list of commands. When adding a body, the request will be sent as a POST, else as a GET. If you wish to send a POST without body, add an empty object as POST argument.
Example to set dynamic current to 3x25A by doing a custom command with POST body:
Set dynamic current:
node.send({
payload: {
path: "/sites/1234/circuits/1345/dynamic_current",
body: { phase1: 25, phase2: 25, phase3: 25 },
}
});
Pause charging:
node.send({
payload: {
path: "/chargers/EH000000/commands/pause_charging",
body: {},
}
});
Development
The nodes are written in TypeScript and compiled to dist/, which is what the npm
package ships. Development uses pnpm, Biome,
Vitest and TypeScript 7, and needs Node.js 22.12 or newer; the
published package itself still runs on Node.js 18 and later.
pnpm install
pnpm gates # lint + format, typecheck, build, tests with coverage, Node-RED load check
Code Quality
pnpm check # Biome lint + format check
pnpm check:fix # apply Biome's fixes
pnpm typecheck # TypeScript
Testing
pnpm build # the package tests inspect the built dist/
pnpm test # all tests
pnpm test:watch # watch mode
pnpm test:coverage # with the coverage floor enforced
pnpm test:unit
pnpm test:integration
pnpm test:compat # load every node from dist/ into a real Node-RED runtime
Continuous Integration
GitHub Actions runs on every pull request:
- Gates:
pnpm gateson Node.js 22, 24 and 26 - Compatibility: the packed package is installed with npm and every node is loaded into Node-RED on Node.js 18, 20, 22 and 24
- Security:
pnpm auditof the dependencies that ship, with known advisories accepted explicitly
Releasing
Releases are cut from GitHub Actions: Actions → Release → Run workflow, choose
patch, minor or major, and untick Dry run. The workflow runs the checks, bumps
the version, pushes the vX.Y.Z tag, publishes to npm with
trusted publishing (so every version
carries provenance), and creates the GitHub release.
Example
See example flows
License
This project is licensed under the MIT License - see the LICENSE file for details.
Credits and Attribution
- Author: Jon Tungland (@runnane)
- Original Fork: Initially forked from node-red-contrib-signalrcore by Scott Page (Apache License 2.0), then extensively rewritten
- API Documentation: developer.easee.com
- Enumerations: developer.easee.com
License Migration Notice
This project was migrated from Apache License 2.0 to MIT License in 2025. The original Apache License 2.0 code from the forked project node-red-contrib-signalrcore has been preserved in the LICENSE file for attribution purposes. All subsequent modifications and additions by Jon Tungland are licensed under the MIT License.
Dependencies
All dependencies are compatible with the MIT License:
@microsoft/signalr: MIT License