Skip to content
Snippets Groups Projects
Verified Commit 061fb01d authored by Nádudvari Ákos's avatar Nádudvari Ákos
Browse files

feat(tervezés): esp32 platform ismertető init

parent b8513808
No related branches found
No related tags found
No related merge requests found
Pipeline #2706 passed
......@@ -613,13 +613,16 @@ kényelmet a biztonság elé helyezni.
hiszen minden valaha létrejött szoftver életciklusában van emberi tényező. Az
emberi tényező hozzájárul a szoftver helytelen működéséhez, az abban keletkező
hibákhoz. A hibák akár sebezhetőséget is tudnak magukkal hordozni, melyek
kihasználásával harmadik fél számára adhatnak hozzáférést a rendszerhez.
A sebezhetőségek túlnyomórészt helytelen memóriakezelésből származnak --
túlcsordulás, use-after-free, nem inicializált memória. \cite{software-vuln}
Ezek elkerülése végett be kell vezetni a helyesség ellenőrzésére alkalmas
eszközöket, vagy ha lehet, az ezt megelőző módszereket alkalmazni. Ez lehet
a szoftver tervezés-fejlesztés-validálás életciklusban változtatás, vagy a
fejlesztői környezetben.
kihasználásával harmadik fél számára adhatnak hozzáférést a rendszerhez. A
Microsoft nemrég egy felmérést végzett a saját termékein, melyben a szofvteres
sebezhetőségekeket kiváltó okokat kereste. Az eremények magukért beszélnek:
a sebezhetőségekre kiadott biztonsági javítások $70 \%$-a memóriakezelési
hibákból származott a megállapításuk szerint. \cite{ms-rust} \cite{ms-vuln-70}
A sebezhetőségek sok forrásból keletkezhetnek, de túlnyomórészt helytelen
memóriakezelésből származnak -- túlcsordulás, use-after-free, nem inicializált
memória. \cite{software-vuln} Ezek elkerülése végett be kell vezetni a helyesség
ellenőrzésére alkalmas eszközöket, vagy ha lehet, az ezt megelőző módszereket
alkalmazni. Ez lehet a szoftver tervezés-fejlesztés-validálás életciklusban
változtatás, vagy a fejlesztői környezetben.
\clearpage % Ez azért kell, hogy nehogy képek átcsússzanak a következő fejezethez
......@@ -100,7 +100,7 @@ szereztem tudást az adott technológiákról, megoldásokról. A következő fe
részletesen adok ismertetést azokról.
\begin{figure}[htbp!]
\includesvg[width=\columnwidth]{images/rendszer.drawio.svg}
\includesvg[width=\textwidth]{images/rendszer.drawio.svg}
\caption{A teljes rendszer magas szintű vázlata}
\label{diag:rendszer}
\end{figure}
......@@ -109,9 +109,81 @@ részletesen adok ismertetést azokról.
\subsection{ESP32 platform}
\paragraph{} Az Espressif más megközelítéssel tervezi a hardvereit, mint hasonló
platfomok. Egy alacsony fogyasztású beépített rendszer általában minimális számú
perifériával van ellátva, elterjedten a mikrokontroller tokozásában nincsenek
kiegészítő perifériák, csak a processzor, órajel vezérlés, debug interfész,
és egyéb alapvető komponensek. Ez jellemző például az STMicroelectronics
ARM mikroprocesszor alapú chipjeire. Ez ideális egy olyan rendszernél,
ahol a hardver tervezését is szeretnénk maximálisan magunk elvégezni minden
részletében. Ezzel a módszerrel a végeredmény nagyon optimalizált összetételt
fog eredményezni egy nagyon specifikus célra. Hátránya, hogy a későbbi
változtatás felmerülő igényével számolni nehezebb, és azt legtöbb esetben
nehezebb kivitelezni, ezért rugalmatlanabb, mint itt az ESP32 esetében. Az
analógia a következő: legyen egy komplett, jól megválasztott perifériákkal
ellátott alaprendszer a chipen (``Systen on a Chip'' -- SoC) a kezünknél. Ez a
hardver tervezésének fázisát segíti elő, illetve a később felmerülő bővítéssel
számolni legtöbb esetben triviális az integrált perifériák jelenlétében. Ez az
analógia jól illeszkedik IoT célú eszközök körében, hiszen beépített WiFi és
Bluetooth rádióval van ellátva, mellé a szoftveres támogatás is integrált, a
gyors tervezés és implementálást elősegítve. \cite{esp32-family} Ahogy láttuk
\aref{kereskedelmi}. fejezetben, egy hagyományos riasztórendszerhez az előbbi
megközelítés áll jobban, és a DIY rendszerekhez az ESP32 megközelítését tartom
ideálisabbnak. Ezért esett rá a választás, hiszen a dolgozat keretében egy
alapot tervezek készíteni egy bővíthető rendszer számára.
Az ESP32 családjában több mikroprocesszor-architektúra is megtalálható,
nevezetesen: Xtensa, ARM és RISC-V. A legtöbb modell esetében Xtensa magok
találhatóak, mely kizárólag az ESP-k körében használatos manapság. 32 bites
ALU-val és 16 darab 32 bites általános célú regiszterrel rendelkezik, 16
bites utasításkészlet mellett (ISA). Az alap ISA 82 RISC utasítást tartalmaz.
\cite{xtensa} Az általam választott ESP32 alapú fejlesztőpanel (ESP32-D1-MINI)
az ESP32-WROOM-32 chipet használja. A chip tartalmaz 4MB beépített SPI
flash memóriát, 520KB SRAM-ot. Megítélésem szerint ez elegendő erőforrás a
fehasználásunkra, hiszen nem fogjuk használni a beépített WiFi rádiót, ami
működtetése szignifikáns ROM és RAM-ot felhasználna. \cite{esp-wroom} A chip
tartalmaz egy beépített MAC interfészt (Media Access Controller), amely 17
vezetéken (MII -- Media Independent Interface) vagy 9 (RMII -- Reduced Media
Independent Interface) vezetéken képes egy fizikai médium vezérlővel (PHY)
kommunikálni. \cite{esp} Ez esetünkben praktikus, mert csupán egy Ethernet
aljzat és PHY vezérlő elegendő Ethernet LAN hálózatokkal való integráláshoz.
Továbbá a chipen a MAC egyedi DMA (Direct Memory Access) vezérlővel működik
beépített adó és vevő oldali 512 szavas FIFO-val. Ezt alkalmazva az adatátvitel
akár $100\ Mbit/s$ sebességen tud működni. \cite{esp} Számunkra nem a sebesség
a fontos, hanem a stabilitás, megbízhatóság, melynek ezek a beépített perifériák
eleget tesznek. Az adatátvitel szoftveres kezelését a gyártó által fejlesztett
framework-ben implementált driver fogja végezni, mely kevésbé rizikósabb, mint
harmadik fél által fejlesztett megoldások.
Az Espressif fenn tart ehhez az architektúrához készült fordítóprogramokat,
melyek az ESP-IDF (Espressif IoT Development Framework) szofverfejlesztői
csomagban használatosak. \cite{idf-tools} A framework alapvetően C/C++ nyelvekre
célzott. A Rust támogatás esete speciális, mely két különböző módon adott.
Az egyik mód keretében az ESP-IDF függvénykönyvtárának felhelhasználásával
implementált Rust standard library (std) segítségével tudunk fejleszteni
alkalmazást. Vagy a sokkal kisebb binárist eredményező és memóriahasználatú,
alacsonyabb szintű út: std és ESP-IDF nélkül (``\verb|no_std|''), úgynevezett
``baremetal Rust'' környezetben tudunk fejleszteni. \cite{esp-rust-approaches}
A dokumentáció jól szemlélteti a két megközelítés közötti különbségeket,
illetve mikor érdemes melyiket választani. A projektünkhöz az std használatát
választom az ESP-IDF kifejledt ökoszisztémája miatt, mellyel korábban pozitív
tapasztalataim voltak. Az eszköz szoftverében a működése óta nem találtam hibát,
ami hasonlóan egy ESP32-WROVER-32 alapú rendszer volt titkosított adatközléssel
WiFi hálozat felett. \cite{onlab} Az ESP-IDF több biztonságot garantál a program
stabilitása érdekében, mint a bare metal megoldás, hiszen ott futásidőben
nincsen operációs rendszer, ezért minden a fejlesztőre van bízva -- nincsen
heap, ezért a memóriakezelés visszaesik ránk. \cite{rust-nostd} \Aref{inf-bizt}.
fejezetben indokoltak miatt a projekt keretében a bare metal használata nem
ideális. Több minden van a fejlesztőre bízva, több befolyást ad a kezünkbe,
de ezzel egyben biztonság kárára optimalizálnánk a program memóriahasználatát
és bináris méretét. A bare metal megközelítést inkább elszigetelt, beágyazott
célhardverekhez tartom jobban igazodónak, nem magas szintű IoT-barát
megoldásoknak.
\subsection{Rust nyelv és környezet}
% Rövid ismertető a nyelvről, miért jó választás esetünkben. A nyelv körüli ekoszisztéma és a hardver integrációjáról ismertetés.
\paragraph{} A Rust nyelv ötlete egy Mozilla-nál dolgozó fejlesztő fejéből
pattant ki, amikor egy liftbe beszállt és az elromlott, hibás szoftver miatt.
\subsection{MQTT protokoll}
......
@thesis{bizt-rendszerek,
author = {Török Krisztián Antal},
author = {Török, Krisztián Antal},
title = {Biztonságtechnikai rendszerek üzemeltetése-karbantartása},
type = {szakdolgozat},
year = {2024},
......@@ -435,3 +435,101 @@ urldate = {2025-04-22},
url = {https://www.home-assistant.io/integrations/mqtt/#setting-up-a-broker},
urldate = {2025-04-23},
}
@manual{esp32-family,
title = {ESP32 Series - Datasheet},
author = {{Espressif}},
url = {
https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
},
urldate = {2025-04-24},
}
@online{idf-tools,
title = {List of ESP-IDF Tools - Downloadable IDF tools - ESP32},
url = {
https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/tools/idf-tools.html#list-of-esp-idf-tools
},
urldate = {2025-04-24},
}
@manual{xtensa,
title = {Xtensa Instruction Set Architecture (ISA)},
type = {Reference Manual},
author = {{Tensilica, Inc.}},
url = {https://0x04.net/~mwk/doc/xtensa.pdf},
urldate = {2025-04-24},
}
@manual{esp,
title = {ESP32 Series - Datasheet version 4.9},
url = {
https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
},
urldate = {2025-04-24},
}
@manual{esp-wroom,
title = {ESP32-WROOM-32 - Datasheet},
url = {https://www.hestore.hu/prod_getfile.php?id=13796},
urldate = {2025-04-24},
}
@online{esp-rust-approaches,
title = {Overview of Development Approaches - The Rust on ESP Book},
url = {
https://docs.esp-rs.org/book/overview/index.html#overview-of-development-approaches
},
urldate = {2025-04-24},
}
@online{rust-nostd,
title = {A no{\_}std Rust Environment},
url = {
https://docs.rust-embedded.org/book/intro/no-std.html#a-no_std-rust-environment
},
urldate = {2025-04-24},
}
@book{rust-book,
title = {The Rust Programming Language (Covers Rust 2018)},
author = {Klabnik, S. and Nichols, C.},
isbn = {9781718500457},
url = {https://doc.rust-lang.org/book},
urldate = {2025-04-24},
year = {2019},
publisher = {No Starch Press},
}
@report{onlab,
author = {Nádudvari, Ákos},
title = {ITK alkalmazás (ITKapp) fejlesztése modern, Web alapú
technológiákkal},
type = "Önálló Laboratórium",
institution = {PPKE ITK},
year = 2024,
month = {5},
url = {https://users.itk.ppke.hu/~nadak/files/itkapp_onlab.pdf},
}
@online{ms-rust,
title = {Microsoft is Getting Rusty: A Review of Successes and Challenges},
type = "presentation",
author = {Mark Russinovich},
organization = {Rust Nation UK},
date = {2025-02-26},
url = {https://youtu.be/1VgptLwP588},
urldate = {2025-04-24},
}
@online{ms-vuln-70,
title = {A proactive approach to more secure code},
author = {Gavin Thomas},
organization = {{Microsoft - MSRC}},
type = "blog",
date = {2019-07-16},
url = {
https://msrc.microsoft.com/blog/2019/07/a-proactive-approach-to-more-secure-code/
},
urldate = {2025-04-24},
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- Do not edit this file with editors other than draw.io -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent; color-scheme: light dark;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="432px" height="267px" viewBox="-0.5 -0.5 432 267" content="&lt;mxfile host=&quot;app.diagrams.net&quot; agent=&quot;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0&quot; version=&quot;26.2.12&quot;&gt;&#10; &lt;diagram name=&quot;Page-1&quot; id=&quot;lOt5DuucHZqO-FceC0Nk&quot;&gt;&#10; &lt;mxGraphModel dx=&quot;598&quot; dy=&quot;967&quot; grid=&quot;1&quot; gridSize=&quot;10&quot; guides=&quot;1&quot; tooltips=&quot;1&quot; connect=&quot;1&quot; arrows=&quot;1&quot; fold=&quot;1&quot; page=&quot;1&quot; pageScale=&quot;1&quot; pageWidth=&quot;850&quot; pageHeight=&quot;1100&quot; math=&quot;0&quot; shadow=&quot;0&quot;&gt;&#10; &lt;root&gt;&#10; &lt;mxCell id=&quot;0&quot; /&gt;&#10; &lt;mxCell id=&quot;1&quot; parent=&quot;0&quot; /&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-6&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=none;startFill=0;dashed=1;startArrow=none;shadow=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontFamily=monospace;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;fKnSCGM_49d5ayVgUhBN-2&quot; target=&quot;fKnSCGM_49d5ayVgUhBN-12&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;170&quot; y=&quot;560&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-7&quot; value=&quot;Ethernet, MQTT&quot; style=&quot;edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=monospace;&quot; vertex=&quot;1&quot; connectable=&quot;0&quot; parent=&quot;fKnSCGM_49d5ayVgUhBN-6&quot;&gt;&#10; &lt;mxGeometry x=&quot;-0.2238&quot; y=&quot;-2&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;-16&quot; y=&quot;-8&quot; as=&quot;offset&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-9&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;fKnSCGM_49d5ayVgUhBN-2&quot; target=&quot;fKnSCGM_49d5ayVgUhBN-8&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-2&quot; value=&quot;Központi egység&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fontFamily=monospace;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;280&quot; y=&quot;515&quot; width=&quot;180&quot; height=&quot;90&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-8&quot; value=&quot;PIR mozgásérzékelők&quot; style=&quot;ellipse;whiteSpace=wrap;html=1;rounded=1;fontFamily=monospace;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;291.09&quot; y=&quot;340&quot; width=&quot;157.81&quot; height=&quot;70&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-12&quot; value=&quot;Home Assistant&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fontFamily=monospace;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;30&quot; y=&quot;530&quot; width=&quot;120&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-18&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;390&quot; y=&quot;515&quot; as=&quot;sourcePoint&quot; /&gt;&#10; &lt;mxPoint x=&quot;390&quot; y=&quot;409&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-19&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;355&quot; y=&quot;515&quot; as=&quot;sourcePoint&quot; /&gt;&#10; &lt;mxPoint x=&quot;355&quot; y=&quot;410&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-20&quot; value=&quot;...&quot; style=&quot;text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;365&quot; y=&quot;448&quot; width=&quot;30&quot; height=&quot;30&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-21&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;340&quot; y=&quot;515&quot; as=&quot;sourcePoint&quot; /&gt;&#10; &lt;mxPoint x=&quot;340&quot; y=&quot;408&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;/root&gt;&#10; &lt;/mxGraphModel&gt;&#10; &lt;/diagram&gt;&#10;&lt;/mxfile&gt;&#10;"><defs/><g><g data-cell-id="0"><g data-cell-id="1"><g data-cell-id="fKnSCGM_49d5ayVgUhBN-6"><g><path d="M 250 220 L 120 220" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-7"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 210px; margin-left: 184px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">Ethernet, MQTT</div></div></div></foreignObject><text x="184" y="214" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="11px" text-anchor="middle">Ethernet, MQTT</text></switch></g></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-9"><g><path d="M 340 175 L 339.99 70" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-2"><g><rect x="250" y="175" width="180" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 220px; margin-left: 251px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Központi egység</div></div></div></foreignObject><text x="340" y="224" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="12px" text-anchor="middle">Központi egység</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-8"><g><ellipse cx="339.99" cy="35" rx="78.905" ry="35" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 156px; height: 1px; padding-top: 35px; margin-left: 262px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">PIR mozgásérzékelők</div></div></div></foreignObject><text x="340" y="39" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="12px" text-anchor="middle">PIR mozgásérzékelők</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-12"><g><rect x="0" y="190" width="120" height="60" rx="9" ry="9" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 220px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Home Assistant</div></div></div></foreignObject><text x="60" y="224" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="12px" text-anchor="middle">Home Assistant</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-18"><g><path d="M 360 175 L 360 69" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-19"><g><path d="M 325 175 L 325 70" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-20"><g><rect x="335" y="108" width="30" height="30" fill="none" stroke="none" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 123px; margin-left: 350px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: nowrap; ">...</div></div></div></foreignObject><text x="350" y="127" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">...</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-21"><g><path d="M 310 175 L 310 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g></g></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent; color-scheme: light dark;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="431px" height="266px" viewBox="-0.5 -0.5 431 266" content="&lt;mxfile host=&quot;app.diagrams.net&quot; agent=&quot;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0&quot; version=&quot;26.2.13&quot;&gt;&#10; &lt;diagram name=&quot;Page-1&quot; id=&quot;lOt5DuucHZqO-FceC0Nk&quot;&gt;&#10; &lt;mxGraphModel dx=&quot;718&quot; dy=&quot;1160&quot; grid=&quot;1&quot; gridSize=&quot;10&quot; guides=&quot;1&quot; tooltips=&quot;1&quot; connect=&quot;1&quot; arrows=&quot;1&quot; fold=&quot;1&quot; page=&quot;1&quot; pageScale=&quot;1&quot; pageWidth=&quot;850&quot; pageHeight=&quot;1100&quot; math=&quot;0&quot; shadow=&quot;0&quot;&gt;&#10; &lt;root&gt;&#10; &lt;mxCell id=&quot;0&quot; /&gt;&#10; &lt;mxCell id=&quot;1&quot; parent=&quot;0&quot; /&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-6&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;endArrow=none;startFill=0;dashed=1;startArrow=none;shadow=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fontFamily=monospace;&quot; parent=&quot;1&quot; source=&quot;fKnSCGM_49d5ayVgUhBN-2&quot; target=&quot;fKnSCGM_49d5ayVgUhBN-12&quot; edge=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;170&quot; y=&quot;560&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-7&quot; value=&quot;Ethernet, MQTT&quot; style=&quot;edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontFamily=monospace;&quot; parent=&quot;fKnSCGM_49d5ayVgUhBN-6&quot; vertex=&quot;1&quot; connectable=&quot;0&quot;&gt;&#10; &lt;mxGeometry x=&quot;-0.2238&quot; y=&quot;-2&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;-16&quot; y=&quot;-8&quot; as=&quot;offset&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-9&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; parent=&quot;1&quot; source=&quot;fKnSCGM_49d5ayVgUhBN-2&quot; target=&quot;fKnSCGM_49d5ayVgUhBN-8&quot; edge=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-2&quot; value=&quot;Központi egység (ESP32)&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fontFamily=monospace;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;280&quot; y=&quot;515&quot; width=&quot;180&quot; height=&quot;90&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-8&quot; value=&quot;PIR mozgásérzékelők&quot; style=&quot;ellipse;whiteSpace=wrap;html=1;rounded=1;fontFamily=monospace;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;291.09&quot; y=&quot;340&quot; width=&quot;157.81&quot; height=&quot;70&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-12&quot; value=&quot;Home Assistant&quot; style=&quot;rounded=1;whiteSpace=wrap;html=1;fontFamily=monospace;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;30&quot; y=&quot;530&quot; width=&quot;120&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-18&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; parent=&quot;1&quot; edge=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;390&quot; y=&quot;515&quot; as=&quot;sourcePoint&quot; /&gt;&#10; &lt;mxPoint x=&quot;390&quot; y=&quot;409&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-19&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; parent=&quot;1&quot; edge=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;355&quot; y=&quot;515&quot; as=&quot;sourcePoint&quot; /&gt;&#10; &lt;mxPoint x=&quot;355&quot; y=&quot;410&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-20&quot; value=&quot;...&quot; style=&quot;text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10; &lt;mxGeometry x=&quot;365&quot; y=&quot;448&quot; width=&quot;30&quot; height=&quot;30&quot; as=&quot;geometry&quot; /&gt;&#10; &lt;/mxCell&gt;&#10; &lt;mxCell id=&quot;fKnSCGM_49d5ayVgUhBN-21&quot; value=&quot;&quot; style=&quot;edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;startFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;fontFamily=monospace;&quot; parent=&quot;1&quot; edge=&quot;1&quot;&gt;&#10; &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;&#10; &lt;mxPoint x=&quot;340&quot; y=&quot;515&quot; as=&quot;sourcePoint&quot; /&gt;&#10; &lt;mxPoint x=&quot;340&quot; y=&quot;408&quot; as=&quot;targetPoint&quot; /&gt;&#10; &lt;/mxGeometry&gt;&#10; &lt;/mxCell&gt;&#10; &lt;/root&gt;&#10; &lt;/mxGraphModel&gt;&#10; &lt;/diagram&gt;&#10;&lt;/mxfile&gt;&#10;"><defs/><g><g data-cell-id="0"><g data-cell-id="1"><g data-cell-id="fKnSCGM_49d5ayVgUhBN-6"><g><path d="M 250 220 L 120 220" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-7"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 211px; margin-left: 185px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">Ethernet, MQTT</div></div></div></foreignObject><text x="185" y="214" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="11px" text-anchor="middle">Ethernet, MQTT</text></switch></g></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-9"><g><path d="M 340 175 L 339.99 70" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-2"><g><rect x="250" y="175" width="180" height="90" rx="13.5" ry="13.5" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 220px; margin-left: 251px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Központi egység (ESP32)</div></div></div></foreignObject><text x="340" y="224" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="12px" text-anchor="middle">Központi egység (ESP32)</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-8"><g><ellipse cx="339.99" cy="35" rx="78.905" ry="35" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 156px; height: 1px; padding-top: 35px; margin-left: 262px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">PIR mozgásérzékelők</div></div></div></foreignObject><text x="340" y="39" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="12px" text-anchor="middle">PIR mozgásérzékelők</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-12"><g><rect x="0" y="190" width="120" height="60" rx="9" ry="9" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 220px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;monospace&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">Home Assistant</div></div></div></foreignObject><text x="60" y="224" fill="light-dark(#000000, #ffffff)" font-family="&quot;monospace&quot;" font-size="12px" text-anchor="middle">Home Assistant</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-18"><g><path d="M 360 175 L 360 69" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-19"><g><path d="M 325 175 L 325 70" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-20"><g><rect x="335" y="108" width="30" height="30" fill="none" stroke="none" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 123px; margin-left: 350px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: nowrap; ">...</div></div></div></foreignObject><text x="350" y="127" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">...</text></switch></g></g></g><g data-cell-id="fKnSCGM_49d5ayVgUhBN-21"><g><path d="M 310 175 L 310 68" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g></g></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment