Skip to content

Commit

Permalink
Merge pull request #23 from bisand/develop
Browse files Browse the repository at this point in the history
Added tibber-notify node
  • Loading branch information
bisand committed Sep 3, 2019
2 parents d2819f3 + c7c92d9 commit 632a106
Show file tree
Hide file tree
Showing 17 changed files with 522 additions and 121 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"env": {
"browser": true,
"commonjs": true,
"node": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
Expand Down
179 changes: 175 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Node Red module for integrating with Tibber api.

*Warning! This is early stage development.*
> *Warning! This is early stage development.*
| Branch | Status |
|----------|------------------|
Expand Down Expand Up @@ -38,11 +38,182 @@ $ npm install node-red-contrib-tibber-api

## Nodes

### Tibber Feed node
### Tibber Feed node (*tibber-feed*)
![tibber-feed](examples/images/tibber-feed.png)

Realtime power consuption data from Tibber Pulse. Provide API token, Home ID and select what kind of information you want to retrieve.
> Note! There can be only one instance of *tibber-feed* per API key. Doing otherwise may return unpredictable result, or even error response from the API.
### Tibber API call node (*tibber-query*)
![tibber-query](examples/images/tibber-query.png)

Do basic calls to Tibber API using GraphQL queries. To query the Tibber API, simply provide raw GraphQL queries in the payload of the incoming message. See Tibber API documentation and API Explorer for more informations.

### Tibber push notification (*tibber-notify*)
![tibber-notify](examples/images/tibber-notify.png)

### Tibber API call node
Do basic calls to Tibber API using GraphQL queries. See Tibber API documentation and API Explorer for more informations.
Send push nofifications to connected TIbber apps via Tibber API using GraphQL queries. Fill in Title, Message and which screen to open in the app directly in the node, or by providing the data via the incomming .

### Tibber data (*tibber-data*)
**TODO!**
Select from a set of predefined queries to retrieve data from Tibber API.

## Examples
<details>
<summary>Node-Red Example flow</summary>
<p>

### Tibber Test Flow.json
```json
[
{
"id": "4e0718b1.2af2a8",
"type": "tab",
"label": "Tibber Test Flow",
"disabled": false,
"info": ""
},
{
"id": "8099995f.515738",
"type": "inject",
"z": "4e0718b1.2af2a8",
"name": "",
"topic": "",
"payload": "{viewer{homes{id size appNickname appAvatar address{address1 address2 address3 postalCode city country latitude longitude}}}}",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 130,
"y": 80,
"wires": [
[
"28454c92.811574"
]
]
},
{
"id": "944c04ef.7b6638",
"type": "debug",
"z": "4e0718b1.2af2a8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 570,
"y": 80,
"wires": []
},
{
"id": "c80cad4f.7a806",
"type": "tibber-feed",
"z": "4e0718b1.2af2a8",
"name": "",
"active": true,
"apiUrl": "wss://api.tibber.com/v1-beta/gql/subscriptions",
"apiToken": "d1007ead2dc84a2b82f0de19451c5fb22112f7ae11d19bf2bedb224a003ff74a",
"homeId": "c70dcbe5-4485-4821-933d-a8a86452737b",
"timestamp": "1",
"power": "1",
"lastMeterConsumption": "1",
"accumulatedConsumption": "1",
"accumulatedProduction": "1",
"accumulatedCost": "1",
"accumulatedReward": "1",
"currency": "1",
"minPower": "1",
"averagePower": "1",
"maxPower": "1",
"powerProduction": "1",
"minPowerProduction": "1",
"maxPowerProduction": "1",
"lastMeterProduction": "1",
"powerFactor": "1",
"voltagePhase1": "1",
"voltagePhase2": "1",
"voltagePhase3": "1",
"currentPhase1": "1",
"currentPhase2": "1",
"currentPhase3": "1",
"x": 120,
"y": 180,
"wires": [
[
"781f5eed.ea2a3"
]
]
},
{
"id": "781f5eed.ea2a3",
"type": "debug",
"z": "4e0718b1.2af2a8",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 350,
"y": 180,
"wires": []
},
{
"id": "28454c92.811574",
"type": "tibber-query",
"z": "4e0718b1.2af2a8",
"name": "",
"active": true,
"apiUrl": "https://api.tibber.com/v1-beta/gql",
"apiToken": "d1007ead2dc84a2b82f0de19451c5fb22112f7ae11d19bf2bedb224a003ff74a",
"x": 350,
"y": 80,
"wires": [
[
"944c04ef.7b6638"
]
]
},
{
"id": "f3a4184a.047968",
"type": "tibber-notify",
"z": "4e0718b1.2af2a8",
"name": "",
"active": true,
"apiUrl": "https://api.tibber.com/v1-beta/gql",
"apiToken": "d1007ead2dc84a2b82f0de19451c5fb22112f7ae11d19bf2bedb224a003ff74a",
"notifyTitle": "",
"notifyMessage": "",
"notifyScreen": "",
"x": 330,
"y": 300,
"wires": []
},
{
"id": "b0e33b71.865f18",
"type": "inject",
"z": "4e0718b1.2af2a8",
"name": "",
"topic": "",
"payload": "{\"title\":\"Test\",\"message2\":\"Dette er en test\",\"screen\":\"HOME\"}",
"payloadType": "json",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 120,
"y": 300,
"wires": [
[
"f3a4184a.047968"
]
]
}
]
```
</p></details>

## License
[MIT](https://choosealicense.com/licenses/mit/)
37 changes: 36 additions & 1 deletion examples/Tibber Test Flow.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"console": false,
"tostatus": false,
"complete": "false",
"x": 560,
"x": 570,
"y": 80,
"wires": []
},
Expand Down Expand Up @@ -108,5 +108,40 @@
"944c04ef.7b6638"
]
]
},
{
"id": "f3a4184a.047968",
"type": "tibber-notify",
"z": "4e0718b1.2af2a8",
"name": "",
"active": true,
"apiUrl": "https://api.tibber.com/v1-beta/gql",
"apiToken": "d1007ead2dc84a2b82f0de19451c5fb22112f7ae11d19bf2bedb224a003ff74a",
"notifyTitle": "",
"notifyMessage": "",
"notifyScreen": "",
"x": 330,
"y": 300,
"wires": []
},
{
"id": "b0e33b71.865f18",
"type": "inject",
"z": "4e0718b1.2af2a8",
"name": "",
"topic": "",
"payload": "{\"title\":\"Test\",\"message2\":\"Dette er en test\",\"screen\":\"HOME\"}",
"payloadType": "json",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 120,
"y": 300,
"wires": [
[
"f3a4184a.047968"
]
]
}
]
Binary file added examples/images/tibber-feed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/images/tibber-notify.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/images/tibber-query.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/send-push-notification.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mutation{sendPushNotification(input: {title: "Notification through API", message: "Hello from me!!", screenToOpen: CONSUMPTION}){successful pushedToNumberOfDevices}}
27 changes: 12 additions & 15 deletions nodes/TibberFeed.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const WebSocket = require('ws');
const events = require('events');
const EventEmitter = require('events').EventEmitter;

