|
2 | 2 | { |
3 | 3 | "id": "18dd279f36d97386", |
4 | 4 | "type": "tab", |
5 | | - "label": "Button+ modes", |
| 5 | + "label": "B+ page logic", |
6 | 6 | "disabled": false, |
7 | 7 | "info": "", |
8 | 8 | "env": [] |
|
23 | 23 | ], |
24 | 24 | "x": 74, |
25 | 25 | "y": 19, |
26 | | - "w": 472, |
| 26 | + "w": 492, |
27 | 27 | "h": 142 |
28 | 28 | }, |
| 29 | + { |
| 30 | + "id": "20f91c554b2bf198", |
| 31 | + "type": "group", |
| 32 | + "z": "18dd279f36d97386", |
| 33 | + "name": "Buttons subscribe to page specific topics for labels etc", |
| 34 | + "style": { |
| 35 | + "label": true |
| 36 | + }, |
| 37 | + "nodes": [ |
| 38 | + "d5ef9aae41093179", |
| 39 | + "44bfea5d2f724782", |
| 40 | + "93ec2f7ec45edc5b", |
| 41 | + "f48878bc94b26aed", |
| 42 | + "41cf2ce5166bbf8a", |
| 43 | + "8fdbb046e8c742e4", |
| 44 | + "b26898a67589d7e3" |
| 45 | + ], |
| 46 | + "x": 14, |
| 47 | + "y": 1099, |
| 48 | + "w": 732, |
| 49 | + "h": 302 |
| 50 | + }, |
29 | 51 | { |
30 | 52 | "id": "1cc89963bcc5d396", |
31 | 53 | "type": "debug", |
32 | 54 | "z": "18dd279f36d97386", |
33 | 55 | "name": "debug 19", |
34 | | - "active": false, |
| 56 | + "active": true, |
35 | 57 | "tosidebar": true, |
36 | 58 | "console": false, |
37 | 59 | "tostatus": false, |
|
140 | 162 | "x": 1810, |
141 | 163 | "y": 580, |
142 | 164 | "wires": [ |
143 | | - [ |
144 | | - "1cc89963bcc5d396" |
145 | | - ] |
| 165 | + [] |
146 | 166 | ] |
147 | 167 | }, |
148 | 168 | { |
|
161 | 181 | "y": 540, |
162 | 182 | "wires": [ |
163 | 183 | [ |
164 | | - "a2a79e0bbb8e37ee" |
| 184 | + "a2a79e0bbb8e37ee", |
| 185 | + "1cc89963bcc5d396" |
165 | 186 | ] |
166 | 187 | ], |
167 | 188 | "icon": "font-awesome/fa-lock" |
|
447 | 468 | "type": "function", |
448 | 469 | "z": "18dd279f36d97386", |
449 | 470 | "g": "3dc14376c3d7d50c", |
450 | | - "name": "01 global config", |
| 471 | + "name": "01 general config", |
451 | 472 | "func": "// Configuration goes here:\nvar bplusdevice = \"wk1\"; // the device this page belongs to\n\n// nothing to be changed below this line\n// -------------------------------------\n\n// retrieve existing config from disk, or create when non-existent\n// this retrieves configuration for all configured B+ devices\nvar bplusconfig = global.get(\"bplusconfig\", \"file\");\nvar bplusconfigbuttons = global.get('bplusconfigbuttons','file');\nvar bplusconfigdisplayitems = global.get('bplusconfigdisplayitems', 'file');\n\n\n\n\nvar buttonpages = bplusconfig[bplusdevice].buttonpages;\nvar pages = bplusconfig[bplusdevice].pages;\n\n\n// retrieve existing config from disk, or create when non-existent\n// this retrieves configuration for all configured B+ devices\nvar bplusconfig = global.get(\"bplusconfig\", \"file\");\nif (bplusconfig == undefined) {\n bplusconfig = {};\n\n}\n\n\n\nvar label = bplusconfigbuttons[bplusdevice].label;\nvar toplabel = bplusconfigbuttons[bplusdevice].toplabel;\nvar ledrgb = bplusconfigbuttons[bplusdevice].ledrgb;\nvar mainbutton = bplusconfigbuttons[bplusdevice].mainbutton;\n\nfor (var i in label) {\n for (var j in label[i]) {\n\n if (mainbutton[j] == \"main\") {\n var label_thisbutton = label[i];\n var label_mainbutton = label[0];\n label_thisbutton[j] = label_mainbutton[j];\n }\n label[i] = label_thisbutton;\n }\n}\n\nfor (var i in toplabel) {\n for (var j in toplabel[i]) {\n\n if (mainbutton[j] == \"main\") {\n var label_thisbutton = toplabel[i];\n var label_mainbutton = toplabel[0];\n label_thisbutton[j] = label_mainbutton[j];\n }\n toplabel[i] = label_thisbutton;\n }\n}\n\nfor (var i in ledrgb) {\n for (var j in ledrgb[i]) {\n\n if (mainbutton[j] == \"main\") {\n var label_thisbutton = ledrgb[i];\n var label_mainbutton = ledrgb[0];\n label_thisbutton[j] = label_mainbutton[j];\n }\n ledrgb[i] = label_thisbutton;\n }\n}\n\n\nbplusconfigbuttons = {\n 'label': label,\n 'toplabel': toplabel,\n 'ledrgb': ledrgb,\n 'mainbutton': mainbutton\n}\n\n\n\n\n// save the configuration and parameters to this flow, for use\n// flow.set('bplusdevice', bplusdevice, \"file\");\n// flow.set('bplusconfigdevice', bplusconfig[bplusdevice], \"file\");\nflow.set('pages',pages,\"file\");\nflow.set('buttonpages', buttonpages, \"file\");\nflow.set('configJSONcore', bplusconfig[bplusdevice].configJSONcore, \"file\");\nflow.set('bplusconfigdisplayitems',bplusconfigdisplayitems[bplusdevice]);\n\n// save the configuration and parameters to this flow, for use\nflow.set('bplusdevice', bplusdevice, \"file\");\nflow.set('bplusconfigdevice', bplusconfig[bplusdevice], \"file\");\nflow.set('bplusconfigbuttons', bplusconfigbuttons, 'file')\n\n\n\n// // save the config of all devices back to the disk\n// global.set(\"bplusconfig\", bplusconfig, \"file\")\n\n\nreturn msg;", |
452 | 473 | "outputs": 1, |
453 | 474 | "timeout": 0, |
454 | 475 | "noerr": 0, |
455 | 476 | "initialize": "", |
456 | 477 | "finalize": "", |
457 | 478 | "libs": [], |
458 | | - "x": 440, |
| 479 | + "x": 450, |
459 | 480 | "y": 60, |
460 | 481 | "wires": [ |
461 | 482 | [ |
|
685 | 706 | "wires": [ |
686 | 707 | [ |
687 | 708 | "920ae05b7da02f5e", |
688 | | - "87ee8d61ca60d62d" |
| 709 | + "87ee8d61ca60d62d", |
| 710 | + "8fdbb046e8c742e4" |
689 | 711 | ] |
690 | 712 | ] |
691 | 713 | }, |
|
750 | 772 | "targetType": "full", |
751 | 773 | "statusVal": "", |
752 | 774 | "statusType": "auto", |
753 | | - "x": 280, |
754 | | - "y": 1000, |
| 775 | + "x": 320, |
| 776 | + "y": 980, |
755 | 777 | "wires": [] |
756 | 778 | }, |
757 | 779 | { |
|
1908 | 1930 | "type": "function", |
1909 | 1931 | "z": "18dd279f36d97386", |
1910 | 1932 | "name": "save buttonpageid", |
1911 | | - "func": "var buttonpage = msg.buttonpage;\nvar buttonpages = flow.get(\"buttonpages\",\"file\");\n\nvar buttonpageid = buttonpages.indexOf(buttonpage);\nmsg.buttonpageid = buttonpageid;\nflow.set(\"buttonpageid\", buttonpageid);\nreturn msg;", |
| 1933 | + "func": "var buttonpage = msg.buttonpage;\nvar buttonpages = flow.get(\"buttonpages\",\"file\");\n\nvar mainbutton = flow.get(\"bplusconfigbuttons\", \"file\").mainbutton;\n\nvar mainbutton_array = [];\n// Object.keys(mainbutton).forEach((element) => {\n// if (mainbutton[i] != \"main\") {\n// mainbutton_array.push(buttonpage);\n// }else{\n// mainbutton_array.push(\"main\");\n// }\n// })\n\nObject.entries(mainbutton).forEach(([key, value]) => {\n // console.log(`${key}: ${value}`)\n if (value != \"main\") {\n mainbutton_array.push(buttonpage);\n } else {\n mainbutton_array.push(\"main\");\n }\n})\n\n// for (var i = 0; i < mainbutton.length; i++) {\n// if (mainbutton[i] != \"main\" ){\n// mainbutton_array.push(buttonpage);\n// }else{\n// mainbutton_array.push(\"main\");\n// }\n// }\n\n\n\nvar buttonpageid = buttonpages.indexOf(buttonpage);\nmsg.buttonpageid = buttonpageid;\nflow.set(\"buttonpageid\", buttonpageid);\nflow.set(\"mainbutton\", mainbutton_array);\nreturn msg;", |
1912 | 1934 | "outputs": 1, |
1913 | 1935 | "timeout": 0, |
1914 | 1936 | "noerr": 0, |
|
1918 | 1940 | "x": 580, |
1919 | 1941 | "y": 380, |
1920 | 1942 | "wires": [ |
1921 | | - [] |
| 1943 | + [ |
| 1944 | + "20bfd02c0d57ca95" |
| 1945 | + ] |
1922 | 1946 | ] |
1923 | 1947 | }, |
1924 | 1948 | { |
|
2200 | 2224 | "y": 880, |
2201 | 2225 | "wires": [] |
2202 | 2226 | }, |
| 2227 | + { |
| 2228 | + "id": "d5ef9aae41093179", |
| 2229 | + "type": "comment", |
| 2230 | + "z": "18dd279f36d97386", |
| 2231 | + "g": "20f91c554b2bf198", |
| 2232 | + "name": "Subscription to generic button MQTT topics", |
| 2233 | + "info": "Translates the generic button presses\ninto menu specific button presses\n\nFor insance, when buttonpage = music and button 4 is pressed:\n\nbuttonplus/<device>/button/4/state (press/release/etc)\nis translated into\nbuttonplus/<device>/button/music/4/state (press/release/etc)\n\nThis way, you can let your music player always listen to\nbuttonplus/<device>/button/music/4/state (value: press)\nto increase the volume", |
| 2234 | + "x": 270, |
| 2235 | + "y": 1140, |
| 2236 | + "wires": [] |
| 2237 | + }, |
| 2238 | + { |
| 2239 | + "id": "44bfea5d2f724782", |
| 2240 | + "type": "mqtt in", |
| 2241 | + "z": "18dd279f36d97386", |
| 2242 | + "g": "20f91c554b2bf198", |
| 2243 | + "name": "", |
| 2244 | + "topic": "", |
| 2245 | + "qos": "2", |
| 2246 | + "datatype": "auto-detect", |
| 2247 | + "broker": "e6dbd5fb3f32ec20", |
| 2248 | + "nl": false, |
| 2249 | + "rap": true, |
| 2250 | + "rh": 0, |
| 2251 | + "inputs": 1, |
| 2252 | + "x": 310, |
| 2253 | + "y": 1240, |
| 2254 | + "wires": [ |
| 2255 | + [ |
| 2256 | + "93ec2f7ec45edc5b" |
| 2257 | + ] |
| 2258 | + ] |
| 2259 | + }, |
| 2260 | + { |
| 2261 | + "id": "93ec2f7ec45edc5b", |
| 2262 | + "type": "function", |
| 2263 | + "z": "18dd279f36d97386", |
| 2264 | + "g": "20f91c554b2bf198", |
| 2265 | + "name": "Translate to generic B+ topics", |
| 2266 | + "func": "// See for more info the function node upstream\n\n// split the received topic:\nvar topic = msg.topic;\ntopic = topic.split(\"/\");\n\n// Button number of the received topic\nvar button = topic[4];\n\n// Page name of the received topic\nvar page = topic[3];\n\n// Array with active mapping of buttons;\n// for instance: [\"main\",\"main\",\"main\",\"page1\",\"page1\",\"page1\"]\n// this is prepared in the \"Save Buttonpageid\" node\nvar mainbutton = flow.get(\"mainbutton\");\n\n// check if received page name equals page name belonging to\n// the mapping in mainbutton\nif (mainbutton[button] == page) {\n // create new topic\n var newtopic = [topic[0], topic[1], topic[2], topic[4], topic[5]];\n msg.topic = newtopic.join(\"/\");\n return msg;\n} else { \n // else do noting\n return null; } \n", |
| 2267 | + "outputs": 1, |
| 2268 | + "timeout": 0, |
| 2269 | + "noerr": 0, |
| 2270 | + "initialize": "", |
| 2271 | + "finalize": "", |
| 2272 | + "libs": [], |
| 2273 | + "x": 430, |
| 2274 | + "y": 1300, |
| 2275 | + "wires": [ |
| 2276 | + [ |
| 2277 | + "41cf2ce5166bbf8a", |
| 2278 | + "b26898a67589d7e3" |
| 2279 | + ] |
| 2280 | + ] |
| 2281 | + }, |
| 2282 | + { |
| 2283 | + "id": "f48878bc94b26aed", |
| 2284 | + "type": "inject", |
| 2285 | + "z": "18dd279f36d97386", |
| 2286 | + "g": "20f91c554b2bf198", |
| 2287 | + "name": "", |
| 2288 | + "props": [ |
| 2289 | + { |
| 2290 | + "p": "payload" |
| 2291 | + }, |
| 2292 | + { |
| 2293 | + "p": "buttonpage", |
| 2294 | + "v": "overdag", |
| 2295 | + "vt": "str" |
| 2296 | + } |
| 2297 | + ], |
| 2298 | + "repeat": "", |
| 2299 | + "crontab": "", |
| 2300 | + "once": true, |
| 2301 | + "onceDelay": 0.1, |
| 2302 | + "topic": "", |
| 2303 | + "payload": "", |
| 2304 | + "payloadType": "date", |
| 2305 | + "x": 130, |
| 2306 | + "y": 1320, |
| 2307 | + "wires": [ |
| 2308 | + [ |
| 2309 | + "8fdbb046e8c742e4" |
| 2310 | + ] |
| 2311 | + ] |
| 2312 | + }, |
| 2313 | + { |
| 2314 | + "id": "41cf2ce5166bbf8a", |
| 2315 | + "type": "debug", |
| 2316 | + "z": "18dd279f36d97386", |
| 2317 | + "g": "20f91c554b2bf198", |
| 2318 | + "name": "debug 41", |
| 2319 | + "active": true, |
| 2320 | + "tosidebar": true, |
| 2321 | + "console": false, |
| 2322 | + "tostatus": false, |
| 2323 | + "complete": "true", |
| 2324 | + "targetType": "full", |
| 2325 | + "statusVal": "", |
| 2326 | + "statusType": "auto", |
| 2327 | + "x": 460, |
| 2328 | + "y": 1360, |
| 2329 | + "wires": [] |
| 2330 | + }, |
| 2331 | + { |
| 2332 | + "id": "8fdbb046e8c742e4", |
| 2333 | + "type": "function", |
| 2334 | + "z": "18dd279f36d97386", |
| 2335 | + "g": "20f91c554b2bf198", |
| 2336 | + "name": "Page specific B+ subscription topics", |
| 2337 | + "func": "// The purpose of this module is to subscribe to page-specific B+ topics\n// for the buttons\n// This means: you can send a topic to \n// buttonplus/<device>/button/<page>/<buttonid>/label\n// and it will be translated to \n// buttonplus/<device>/button/<buttonid>/label\n// but ONLY when that page is active.\n// This way, you can control the labels for the buttons \n// through MQTT, per page.\n// make sure to switch on the retain flag when issueing messages\n\n// Get base topic\nvar basetopic = flow.get('bplusconfigdevice','file').buttonpublishtopic;\n// Active button page\nvar buttonpage = msg.buttonpage;\n\n//prepare array\nvar topic = [];\n// topics to subscribe to\ntopic[0] = basetopic+buttonpage+\"/+/label\"\ntopic[1] = basetopic + buttonpage + \"/+/toplabel\"\ntopic[2] = basetopic + buttonpage + \"/+/ledrgb\"\ntopic[3] = basetopic + \"main\" + \"/+/label\"\ntopic[4] = basetopic + \"main\" + \"/+/toplabel\"\ntopic[5] = basetopic + \"main\" + \"/+/ledrgb\"\nmsg.topic = topic;\n// Activate the MQTT node\nmsg.action = 'subscribe';\nreturn msg;", |
| 2338 | + "outputs": 1, |
| 2339 | + "timeout": 0, |
| 2340 | + "noerr": 0, |
| 2341 | + "initialize": "", |
| 2342 | + "finalize": "", |
| 2343 | + "libs": [], |
| 2344 | + "x": 250, |
| 2345 | + "y": 1180, |
| 2346 | + "wires": [ |
| 2347 | + [ |
| 2348 | + "44bfea5d2f724782" |
| 2349 | + ] |
| 2350 | + ] |
| 2351 | + }, |
| 2352 | + { |
| 2353 | + "id": "20bfd02c0d57ca95", |
| 2354 | + "type": "debug", |
| 2355 | + "z": "18dd279f36d97386", |
| 2356 | + "name": "debug 43", |
| 2357 | + "active": true, |
| 2358 | + "tosidebar": true, |
| 2359 | + "console": false, |
| 2360 | + "tostatus": false, |
| 2361 | + "complete": "true", |
| 2362 | + "targetType": "full", |
| 2363 | + "statusVal": "", |
| 2364 | + "statusType": "auto", |
| 2365 | + "x": 690, |
| 2366 | + "y": 440, |
| 2367 | + "wires": [] |
| 2368 | + }, |
| 2369 | + { |
| 2370 | + "id": "b26898a67589d7e3", |
| 2371 | + "type": "mqtt out", |
| 2372 | + "z": "18dd279f36d97386", |
| 2373 | + "g": "20f91c554b2bf198", |
| 2374 | + "name": "", |
| 2375 | + "topic": "", |
| 2376 | + "qos": "", |
| 2377 | + "retain": "", |
| 2378 | + "respTopic": "", |
| 2379 | + "contentType": "", |
| 2380 | + "userProps": "", |
| 2381 | + "correl": "", |
| 2382 | + "expiry": "", |
| 2383 | + "broker": "e6dbd5fb3f32ec20", |
| 2384 | + "x": 670, |
| 2385 | + "y": 1300, |
| 2386 | + "wires": [] |
| 2387 | + }, |
2203 | 2388 | { |
2204 | 2389 | "id": "e6dbd5fb3f32ec20", |
2205 | 2390 | "type": "mqtt-broker", |
|
0 commit comments