The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Battery AI \u2013 Savings Tracker",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "55 23 * * *"
}
]
}
},
"id": "savings-schedule-trigger",
"name": "Trigger: t\u00e4glich 23:55",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
0
],
"typeVersion": 1.3
},
{
"parameters": {
"url": "http://homeassistant:8123/api/states/input_boolean.ki_batteriesteuerung_aktiv",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {}
},
"id": "savings-ha-ki-check",
"name": "HA: KI-Schalter pr\u00fcfen",
"type": "n8n-nodes-base.httpRequest",
"position": [
224,
0
],
"typeVersion": 4.4,
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.state }}",
"value2": "on"
}
]
},
"options": {}
},
"id": "savings-ki-aktiv",
"name": "KI aktiv?",
"type": "n8n-nodes-base.if",
"position": [
448,
0
],
"typeVersion": 2.3
},
{
"parameters": {
"jsCode": "const now = new Date();\nconst todayUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())).toISOString();\nconst monthUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)).toISOString();\nreturn [{ json: {\n today_utc: todayUTC,\n month_utc: monthUTC,\n query_battery_power: 'SELECT integral(\"value\") / 3600000 FROM \"batteryPower\" WHERE \"value\" > 0 AND time >= \\'' + todayUTC + '\\' GROUP BY time(1h) fill(0)',\n query_tariff_hourly: 'SELECT mean(\"value\") * 100 FROM \"tariffGrid\" WHERE time >= \\'' + todayUTC + '\\' GROUP BY time(1h) fill(none)',\n query_tariff_avg: 'SELECT mean(\"value\") * 100 FROM \"tariffGrid\" WHERE time >= \\'' + todayUTC + '\\'',\n query_savings_month: 'SELECT sum(\"savings_eur\") FROM \"battery_savings\" WHERE time >= \\'' + monthUTC + '\\''\n}}];"
},
"id": "savings-heute-berechnen",
"name": "Heute berechnen",
"type": "n8n-nodes-base.code",
"position": [
672,
0
],
"typeVersion": 2
},
{
"parameters": {
"url": "http://a0d7b954-influxdb:8086/query",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "db",
"value": "evcc"
},
{
"name": "q",
"value": "={{ $json.query_battery_power }}"
}
]
},
"options": {}
},
"id": "savings-influxdb-battery",
"name": "InfluxDB: batteryPower st\u00fcndlich",
"type": "n8n-nodes-base.httpRequest",
"position": [
896,
0
],
"typeVersion": 4.4,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "http://a0d7b954-influxdb:8086/query",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "db",
"value": "evcc"
},
{
"name": "q",
"value": "={{ $('Heute berechnen').first().json.query_tariff_hourly }}"
}
]
},
"options": {}
},
"id": "savings-influxdb-tariff-hourly",
"name": "InfluxDB: tariffGrid st\u00fcndlich",
"type": "n8n-nodes-base.httpRequest",
"position": [
1120,
0
],
"typeVersion": 4.4,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "http://a0d7b954-influxdb:8086/query",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "db",
"value": "evcc"
},
{
"name": "q",
"value": "={{ $('Heute berechnen').first().json.query_tariff_avg }}"
}
]
},
"options": {}
},
"id": "savings-influxdb-tariff-avg",
"name": "InfluxDB: tariffGrid Durchschnitt",
"type": "n8n-nodes-base.httpRequest",
"position": [
1344,
0
],
"typeVersion": 4.4,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const powerValues = $('InfluxDB: batteryPower st\u00fcndlich').first()?.json?.results?.[0]?.series?.[0]?.values ?? [];\nconst priceValues = $('InfluxDB: tariffGrid st\u00fcndlich').first()?.json?.results?.[0]?.series?.[0]?.values ?? [];\nconst avgCtRaw = $('InfluxDB: tariffGrid Durchschnitt').first()?.json?.results?.[0]?.series?.[0]?.values?.[0]?.[1] ?? null;\n\nconst now = new Date().toISOString();\n\nif (avgCtRaw === null || powerValues.length === 0) {\n return [{ json: { savings_today_eur: 0, avg_ct: 0, slots_count: 0, timestamp: now, line_protocol: 'battery_savings,period=daily savings_eur=0.0' } }];\n}\n\nconst avg_ct = avgCtRaw;\nconst priceMap = {};\nfor (const [ts, price_ct] of priceValues) {\n if (price_ct !== null) priceMap[ts] = price_ct;\n}\n\nlet savings_today = 0;\nlet slots_count = 0;\nfor (const [ts, kwh] of powerValues) {\n if (kwh === null || kwh <= 0) continue;\n const slot_ct = priceMap[ts] ?? avg_ct;\n const saved = kwh * (avg_ct - slot_ct) / 100;\n savings_today += Math.max(0, saved);\n slots_count++;\n}\n\nconst savings_rounded = Math.round(savings_today * 10000) / 10000;\nreturn [{ json: {\n savings_today_eur: savings_rounded,\n avg_ct: Math.round(avg_ct * 100) / 100,\n slots_count,\n timestamp: now,\n line_protocol: 'battery_savings,period=daily savings_eur=' + savings_rounded\n} }];"
},
"id": "savings-ersparnis-berechnen",
"name": "Ersparnis berechnen",
"type": "n8n-nodes-base.code",
"position": [
1568,
0
],
"typeVersion": 2
},
{
"parameters": {
"method": "POST",
"url": "http://homeassistant:8123/api/states/sensor.battery_ai_savings_today",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { \"state\": String($json.savings_today_eur), \"attributes\": { \"unit_of_measurement\": \"EUR\", \"friendly_name\": \"KI Ersparnis heute\", \"avg_ct\": $json.avg_ct, \"slots_count\": $json.slots_count, \"timestamp\": $json.timestamp } } }}",
"options": {}
},
"id": "savings-ha-heute",
"name": "HA: Ersparnis heute aktualisieren",
"type": "n8n-nodes-base.httpRequest",
"position": [
1792,
0
],
"typeVersion": 4.4,
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "http://a0d7b954-influxdb:8086/write?db=evcc",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendBody": true,
"contentType": "raw",
"rawContentType": "text/plain",
"body": "={{ $('Ersparnis berechnen').first().json.line_protocol }}",
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
}
},
"id": "savings-influxdb-write",
"name": "InfluxDB: Ersparnis schreiben",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
2016,
0
],
"typeVersion": 4.4,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "http://a0d7b954-influxdb:8086/query",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "db",
"value": "evcc"
},
{
"name": "q",
"value": "={{ $('Heute berechnen').first().json.query_savings_month }}"
}
]
},
"options": {}
},
"id": "savings-influxdb-month",
"name": "InfluxDB: Ersparnis Monat",
"type": "n8n-nodes-base.httpRequest",
"position": [
2240,
0
],
"typeVersion": 4.4,
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const results = $input.first()?.json?.results;\nlet val = 0;\nif (results && results[0] && results[0].series && results[0].series[0] &&\n results[0].series[0].values && results[0].series[0].values[0]) {\n val = results[0].series[0].values[0][1] || 0;\n}\nconst savings_month_eur = Math.round(val * 10000) / 10000;\nreturn [{ json: { savings_month_eur } }];"
},
"id": "savings-monat-berechnen",
"name": "Monatswert berechnen",
"type": "n8n-nodes-base.code",
"position": [
2352,
0
],
"typeVersion": 2
},
{
"parameters": {
"method": "POST",
"url": "http://homeassistant:8123/api/states/sensor.battery_ai_savings_month",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { \"state\": String($json.savings_month_eur), \"attributes\": { \"unit_of_measurement\": \"EUR\", \"friendly_name\": \"KI Ersparnis Monat\" } } }}",
"options": {}
},
"id": "savings-ha-monat",
"name": "HA: Ersparnis Monat aktualisieren",
"type": "n8n-nodes-base.httpRequest",
"position": [
2576,
0
],
"typeVersion": 4.4,
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"httpMethod": "POST",
"path": "battery-ai-savings-restore",
"options": {}
},
"id": "webhook-savings-restore",
"name": "Webhook: Savings wiederherstellen",
"type": "n8n-nodes-base.webhook",
"position": [
0,
-160
],
"typeVersion": 2
}
],
"connections": {
"Trigger: t\u00e4glich 23:55": {
"main": [
[
{
"node": "HA: KI-Schalter pr\u00fcfen",
"type": "main",
"index": 0
}
]
]
},
"HA: KI-Schalter pr\u00fcfen": {
"main": [
[
{
"node": "KI aktiv?",
"type": "main",
"index": 0
}
]
]
},
"KI aktiv?": {
"main": [
[
{
"node": "Heute berechnen",
"type": "main",
"index": 0
}
],
[]
]
},
"Heute berechnen": {
"main": [
[
{
"node": "InfluxDB: batteryPower st\u00fcndlich",
"type": "main",
"index": 0
}
]
]
},
"InfluxDB: batteryPower st\u00fcndlich": {
"main": [
[
{
"node": "InfluxDB: tariffGrid st\u00fcndlich",
"type": "main",
"index": 0
}
]
]
},
"InfluxDB: tariffGrid st\u00fcndlich": {
"main": [
[
{
"node": "InfluxDB: tariffGrid Durchschnitt",
"type": "main",
"index": 0
}
]
]
},
"InfluxDB: tariffGrid Durchschnitt": {
"main": [
[
{
"node": "Ersparnis berechnen",
"type": "main",
"index": 0
}
]
]
},
"Ersparnis berechnen": {
"main": [
[
{
"node": "HA: Ersparnis heute aktualisieren",
"type": "main",
"index": 0
}
]
]
},
"HA: Ersparnis heute aktualisieren": {
"main": [
[
{
"node": "InfluxDB: Ersparnis schreiben",
"type": "main",
"index": 0
}
]
]
},
"InfluxDB: Ersparnis schreiben": {
"main": [
[
{
"node": "InfluxDB: Ersparnis Monat",
"type": "main",
"index": 0
}
]
]
},
"InfluxDB: Ersparnis Monat": {
"main": [
[
{
"node": "Monatswert berechnen",
"type": "main",
"index": 0
}
]
]
},
"Monatswert berechnen": {
"main": [
[
{
"node": "HA: Ersparnis Monat aktualisieren",
"type": "main",
"index": 0
}
]
]
},
"Webhook: Savings wiederherstellen": {
"main": [
[
{
"node": "HA: KI-Schalter pr\u00fcfen",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
httpBasicAuthhttpHeaderAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Battery AI – Savings Tracker. Uses httpRequest. Scheduled trigger; 14 nodes.
Source: https://github.com/OZON08/EVCC-KI-Automation/blob/2bfdecebb50d632e0cba046a2074c8ca9a9a289d/n8n-workflows/savings-tracker.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
This template runs two scheduled workflows to govern Microsoft Entra ID (Azure AD) guest accounts by detecting stale users via Microsoft Graph, staging deletions in SharePoint with a 72-hour window, n
Jira-Allure-Auto-Qa. Uses httpRequest, jira. Scheduled trigger; 68 nodes.
Spotify-Sync-Surrealdb-V1. Uses httpRequest, n8n-nodes-surrealdb, spotify. Scheduled trigger; 62 nodes.
As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o