node-red-contrib-senec-cloud-v2 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/assets/fonts/senec-sans.ttf +0 -0
- package/dist/lib/dashboard-html-renderer.d.ts +18 -0
- package/dist/lib/dashboard-html-renderer.d.ts.map +1 -0
- package/dist/lib/dashboard-html-renderer.js +604 -0
- package/dist/lib/dashboard-html-renderer.js.map +1 -0
- package/dist/lib/dashboard-layout.d.ts +152 -0
- package/dist/lib/dashboard-layout.d.ts.map +1 -0
- package/dist/lib/dashboard-layout.js +201 -0
- package/dist/lib/dashboard-layout.js.map +1 -0
- package/dist/lib/geocoding-client.d.ts +61 -0
- package/dist/lib/geocoding-client.d.ts.map +1 -0
- package/dist/lib/geocoding-client.js +77 -0
- package/dist/lib/geocoding-client.js.map +1 -0
- package/dist/lib/senec-image-renderer.d.ts +107 -0
- package/dist/lib/senec-image-renderer.d.ts.map +1 -0
- package/dist/lib/senec-image-renderer.js +872 -0
- package/dist/lib/senec-image-renderer.js.map +1 -0
- package/dist/lib/senec-layout.d.ts +212 -0
- package/dist/lib/senec-layout.d.ts.map +1 -0
- package/dist/lib/senec-layout.js +252 -0
- package/dist/lib/senec-layout.js.map +1 -0
- package/dist/lib/weather-client.d.ts +62 -0
- package/dist/lib/weather-client.d.ts.map +1 -0
- package/dist/lib/weather-client.js +234 -0
- package/dist/lib/weather-client.js.map +1 -0
- package/dist/nodes/senec-data.js +10 -2
- package/dist/nodes/senec-data.js.map +1 -1
- package/dist/nodes/senec-image.html +73 -53
- package/dist/nodes/senec-image.js +189 -14
- package/dist/nodes/senec-image.js.map +1 -1
- package/dist/nodes/weather.d.ts +2 -0
- package/dist/nodes/weather.d.ts.map +1 -0
- package/dist/nodes/weather.html +179 -0
- package/dist/nodes/weather.js +138 -0
- package/dist/nodes/weather.js.map +1 -0
- package/package.json +4 -2
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Weather Client
|
|
4
|
+
*
|
|
5
|
+
* Fetches current weather + a short forecast from the free Open-Meteo API
|
|
6
|
+
* (https://open-meteo.com) which requires no API key, and maps the raw
|
|
7
|
+
* response onto the normalized {@link WeatherData} structure consumed by
|
|
8
|
+
* the dashboard renderer.
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.WeatherClient = void 0;
|
|
15
|
+
const axios_1 = __importDefault(require("axios"));
|
|
16
|
+
const WEATHER_CODES = {
|
|
17
|
+
0: { icon: '☀️', de: 'Klar', en: 'Clear sky' },
|
|
18
|
+
1: { icon: '🌤️', de: 'Überwiegend klar', en: 'Mainly clear' },
|
|
19
|
+
2: { icon: '⛅', de: 'Teilweise bewölkt', en: 'Partly cloudy' },
|
|
20
|
+
3: { icon: '☁️', de: 'Bewölkt', en: 'Overcast' },
|
|
21
|
+
45: { icon: '🌫️', de: 'Nebel', en: 'Fog' },
|
|
22
|
+
48: { icon: '🌫️', de: 'Reifnebel', en: 'Depositing rime fog' },
|
|
23
|
+
51: { icon: '🌦️', de: 'Leichter Nieselregen', en: 'Light drizzle' },
|
|
24
|
+
53: { icon: '🌦️', de: 'Nieselregen', en: 'Moderate drizzle' },
|
|
25
|
+
55: { icon: '🌧️', de: 'Starker Nieselregen', en: 'Dense drizzle' },
|
|
26
|
+
56: { icon: '🌧️', de: 'Gefrierender Nieselregen', en: 'Freezing drizzle' },
|
|
27
|
+
57: { icon: '🌧️', de: 'Gefrierender Nieselregen', en: 'Freezing drizzle' },
|
|
28
|
+
61: { icon: '🌧️', de: 'Leichter Regen', en: 'Slight rain' },
|
|
29
|
+
63: { icon: '🌧️', de: 'Regen', en: 'Moderate rain' },
|
|
30
|
+
65: { icon: '🌧️', de: 'Starker Regen', en: 'Heavy rain' },
|
|
31
|
+
66: { icon: '🌧️', de: 'Gefrierender Regen', en: 'Freezing rain' },
|
|
32
|
+
67: { icon: '🌧️', de: 'Gefrierender Regen', en: 'Freezing rain' },
|
|
33
|
+
71: { icon: '🌨️', de: 'Leichter Schneefall', en: 'Slight snow' },
|
|
34
|
+
73: { icon: '🌨️', de: 'Schneefall', en: 'Moderate snow' },
|
|
35
|
+
75: { icon: '❄️', de: 'Starker Schneefall', en: 'Heavy snow' },
|
|
36
|
+
77: { icon: '🌨️', de: 'Schneegriesel', en: 'Snow grains' },
|
|
37
|
+
80: { icon: '🌦️', de: 'Leichte Schauer', en: 'Slight showers' },
|
|
38
|
+
81: { icon: '🌧️', de: 'Schauer', en: 'Moderate showers' },
|
|
39
|
+
82: { icon: '⛈️', de: 'Starke Schauer', en: 'Violent showers' },
|
|
40
|
+
85: { icon: '🌨️', de: 'Schneeschauer', en: 'Slight snow showers' },
|
|
41
|
+
86: { icon: '❄️', de: 'Starke Schneeschauer', en: 'Heavy snow showers' },
|
|
42
|
+
95: { icon: '⛈️', de: 'Gewitter', en: 'Thunderstorm' },
|
|
43
|
+
96: { icon: '⛈️', de: 'Gewitter mit Hagel', en: 'Thunderstorm with hail' },
|
|
44
|
+
99: { icon: '⛈️', de: 'Gewitter mit Hagel', en: 'Thunderstorm with hail' },
|
|
45
|
+
};
|
|
46
|
+
const DEFAULT_CODE = { icon: '❓', de: 'Unbekannt', en: 'Unknown' };
|
|
47
|
+
/** Weekday short labels per language. Index 0 = Sunday (JS getDay()). */
|
|
48
|
+
const WEEKDAYS = {
|
|
49
|
+
de: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
|
|
50
|
+
en: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
|
|
51
|
+
};
|
|
52
|
+
/** 16-point compass labels per language. */
|
|
53
|
+
const COMPASS = {
|
|
54
|
+
de: [
|
|
55
|
+
'N', 'NNO', 'NO', 'ONO', 'O', 'OSO', 'SO', 'SSO',
|
|
56
|
+
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW',
|
|
57
|
+
],
|
|
58
|
+
en: [
|
|
59
|
+
'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
|
|
60
|
+
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW',
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
class WeatherClient {
|
|
64
|
+
/**
|
|
65
|
+
* Fetch current weather + a 5-day forecast for the given coordinates.
|
|
66
|
+
*/
|
|
67
|
+
async getWeather(options) {
|
|
68
|
+
// Validate coordinates defensively. The request URL host is a fixed
|
|
69
|
+
// constant (no SSRF), but we still guard against non-finite / out-of
|
|
70
|
+
// -range values being serialized into the query string.
|
|
71
|
+
const lat = Number(options.latitude);
|
|
72
|
+
const lon = Number(options.longitude);
|
|
73
|
+
if (!isFinite(lat) || lat < -90 || lat > 90) {
|
|
74
|
+
throw new Error('Invalid latitude (expected -90..90)');
|
|
75
|
+
}
|
|
76
|
+
if (!isFinite(lon) || lon < -180 || lon > 180) {
|
|
77
|
+
throw new Error('Invalid longitude (expected -180..180)');
|
|
78
|
+
}
|
|
79
|
+
const language = (options.language || 'de').toLowerCase();
|
|
80
|
+
const timeout = options.timeout ?? 10000;
|
|
81
|
+
const retries = Math.max(0, options.retries ?? 2);
|
|
82
|
+
const retryDelay = Math.max(0, options.retryDelay ?? 500);
|
|
83
|
+
const url = 'https://api.open-meteo.com/v1/forecast';
|
|
84
|
+
const params = {
|
|
85
|
+
latitude: options.latitude,
|
|
86
|
+
longitude: options.longitude,
|
|
87
|
+
current: 'temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m,wind_direction_10m',
|
|
88
|
+
daily: 'weather_code,temperature_2m_max,temperature_2m_min',
|
|
89
|
+
timezone: 'auto',
|
|
90
|
+
forecast_days: 5,
|
|
91
|
+
wind_speed_unit: 'kmh',
|
|
92
|
+
};
|
|
93
|
+
const response = await WeatherClient.requestWithRetry(url, params, timeout, retries, retryDelay);
|
|
94
|
+
const mapped = WeatherClient.mapResponse(response.data, language);
|
|
95
|
+
mapped.latitude = options.latitude;
|
|
96
|
+
mapped.longitude = options.longitude;
|
|
97
|
+
mapped.location =
|
|
98
|
+
options.location && options.location.length > 0
|
|
99
|
+
? options.location
|
|
100
|
+
: WeatherClient.formatCoords(options.latitude, options.longitude);
|
|
101
|
+
return mapped;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A deterministic sample weather payload, used ONLY as a fallback when
|
|
105
|
+
* the Open-Meteo server cannot be reached.
|
|
106
|
+
*/
|
|
107
|
+
static sample(options) {
|
|
108
|
+
const lat = options?.latitude ?? 52.52;
|
|
109
|
+
const lon = options?.longitude ?? 13.405;
|
|
110
|
+
return {
|
|
111
|
+
temperature: 18,
|
|
112
|
+
condition: (options?.language || 'de') === 'en' ? 'Partly cloudy' : 'Leicht bewölkt',
|
|
113
|
+
icon: '🌤️',
|
|
114
|
+
tempMax: 20,
|
|
115
|
+
tempMin: 11,
|
|
116
|
+
humidity: 45,
|
|
117
|
+
windSpeed: 15,
|
|
118
|
+
windDirection: 'WSW',
|
|
119
|
+
forecast: [
|
|
120
|
+
{ day: 'Di', icon: '🌤️', temp: 20 },
|
|
121
|
+
{ day: 'Mi', icon: '☁️', temp: 19 },
|
|
122
|
+
{ day: 'Do', icon: '🌧️', temp: 17 },
|
|
123
|
+
{ day: 'Fr', icon: '⛅', temp: 21 },
|
|
124
|
+
{ day: 'Sa', icon: '☀️', temp: 24 },
|
|
125
|
+
],
|
|
126
|
+
latitude: lat,
|
|
127
|
+
longitude: lon,
|
|
128
|
+
location: options?.location && options.location.length > 0
|
|
129
|
+
? options.location
|
|
130
|
+
: WeatherClient.formatCoords(lat, lon),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Perform the Open-Meteo GET request, retrying on transient failures
|
|
135
|
+
* (HTTP 5xx such as 503, 429 rate limiting, timeouts and low-level
|
|
136
|
+
* network errors) using exponential backoff. Non-transient errors
|
|
137
|
+
* (e.g. HTTP 4xx other than 429) fail immediately.
|
|
138
|
+
*/
|
|
139
|
+
static async requestWithRetry(url, params, timeout, retries, retryDelay) {
|
|
140
|
+
let lastError;
|
|
141
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
142
|
+
try {
|
|
143
|
+
return await axios_1.default.get(url, { params, timeout });
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
lastError = error;
|
|
147
|
+
if (attempt >= retries || !WeatherClient.isTransientError(error)) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
// Exponential backoff: retryDelay * 2^attempt.
|
|
151
|
+
const wait = retryDelay * Math.pow(2, attempt);
|
|
152
|
+
await WeatherClient.delay(wait);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
throw lastError;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Classify an axios error as transient (worth retrying) or not.
|
|
159
|
+
* Transient: no HTTP response (network/timeout), HTTP 429, or any 5xx.
|
|
160
|
+
*/
|
|
161
|
+
static isTransientError(error) {
|
|
162
|
+
const status = error?.response?.status;
|
|
163
|
+
if (status === undefined) {
|
|
164
|
+
// No response at all -> network error or timeout.
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
return status === 429 || (status >= 500 && status <= 599);
|
|
168
|
+
}
|
|
169
|
+
static delay(ms) {
|
|
170
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
171
|
+
}
|
|
172
|
+
static formatCoords(lat, lon) {
|
|
173
|
+
const fmt = (v) => (Math.round(v * 100) / 100).toFixed(2);
|
|
174
|
+
return `${fmt(lat)}, ${fmt(lon)}`;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Map a raw Open-Meteo forecast response to normalized WeatherData.
|
|
178
|
+
* Exposed statically so it can be unit-tested without network access.
|
|
179
|
+
*/
|
|
180
|
+
static mapResponse(data, language = 'de') {
|
|
181
|
+
const lang = WEEKDAYS[language] ? language : 'en';
|
|
182
|
+
const current = data?.current ?? {};
|
|
183
|
+
const daily = data?.daily ?? {};
|
|
184
|
+
const currentCode = Number(current.weather_code ?? 0);
|
|
185
|
+
const info = WEATHER_CODES[currentCode] ?? DEFAULT_CODE;
|
|
186
|
+
const condition = lang === 'de' ? info.de : info.en;
|
|
187
|
+
const maxArr = Array.isArray(daily.temperature_2m_max)
|
|
188
|
+
? daily.temperature_2m_max
|
|
189
|
+
: [];
|
|
190
|
+
const minArr = Array.isArray(daily.temperature_2m_min)
|
|
191
|
+
? daily.temperature_2m_min
|
|
192
|
+
: [];
|
|
193
|
+
const codeArr = Array.isArray(daily.weather_code) ? daily.weather_code : [];
|
|
194
|
+
const timeArr = Array.isArray(daily.time) ? daily.time : [];
|
|
195
|
+
const forecast = [];
|
|
196
|
+
for (let i = 0; i < Math.min(5, timeArr.length || maxArr.length); i++) {
|
|
197
|
+
const dayCode = Number(codeArr[i] ?? currentCode);
|
|
198
|
+
const dayInfo = WEATHER_CODES[dayCode] ?? DEFAULT_CODE;
|
|
199
|
+
forecast.push({
|
|
200
|
+
day: WeatherClient.weekdayLabel(timeArr[i], lang),
|
|
201
|
+
icon: dayInfo.icon,
|
|
202
|
+
temp: Math.round(Number(maxArr[i] ?? current.temperature_2m ?? 0)),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
temperature: Math.round(Number(current.temperature_2m ?? 0)),
|
|
207
|
+
condition,
|
|
208
|
+
icon: info.icon,
|
|
209
|
+
tempMax: Math.round(Number(maxArr[0] ?? current.temperature_2m ?? 0)),
|
|
210
|
+
tempMin: Math.round(Number(minArr[0] ?? current.temperature_2m ?? 0)),
|
|
211
|
+
humidity: Math.round(Number(current.relative_humidity_2m ?? 0)),
|
|
212
|
+
windSpeed: Math.round(Number(current.wind_speed_10m ?? 0)),
|
|
213
|
+
windDirection: WeatherClient.compassLabel(Number(current.wind_direction_10m ?? 0), lang),
|
|
214
|
+
forecast,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
static weekdayLabel(isoDate, lang) {
|
|
218
|
+
const labels = WEEKDAYS[lang] ?? WEEKDAYS.en;
|
|
219
|
+
if (!isoDate) {
|
|
220
|
+
return labels[0];
|
|
221
|
+
}
|
|
222
|
+
const d = new Date(`${isoDate}T00:00:00`);
|
|
223
|
+
const idx = isNaN(d.getTime()) ? 0 : d.getDay();
|
|
224
|
+
return labels[idx];
|
|
225
|
+
}
|
|
226
|
+
static compassLabel(degrees, lang) {
|
|
227
|
+
const labels = COMPASS[lang] ?? COMPASS.en;
|
|
228
|
+
const normalized = ((degrees % 360) + 360) % 360;
|
|
229
|
+
const idx = Math.round(normalized / 22.5) % 16;
|
|
230
|
+
return labels[idx];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.WeatherClient = WeatherClient;
|
|
234
|
+
//# sourceMappingURL=weather-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weather-client.js","sourceRoot":"","sources":["../../src/lib/weather-client.ts"],"names":[],"mappings":"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"}
|
package/dist/nodes/senec-data.js
CHANGED
|
@@ -31,18 +31,26 @@ module.exports = function (RED) {
|
|
|
31
31
|
async function fetchData() {
|
|
32
32
|
if (!node.apiClient)
|
|
33
33
|
return;
|
|
34
|
+
const timestamp = new Date().toISOString();
|
|
34
35
|
try {
|
|
35
36
|
node.status({ fill: 'blue', shape: 'dot', text: 'fetching...' });
|
|
36
37
|
const parsedData = await node.apiClient.getData();
|
|
37
38
|
node.send({
|
|
38
39
|
payload: parsedData,
|
|
39
|
-
topic: 'senec/data'
|
|
40
|
+
topic: 'senec/data',
|
|
41
|
+
status: { ok: true, timestamp, fallback: false }
|
|
40
42
|
});
|
|
41
|
-
node.status({ fill: 'green', shape: 'dot', text:
|
|
43
|
+
node.status({ fill: 'green', shape: 'dot', text: `ok ${timestamp.slice(11, 16)}` });
|
|
42
44
|
}
|
|
43
45
|
catch (error) {
|
|
44
46
|
node.error('Failed to fetch data: ' + error.message);
|
|
45
47
|
node.status({ fill: 'red', shape: 'ring', text: 'error' });
|
|
48
|
+
// Report the failed status so downstream (image) can render it.
|
|
49
|
+
node.send({
|
|
50
|
+
payload: null,
|
|
51
|
+
topic: 'senec/status',
|
|
52
|
+
status: { ok: false, timestamp, error: error.message, fallback: false }
|
|
53
|
+
});
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
56
|
// Handle input messages
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"senec-data.js","sourceRoot":"","sources":["../../src/nodes/senec-data.ts"],"names":[],"mappings":";;AACA,8DAAyD;AAiBzD,MAAM,CAAC,OAAO,GAAG,UAAS,GAAQ;IAChC,SAAS,aAAa,CAAsB,MAAwB;QAClE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAEnC,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,kBAAkB;QAClB,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAQ,CAAC;QAE3D,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,iCAAc,CAAC;gBAClC,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,QAAQ,EAAE,UAAU,CAAC,WAAW,CAAC,QAAQ;aAC1C,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,mCAAmC,GAAG,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,sBAAsB;QACtB,KAAK,UAAU,SAAS;YACtB,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,OAAO;YAE5B,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBAEjE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBAElD,IAAI,CAAC,IAAI,CAAC;oBACR,OAAO,EAAE,UAAU;oBACnB,KAAK,EAAE,YAAY;
|
|
1
|
+
{"version":3,"file":"senec-data.js","sourceRoot":"","sources":["../../src/nodes/senec-data.ts"],"names":[],"mappings":";;AACA,8DAAyD;AAiBzD,MAAM,CAAC,OAAO,GAAG,UAAS,GAAQ;IAChC,SAAS,aAAa,CAAsB,MAAwB;QAClE,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAEnC,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,kBAAkB;QAClB,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAQ,CAAC;QAE3D,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,iCAAc,CAAC;gBAClC,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,QAAQ,EAAE,UAAU,CAAC,WAAW,CAAC,QAAQ;aAC1C,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,mCAAmC,GAAG,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,sBAAsB;QACtB,KAAK,UAAU,SAAS;YACtB,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,OAAO;YAE5B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAE3C,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;gBAEjE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBAElD,IAAI,CAAC,IAAI,CAAC;oBACR,OAAO,EAAE,UAAU;oBACnB,KAAK,EAAE,YAAY;oBACnB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE;iBACjD,CAAC,CAAC;gBAEH,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACtF,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,IAAI,CAAC,KAAK,CAAC,wBAAwB,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;gBACrD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC3D,gEAAgE;gBAChE,IAAI,CAAC,IAAI,CAAC;oBACR,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,cAAc;oBACrB,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;iBACxE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,WAAU,IAAS;YACvC,MAAM,SAAS,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,mCAAmC;QACnC,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;QAC9D,CAAC;QAED,mBAAmB;QACnB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE;YACf,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;AACtD,CAAC,CAAC"}
|
|
@@ -4,17 +4,21 @@
|
|
|
4
4
|
color: '#00A0E3',
|
|
5
5
|
defaults: {
|
|
6
6
|
name: { value: '' },
|
|
7
|
-
width: { value:
|
|
8
|
-
height: { value:
|
|
9
|
-
layout: { value: '
|
|
7
|
+
width: { value: 1600, validate: RED.validators.number() },
|
|
8
|
+
height: { value: 0 },
|
|
9
|
+
layout: { value: 'dashboard' },
|
|
10
|
+
outputFormat: { value: 'buffer' },
|
|
11
|
+
filePath: { value: '' }
|
|
10
12
|
},
|
|
11
|
-
inputs:
|
|
12
|
-
outputs:
|
|
13
|
+
inputs: 2,
|
|
14
|
+
outputs: 2,
|
|
15
|
+
inputLabels: ['SENEC', 'Weather'],
|
|
16
|
+
outputLabels: ['PNG', 'HTML'],
|
|
13
17
|
icon: 'font-awesome/fa-image',
|
|
14
|
-
label: function() {
|
|
18
|
+
label: function () {
|
|
15
19
|
return this.name || 'SENEC Image';
|
|
16
20
|
},
|
|
17
|
-
labelStyle: function() {
|
|
21
|
+
labelStyle: function () {
|
|
18
22
|
return this.name ? 'node_label_italic' : '';
|
|
19
23
|
}
|
|
20
24
|
});
|
|
@@ -27,68 +31,84 @@
|
|
|
27
31
|
</div>
|
|
28
32
|
<div class="form-row">
|
|
29
33
|
<label for="node-input-width"><i class="fa fa-arrows-h"></i> Width</label>
|
|
30
|
-
<input type="number" id="node-input-width" placeholder="
|
|
34
|
+
<input type="number" id="node-input-width" placeholder="1600" min="200">
|
|
31
35
|
</div>
|
|
32
36
|
<div class="form-row">
|
|
33
37
|
<label for="node-input-height"><i class="fa fa-arrows-v"></i> Height</label>
|
|
34
|
-
<input type="number" id="node-input-height" placeholder="
|
|
38
|
+
<input type="number" id="node-input-height" placeholder="0 = auto (16:9)" min="0">
|
|
35
39
|
</div>
|
|
36
40
|
<div class="form-row">
|
|
37
41
|
<label for="node-input-layout"><i class="fa fa-th-large"></i> Layout</label>
|
|
38
42
|
<select id="node-input-layout">
|
|
39
|
-
<option value="
|
|
40
|
-
<option value="compact">Compact</option>
|
|
41
|
-
<option value="trmnl">TRMNL Display</option>
|
|
43
|
+
<option value="dashboard">Energy Dashboard (4 cards, 16:9)</option>
|
|
42
44
|
</select>
|
|
43
45
|
</div>
|
|
46
|
+
<div class="form-row">
|
|
47
|
+
<label for="node-input-outputFormat"><i class="fa fa-download"></i> PNG Output</label>
|
|
48
|
+
<select id="node-input-outputFormat">
|
|
49
|
+
<option value="buffer">Buffer (PNG)</option>
|
|
50
|
+
<option value="base64">Base64 Data URL</option>
|
|
51
|
+
<option value="file">File</option>
|
|
52
|
+
</select>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="form-row" id="node-row-filePath">
|
|
55
|
+
<label for="node-input-filePath"><i class="fa fa-folder-open"></i> File Path</label>
|
|
56
|
+
<input type="text" id="node-input-filePath" placeholder="/path/to/dashboard.png">
|
|
57
|
+
</div>
|
|
44
58
|
</script>
|
|
45
59
|
|
|
46
60
|
<script type="text/html" data-help-name="senec-image">
|
|
47
|
-
<p>
|
|
48
|
-
|
|
61
|
+
<p>Renders a 16:9 energy dashboard combining SENEC energy data and weather
|
|
62
|
+
data. Produces a PNG image on output 1 and a fully resizable HTML document
|
|
63
|
+
on output 2, in parallel.</p>
|
|
64
|
+
|
|
49
65
|
<h3>Inputs</h3>
|
|
50
|
-
<
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
66
|
+
<ol class="node-ports">
|
|
67
|
+
<li>SENEC
|
|
68
|
+
<dl class="message-properties">
|
|
69
|
+
<dt>payload <span class="property-type">object</span></dt>
|
|
70
|
+
<dd>SENEC data object (from the <b>senec-data</b> node).</dd>
|
|
71
|
+
</dl>
|
|
72
|
+
</li>
|
|
73
|
+
<li>Weather
|
|
74
|
+
<dl class="message-properties">
|
|
75
|
+
<dt>payload <span class="property-type">object</span></dt>
|
|
76
|
+
<dd>Weather data object (from the <b>weather</b> node). Optional; the
|
|
77
|
+
weather card renders a placeholder until data arrives.</dd>
|
|
78
|
+
</dl>
|
|
79
|
+
</li>
|
|
80
|
+
</ol>
|
|
81
|
+
|
|
55
82
|
<h3>Outputs</h3>
|
|
56
|
-
<
|
|
57
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<dd>Image layout template:
|
|
77
|
-
<ul>
|
|
78
|
-
<li><b>Default</b> - Standard layout with all data</li>
|
|
79
|
-
<li><b>Compact</b> - Minimal layout for small displays</li>
|
|
80
|
-
<li><b>TRMNL Display</b> - Optimized for TRMNL e-ink display (800x480)</li>
|
|
81
|
-
</ul>
|
|
82
|
-
</dd>
|
|
83
|
-
</dl>
|
|
84
|
-
|
|
83
|
+
<ol class="node-ports">
|
|
84
|
+
<li>PNG
|
|
85
|
+
<dl class="message-properties">
|
|
86
|
+
<dt>payload <span class="property-type">buffer | string</span></dt>
|
|
87
|
+
<dd>PNG image as a Buffer (or base64 data URL / file path depending
|
|
88
|
+
on the PNG Output setting).</dd>
|
|
89
|
+
<dt>contentType <span class="property-type">string</span></dt>
|
|
90
|
+
<dd>Set to "image/png".</dd>
|
|
91
|
+
</dl>
|
|
92
|
+
</li>
|
|
93
|
+
<li>HTML
|
|
94
|
+
<dl class="message-properties">
|
|
95
|
+
<dt>payload <span class="property-type">string</span></dt>
|
|
96
|
+
<dd>Self-contained, resizable HTML document of the dashboard.</dd>
|
|
97
|
+
<dt>contentType <span class="property-type">string</span></dt>
|
|
98
|
+
<dd>Set to "text/html".</dd>
|
|
99
|
+
</dl>
|
|
100
|
+
</li>
|
|
101
|
+
</ol>
|
|
102
|
+
|
|
85
103
|
<h3>Details</h3>
|
|
86
|
-
<p>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
104
|
+
<p>The node caches the latest SENEC and weather messages and re-renders on
|
|
105
|
+
each input, so it can be driven from two independent sources. Rendering
|
|
106
|
+
begins once SENEC data has been received at least once.</p>
|
|
107
|
+
|
|
90
108
|
<h3>Example Flow</h3>
|
|
91
109
|
<pre>
|
|
92
|
-
[senec-data]
|
|
110
|
+
[senec-data] ──────────┐
|
|
111
|
+
├→ [senec-image] ─┬→ [file out] (PNG)
|
|
112
|
+
[weather] ─────────────┘ └→ [http res] (HTML)
|
|
93
113
|
</pre>
|
|
94
114
|
</script>
|