1.Co to jest Node-RED?
Node-RED to środowisko programistyczne w którym za pomocą bloków możemy utworzyć algorytm programu. Node-RED oparty jest o node.js (JavaScript – język skryptowy). Projekt który został zapoczątkowany przez IBM oddany w ręce społeczności, obecnie rozwija się bardzo dynamicznie. Projekt działa na wszystkich platformach tj. Windows, MacOS oraz Linuks i pozwala w prosty sposób wkroczyć w świat Przemysłowego Internetu Rzeczy.
Nowoczesne urządzenia NUMERON proBox2, proBox2ETH i smartBOX (w odpowiedniej wersji hardware) wyposażone są standardowo w pełni funkcjonalne wersje Node-RED. Urządzenia udostępniają odczytane dane z liczników za pomocą wewnętrznej szyny danych w taki sposób, że aplikacje napisane w Node-RED mogą z nich bezpośrednio korzystać.
Poniżej znajdą Państwo instrukcję konfiguracji, uruchomienia prostego ekranu wizualizacji oraz szereg gotowych przykładów do wykorzystania.
2.Konfiguracja urządzeń
Aby rozpocząć korzystanie z modułu Node-RED w urządzeniach NUMERON należy wykonać kilka czynności konfiguracyjnych.
Po pierwsze należy upewnić się, że moduł jest włączony i/lub włączyć go wchodząc do menu „Node-RED – konfiguracja”,
i przestawić opcję menu na „włączony”.
2.1.Konfiguracja odczytów
Aby aplikacje Node-RED mogły wizualizować dane pozyskiwane przez urządzenie (proBox2, proBox2ETH, smartBOX) na którym są uruchomione należy odpowiednio skonfigurować to urządzenie. Zachęcamy do wcześniejszego zapoznania się z DTR konkretnego urządzenia. Zawarte są tam niezbędne informacje dotyczące fizycznego podłączenia liczników do interfejsów urządzenia, jak również konfiguracji harmonogramów odczytowych.
Poniżej skrót najważniejszych ustawień niezbędnych do pozyskania danych w aplikacjach Node-RED.
Po wprowadzeniu/przy wprowadzaniu licznika na listę urządzeń w urządzeniu (menu „Odczyt urządzeń -> Lista urządzeń”), pozycję „Przetwarzanie danych online” należy ustawić na „Tak”.
Następnie proszę upewnić się, że dany licznik znajduje się na liście harmonogramu Online.
2.2.Logowanie do Node-RED
Aby przejść do ekranu administracyjnego należy z menu urządzenia wybrać „Node-RED – schemat”.
Wyświetli się ekran logowania.
Nazwa użytkownika (Username) to: admin
Hasło (Password) to bieżące hasło administracyjne do urządzenia. Hasło do ekranu administracyjnego Node-RED będzie automatycznie zmieniać się wraz ze zmianą głównego hasła.
3.Ekran administracyjny
Po zalogowaniu do ekranu administracyjnego Node-RED powinien pojawić się ekran z domyślnymi schematami aplikacji.
Pierwsza zakładka „Flow 1” jest gotowa na projektowanie własnej aplikacji. W wyłączonej (wyszarzonej) zakładce „Demo (dane z liczników)” znajduje się przykład wizualizacji dla jednego licznika. W następnym kroku pokazano jak z niego skorzystać.
3.1.Użycie domyślnego przykładu
Aby skorzystać z wgranego domyślnie przykładu wizualizacji należy go w pierwszej kolejności włączyć.
Dwukrotne kliknięcie w nazwę zakładki otwiera menu podręczne, gdzie możemy m.in. zmienić jej nazwę, ale przede wszystkim ją włączać i wyłączać.
Zmieniamy kliknięciem status zakładki (grafu – aplikacji) na „Enabled” i zamykamy okno właściwości przyciskiem „Done”.
Następnie należy zmienić przykładowy numer licznika, na numer fizycznego licznika podłączonego do urządzenia, który został skonfigurowany wcześniej w rozdziale „Konfiguracja odczytów”.
Klikamy dwukrotnie na element grafu „Licznik 96481317” i zmieniamy numer licznika z 96481317 na numer swojego licznika odczytywanego przez urządzenie.
Zamykamy okno właściwości przyciskiem „Done”, a na sam koniec zapisujemy wszystkie grafy i zakładki za pomocą przycisku „Deploy” w prawym górnym rogu.
Po zapisaniu zmian, ekran wizualizacji „Dashboard” możemy wyświetlić klikając znaczek w zakładce, w prawym górnym rogu albo wybierając opcję „Node-RED – dashboard” w menu urządzenia.
4.Import gotowego szablonu
Importowanie gotowych szablonów do swojego środowiska Node-RED polega na skopiowaniu i wklejeniu przygotowanego kodu.
Proszę przejść do pozycji z szablonem, a następnie skopiować (do schowka) kod np. za pomocą przycisku „copy” lub pobrać plik, otworzyć go w „notatniku”, i dopiero skopiować.
Następnie przechodzimy do okna administracyjnego Node-RED, i z menu w prawym górnym rogu ekranu wybieramy opcję „Import -> Clipboard”.
Wklejamy (CTRL+V) zawartość schowka w nowo otwartym oknie i klikamy w przycisk „Import”.
W wyniku otrzymamy nową zakładkę z zaimportowanym kodem wybranego szablonu.
Kolejnym krokiem będzie zapis „Deploy” lub wcześniejsza modyfikacja grafu np. zmiana numeru licznika.
Oto efekt importu domyślnego szablonu i zmiany numeru licznika.
5.Import modułów do urządzeń
W celu aktualizacji niektórych funkcji lub dodaniu nowych należy wgrać odpowiednie moduły do urządzeń.
Wybieramy menu „Moduły -> Dodanie modułu/licencji”,
wskazujemy właściwy plik, i klikamy przycisk „Dodaj”.
5.1.Moduł Plotly.js
Moduł Plotly.js dodaje bibliotekę graficzną do zasobów urządzenia Numeron, aby móc z niej skorzystać bez dostępu do Internetu. Zamiast kodu:
<script src="https://node-red.numeron.pl/plotly-1.34.0.min.js"></script>
można użyć:
<script src="/static/plotly-1.34.0.min.js"></script>
Pierwsza wersja modułu uwzględnia bibliotekę w wersji 1.34.0. Jeśli zajdzie potrzeba użycia biblioteki w innej wersji zostanie taka wersja udostępniona.
Moduł funkcyjny Plotly.js v1.34.05.2.Moduł ustawień domyślnych Node-RED w urządzeniach
Jeśli w czasie pracy z Node-RED zabrniemy w sytuację w której błędy konfiguracyjne uniemożliwią poprawną pracę narzędzia istnieje możliwość przywrócenia ustawień domyślnych.
Pamiętajmy, że aktualizacja firmware oraz przywracanie ustawień domyślnych urządzenia nie powoduje żadnych zmian w konfiguracji Node-RED.
Dlatego aby celowo usunąć/przywrócić do ustawień domyślnych konfigurację Node-RED należy wgrać do urządzenia odpowiedni moduł.
Mamy do wyboru dwa moduły:
- usuwa wszystko łącznie z zapisanymi danymi logowania do wcześniej przygotowanych schematów/flow – Ustawienia domyślne modułu Node-RED w urządzeniach Numeron,
- usuwa/przywraca tylko domyślne schematy/flow pozostawiając dane logowania – Ustawienia domyślne modułu Node-RED w urządzeniach Numeron (bez usuwania danych logowania).
6.Gotowe szablony grafów/aplikacji
Poniżej zamieszczamy przykładowe szablony grafów/aplikacji do wykorzystania w Państwa wdrożeniach. Zachęcamy do modyfikacji i rozwijania istniejących przykładów.
Służymy również pomocą w przygotowaniu, opracowaniu i wdrożeniu dedykowanych wizualizacji według Państwa pomysłu i projektu. Wymaga to dodatkowych ustaleń i wyceny. Zapraszamy do rozmowy -> Kontakt
Część z poniższych przykładów mogą Państwo obejrzeć na żywo na serwerze demo pod adresem https://node-red.numeron.pl/ui/
6.1.Domyślny schemat startowy Demo
Pobierz plik Domyślny schemat startowy Demo lub skopiuj poniższy kod:
[
{
"id": "c0455411.1a7a98",
"type": "tab",
"label": "Demo [Dane z liczników]",
"disabled": true,
"info": ""
},
{
"id": "885f5981.cd8358",
"type": "json",
"z": "c0455411.1a7a98",
"name": "json",
"x": 210,
"y": 60,
"wires": [
[
"64cdc587.38e91c"
]
]
},
{
"id": "64cdc587.38e91c",
"type": "switch",
"z": "c0455411.1a7a98",
"name": "Licznik 2302353",
"property": "payload.data[0].number",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "2302353",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 160,
"y": 280,
"wires": [
[
"c2e3de01.e4f2c",
"89fc1a.0e4a33e8",
"29daab0b.5aefc4",
"d9cd35e1.631f68",
"b6c9e68e.0536c8"
]
]
},
{
"id": "78df6d29.222f84",
"type": "udp in",
"z": "c0455411.1a7a98",
"name": "proBox",
"iface": "",
"port": "1900",
"ipv": "udp4",
"multicast": "false",
"group": "",
"datatype": "utf8",
"x": 70,
"y": 60,
"wires": [
[
"885f5981.cd8358"
]
]
},
{
"id": "baef394e.4050a8",
"type": "ui_audio",
"z": "c0455411.1a7a98",
"name": "",
"group": "7acd9f72.83e03",
"voice": "0",
"always": true,
"x": 820,
"y": 380,
"wires": []
},
{
"id": "c2e3de01.e4f2c",
"type": "function",
"z": "c0455411.1a7a98",
"name": "Alarm U",
"func": "\nvar str;\nvar U = new Array(3);\nvar maxU = 280;\n\nU[0] = msg.payload.data[0].data.energy.U_L1;\nU[1] = msg.payload.data[0].data.energy.U_L2;\nU[2] = msg.payload.data[0].data.energy.U_L3;\n\nstr = \"U1=\" + U[0] + \", U2=\" + U[1] + \", U3=\" + U[2];\nif ((U[0] > maxU) || (U[1] > maxU) || (U[2] > maxU)) \n{\n str = \"Alarm, napięcie \" + str;\n var newMsg = { payload: str };\n \n return newMsg\n}\n\nreturn null;",
"outputs": 1,
"noerr": 0,
"x": 400,
"y": 380,
"wires": [
[
"2719cabf.0309b6"
]
]
},
{
"id": "2719cabf.0309b6",
"type": "delay",
"z": "c0455411.1a7a98",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "15",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 620,
"y": 380,
"wires": [
[
"d28b42a1.984ad",
"baef394e.4050a8"
]
]
},
{
"id": "4fd27755.004fb8",
"type": "ui_chart",
"z": "c0455411.1a7a98",
"name": "",
"group": "7acd9f72.83e03",
"order": 2,
"width": "14",
"height": "6",
"label": "Wykres P [W]",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm:ss",
"interpolate": "bezier",
"nodata": "",
"ymin": "",
"ymax": "",
"removeOlder": "1",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"colors": [
"#1f77b4",
"#00ff40",
"#ff7f0e",
"#ff0000",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"x": 800,
"y": 80,
"wires": [
[]
]
},
{
"id": "372460c0.a8ade",
"type": "ui_text",
"z": "c0455411.1a7a98",
"group": "1d582f3.dde51d1",
"order": 1,
"width": "5",
"height": "1",
"name": "Data",
"label": "Data",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 830,
"y": 540,
"wires": []
},
{
"id": "99838e3.d28eb7",
"type": "ui_text",
"z": "c0455411.1a7a98",
"group": "1d582f3.dde51d1",
"order": 2,
"width": "5",
"height": "1",
"name": "EPP Suma",
"label": "Liczydło P+ Suma",
"format": "{{msg.payload}} kW",
"layout": "row-spread",
"x": 810,
"y": 580,
"wires": []
},
{
"id": "36f0ba11.630966",
"type": "ui_gauge",
"z": "c0455411.1a7a98",
"name": "",
"group": "1d582f3.dde51d1",
"order": 4,
"width": "5",
"height": "3",
"gtype": "gage",
"title": "Prognoza mocy",
"label": "kW",
"format": "{{value}}",
"min": 0,
"max": "1.2",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "0.8",
"seg2": "1",
"x": 800,
"y": 180,
"wires": []
},
{
"id": "7a78368a.a6df48",
"type": "ui_gauge",
"z": "c0455411.1a7a98",
"name": "U1",
"group": "67299838.fc46c8",
"order": 1,
"width": "5",
"height": "3",
"gtype": "gage",
"title": "U1",
"label": "V",
"format": "{{value}}",
"min": 0,
"max": "470",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "240",
"seg2": "245",
"x": 830,
"y": 240,
"wires": []
},
{
"id": "224f8ade.6bf0a6",
"type": "ui_gauge",
"z": "c0455411.1a7a98",
"name": "U2",
"group": "67299838.fc46c8",
"order": 2,
"width": "5",
"height": "3",
"gtype": "gage",
"title": "U2",
"label": "V",
"format": "{{value}}",
"min": 0,
"max": "470",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "240",
"seg2": "245",
"x": 830,
"y": 280,
"wires": []
},
{
"id": "a73a3bfe.741d38",
"type": "ui_gauge",
"z": "c0455411.1a7a98",
"name": "U3",
"group": "67299838.fc46c8",
"order": 3,
"width": "5",
"height": "3",
"gtype": "gage",
"title": "U3",
"label": "V",
"format": "{{value}}",
"min": 0,
"max": "470",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "240",
"seg2": "245",
"x": 830,
"y": 320,
"wires": []
},
{
"id": "25045341.be3d8c",
"type": "function",
"z": "c0455411.1a7a98",
"name": "kW -> kW",
"func": "\nvar P = parseFloat(msg.payload) / 1;\n\nP = P.toFixed(2);\n\nvar newMsg = { payload: P };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 620,
"y": 180,
"wires": [
[
"36f0ba11.630966"
]
]
},
{
"id": "d28b42a1.984ad",
"type": "function",
"z": "c0455411.1a7a98",
"name": "mail",
"func": "var msgStr = \"Dane:\\r\\n\";\n\nvar newMsg = \n { \n payload: msg.payload,\n title: \"Licznik 96481317\",\n bodytext: msgStr\n }\n \nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 510,
"y": 460,
"wires": [
[
"7bdc0d19.2af204"
]
]
},
{
"id": "7bdc0d19.2af204",
"type": "debug",
"z": "c0455411.1a7a98",
"name": "debug",
"active": false,
"console": "false",
"complete": "payload",
"x": 810,
"y": 460,
"wires": []
},
{
"id": "a01ff44e.44d618",
"type": "ui_text",
"z": "c0455411.1a7a98",
"group": "1d582f3.dde51d1",
"order": 3,
"width": 0,
"height": 0,
"name": "",
"label": "P+ chwilowa",
"format": "{{msg.payload}} kW",
"layout": "row-spread",
"x": 810,
"y": 140,
"wires": []
},
{
"id": "ac116467.6166f8",
"type": "function",
"z": "c0455411.1a7a98",
"name": "kW -> kW",
"func": "\nvar P = parseFloat(msg.payload) / 1;\n\nP = P.toFixed(2);\n\nvar newMsg = { payload: P };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 620,
"y": 140,
"wires": [
[
"a01ff44e.44d618"
]
]
},
{
"id": "89fc1a.0e4a33e8",
"type": "function",
"z": "c0455411.1a7a98",
"name": "Moce P+",
"func": "\nvar result = new Array({}, {}, {}, {});\n\nresult[0].topic = \"P+Sum\";\nresult[0].payload = msg.payload.data[0].data.energy.PP;\nresult[1].topic = \"P+ L1\";\nresult[1].payload = msg.payload.data[0].data.energy.PP_L1;\nresult[2].topic = \"P+ L2\";\nresult[2].payload = msg.payload.data[0].data.energy.PP_L2;\nresult[3].topic = \"P+ L3\";\nresult[3].payload = msg.payload.data[0].data.energy.PP_L3;\n\nreturn result;",
"outputs": 4,
"noerr": 0,
"x": 400,
"y": 80,
"wires": [
[
"ac116467.6166f8",
"4fd27755.004fb8"
],
[
"4fd27755.004fb8"
],
[
"4fd27755.004fb8"
],
[
"4fd27755.004fb8"
]
]
},
{
"id": "29daab0b.5aefc4",
"type": "function",
"z": "c0455411.1a7a98",
"name": "Prognoza",
"func": "\nvar result = new Array({}, {});\n\nresult[0].topic = \"PredictedPower\";\nresult[0].payload = msg.payload.data[0].data.energy.PredictedPower;\nresult[1].topic = \"GrowingPower\";\nresult[1].payload = msg.payload.data[0].data.energy.GrowingPower;\n\nreturn result;",
"outputs": 2,
"noerr": 0,
"x": 400,
"y": 180,
"wires": [
[
"25045341.be3d8c"
],
[]
]
},
{
"id": "d9cd35e1.631f68",
"type": "function",
"z": "c0455411.1a7a98",
"name": "Napięcia",
"func": "\nvar result = new Array({}, {}, {});\n\nresult[0].topic = \"U_L1\";\nresult[0].payload = msg.payload.data[0].data.energy.U_L1;\nresult[1].topic = \"U_L2\";\nresult[1].payload = msg.payload.data[0].data.energy.U_L2;\nresult[2].topic = \"U_L3\";\nresult[2].payload = msg.payload.data[0].data.energy.U_L3;\n\n\nreturn result;",
"outputs": 3,
"noerr": 0,
"x": 400,
"y": 280,
"wires": [
[
"7a78368a.a6df48"
],
[
"224f8ade.6bf0a6"
],
[
"a73a3bfe.741d38"
]
]
},
{
"id": "b6c9e68e.0536c8",
"type": "function",
"z": "c0455411.1a7a98",
"name": "",
"func": "\nvar result = new Array({}, {});\n\nresult[0].topic = \"date\";\nresult[0].payload = msg.payload.data[0].date;\nresult[1].topic = \"epp0\";\nresult[1].payload = msg.payload.data[0].data.energy.EPP0;\n\nreturn result;",
"outputs": 2,
"noerr": 0,
"x": 390,
"y": 560,
"wires": [
[
"372460c0.a8ade"
],
[
"99838e3.d28eb7"
]
]
},
{
"id": "b131ec9.24e0f1",
"type": "http request",
"z": "c0455411.1a7a98",
"name": "",
"method": "GET",
"ret": "txt",
"url": "",
"tls": "",
"x": 470,
"y": 740,
"wires": [
[
"b35fc84d.2db4e8"
]
]
},
{
"id": "6ca315a3.86c2fc",
"type": "function",
"z": "c0455411.1a7a98",
"name": "Licznik 2302353",
"func": "\nvar deviceNumber = \"2302353\"\n\nmsg.url = \"http://localhost/api/main/devicereading/devices/number/\" + deviceNumber + \"/data/online\";\nmsg.headers = [];\nmsg.headers[\"X-ApiKey\"] = \"008c2af71bdf007af7d0d9c6012bfaf0\";\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 280,
"y": 740,
"wires": [
[
"b131ec9.24e0f1"
]
]
},
{
"id": "d5a77964.58dc18",
"type": "debug",
"z": "c0455411.1a7a98",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 790,
"y": 740,
"wires": []
},
{
"id": "408871f3.d7fa9",
"type": "inject",
"z": "c0455411.1a7a98",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 100,
"y": 740,
"wires": [
[
"6ca315a3.86c2fc"
]
]
},
{
"id": "b35fc84d.2db4e8",
"type": "json",
"z": "c0455411.1a7a98",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 630,
"y": 740,
"wires": [
[
"d5a77964.58dc18"
]
]
},
{
"id": "bdc5ac9c.67141",
"type": "comment",
"z": "c0455411.1a7a98",
"name": "Metoda odczytu danych wykorzystująca Api Rest",
"info": "",
"x": 200,
"y": 660,
"wires": []
},
{
"id": "7acd9f72.83e03",
"type": "ui_group",
"z": "",
"name": "Wykres P",
"tab": "2fdc1493.109e5c",
"order": 1,
"disp": false,
"width": "16",
"collapse": false
},
{
"id": "1d582f3.dde51d1",
"type": "ui_group",
"z": "",
"name": "Stany",
"tab": "2fdc1493.109e5c",
"order": 2,
"disp": false,
"width": "5",
"collapse": false
},
{
"id": "67299838.fc46c8",
"type": "ui_group",
"z": "",
"name": "Column 1",
"tab": "2fdc1493.109e5c",
"order": 3,
"disp": false,
"width": "6"
},
{
"id": "2fdc1493.109e5c",
"type": "ui_tab",
"z": "",
"name": "Licznik 2302353",
"icon": "dashboard",
"order": 1
}
][
{
"id": "dd9c4191.af407",
"type": "tab",
"label": "Demo [Dane z liczników]",
"disabled": false,
"info": ""
},
{
"id": "c505834.b962b8",
"type": "json",
"z": "dd9c4191.af407",
"name": "json",
"x": 210,
"y": 60,
"wires": [
[
"ecdd5ab0.c755f8",
"505114e0.49b1ac"
]
]
},
{
"id": "ecdd5ab0.c755f8",
"type": "switch",
"z": "dd9c4191.af407",
"name": "Licznik 96481317",
"property": "payload.data[0].number",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "96481317",
"vt": "str"
}
],
"checkall": "true",
"outputs": 1,
"x": 130,
"y": 320,
"wires": [
[
"81dd5338.ce71d",
"410e74e3.f42a9c",
"b662a363.0a4f6",
"12a97e65.e56552",
"88e14f47.0216b"
]
]
},
{
"id": "81dd5338.ce71d",
"type": "Input Split",
"z": "dd9c4191.af407",
"name": "Moce P+",
"inputProps": [
"payload.data[0].data.energy.PP",
"payload.data[0].data.energy.PP_L1",
"payload.data[0].data.energy.PP_L2",
"payload.data[0].data.energy.PP_L3"
],
"inputTopics": [
"P+Sum",
"P+ L1",
"P+ L2",
"P+ L3"
],
"outputs": 4,
"x": 420,
"y": 80,
"wires": [
[
"1e003d2e.bd1863",
"dc3c131a.10967"
],
[
"1e003d2e.bd1863"
],
[
"1e003d2e.bd1863"
],
[
"1e003d2e.bd1863"
]
]
},
{
"id": "57d92c7f.76db94",
"type": "udp in",
"z": "dd9c4191.af407",
"name": "proBox",
"iface": "",
"port": "1910",
"ipv": "udp4",
"multicast": "false",
"group": "",
"datatype": "utf8",
"x": 70,
"y": 60,
"wires": [
[
"c505834.b962b8"
]
]
},
{
"id": "410e74e3.f42a9c",
"type": "Input Split",
"z": "dd9c4191.af407",
"name": "Prognoza",
"inputProps": [
"payload.data[0].data.energy.PredictedPower",
"payload.data[0].data.energy.GrowingPower"
],
"inputTopics": [
"PredictedPower",
"GrowingPower"
],
"outputs": 2,
"x": 420,
"y": 180,
"wires": [
[
"d0721be6.971fd8"
],
[]
]
},
{
"id": "b662a363.0a4f6",
"type": "Input Split",
"z": "dd9c4191.af407",
"name": "Napięcia",
"inputProps": [
"payload.data[0].data.energy.U_L1",
"payload.data[0].data.energy.U_L2",
"payload.data[0].data.energy.U_L3"
],
"inputTopics": [
"U_L1",
"U_L2",
"U_L3"
],
"outputs": 3,
"x": 420,
"y": 300,
"wires": [
[
"7152669d.676e18"
],
[
"8f9f45ba.13b448"
],
[
"73c944a2.cf58ec"
]
]
},
{
"id": "1f672acd.848e05",
"type": "ui_audio",
"z": "dd9c4191.af407",
"name": "",
"group": "f464e111.78b9",
"voice": "0",
"always": true,
"x": 820,
"y": 400,
"wires": []
},
{
"id": "88e14f47.0216b",
"type": "function",
"z": "dd9c4191.af407",
"name": "Alarm U",
"func": "\nvar str;\nvar U = new Array(3);\nvar maxU = 280;\n\nU[0] = msg.payload.data[0].data.energy.U_L1;\nU[1] = msg.payload.data[0].data.energy.U_L2;\nU[2] = msg.payload.data[0].data.energy.U_L3;\n\nstr = \"U1=\" + U[0] + \", U2=\" + U[1] + \", U3=\" + U[2];\nif ((U[0] > maxU) || (U[1] > maxU) || (U[2] > maxU)) \n{\n str = \"Alarm, napięcie \" + str;\n var newMsg = { payload: str };\n \n return newMsg\n}\n\nreturn null;",
"outputs": 1,
"noerr": 0,
"x": 420,
"y": 400,
"wires": [
[
"1b63d8ae.8e9ef7"
]
]
},
{
"id": "1b63d8ae.8e9ef7",
"type": "delay",
"z": "dd9c4191.af407",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "15",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 620,
"y": 400,
"wires": [
[
"d6a9f6ca.36d5b8",
"1f672acd.848e05"
]
]
},
{
"id": "1e003d2e.bd1863",
"type": "ui_chart",
"z": "dd9c4191.af407",
"name": "",
"group": "f464e111.78b9",
"order": 2,
"width": "14",
"height": "6",
"label": "Wykres P [W]",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm:ss",
"interpolate": "bezier",
"nodata": "",
"ymin": "",
"ymax": "",
"removeOlder": "1",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"colors": [
"#1f77b4",
"#00ff40",
"#ff7f0e",
"#ff0000",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"x": 680,
"y": 80,
"wires": [
[],
[]
]
},
{
"id": "12a97e65.e56552",
"type": "Input Split",
"z": "dd9c4191.af407",
"name": "",
"inputProps": [
"payload.data[0].date",
"payload.data[0].data.energy.EPP0"
],
"inputTopics": [
"date",
"epp0"
],
"outputs": 2,
"x": 420,
"y": 580,
"wires": [
[
"a6e9270.456bad8"
],
[
"3fd56cb1.1d86a4"
]
]
},
{
"id": "a6e9270.456bad8",
"type": "ui_text",
"z": "dd9c4191.af407",
"group": "2566d913.982b36",
"order": 1,
"width": "4",
"height": "1",
"name": "Data",
"label": "Data",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 650,
"y": 560,
"wires": []
},
{
"id": "3fd56cb1.1d86a4",
"type": "ui_text",
"z": "dd9c4191.af407",
"group": "2566d913.982b36",
"order": 2,
"width": "4",
"height": "1",
"name": "EPP Suma",
"label": "Liczydło P+ Suma",
"format": "{{msg.payload}} kW",
"layout": "row-spread",
"x": 670,
"y": 600,
"wires": []
},
{
"id": "5fb4c5f.35d583c",
"type": "ui_gauge",
"z": "dd9c4191.af407",
"name": "",
"group": "2566d913.982b36",
"order": 4,
"width": "4",
"height": "3",
"gtype": "gage",
"title": "Prognoza mocy",
"label": "kW",
"format": "{{value}}",
"min": 0,
"max": "1.2",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "0.8",
"seg2": "1",
"x": 800,
"y": 180,
"wires": []
},
{
"id": "7152669d.676e18",
"type": "ui_gauge",
"z": "dd9c4191.af407",
"name": "U1",
"group": "9dbb2d7f.0c0db",
"order": 1,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "U1",
"label": "V",
"format": "{{value}}",
"min": 0,
"max": "470",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "240",
"seg2": "245",
"x": 650,
"y": 260,
"wires": []
},
{
"id": "8f9f45ba.13b448",
"type": "ui_gauge",
"z": "dd9c4191.af407",
"name": "U2",
"group": "e8096100.c5a08",
"order": 1,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "U2",
"label": "V",
"format": "{{value}}",
"min": 0,
"max": "470",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "240",
"seg2": "245",
"x": 650,
"y": 300,
"wires": []
},
{
"id": "73c944a2.cf58ec",
"type": "ui_gauge",
"z": "dd9c4191.af407",
"name": "U3",
"group": "9b7d58ea.52e548",
"order": 1,
"width": 0,
"height": 0,
"gtype": "gage",
"title": "U3",
"label": "V",
"format": "{{value}}",
"min": 0,
"max": "470",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "240",
"seg2": "245",
"x": 650,
"y": 340,
"wires": []
},
{
"id": "d0721be6.971fd8",
"type": "function",
"z": "dd9c4191.af407",
"name": "W -> kW",
"func": "\nvar P = parseFloat(msg.payload) / 1000;\n\nP = P.toFixed(2);\n\nvar newMsg = { payload: P };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 620,
"y": 180,
"wires": [
[
"5fb4c5f.35d583c"
]
]
},
{
"id": "d6a9f6ca.36d5b8",
"type": "function",
"z": "dd9c4191.af407",
"name": "mail",
"func": "var msgStr = \"Dane:\\r\\n\";\n\nvar newMsg = \n { \n payload: msg.payload,\n title: \"Licznik 96481317\",\n bodytext: msgStr\n }\n \nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 510,
"y": 480,
"wires": [
[
"71b32ac5.b534b4"
]
]
},
{
"id": "71b32ac5.b534b4",
"type": "debug",
"z": "dd9c4191.af407",
"name": "debug",
"active": false,
"console": "false",
"complete": "payload",
"x": 810,
"y": 480,
"wires": []
},
{
"id": "dd0dfb64.5a4378",
"type": "ui_text",
"z": "dd9c4191.af407",
"group": "2566d913.982b36",
"order": 3,
"width": 0,
"height": 0,
"name": "",
"label": "P+ chwilowa",
"format": "{{msg.payload}} kW",
"layout": "row-spread",
"x": 790,
"y": 140,
"wires": []
},
{
"id": "dc3c131a.10967",
"type": "function",
"z": "dd9c4191.af407",
"name": "W -> kW",
"func": "\nvar P = parseFloat(msg.payload) / 1000;\n\nP = P.toFixed(2);\n\nvar newMsg = { payload: P };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 620,
"y": 140,
"wires": [
[
"dd0dfb64.5a4378"
]
]
},
{
"id": "505114e0.49b1ac",
"type": "debug",
"z": "dd9c4191.af407",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 130,
"y": 165,
"wires": []
},
{
"id": "f464e111.78b9",
"type": "ui_group",
"z": "",
"name": "Wykres P",
"tab": "c76d7630.6dfab8",
"order": 1,
"disp": false,
"width": "14"
},
{
"id": "2566d913.982b36",
"type": "ui_group",
"z": "",
"name": "Stany",
"tab": "c76d7630.6dfab8",
"order": 2,
"disp": false,
"width": "4"
},
{
"id": "9dbb2d7f.0c0db",
"type": "ui_group",
"z": "",
"name": "Column 1",
"tab": "c76d7630.6dfab8",
"order": 3,
"disp": false,
"width": "6"
},
{
"id": "e8096100.c5a08",
"type": "ui_group",
"z": "",
"name": "Column 2",
"tab": "c76d7630.6dfab8",
"order": 4,
"disp": false,
"width": "6"
},
{
"id": "9b7d58ea.52e548",
"type": "ui_group",
"z": "",
"name": "Column 3",
"tab": "c76d7630.6dfab8",
"order": 5,
"disp": false,
"width": "6"
},
{
"id": "c76d7630.6dfab8",
"type": "ui_tab",
"z": "",
"name": "Licznik 96481317",
"icon": "dashboard",
"order": 1
}
]
6.2.Strażnik Mocy - biblioteka Plotly.js
Przykład 15-minutowego Strażnika Mocy Energii Elektrycznej wykorzystując bibliotekę Plotly.js
Instrukcja opcjonalnego dodania modułu Plotly.js do urządzenia Numeron znajduje się pod adresem https://docs.numeron.pl/node-red/#import-modulow-do-urzadzen
Pobierz plik Strażnik Mocy - biblioteka Plotly.js lub skopiuj poniższy kod:
[
{
"id": "974263be.d8d2c",
"type": "tab",
"label": "Strażnik Mocy",
"disabled": false,
"info": ""
},
{
"id": "7da97b4.a468784",
"type": "function",
"z": "974263be.d8d2c",
"name": "Chart Preparator P+ plotly.js Online",
"func": "var maxSM = 800;\nif (context.global.get(\"maxSM\") !== undefined)\n{\n maxSM = context.global.get(\"maxSM\");\n}\nvar multip = 1;\n\nif (context.global.get(\"multip\") !== undefined)\n{\n multip = context.global.get(\"multip\");\n}\n\nif (context.global.get(\"dataSetGlobal\") !== undefined)\n{\n dataSetGlobal = context.global.get(\"dataSetGlobal\");\n}\n\nif (!dataSet) {\n var dataSet = [];\n}\nif (!dataSetGlobal) {\n var dataSetGlobal = [];\n}\n\nvar dataSeries1 = {};\nvar dataSeries2 = {};\nvar dataSeries3 = {};\nvar dataSeries4 = {};\nvar dataSeries5 = {};\n\n var tempDatax = [];\n var tempDatay = [];\n var tempDatax2 = [];\n var tempDatay2 = [];\n var tempDatax3 = [];\n var tempDatay3 = [];\n var tempDatax4 = [];\n var tempDatay4 = [];\n var tempDatax5 = [];\n var tempDatay5 = []; \n\n tempDatax[0] = msg.payload.data[0].date;\n tempDatay[0] = msg.payload.data[0].data.energy.PP * multip;\n tempDatax2[0] = msg.payload.data[0].date;\n tempDatay2[0] = msg.payload.data[0].data.energy.GrowingPower * multip;\n tempDatax3[0] = msg.payload.data[0].date;\n tempDatay3[0] = msg.payload.data[0].data.energy.PredictedPower * multip;\n tempDatax4[0] = msg.payload.data[0].date;\n tempDatay4[0] = msg.payload.data[0].data.energy.PP_L3 * multip;\n tempDatax5[0] = msg.payload.data[0].date;\n tempDatay5[0] = maxSM; \n\ndataSeries1.x = tempDatax;\ndataSeries1.y = tempDatay;\ndataSeries1.type = 'scatter';\ndataSeries1.name = 'P+ SUM';\ndataSeries1.mode = 'lines';\ndataSeries2.x = tempDatax2;\ndataSeries2.y = tempDatay2;\ndataSeries2.type = 'bar';\ndataSeries2.name = 'Moc narastająca';\ndataSeries2.opacity = 1;\ndataSeries2.marker = {color: 'rgba(22, 180, 22, 1)'};\ndataSeries3.x = tempDatax3;\ndataSeries3.y = tempDatay3;\ndataSeries3.type = 'scatter';\ndataSeries3.mode = 'lines';\ndataSeries3.name = 'Prognoza';\ndataSeries4.x = tempDatax4;\ndataSeries4.y = tempDatay4;\ndataSeries4.type = 'scatter';\ndataSeries4.name = 'P+ L3';\ndataSeries4.mode = 'lines';\ndataSeries5.x = tempDatax5;\ndataSeries5.y = tempDatay5;\ndataSeries5.type = 'scatter';\ndataSeries5.name = 'Moc zamówiona';\ndataSeries5.line = {color: 'rgb(255, 255, 0)', width: 3};\ndataSeries5.mode = 'lines';\n\ndataSet.push(dataSeries1, dataSeries2);\n\nmsg.payload=dataSet;\nmsg.prognozax = dataSeries3.x[0];\nmsg.prognozay = dataSeries3.y[0];\nmsg.maxSM = maxSM;\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 460,
"y": 60,
"wires": [
[
"25300060.9c1b4"
]
]
},
{
"id": "25300060.9c1b4",
"type": "ui_template",
"z": "974263be.d8d2c",
"group": "3fc58583.6ceb4a",
"name": "Straznik mocy plotly.js",
"order": 1,
"width": "13",
"height": "10",
"format": "<script src=\"https://node-red.numeron.pl/plotly-1.34.0.min.js\"></script>\n<div id=\"straznik\" style=\"min-width: 100%; min-height: 80%; margin: 0 auto\">\n<!-- Plotly chart will be drawn inside this DIV -->\n</div>\n<div id=\"dane\" style=\"min-width: 100%; min-height: 100px; margin: 0 auto\">\n Czekam na dane...\n</div>\n<script>\n\n(function() \n{\n\n var chartCanvasId = \"straznik\";\n var maxSM;\n var prognozax;\n var prognozay;\n\n var chartLayout = \n {\n xaxis: \n {\n type: 'date',\n title: 'Czas',\n fixedrange: true,\n tickformat: '%H:%M\\r\\n%Y-%m-%d',\n tickangle: 0,\n hoverformat: '%H:%M:%S',\n },\n yaxis: \n {\n title: 'Moc W',\n fixedrange: true,\n rangemode: 'tozero',\n anchor: 'x',\n range: [0, 1000],\n overlaying: 'y2',\n dtick: 100,\n tick0: 0\n },\n yaxis2: \n {\n title: null,\n overlaying: 'n',\n side: 'right',\n fixedrange: true,\n range: [0, 1000],\n rangemode: 'tozero',\n tick0: 0,\n dtick: 100,\n zeroline: false,\n showline: false,\n showticklabels: false,\n showgrid: false\n },\n title: 'Strażnik Mocy',\n showlegend: true,\n legend: \n {\n x: 0,\n y: 1.05,\n orientation: 'h',\n },\n autosize: true,\n font: {\n family: 'BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif',\n color: '#ffffff'\n },\n margin: \n {\n l: 50,\n r: 25,\n b: 50,\n t: 70,\n pad: 4\n },\n paper_bgcolor: '#363636',\n plot_bgcolor: '#363636'\n };\n \n var chartOptions = \n {\n displayModeBar: false, \n displaylogo: false,\n editable: false,\n showLink: false,\n scrollZoom: false\n };\n\n var chartDataSeries = null;\n var gscope;\n var initPlot = 0;\n \n function ShowChart()\n {\n if (chartDataSeries !== null)\n {\n var date = new Date();\n date = new Date(date.getTime() - (date.getTimezoneOffset() * 60000));\n var datefrom = new Date(Math.floor(new Date(date).getTime()/900000)*900000);\n var datefromlate = datefrom; \n datefromlate.setSeconds(datefromlate.getSeconds() + 33);\n datefrom = datefrom.toISOString().substr(0, 19).replace('T', ' ');\n datefromlate = datefromlate.toISOString().substr(0, 19).replace('T', ' ');\n var dateto = new Date(Math.ceil(new Date(date).getTime()/900000)*900000);\n dateto = dateto.toISOString().substr(0, 19).replace('T', ' '); \n chartLayout.xaxis.range = [ datefrom, dateto ];\n \n if ((chartDataSeries[0].x.length == 1) && (initPlot == 0))\n {\n var tracemaxSM = {\n x: [datefrom, datefrom],\n y: [0, 0],\n type: 'scatter',\n name: 'Moc zamówiona',\n line: {color: 'rgba(215, 215, 38, 1)', width: 1},\n mode: 'lines',\n opacity: 1,\n fill: 'tozeroy',\n fillcolor: 'rgba(215, 215, 38, 1)',\n yaxis: 'y2'\n };\n\n var tracePrognoza = {\n x: [prognozax, dateto],\n y: [chartDataSeries[1].y[chartDataSeries[1].y.length -1], prognozay],\n type: 'scatter',\n name: 'Prognoza',\n mode: 'lines',\n line: {color: 'rgba(153, 73, 9, 1)', width: 3}\n };\n \n chartDataSeries[3] = tracemaxSM;\n chartDataSeries[2] = tracePrognoza;\n\n maxRange = (parseInt(maxSM * 1.2 / 100) * 100) + 100;\n chartLayout.yaxis.range = [ 0, maxRange ];\n chartLayout.yaxis2.range = [ 0, maxRange ];\n \n Plotly.plot(chartCanvasId, chartDataSeries, chartLayout, chartOptions);\n \n Plotly.animate(chartCanvasId, {\n data: [ {x: [datefrom, dateto], y: [0, maxSM] } ],\n traces: [3],\n layout: {}\n }, {\n transition: {\n duration: 2000,\n easing: 'cubic-in-out'\n }\n })\n \n document.getElementById(\"dane\").innerHTML=\"<b>Moc chwilowa: </b>\" + chartDataSeries[0].y[chartDataSeries[0].y.length -1].toFixed(2) +\n \"<br><b>Prognoza: </b>\" + chartDataSeries[2].y[chartDataSeries[2].x.length -1].toFixed(2) + \"<br><b>Moc zamówiona: </b>\" + maxSM.toFixed(2) +\n \"<br><b>Zapas mocy: </b>\" + (maxSM - chartDataSeries[2].y[chartDataSeries[2].x.length -1]).toFixed(2);\n \n chartDataSeries = null;\n initPlot = 1;\n \n } \n else\n if (chartDataSeries[0].x.length == 1)\n {\n Plotly.extendTraces(chartCanvasId, {\n x:[\n [chartDataSeries[0].x[chartDataSeries[0].x.length -1]],\n [chartDataSeries[1].x[chartDataSeries[1].x.length -1]]\n ],\n y:[\n [chartDataSeries[0].y[chartDataSeries[0].y.length -1]],\n [chartDataSeries[1].y[chartDataSeries[1].y.length -1]]\n ]}, [0,1]);\n \n var tracePrognoza = {\n x: [prognozax, dateto],\n y: [chartDataSeries[1].y[chartDataSeries[1].y.length -1], prognozay],\n type: 'scatter',\n name: 'Prognoza',\n mode: 'lines',\n line: {color: 'rgba(153, 73, 9, 1)', width: 3}\n };\n \n maxRange = (parseInt(maxSM * 1.2 / 100) * 100) + 100;\n var updateLayout = {'yaxis.range': [ 0, maxRange ], 'yaxis2.range': [ 0, maxRange ]};\n Plotly.relayout(chartCanvasId, updateLayout);\n var update = {x: [[prognozax, dateto]], y: [[chartDataSeries[1].y[chartDataSeries[1].y.length -1], prognozay]] };\n Plotly.restyle(chartCanvasId, update, [2]);\n \n var updateSM = {x: [[datefrom, dateto]], y: [[0, maxSM]] };\n Plotly.restyle(chartCanvasId, updateSM, [3]);\n \n document.getElementById(\"dane\").innerHTML=\"<b>Moc chwilowa: </b>\" + chartDataSeries[0].y[chartDataSeries[0].y.length -1].toFixed(2) +\n \" <br><b>Prognoza: </b>\" + prognozay.toFixed(2) + \" <br><b>Moc zamówiona: </b>\" + maxSM.toFixed(2) +\n \" <br><b>Zapas mocy: </b>\" + (maxSM - prognozay).toFixed(2);\n\n if (prognozay.toFixed(2) > maxSM.toFixed(2))\n {\n var przekroczenie = Math.abs(maxSM - prognozay).toFixed(2);\n przekroczenie = 'Alert z Node-Red! Prognozowane przekroczenie o ' + przekroczenie + 'W';\n gscope.send({payload: \"sendSMS\", wiadomosc: przekroczenie}); \n }\n \n }\n }\n };\n\n (function(scope)\n {\n gscope = scope;\n scope.$watch('msg', function(msg)\n {\n if (msg)\n {\n chartDataSeries = msg.payload;\n maxSM = msg.maxSM;\n prognozax = msg.prognozax;\n prognozay = msg.prognozay;\n setTimeout(ShowChart, 1000);\n }\n });\n })(scope);\n})(); \n</script>\n\n",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 720,
"y": 60,
"wires": [
[]
]
},
{
"id": "4e5cb354.289aac",
"type": "json",
"z": "974263be.d8d2c",
"name": "",
"pretty": false,
"x": 250,
"y": 60,
"wires": [
[
"7da97b4.a468784"
]
]
},
{
"id": "2d1df23d.fba84e",
"type": "udp in",
"z": "974263be.d8d2c",
"name": "proBox",
"iface": "",
"port": "1900",
"ipv": "udp4",
"multicast": "false",
"group": "",
"datatype": "buffer",
"x": 80,
"y": 60,
"wires": [
[
"4e5cb354.289aac"
]
]
},
{
"id": "3fc58583.6ceb4a",
"type": "ui_group",
"z": "",
"name": "Strażnik Mocy",
"tab": "d8b792ac.3d912",
"disp": false,
"width": "13",
"collapse": false
},
{
"id": "d8b792ac.3d912",
"type": "ui_tab",
"z": "",
"name": "IIoT Numeron - Dashboard",
"icon": "dashboard",
"order": 2
}
]
6.3.Prosty wykres mocy
Pobierz plik Prosty wykres mocy lub skopiuj poniższy kod:
[
{
"id": "da120f98.f7424",
"type": "tab",
"label": "Prosty wykres mocy",
"disabled": false,
"info": ""
},
{
"id": "f969d2ea.772ef",
"type": "json",
"z": "da120f98.f7424",
"name": "",
"pretty": false,
"x": 230,
"y": 100,
"wires": [
[
"a8e0377d.8a7798",
"fc927b8.b1a6b88",
"1ead6a2d.932156",
"8242451f.911708"
]
]
},
{
"id": "fc927b8.b1a6b88",
"type": "function",
"z": "da120f98.f7424",
"name": "Moc P+ L1",
"func": "var P = parseFloat(msg.payload.data[0].data.energy.PP_L1);\nvar multip = 1;\nif (context.global.get(\"multip\") !== undefined)\n{\n multip = context.global.get(\"multip\");\n}\nP = P * multip;\nP = P.toFixed(2);\n\nvar newMsg = { payload: P, topic:'P+ L1' };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 444,
"y": 49,
"wires": [
[
"22a133f1.e4a8fc"
]
]
},
{
"id": "1ead6a2d.932156",
"type": "function",
"z": "da120f98.f7424",
"name": "Moc P+ L2",
"func": "var P = parseFloat(msg.payload.data[0].data.energy.PP_L2);\nvar multip = 1;\nif (context.global.get(\"multip\") !== undefined)\n{\n multip = context.global.get(\"multip\");\n}\nP = P * multip;\nP = P.toFixed(2);\n\nvar newMsg = { payload: P, topic:'P+ L2' };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 444,
"y": 89,
"wires": [
[
"22a133f1.e4a8fc"
]
]
},
{
"id": "8242451f.911708",
"type": "function",
"z": "da120f98.f7424",
"name": "Moc P+ L3",
"func": "var P = parseFloat(msg.payload.data[0].data.energy.PP_L3);\nvar multip = 1;\nif (context.global.get(\"multip\") !== undefined)\n{\n multip = context.global.get(\"multip\");\n}\nP = P * multip;\nP = P.toFixed(2);\n\nvar newMsg = { payload: P, topic:'P+ L3' };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 444,
"y": 129,
"wires": [
[
"22a133f1.e4a8fc"
]
]
},
{
"id": "a8e0377d.8a7798",
"type": "function",
"z": "da120f98.f7424",
"name": "Moc P+ SUMA",
"func": "var P = parseFloat(msg.payload.data[0].data.energy.PP);\nvar multip = 1;\nif (context.global.get(\"multip\") !== undefined)\n{\n multip = context.global.get(\"multip\");\n}\nP = P * multip;\nP = P.toFixed(2);\n\nvar newMsg = { payload: P, topic:'P+ SUM' };\n\nreturn newMsg;",
"outputs": 1,
"noerr": 0,
"x": 454,
"y": 169,
"wires": [
[
"22a133f1.e4a8fc"
]
]
},
{
"id": "22a133f1.e4a8fc",
"type": "ui_chart",
"z": "da120f98.f7424",
"name": "",
"group": "289045f7.9d9c9a",
"order": 1,
"width": "12",
"height": "5",
"label": "Moc P+ L1, L2, L3",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "czekam na dane online",
"dot": false,
"ymin": "",
"ymax": "",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"colors": [
"#aa5500",
"#0080c0",
"#00a800",
"#ff8000",
"#ff0000",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"x": 664,
"y": 109,
"wires": [
[],
[]
],
"inputLabels": [
"wejscie"
]
},
{
"id": "e06426e9.dd9208",
"type": "udp in",
"z": "da120f98.f7424",
"name": "proBox",
"iface": "",
"port": "1900",
"ipv": "udp4",
"multicast": "false",
"group": "",
"datatype": "buffer",
"x": 90,
"y": 100,
"wires": [
[
"f969d2ea.772ef"
]
]
},
{
"id": "289045f7.9d9c9a",
"type": "ui_group",
"z": "",
"name": "Prosty wykres mocy",
"tab": "d8b792ac.3d912",
"disp": false,
"width": "12",
"collapse": false
},
{
"id": "d8b792ac.3d912",
"type": "ui_tab",
"z": "",
"name": "IIoT Numeron - Dashboard",
"icon": "dashboard",
"order": 2
}
]