Node-RED

1.Co to jest Node-RED?

Node-RED Numeron

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.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 17 grudnia 2020
3 of 3 użytkowników uznało to za pomocne

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”.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 23 lipca 2018
2 of 2 użytkowników uznało to za pomocne

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.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 4 czerwca 2018
0 of 0 użytkowników uznało to za pomocne

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.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 23 lipca 2018
0 of 0 użytkowników uznało to za pomocne

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ć.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 5 czerwca 2018
0 of 0 użytkowników uznało to za pomocne

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.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 23 lipca 2018
0 of 0 użytkowników uznało to za pomocne

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.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 5 czerwca 2018
0 of 0 użytkowników uznało to za pomocne

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”.

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 23 lipca 2018
0 of 0 użytkowników uznało to za pomocne

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.0
Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 9 listopada 2018
0 of 0 użytkowników uznało to za pomocne

5.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:

  1. 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,
  2. 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).
Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 27 kwietnia 2020
1 of 1 użytkowników uznało to za pomocne

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/

Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 4 czerwca 2018
0 of 0 użytkowników uznało to za pomocne

6.1.Domyślny schemat startowy Demo

Pobierz plik Domyślny schemat startowy Demo lub skopiuj poniższy kod:

[
 {
 "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
 }
]
Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 7 czerwca 2018
1 of 1 użytkowników uznało to za pomocne

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
 }
]
Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 7 czerwca 2018
0 of 0 użytkowników uznało to za pomocne

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
 }
]
Tak Nie Zaproponuj zmianę
Ostatnia aktualizacja 7 czerwca 2018
2 of 2 użytkowników uznało to za pomocne
Zaproponuj zmianę