Spojení NPA ↔︎ NPA přes
VPN-ID (dd_npaid)
Platí pro verzi NPA R04: 2.15.beta1 · Vytvořeno: 2026-07-16
Tento dokument popisuje mechanismus, kterým se jednotka NPA připojuje
k jiné jednotce NPA přes VPN pomocí ID modulu místo
pevné IP adresy, a obsahuje zadání pro serverovou
stranu (endpoint moduleslist), bez které nelze
výběr ID na webu naplnit a spojení zprovoznit.
Starý web (Flask aplikace v
~/Nextcloud/src/NPA_R04_MODBUS/ea/ea.py) endpoint
/moduleslist poskytoval; nový monitoring (EnergyCore,
monitoring.dev.energyadmin.cz) ho zatím nemá — proto NPA nedokáže seznam
modulů nabídnout a dd_npaid není jak vyplnit.
1. K čemu to je
Zařízení typu „Obchodní měření na podřízeném NPA"
(npa_slave_tml) a „Rozpadové místo na podřízeném
NPA" (npa_slave_ds) čtou data z jiné jednotky NPA
po Modbus TCP. Nadřízená jednotka se k podřízené může připojit dvěma
způsoby (web: Zařízení → nastavit → Datová komunikace, šablona
device_edit_commTcpId.html):
- Zadat IP adresu
(
dd_ip_npaid = "dd_ip") — pevně zadanádd_ip,dd_portadd_idNet; - Vybrat ID
(
dd_ip_npaid = "dd_id_npaid") — uloží sedd_npaid(ID modulu), IP se dohledává za běhu.
Výhoda ID: adresa přidělená VPN serverem se může změnit (reinstalace, přečíslování sítě), ID modulu v databázi serveru je stabilní. IP se dohledává při každém navazování spojení, takže změna adresy nevyžaduje zásah do konfigurace nadřízené jednotky.
2. Architektura
VPN síť (OpenVPN, rozhraní tun_npa_r04)
+-----------------------------------------+
| NPA server (HTTP :80) na <a.b>.0.1 |
| - POST /moduleslist (tento dokument) |
| - POST /measuring, /config, ... |
+-------------------+---------------------+
|
| 1. dotaz do adresáře:
| dd_npaid -> aktuální VPN IP
|
+--------------------+ | +------------------+
| NPA "master" +--+ | NPA "slave" |
| (npa_slave_tml/ds) | | (id 2 v DB) |
+---------+----------+ +---------+--------+
| ^
| 2. JSON-RPC :7777 |
| get_modbus_srv_param |
| -> mb_port, mb_id |
| |
+--- 3. Modbus TCP -----------+
ip:mb_port (čtení registrů)
Datový tok jde přímo mezi jednotkami po VPN (Modbus TCP). Server slouží pouze jako adresář „ID → aktuální VPN IP".
Jak jednotka najde server
GetVpnNpaServerIp() (util/nutils.cpp) vezme
IPv4 adresu rozhraní tun_npa_r04 a nahradí poslední dva
oktety 0.1 — z 10.81.0.14 tedy vyjde server
10.81.0.1. Server proto musí poslouchat na HTTP
portu 80 na VPN adrese <a.b>.0.1. Bez
navázané VPN vrací funkce prázdný řetězec a všechny cloudové funkce se
přeskočí.
3. Průběh připojení (strana NPA, stávající kód)
- Výběr na webu —
NHtml::GetNpaToSelect()(nhtml.cpp) zavoláNModules::GetModules()a naplní<select id="dd_npaid">položkamiid → "name - sn - online". Online modul je zvýrazněn. - Uložení —
dd_npaid(číselnéidmodulu) se uloží do configu zařízení. - Připojení —
DeviceModbus::NpaIdConnect()(device/devicemodbus.cpp):NModules::GetModuleIp(dd_npaid)→ POSThttp://<a.b>.0.1/moduleslist, v odpovědi najde modul se shodnýmida vezme jehoip;NJCli::GetModbusSrvParam(ip)→ JSON-RPC nahttp://<ip>:7777/s{"req": "get_modbus_srv_param"}; podřízená jednotka vrátímb_port(= jejíns_netPort) amb_id(=ns_netId);- otevře Modbus TCP spojení
ip:mb_porta čte registry (npa_slave_tml: blok 2000–2056;npa_slave_ds: blok 3000+offset, 121 registrů).
- Při výpadku spojení se celý postup opakuje (znovu se dohledá i IP).
Požadavek na
klienta /moduleslist (přesný tvar)
NModules::GetModules() posílá:
POST /moduleslist HTTP/1.1
Host: <a.b>.0.1
Content-Type: application/json
{ "sn": "NPA20240418-1801", "time": "2026-07-16T07:30:00" }
sn— sériové číslo žádající jednotky (NConfig::mSN),time— UTC čas jednotky (ISO 8601).
Očekávaná odpověď — objekt s polem modules:
{
"modules": [
{
"id": 1,
"sn": "NPA20240418-1801",
"name": "ABEGU - Testovací",
"ip": "10.81.0.14",
"online": 1
},
{ "id": 2, "sn": "NPA20240905-2116", "name": "ABEGU - Testovací 2",
"ip": "10.81.0.10", "online": 0 }
]
}
Neregistrované sn:
{ "error": "modul neexistuje" } (klient pak zobrazí prázdný
výběr).
Klient čte pouze klíče id, ip,
name, sn, online; ostatní klíče
ignoruje (starý server posílal celé řádky tabulky modules
včetně setting — není potřeba).
4. Zadání pro serverovou stranu
4.1 Cíl
Implementovat na monitorovacím serveru (EnergyCore) endpoint
POST /moduleslist dostupný na VPN
adrese <a.b>.0.1, port 80 tak, aby jednotky
NPA mohly:
- na webu jednotky nabídnout seznam modulů pro výběr
dd_npaid, - za běhu překládat
dd_npaid → aktuální VPN IPpro spojení NPA ↔︎ NPA.
4.2 Funkční požadavky
- Kontrakt přesně dle kapitoly 3 (request
{sn, time}, response{modules: [...]}). Klient je nasazený v terénu — tvar odpovědi nelze měnit. - Povinné klíče každého modulu:
id(int, stabilní identifikátor — plní se dodd_npaid),sn(string),name(string),ip(string — aktuální VPN adresa),online(číslo 0/1). Klient čteidaonlinetolerantně (číslo i řetězec), přesto posílejte čísla — starý server mělonlinejako String. - Filtrování: vrátit pouze moduly, které patří ke
stejné instalaci/zákazníkovi jako žádající
sn(starý server filtroval přespractitioner; v nové DB odpovídá vazbě instalace/zákazník). Jednotka nesmí vidět cizí moduly. ipmusí být aktuální VPN adresa jednotky. Doporučené řešení: pevné přidělení adres v OpenVPN (ccd/ifconfig-push) + evidence v DB (monitoring už sloupec „IP VPN" u PLC má). Alternativa: číst OpenVPN status log / management interface.online: stav připojení k VPN (OpenVPN status), případně odvozený z posledního příjmu na/measuring(např. < 2 min = online) — stejný údaj, který monitoring zobrazuje jako „Je online".- Neznámé
sn→{"error": "modul neexistuje"}, HTTP 200 (kompatibilita).
4.3 Nefunkční požadavky
- Dostupnost pouze z VPN sítě — endpoint nesmí být
vystaven do internetu; bind na VPN adresu serveru nebo firewall na
tunrozhraní. Jiná autentizace není (klient posílá jensn), proto je izolace na VPN nutná podmínka. - Latence: klient čeká na odpověď nejvýše 3 s, pak požadavek přeruší — pomalejší odpověď znamená, že se seznam na webu nenaplní a spojení přes ID se nenaváže. Odpověď proto musí být rychlá (< 1 s). Nekešovat — smysl VPN-ID je právě v tom, že se IP může měnit; odpověď musí vždy odrážet aktuální stav (IP, online).
- Logování: příchozí
sn+ čas se hodí evidovat (server tím zadarmo získává heartbeat jednotek, stejně jako to dělal starý web).
4.4 Návazné endpointy (informativně)
Na téže adrese očekává jednotka i endpointy, které dnes obsluhoval
starý web (NRemoteLog): POST /measuring
(periodické stavy, v odpovědi srv_setting),
POST /config (záloha konfigurace),
POST /getlastmeas (poslední uložený stav po startu). Nejsou
předmětem tohoto zadání, ale při návrhu serveru je dobré s nimi počítat
— viz doc/interfaces.md, sekce cloudoví klienti.
4.5 Akceptační test
# na stroji ve VPN (nebo přímo na serveru):
curl -s -X POST http://10.81.0.1/moduleslist \
-H 'Content-Type: application/json' \
-d '{"sn": "NPA20240418-1801", "time": "2026-07-16T07:30:00"}'
# očekávám: {"modules": [ ... id/ip/name/sn/online ... ]}, jen moduly stejné instalace
Poté na NPA:
- Zařízení → přidat/nastavit zařízení typu
npa_slave_tml(MODBUS TCP) — v sekci Datová komunikace zvolit Vybrat ID; v selectu se objeví seznam modulů (=/moduleslistfunguje). - Vybrat podřízenou jednotku, uložit (
dd_npaid). - Do ~10 s se zařízení připojí (stav na stránce Přehled /
detail zařízení); v logu jednotky
remote connect - Device UUID ... mIp: <vpn-ip>, mPort: <port>. - Ověřit tok dat: hodnoty TML (P, Q, U…) z podřízené jednotky na stránce Přehled.
5. Postup zprovoznění spojení (checklist)
- Obě jednotky mají zapnutou vzdálenou správu (Nastavení sítě → Vzdálená správa) a navázanou VPN (stránka Přehled → IP Adresa VPN).
- Server implementuje
/moduleslist(kap. 4) a zná VPN IP obou jednotek. - Na podřízené jednotce zkontrolovat
ns_netPort/ns_netId(Modbus TCP server) — tyto hodnoty si nadřízená jednotka zjistí sama přes JSON-RPC. - Na nadřízené jednotce nakonfigurovat zařízení
npa_slave_tml/npa_slave_dss volbou Vybrat ID (kap. 4.5, body 1–4).