class TibberFeed {
class TibberFeed extends EventEmitter {

constructor(config, timeout = 30000) {

super();

var node = this;
node._timeout = timeout;
Expand All @@ -12,8 +14,6 @@ class TibberFeed {
node._hearbeatTimeouts = [];
node._isConnected = false;

node.events = new events.EventEmitter();

if (!config.apiToken || !config.homeId || !config.apiUrl) {
node._active = false;
config.active = false;
Expand Down Expand Up @@ -101,15 +101,15 @@ class TibberFeed {
if (!node._webSocket)
return;
node._webSocket.send('{"type":"connection_init","payload":"token=' + node._config.apiToken + '"}');
node.events.emit('connected', "Connected to Tibber feed.");
node.emit('connected', "Connected to Tibber feed.");
});

node._webSocket.on('message', function (message) {
if (message.startsWith('{')) {
var msg = JSON.parse(message);
if (msg.type == 'connection_ack') {
node._isConnected = true;
node.events.emit('connection_ack', msg);
node.emit('connection_ack', msg);
var str = JSON.stringify(node._query);
if (node._webSocket)
node._webSocket.send(str);
Expand All @@ -120,14 +120,14 @@ class TibberFeed {
if (!msg.payload.data)
return;
var data = msg.payload.data.liveMeasurement;
node.events.emit('data', data);
node.emit('data', data);
}
}
});

node._webSocket.on('close', function () {
node._isConnected = false;
node.events.emit('disconnected', "Disconnected from Tibber feed");
node.emit('disconnected', "Disconnected from Tibber feed");
});

node._webSocket.on('error', function (error) {
Expand All @@ -151,7 +151,7 @@ class TibberFeed {

heartbeat() {
var node = this;
for( var i = 0; i < node._hearbeatTimeouts.length; i++){
for (var i = 0; i < node._hearbeatTimeouts.length; i++) {
var timeout = node._hearbeatTimeouts[i];
clearTimeout(timeout);
node._hearbeatTimeouts.shift()
Expand All @@ -169,26 +169,23 @@ class TibberFeed {

log(message) {
try {
if (this.events)
this.events.emit('log', message);
this.emit('log', message);
} catch (error) {
console.error(error);
}
}

warn(message) {
try {
if (this.events)
this.events.emit('warn', message);
this.emit('warn', message);
} catch (error) {
console.error(error);
}
}

error(message) {
try {
if (this.events)
this.events.emit('error', message);
this.emit('error', message);
} catch (error) {
console.error(error);
}
Expand Down
Loading

0 comments on commit 632a106

Please sign in to comment.