Gyártósoron termék darab számlálás

Fórumok

Van egy palack gyártó üzem ahol a gyártósorokon van beépített darab számlálás. Viszont ez nem elégséges a termékek pontos követéséhez.
A soron másodpercenként 2-4 darab termék jön le, ennyit kell számolni.
Az lenne az elképzelés, hogy ESP-modulokkal a sori darab érzékelő jeleit kivezetve SQL-be küldve az adatokat (1 db , időpont), utána ebből webes felületű grafikonokat, és numerikus adatokat kéne megjeleníteni. 
A számolás ESP -modullal WiFi-n keresztül megoldható és ARDUINO IDE-ben írt (egyenlőre) MySQL-be közvetlenül író programmal.

De a félelmem az, hogy ha a gyárban lévő 12 gyártósor több pontjára (soronként 2-3 egység, mert a selejtet is szeretnénk követni, illetve a termékváltásnál a soron lévő puffert is kezelni) szerelt ESP-k annyira meg fogják terhelni az SQL szervert, hogy nem fogja bírni.
Ha jól számolok a 12 * 2 egység , másodpercenként 4 termék számolásánál eléggé megterheli , megterhelheti a szervert.

Kérdésem :
  1. Milyen SQL adatbázisban gondolkodjak (MySQL, PostgreSQL ,... ) ?
  2. Az SQL és a web szerver lehet-e , legyen-e egy gépen ?
  3. Webszervernek milyet (Apache, Nginx) ?
  4. Az ESP-k egyből az SQL-be írjanak, vagy inkább egy php -oldalt hívjanak meg és az írja az adatokat az SQL-be ?

Hozzászólások

Szerkesztve: 2021. 02. 04., cs – 17:12

Azt nézném meg, hogy milyen vezérlője van a gépnek? A darab számlálást a PLC-vel valósítanám meg, ha kell azokat kötném hálózatra.

Gondolom nem minden darab után akarsz adatbázis műveletet!?

Iparban az ilyen "kritikus" helyeken lévő eszközöket csakis kábellel kötünk össze ( Wifi fejeltős: csak a szívás van vele és megbízhatatlan).

Erre semmilyen "szoftveres" megoldás nincs, kicsit az "architektúrán" kell vátloztatni.

De létezik megoldás: RFID coin-tag ( fillérekbe kerűl nagy mennyiségben )
Mondjuk, minden palack kap egy ilyet még a gyártás legelején, ahogy megy tovább a gyártósoron, a RFID gépi-leolvasók segítségével nyomon lehet követni az aktuális állapotot.
A coin-tag -ket regisztrálni kell az adatbázisban, és ehhez rendelni az adatokat.

Ez még "offline" is működik, mert kézi leolvasóval is azonosítható a palack :)

A gyártó sor elején nem palack van hanem alluminium korong, ebből van kinyomva a palack.  A korongokat egy beszállító hozza tonnaszám...

Így az egyesével való "megjelölés" ne jöhet szóba. De úgy tűnik az ESP32-vel meg tudom oldani a dolgot.

A soron lévő infra érzékelők, amik a futószalagra van építve több helyen, adják a 24Voltos jelet. Ezt én egy Finder relén keresztül  kötöttem rá az ESP32-re. Ha elhalad a ternék az infra kapu előtt (eltakarja a fényt) , GND-re zár az ESP32 és növelem a számlálót. Szóval számol..

Az ESP32-re írt progi az aktuális számolt értéket kitesz a TCP 80-as portján futó webszerverre. Amíg nem nyit meg senki egy kapcsolatot a webszervere felé addig 1 másodpercenként kiírja az aktuális számolt darabot.  Az SQL-szerveren, ami a céges belső webszerver is, fut egy python script, ami CURL-al  ránéz 5 másodpercenként az ESP32-n futó weboldalra, amin az éppen összeszámolt darab érték van kiírva. Ezt az adatot pedig felírja az SQL adatbázisba. Még annyi , hogy az ESP32 -re kötve van egy RTC -modul (elemes real time clock), így a darabszámokkal kiirja a weboldalára azt az időpontot, amikor az a ternéket érzékelte, illetve a későbbi azonosítás miatt a saját IP-címét is.

Valami ilyesmit :
  ('2021-02-09 15:14:00',192.168.1.182','10'),('2021-02-09 15:14:01',192.168.1.182','9'),  ...

Ha az  ESP32 érzékeli, hogy valaki ránézett, és kiolvasa taz aktuális adatokat, törli a weboldalát és kiírja az adatokat, amíg megint rá nem néz valaki a 80-as web portjára..

Tehát az ESP32  számol, és egy másik gép (nálam maga az sql-szerver) kiolvas, és SQL-be ír.

Nagyjából ennyi ...

Biztos nem a legszebb megoldás, de úgy tűnik , működik.

Ha jól számolok az kb 1 hét várható működést jelentene ha eltekintenénk a kapcsolás gyorsaságától. Nem tűnik jó megoldásnak. Lehet, hogy túl fogja élni a hetet, mert általában ezek többet bírnak mint a speckó, de szinte biztos hogy nem fog évekig működni hiba nélkül.

Egy ilyesminek van elvileg tisztességesen megcsinált védett 24V bemenete, én ilyennel csinálnám, és Ethernetre kötném, azon nyomnám ki a kiementet, nem Wifin. Ez már ilyen fél-ipari minőség talán (sajnos nem vagyok HW szakértő): https://www.conrad.hu/hu/spsplc-vezerloegyseg-1224-vdc-controllino-maxi…

Ez nem relé, ez relé socket. Amibe kell még relé, 40-es sorozatú, ami ~10-100 ezer közötti kapcsolási élettartamú, de legalább olcsó és egyszerű cserélni.

Vagy úgy érted, hogy simán csak ezt a socket-et használod, mint csatlakozó?

töröltem

1920. augusztus 01. a Magyarországi Tanácsköztársaság vége.

1918. március 21. – 1920. augusztus 01. Magyarországi Szocialista Szövetséges Tanácsköztársaság.

Nagyon nagy történelmi bűn, hogy létrejöhetett Magyarországon, 1918-ban a tanácsköztársaság.

A PLC -vel az a gond, hogy nincs infója, hogy éppen milyen termék (cikkszám) van a soron. És a PLC jóval költségesebb, mint a feni elképzelés.

Illetve nem tudom, hogy a PLC -vel hogy lehetne on-line módon SQL-be írni adatokat. Itt nem is az ESP-WiFi-s eszközökkel lenne a gond, hanem a szerver résszel, hogy melyik az az adatbázis szerver, ami nem szakadna meg ilyen sok és gyors adat írástól. 

Ja és még közben ki kell szolgálnia a lekérdező oldalt is ami webes...

És a PLC jóval költségesebb, mint a feni elképzelés.

Azt gondolom, hogy ilyen környezetben a gépben van PLC.

 

Illetve nem tudom, hogy a PLC -vel hogy lehetne on-line módon SQL-be írni adatokat.

PLC-vel is lehet. Egyrészt létezik SQL Gateway, másrészt pl. Omron NX sorozatú gépvezérlők egy része tud SQL szerverrel kommunikálni: http://www.ia.omron.com/products/family/3698/specification.html

Azon kívűl számos lehetőség van kommunikációra, Omron esetén FINS, Sysmac Gateway, EthernetIP, Profinet, Modbus és persze az OPC server.

Szerintem meg kell nézni a beépített gépvezérlő lehetőségeit.

Szerkesztve: 2021. 02. 04., cs – 17:16

ha nagy a terheles az sql-nek, akkor en ugy csinalnam meg hogy lenne egy vegpont ahol nagyon gyorsan lefut egy program ami minden kerest letesz egy konyvtarba kulon-kulon fajlba, de lehet erzekelonkent es percenkent masik konyvtarat is hasznalni. cronbol pedig percenkent futna egy masik program ami felolvassa a konyvtar tartalmat, beszurja adatbazisba 1 inserttel, es letorli a fajlt. mivel ez naponta 8 640 000 rekord, azon is elgondolkoznek hogy minden egyes rekordra szuksegem van-e adatbazisban, vagy eleg egy percenkenti osszefoglalot eltenni mert az csak napi 1440 rekord.

neked aztan fura humorod van...

Hát ennek az egésznek másodperc pontosan kell adatokat szolgáltatnia, mert még a sor néhány másodperces megállását (illetve ha nem érkezik az érzékelőhöz termék mondjuk 2 másodperc után) is ézékelnie kell és jelezni a munkás részére, hogy gond van.

ja hogy ugy. akkor irnek egy olyan programot ami folyamatosan fut es tartja a kapcsolatot az erzekelokkel (hogy tudja melyik erzekelorol mikor erkezett az utolso adat, stb.) es a frontenddel server-sents-events-en keresztul, es ha a program azt erzekeli hogy a megadott idon belul nem erkezett adat az erzekelotol, akkor a frontendnek kuld egy esemenyt, amit az megjelenit. ha kesobbi elemzes celjabol el kell tenni az adatokat sql-be akkor azt is elteheti.

neked aztan fura humorod van...

Itt tartok :::

A soron lévő infra érzékelők, amik a futószalagra van építve több helyen, adják a 24Voltos jelet. Ezt én egy Finder relén keresztül  kötöttem rá az ESP32-re. Ha elhalad a ternék az infra kapu előtt (eltakarja a fényt) , GND-re zár az ESP32 és növelem a számlálót. Szóval számol..

Az ESP32-re írt progi az aktuális számolt értéket kitesz a TCP 80-as portján futó webszerverre. Amíg nem nyit meg senki egy kapcsolatot a webszervere felé addig 1 másodpercenként kiírja az aktuális számolt darabot.  Az SQL-szerveren, ami a céges belső webszerver is, fut egy python script, ami CURL-al  ránéz 5 másodpercenként az ESP32-n futó weboldalra, amin az éppen összeszámolt darab érték van kiírva. Ezt az adatot pedig felírja az SQL adatbázisba. Még annyi , hogy az ESP32 -re kötve van egy RTC -modul (elemes real time clock), így a darabszámokkal kiirja a weboldalára azt az időpontot, amikor az a ternéket érzékelte, illetve a későbbi azonosítás miatt a saját IP-címét is.

Valami ilyesmit :
  ('2021-02-09 15:14:00',192.168.1.182','10'),('2021-02-09 15:14:01',192.168.1.182','9'),  ...

Ha az  ESP32 érzékeli, hogy valaki ránézett, és kiolvasa taz aktuális adatokat, törli a weboldalát és kiírja az adatokat, amíg megint rá nem néz valaki a 80-as web portjára..

Tehát az ESP32  számol, és egy másik gép (nálam maga az sql-szerver) kiolvas, és SQL-be ír.

még a sor néhány másodperces megállását (illetve ha nem érkezik az érzékelőhöz termék mondjuk 2 másodperc után) is ézékelnie kell és jelezni a munkás részére, hogy gond van.

Az rendben van, de erre nem kell feltétlenül a számolásra használt SQL-t használni. Az ESP ügyesen tud egy teljesen más üzenetet küldeni egy másik gépnek, ami bekapcsolja a szirénát meg a légvédelmi reflektorokat.

Meg lehet csinálni sok módon, de nekem pont az jutott eszembe, hogy ez a riasztás teljesen olyan, mint amit nemrég összeraktam, ahol a home assistant fut egy Raspberry-n, vagy néhány ESP és MQTT-vel küldik az üzenetet, ha túl hideg van, túl meleg van, vagy akármi.

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

No akkor van egyszer a feladat a palack/s érték DB-de juttatása, és van egyszer a feladat, hogy nincs palack x ideig, akkor riasztani köll. Szépen válasszuk ketté a dolgot - a folyamatperiféria (hogy plc vagy arduino vagy józsinéni, aki a szalag mellett áll, miot mindegy) mérje a számlált események közti időt, és ha az nagyobb, mint egy beállított limit, akkor adjon egy inputot a naplózás és a megjelenítés felé, hogy x ideje nincs palack a soron.

Az ábrázolás felbontása szerintem önmagában egy optimumot ad az adatbeküldés gyakoriságára.

 

TFH

4000px szélesen ábrázolja a napi intervallumot, akkor 1 px 60*60*24/4000 sec vagyis 1 px 21.6 sec-enként egy szumma mennyiség elég.  Ez még csak a vizuális értelmezése az adatoknak.

Ezt oldottam meg könytárak és fájlok nélkül webesen most. GET-tel kiolvasom az ESP által eddig számolt darabokat 5 mp-ként. Az ESP ezt érzékeli, és törli a webszervere kimenetét és számol tovább, amíg megint rá nem lép a kiolvasó gép a TCP 80-as portjára a GET-tel ...  És így tovább.

Melyik adatbázis (MySQL esetén milyen adatbázis tipus, MySAM, InoDB)  lenne a legoptimálisabb ilyen sok és sűrű adatírás leviselésére ??

ezekre, a lenyeg hogy nem sql-en keresztul csinalnam az adatcseret, oda csak azt tennem el ami kesobbi elemzeshez is kell.

memcached - high-performance memory object caching system

php-memcached - memcached extension module for PHP, uses libmemcached

neked aztan fura humorod van...

Szerkesztve: 2021. 02. 04., cs – 17:52

Csak én érzem úgy, hogy ez teljesen rossz hozzáállás és eleve kapufa lesz?

Nem hinném, hogy tizedmásodpercenkénti egy-egy rekordos birizgálásra való az sql. Egyáltalán válaszol annyi idő alatt?
Mindenképpen kell valami batchelést használni, ami eltárolja (ha szükséges ) az időpontot, vonakódot egy - egy áthaladáshoz és valamekkora időnként küld fel egy adagot egyben. 
Egyáltalán képes az sql kérés ideje alatt számolni egy ilyen modul vagy addig blokkolva van más művelet? Lehet kell egy adatgyűjtő buffer és egy másik eszköz, ami kiolvassa és üríti a már kiolvasottakat, s továbbítja a szervernek.

Gyanítom, hogy teljesen irreális elvárás a valós idejű megjelenítés. Eleve nem is lehetséges sql és webszerverekkel. Pár másodpercenként is bőven jó, ha kiértékelődnek, nem rakétasiló ez. Az adatok meglétéhez, a pontos időpontokhoz nem kell realtime feldolgozás.

Pedig létezik ilyen megoldás, mert láttam élőben.  ESP32 -re kötött érzékelőkkel küldik fel a szerverre az adatokat és elég on-line, mert amikor a soron a termékek között 2 másodperc szünet volt, ki is írta a frontenden, hogy nem érzékel terméket. Amikor jött a következő, akkor el is tűnt a figyelmeztetés.

A darab számlálás is elég szinkronban volt...
 

Ez volt az a megoldás ::
https://www.dropbox.com/s/n2e8tixyvv4moqr/kdpafkfhoecbeehl.png?dl=0
https://www.dropbox.com/s/jxabnavri9s6kj7/oilppnhacakfpoib.png?dl=0

CSak elég drágán adják, ezért gondoltam megcsinálom házon belül...

OEE, Hatékonyság, Állásidő, Minőség számlálót kb. 10 perc alatt össze lehet rakni LAD-ban, amit meg lehet jeleníteni HMI-n, SCADA-ban stb. vagy fel lehet küldeni hálózatra. Pénzben is csak annyi, amennyi a PLC programozó munkabér költsége arra a pár órára amíg megírja. Nem értem miért kell OEE-t realtime megjeleníteni, azt műszakokra szokták kimutatni.

PostgreSql segítségével, megfelelő adatbázis kialakítással és tábla "darabolással" minden további nélkül megoldható, ez nem nagyon sok adat. 

Viszont jól megtervezni csak a teljes kép ismeretében lehet.

Ha jól számolok a 12 * 2 egység , másodpercenként 4 termék számolásánál eléggé megterheli , megterhelheti a szervert.

Lófaszt terheli, miért, min fut kávédarálón? Nehogy már 100 tps sok legyen...

per gyártósor. Aqua Lorenzo nem kisüzem. :)

Oszt? Ez miben befolyásolja, hogy 100 tps lófasz egy SQL szervernek?

Ami "megterheli" az a válaszidő. 1-1 put-ra minimum 200ms elmegy. Vagyis 5 termk per mp az elméleti maximum.

Egyrészt mert még nem találták fel az aszinkron kommunikációt, ugye?

Másrészt, ha 200 ms elmegy egy írására, akkor ott valami komoly probléma van, keresni kellene egy hozzáértő DBA-t és/vagy kirúgni a meglévőt.

Csináltál már ilyen sűrű mintavételezést és adat továbbítást?

Igen, több tízezer tps is gond nélkül ment már, átlagos hardveren 2000-3000 req/sec is gond nélkül elérhető.

Szerintem próbáld ki, hamar rájössz, hogy 24/7 OSI-modellel használhatatlan egy kis beágyazott rendszerrel. 

Aham, akkor én túlmentem a lehetetlenen... többször is. Legközelebb jobban meg kell néznem, hogy miért sikerült.

ps.:én próbáltam, hamar összeomlik

Nézd, lehet, hogy a te szaktudásoddal van baj...

Egyrészt igazad van, hogy ez a terhelés még évekig tartó adatmegőrzési időkkel is fenntarthatóan működtethető lehet.

Viszont azért volnánk mérnökök, hogy ha tervezünk egy rendszert, akkor az ne fogyasszon többeszerszeres erőforrást, mint amit a feladathoz feltétlenül kell. A nagy_peter által javasolt 5 percenkénti összegséssel a bejegyzések száma 1200-ad része lesz az általad javasoltnak, tehát az ezres nagyságrendű becslés helytálló lehet.

Még ha esetleg az elemzés eredménye az is lesz, hogy ebben az esetben olcsóbb a vas, mint a mérnökóra, és nem érdemes optimalizálni, akkor sem felesleges legalább belegondolni, hogy az adott problémának mi volna a vas szempontjából optimális megoldása. A posztoló nagyon jól érezte, hogy a megoldása messze nem optimális, és feleslegesen tekeri a DB-t.

Lehet hogy valamit félreértek, de ennél szarabbul megírni még én se tudtam, meg kb. ilyesmi lehet a terv:

echo "truncate table t00;" | mysql blogv3
for Rec in $(seq 1 1000);
do
        ID=${Rec};
        Count=1
        Date=$(date "+%Y-%m-%d %H:%M:%S")
        echo "insert into t00 (id, count, date) values (${ID}, ${Count}, '${Date}');" | mysql blogv3
done

Direkt egy olyan gépen, amin eleve lassú minden is:

root@db0:~# time ./load.sh

real    0m15.826s
user    0m7.065s
sys     0m5.117s

Az itthoni aprószerveren:

root@db0:~# time ./load.sh

real    0m15.485s
user    0m4.723s
sys     0m2.999s

Raspberryn most nincs kéznél mysql, szóval azon nem tudom megnézni, meg "a szerver" eléggé aluldefiniált, de imho egy terheléses tesztet megérne.

Túl sok réteg és a hálózat terheltsége exponenciális robbanás lesz.

Mi a lófasz?

Ilyen adatmennyiséget  ami ugye ahány adat annyi kapcsolat lehet utp-n továbbitani csak nem osi-n, hanem direktbe biteket olvasva.

Milyen adatmennyiség? 24-36 darab valami küld másodpercenként 4 valamit. Ismét: ez lófasz, se nem nagy adatmennyiség, se nem nagy forgalom.

Ahány adat itt annyi kapcsolat értelmezésem szerint . 

Oszt? Ha direkt magunkkal való kibaszásból nem MQTT-t használunk, hanem HTTP-t, ahol szintén magunkkal való direkt kibaszásból nem keep-alive a kapcsolat, akkor se sok másodpercenként 4 adat küldése.

Ha meg a szerveren direkt magunkkal való kibaszásból szinkron megvárjuk, amíg a geo-cluster egy másik kontinensen beírja az adatot (akkor járunk ugyanis 200ms körül) és nem egy helyi message queue cluster kapja meg és jegyzi fel <2ms alatt, akkor sincs még gond.

Persze, minden el lehet baszni, ha az ember nem ért hozzá.

Nem az adat mennyiség a sok, hanem a kapcsolat mennyisége.

Az a 24-36 darab? Nyilván sok lesz.

Aham, ez a legkevésbé cizellált ág, de még ebben is bőven tudna kell, mert még mindig nyomorult 24-36 kapcsolatról beszélünk és nyomorult 4 adatról másodpercenként. És 2021 van nem 1991. Az IoT eszköz a küldő oldalon van, tud küldeni nyomorult 4 adatot másodpercenként.

A legtöbb egyszálon futó programnyelvnél, http kapcsolat esetén amíg nincs válasz áll a process. Én erre mondtam, hogy nem fogja bírni és ezt fenntartom, mert ezt tapasztaltam. Ha http-n akar küldeni adatot, akkor nem jó ötlet 1mp alá menni.

Nem azt mondtam, hogy a feladat megoldhatatlan, hanem azt ahogyan ki van írva úgy nem fog működni. lásd poszt.

A legtöbb egyszálon futó programnyelvnél, http kapcsolat esetén amíg nincs válasz áll a process. Én erre mondtam, hogy nem fogja bírni és ezt fenntartom, mert ezt tapasztaltam. Ha http-n akar küldeni adatot, akkor nem jó ötlet 1mp alá menni.

Létezik async HTTP, azt is feltalálták már, nem kell megvárni a választ, keep-alive kapcsolat, tolod be az adatot és nem várod a választ, hanem olvasod időnként, hogy van-e válasz.

Nem azt mondtam, hogy a feladat megoldhatatlan, hanem azt ahogyan ki van írva úgy nem fog működni. lásd poszt.

Onnan indultunk, hogy sok-e 100 tps szerver oldalon. Lófaszt sok. Sok-e hálózati oldalon. Lófaszt sok. Problémás-e kliens oldalon. Lófaszt problémás. Lehet szarul csinálni? Hogyne lehetne.

Szerkesztve: 2021. 02. 04., cs – 19:23

A realtime megjelenítést és az adatok eltárolását/archiválását lehet külön választanám.

Érzékelő -> Queue -> Frontend service -> Webclient
                 \-> Backend service -> DB

A Webkliens meghívja a Frontend service-t és felépít egy WebSocket kapcsolatot hogy azon keresztül kapja meg a megjelenítendő adatot. A frontend service hideg indítás esetén lekéri az utolsó X perc / óra adatmennyiségét és eltárolja memóriában. A Queue által szolgáltatott adatot a Frontend service memóriába menti FIFO collection alapon managelve a memória használatot.

A másik irányban a Queue által szolgáltatott adatot a Backend service egy bizonyos (pl. 100-1000) darabszámig memóriában tárolja, majd egy batchben kiírja az adatbázisba.

Én valószínüleg valahogy így állnék neki. Persze mivel az adatok DB-be írása batchelve történik, ezért szerver leállás esetén elveszhet valamennyi historikus adat (pl. utolsó 1-2 perc adata), de kérdés, hogy ez mekkora gond.

Én is ilyesmit csinálnék.

Amivel kiegészíteném:

Ha tényleg minden munkadarabról minden adat kell tizedmásodpercenként, akkor sem kötelező munkadarabonként egy DB bejegyzést csinálni: 99.9%-ban úgyis minden bejegyzés egyforma lesz, az lesz benne, hogy OK, meg egy sorszám+időbélyeg. A sorszám és az időbélyeg is pici növekményű sorozatok. Ezért binárisan nagyon jól tömöríthető (például delta tömörítés+variable length encoding), 100-asával, 1000-esével, és azt már simán elbír egy kávédaráló is tranzakciószámmal. (Nem kell ágyúval lőni verébre ugyebár.) De azt mondanám, hogy hibátlan esetben bőven elég lehet annyi, hogy mai napon 10:13 és 10:14 között a 123456789-től 123466789 sorszámig gurultak le a munkadarabok. Továbbmenve, elég lehet csak a normáltól eltérő eseményeket tárolni - magyarul a hibákat - , illetve időnként mintavételezve 1-1 sorszám-időbélyeg összerendelést, a többi utólag kiszámítható, mivel maga a gép periodikusan idővezérelten működik.

Na meg az sem mindegy, hogy mennyi adatot kell backupolni, azért is érdemes lehet ilyen tömörebb formában tárolni az eseményeket, nem csak a beíráskori terhelések miatt.

Jól értem, hogy attól félsz, hogy a mySQL nem fog tudni megbírkózni másodpercenként kb. 144 insert utasítással?

Egyfelől ezt letesztelném. Létesítség 144 alkalommal kapcsolatot, küldjél be egy insertet, zárd le! Nézd meg, hogy bírja-e ezt perceken / órákon át! Létesíts 36 párhuzamos kapcsolatot, és mindegyikben kezdd el tolni az insert utasításokat és nézd meg, hogy mittudomén 10 perc alatt mennyit sikerült beküldeni tranzakció lezárással Látni fogod, hogy mennyit bír másodpercenként.

MySQL-t nem ismerem, de Oracle alatt (több, mint 20 évvel ezelőtt) mi azt csináltuk, hogy egyfelől nem építettünk fel új kapcsolatot minden utasítás beküldéséhez, mert a kapcsolat felépítése lassú és megterhelő volt, hanem megnyitotta az eszköz a kapcsolatot és aztán csak fosta be az SQL utasításokat. Másfelől nem egyesével toltunk volna mondjuk 144 insert utasítást, hanem tömböt használva összegyűjtöttünk egy adagnyi bemenő adatot és akkor egy utasításban ment be mondjuk néhány száz vagy ezer rekord. Pl. neked a mérőeszközeid is csinálhatják azt, hogy gyűjtik az időpontokat, számokat, és mondjuk percenként egyszer felküldi, hogy akkor az előző felküldés óta volt 210 esemény.

Csodálkoznék, ha percenként 36 insert utasítást nem bírna lekezelni egy mai szerver.

disclaimer: ha valamit beidéztem és alá írtam valamit, akkor a válaszom a beidézett szövegre vonatkozik és nem mindenféle más, random dolgokra.

Szerkesztve: 2021. 02. 04., cs – 21:01

Fisher  kollága scriptjét futtattam két gépen (egy linux asztali gépről, és egy Banana PI-ről nem localhostban) párhuzamosan, és úgy látom
gépenként 3-4 record íródik MySQL -be másodpercenként..
Holnap futtatom még több gépen egyszerre és meglátom hogy megy...

Érzésem szerint bírni fogja ...

A linux gépeken eléri a 20-25 recordot is másodpercenként, de a Banana Pi M1 (UTP - Giga) -en fixen 3 record / másodperc .
Tehát a kliens sebessége (cpu, RAM) nagyban befolyásolja az SQL-be írást , ezek szerint ..

Holnap letesztelem ESP32 modullal (WiFi)  is.

http -n ??  mysql paranccsal írom a rekordokat bash -ből ..  Vagy mire gondolsz ?

Na most átírtam a scriptben hogy 10000 recordot írjon...  

A Banana PI-n most is 3 és 4  record/s szinte felváltva , a linux-os I7 gépemen 34-37 record/s. 

Ugye amit írtam, az direkt sebesült, kb. csak jobban lehet megírni. Pl. az, hogy minden alkalommal indítja a klienst, belép, majd nyom egy insertet, az... hááát... szóval rosszabbat nem tudtam kitalálni. Esélyes, hogy a valódi implementáció azért kevésbé agyhalott (én pl. abszolút nem ilyen irányba indulnék).

#!/bin/bash

##echo "truncate table t00;" | mysql blogv3 -h192.168.168.6 -ublogv3
let i=0;
for Rec in $(seq 1 1000);
do
        ID=${Rec};
        ##Count=1
        let i=$i+1;
        Date=$(date "+%Y-%m-%d %H:%M:%S")
        adat=$adat"(${ID}, '${Date}', '53')"
        if [ "$i" != "20" ]; then
            adat=$adat",";
        fi
        if [ "$i" -eq "20" ]; then
            adat=$adat";";
            echo "insert into t00 (count, date, gep) values $adat" | mysql blogv3 -h192.168.168.6 -ublogv3
            let i=0;
            echo $adat;
            adat="";
        fi
done

Így a Banana PI -n 12-38 record / mp...   

real    0m22.326s
user    0m13.520s
sys    0m2.110s
 

A legegyszerűbb az lenne, hogy ha egyszer belépne és utána olvasná az inputról:

echo "truncate table t00;" | mysql blogv3
for Rec in $(seq 1 1000);
do
        ID=${Rec};
        Count=1
        Date=$(date "+%Y-%m-%d %H:%M:%S")
        echo "insert into t00 (id, count, date) values (${ID}, ${Count}, '${Date}');"
done| mysql blogv3

Így ugye a mysql indítása nem probléma:

root@db0:~# time ./load.sh

real    0m7.883s
user    0m0.974s
sys     0m0.453s

Ezen még kb. csak javítani lehet, pl. úgy, ahogy csináltad, hogy nem egyenként csapatni az inserteket, hanem akár darabszám, akár eltelt idő alapján összevárni és úgy bepattintani a db-be egy inserttel 1-1000-valamennyi rekordot.

De abban mindenképp igaza van Oregonnak, hogy ez így fogjuk rá hogy megoldás helyben/localhoston. Hálózaton át, 7x24-ben ez így... hehe.

Ahogy írták: külön kéne választani az "azonnali" beavatkozást igénylő dolgokat azoktól, amik kibírnak mondjuk egy egyperces késést. Nem vagyok nagy mq fan, de akár még az is megoldás lehet. Illetve felteszem a "gyári" megoldás esetén fejlesztettek saját bigyót, ami kb. a nc|tee funkcionalitást tudja (a konkrét igényeket nem ismerem, pl. hogy a kliens vár-e egy visszajelzést a szervertől hogy megkapta-e a "pinget", de az azért nem nagy puki megírni kb. bármiben).

Jaja: https://hup.hu/comment/2585396#comment-2585396

De ha jól értem, akkor alap elvárás, hogy ha egy palack elhalad, akkor "azonnal" legyen nyoma, és van egy viszonylag rövid idő (pár másodperc), ami után már hiba (vagy a lehetősége) van a soron.

Szóval pont erről van szó. Nem az az elsődleges probléma, hogy nem lehet egy adatbázisba viszonylag gyorsan viszonylag sok adatot bepattintani.

"De ha jól értem, akkor alap elvárás, hogy ha egy palack elhalad, akkor "azonnal" legyen nyoma, és van egy viszonylag rövid idő (pár másodperc), ami után már hiba (vagy a lehetősége) van a soron."

ha birja az sql akkor lehet abban is az adatcsere nem kerdes, ha nem birja akkor fajlrendszeren vagy memoriaban csinalnam

bar a napi 8.6millio rekord idovel lehet hogy kezelhetetlen lesz, en anno syslogot tettem sql-be, de mar leszoktam rola :)

neked aztan fura humorod van...

Igazság szerint az se kérdés, hogy a DB bírja-e. Gyanús volt nekem, és nem bírtam olyan rosszul megírni, hogy ne bírja. De én ugye nem vagyok fejlesztő.

Az se kérdéses, hogy külön-külön a komponensek bírják (kliens, szerver, network, storage). De én már láttam olyat, hogy amikor összerakták a külön-külön jól működő dolgokat, akkor egyszer csak kiderült, hogy van, amikor mégse.

Ez az egész, amit írtál egy tök egyszerű feladat, csak le kell vetkőzni a web programozói vénát, mivel webes eszközökkel nem lehet ezt a feladatot jól megoldani. A webes eszközök nem valós idejű és időkritikus alkalmazásokra készültek, a kommunikációjuk ehhez lassú. Jellemzően a szkript és GS-s nyelvek is lassúak és kiszámíthatatlanok valós idejű és idő kritikus rendszerek készítéséhez (szóval php-t és társait is buktad).

Amit szerintem tenned kell:

  1.  megnézed, hogy a jelenleg gyártósorban lévő plc-kből lekérdezhető-e a kívánt adat. Ha nem akkor csinálsz rá valami érzékelőt, de valószínűleg a jelenlegi rendszer is képes lehet rá.
  2. Az adatokat begyűjtöd (akár a gyártósori PLC-ről, akár érzékelőről) és valamilyen kompakt programmal beszórod egy dinamikus memória tömbbe bináris formában. Ugyan itt értékeled ki (közel valós időben) a bejövő adatokat, illetve valósítod meg ez alapján a szükséges riasztási eseményeket. Továbbá a memóriában gyűlő adatokat (amiket már kiértékeltél és csak historikusak) bulkban letoldod valami tárolóra. Akár bármilyen SQL szerverre is hatékonyan leküldhető. Ez lesz az első réteged. Ha old-school vagy ezt megírod C-ben, ha nagyon modern akarsz lenni, akkor mondjuk rustban, ha villamos mérnök vagy, akkor meg ladderben (létra) PLC-re. 
  3. Most előveszed az általad állandóan emlegetett web szervert, php-t, és a többi lassú kacatot, amikben csinálsz még egy front-endet, ami a vezetés által igényelt színes-szagos grafikonokat és riportokat legenerálja az elmetett adatok alapján.

Az architektúra lényege: a számlálást és a beavatkozást (mivel ezek idő kritikus dolgok) megcsinálod egy gyors kompakt rendszerben. A begyűjtött adatokat pedig elmented későbbi felhasználásra. Az elmetett adatok alapján pedig a webes szerveren megvalósíthatod a színes szagos de lassú dolgokat. Így szétválaszthatod a számlálás és a hiba esetén történő gyors beavatkozást (jelzést, a kezelő fele) a számlálás eredményeként keletkező statisztikáktól és nyomon követési adatoktól. Az előbbi idő kritikus (ha lemaradsz a darabról, már nem tudod megszámolni), az utóbbi meg ráér, csak túl sok adatot mozgat (a managernek tök mindegy, hogy egy cache rebild miatt két másodperccel később jön meg a riport). Ez egyben azt is jelenti, hogy az alsó rétegnek a lehető legegyszerűbbnek és butábbnak kell lennie. Neki nem kell tudnia, hogy milyen darabot gyártotok, elég azt hogy jön a darab és mennyi, illetve nem jön, pedig kéne (hibajelzés). Az összes többi adatot (pl.: melyik gyártósor mikor mit gyárt) a felsőbb rétegben rakod mellé.

Zavard össze a világot: mosolyogj hétfőn.

Szerkesztve: 2021. 02. 04., cs – 22:10

Graphite, vagy Influxdb, Grafanában meg szép grafikonokat is összerakhatsz. SQL messze nem a legjobb erre.

Szerkesztve: 2021. 02. 05., p – 00:37

Ahogy én csinálnám.

 

Tipikusan MQTT feladat, mission critical szempontból:

a, ha fontos a rendelkezésre állás, akkor EMQX, tud cluster, van retention policy meg rengeteg plugin, használom pár helyen, agyonverhetetlen, Erlang és kell alá erőforrás,

b, ha nem fontos, akkor Mosquitto, egyszerű, mint a faék, mindenre is van, minden is ismeri.

 

A kliensek MQTT-n küldenek adatokat, mission critical szempontból:

a, ha fontos a rendelkezésre állás, akkor várnak MQTT-n egy ACK-ot a szervertől, addig tárolják és ismétlik a küldést

b, ha nem fontos a rendelkezésre állás, akkor tolják be az adatot, fire-and-forget

 

Szerveren meg figyel valami MQTT-n, mission critical szempontból:

a, ha fontos a rendelkezésre állás, akkor valami cluster cucc, ami adatbázis cluster-be ment, lehet Halálcsillag-design pattern,

b, NodeRed-ben össze tudod kattintani, hogy mit hova tegyen, és teszi oda.

 

Rajtad áll, hogy mennyire készülsz fel a hibákra, de ahogy látom, ez egy nice-to-have dolog, ha megállt, akkor meg van állva. Ha meg a vezetőség rájön, hogy mégis fasza cucc, akkor lásd a, pontok és pénztárca nyitogatás. Nyilván a dobozos cucc nem azért drága, mert kevés munkával sokat keresnek rajta.

Szerkesztve: 2021. 02. 05., p – 02:34

Gondoltam tesztelek egy picit én is, direkt elkövettem az összes dolgot amit mindenki említett, hogy szar, vagyis:

  • http
  • Hálózat (magyar mobilnet -> németország) - 30-50ms ping a két végpont között
  • Nem egy kövér vas, faék VPS (1 mag / 1GB ram / MySQL és fut egy csomó dolog még, szóval nem mind volt az övé)
  • ab -vel terhelve (mert tökéletes példája a szar kliens oldalnak :D, ennél csak jobb benchmark eszköz létezik)

Endpoint: szimpla get hívás, last_insert_id -vel tér vissza, egy hívás egy insert

Tábla: InnoDB BIGINT id (autoincrement, primary uniqe btree index, hogy a MySQL se unatkozzon), BIGINT count, DATETTIME date

Minden teszt 10000 request, különböző concurrency level-el, a tesztek között direkt nem nyomtam truncate-et, hogy hízzon az index:

- Concurrency level: 15 / Requests per second: 159.89 / Time per request: 93.815

- Concurrency level: 25 / Requests per second: 255.94 / Time per request: 97.680

- Concurrency level: 50 / Requests per second: 413.43 / Time per request: 120.939

- Concurrency level: 100 / Requests per second: 741.91 / Time per request: 134.787

- Concurrency level: 250 / Requests per second: 661.94 / Time per request: 377.678

Ugyanez, faék táblával, autoincrement és index nélkül:

- Concurrency level: 15 / Requests per second: 157.48 / Time per request: 95.249

- Concurrency level: 25 / Requests per second: 263.22 / Time per request: 97.411

- Concurrency level: 50 / Requests per second: 458.19 / Time per request: 109.124

- Concurrency level: 100 / Requests per second: 706.84 / Time per request: 141.476

- Concurrency level: 250 / Requests per second: 647.78 / Time per request: 385.933

Érdekes hogy index nélkül picit lassabb.

Pici kiegészítéssel (1 másodpercnyi request-et összevárva):

- Concurrency level: 50 / Requests per second: 468.19 / Time per request: 106.744

- Concurrency level: 250 / Requests per second: 1309.52 / Time per request: 190.909

De hogy megnézzük mit megy az SQL ha picit gondosabban nyúlok hozzá:

  • 1 query = 1 insert / összesen 1000 insert
  • connection pool (30 connection-el)
  • a mért időben benne van a csatlakozás is

Eredmény:

real    0m2.018s
user    0m0.069s
sys     0m0.086s

Az előbbi kód, csak minimális cache-t szimulálva, 1 query = 50 insert, összesen 1000 query (50000 insert), eredmény:

real    0m3.310s
user    0m0.105s
sys     0m0.076s

Ugyan ez, csak 1 query = 500 insert, összesen 1000 query (500000 insert), eredmény

real    0m11.249s
user    0m0.162s
sys     0m0.211s

Beraktam 6000000 sort a táblába és az előbbi teszt újra:

real    0m12.124s
user    0m0.176s
sys     0m0.221s

// Happy debugging, suckers
#define true (rand() > 10)

Igény volt, hogy öt évig online kell tartani? Nem láttam.

Amúgy meg egy kis adatbázis szervezéssel az is megoldható: napi ~8 millió sor, havonta ~250 millió, havonta új tábla, régire egy maintenance, index le, index vissza, aztán meg úgyis csak olvasni kell belőle. Ha kevés a storage, akkor ki kell exportálni vagy archiválni egyben, aztán kalap-kabát.

Persze, mindenre is van megoldás akár mysql-ben is, de csak kerülgetjük a problémát, nem megoldjuk.

Szerintem még mindig ott tartunk, hogy 100 tps simán elérhető és 250 millió sort egy táblában meg bármi képes kezelni, továbbra se látom azt, hogy csilliárd pénzből vett erőforrás kellene alá... pláne, hogy ez egy szabadidős projekt, nem egy négy-kilences ERP.

250M sort bármi képes kezelni, jah, amíg csak írni kell bele. 
Ettől ez még nem lesz jó architektúra.

Hó végén mennyivel lesz lassabb mint hó elején?
És ha egyszer nem fut le az archív?

Ha jól láttam ez nem egy szabadidős projekt, hanem gyártás.

zászló, zászló, szív

250M sort bármi képes kezelni, jah, amíg csak írni kell bele. Ettől ez még nem lesz jó architektúra.

Tényleg sírni fogok lassan. Mi a lófasztól lenne sok egy táblában ~250 millió sor? Ráadásul van benne gyakorlatilag egy timestamp meg egy id, ami még memóriában is elfér egyben. Ha még mellé teszünk pár dolgot, akkor se lesz több az egész havi adat mint 8 GB... amennyi memória azért már lassan egy telefonban is van.

Hó végén mennyivel lesz lassabb mint hó elején? És ha egyszer nem fut le az archív?

...és ha ráesik a meteor, valóban, arra sem gondoltam még.

Ha jól láttam ez nem egy szabadidős projekt, hanem gyártás.

A gyártás mintha menne enélkül is, úgy vettem ki. Ha meg gyártás, akkor egy kicsit tágabbra kell nyitni a pénztárcát, mert akkor nem ESP8266 küldi az adatot egy kávéfőzőnek, ami SD kártyára menti, és akkor ismét ott tartunk, hogy lófasz feladat.

De, oké, feladom, kezelhetetlenül kurva sok a 100 tps és kezelhetetlenül kurva sok lesz egy hónap adata. Jó így?

A darabszámokat nem kell 5 évig tárolni.. Minek ??  Ha a megrendelt mennyiség le van gyártva, elvitte a vevő, nincs rá többet szükség.

Nem ez alapján számláznk..  Ez csak a vezetőknek kell,   hogy on-line lássák, hogy mennyire van kihasználva a gyártósor, mennyi termék jön le, esetleg egy adott soron mely részen hány (félkész)termék van éppen.  Tehát max 14 napig érdekes az adat. Utána törölhető is, dátum alapján.

Pont a count AFAIK egy tree indexszel gyors volna. Szerintem a részfákon tárolja, hogy hány elem van alatta (a fa balanszolás miatt kell is), és ezért a count indexelt tartományokra gyors kell hogy legyen. (Disclaimer: Inkább csak elvi szakértő vagyok, egyébként keveset adatbázisozok.)

(Biztos elég kreatív vagy a feladat megoldásához, de ha netán felmerül benned, hogy túlvállaltad magad, szerintem vonj be valakit, aki ilyesmivel foglalkozik. Kevesebb lesz a lóvéd, cserébe tanulsz és nem lesz elbaszva a projekt. Az ügyfél elégedett lesz, és ajánl másoknak. A bevont szakértővel való kapcsolat is hasznos lehet a jövőben.)

:)

Szerkesztve: 2021. 02. 05., p – 12:20

A lóvém a bérem. Itt vagyok rendszergazda, a munkaidőmből kitelik .. Már csináltam hasonló projektet , de kíváncsi voltam, hogy ki mit szól az eddigi elgondolásomhoz, megoldásomhoz. 

Persze , lehet szebben és okosabban csinálni , de alapvetően a megoldásom működőképes lehet.

Itt még a ESP32 Wifi-s egységet kell letesztelnem, hogy mit bír ezügyben mint érzékelő-kliens. A bulk insert ezért jó ötlet. Illetve a SSE (Server Sent Events) tetszik, ezt még beleépítem a  projektbe  a megjelenítésnél.

Aztán hatósági vagy vevői audit/felülvizsgálatkor stb. alkalmával, majd elcsodálkozik a auditor, hogy "mi az a kütyü ami ott lóg a gépen"... aztán ír egy "Nem megfelelő" minősítést. Utána meg hosszú hónapokig fogtok meetingelni arról, hogy miként lehetne levágni a cuccot a gépről, időtervet fogsz csinálni, az auditort fogod virtuálisan kényeztetni heti rendszerességgel... A tömeggyártásban használt gépet nem lehet adhoc átalakítani, illetve a változás bevezetésének előírt folyamata van. Súlyos eltérésnél akár visszavonhatják a gyár ISO, IATF, mindenlófasz engedélyét...

ha tetszik a server-sent-events, akkor azt tudnod kell hogy csatlakozaskor elindul es a tovabbiakban folyamatosan futni fog egy apache-php process, ameddig a php max_execution_time engedi, utana leall, amikor a bongeszo ezt eszreveszi automatikusan indit egy uj kerest. a php max_execution_time legyen olyan nagy amikor mar nem lesz zavaro ez a kis leallas. ezen kivul egy vegtelen ciklusban kell lekerned az adatokat hogy kell-e esemenyt kuldened a frontendnek, az usleep-el tudod szabalyozni hogy milyen gyakran nezz ra az adatokra es hogy mennyi cput hasznaljon.

neked aztan fura humorod van...

Ipari automatizálással ezek szerint nem foglalkoztál. Még. Ez a feladat ugyanis nem "Linuxrendszergazdakevésa2GBmobilnet" szint - nem véletlenül okítják külön az ilyen jellegű szakembereket (mérés- és automatizálási mérnök), mert egészen más eszközkészlettel és megközelítéssel kell az ilyen feladatoknak nekilátni.

így van. aztán majd jönnek a meglepetések a ESP-vel, ha hirtelen nincs jel meg lyukak lesznek az adatbázisban.

Ahogy fentebb többen is írták, a jelet a PLC-böl kell kiszedni. Ha ez nem lehetséges, akkor kell egy MQTT-t tudó fejegység (~400€ lista áron) meg egy 24V DC-s bemenet, mert ugye valamivel fizikálisan is el kell végezni a számlálást. Itt egy fénysorompóra gondoltam, amit az áthaladó palack megszakít. Ennek a bemeneti jelét feltolni MQTT-n egy LAN-on futó message brokerbe, amire illetszhetsz python-on vagy Node-Red-en keresztül egy klienst, ami pedig tolja a jelet InfluxDB-be (time series database, pont ERRE való) és nem MySQL-be. Onnan meg Grafana-n keresztül elkészíted a grafikont és egyben Grafana-ban az értesítést is meg tudod csinálni, pl. Telegram, MS Teams, Google Hangouts, Threema, Discord, stb-re. Én Telegram-ra küldöm és egyböl egy kis képernyökép is érkezik az üzenetben, amiböl egyböl látod mi a hiba.

A message broker-töl elvileg hazai pálya kéne legyen neked, ha admin vagy. Itt az adattárolásra stb. egy általad üzemeltetett linux/BSD rendszert használhatsz, aminek már nincs köze az ipari automatizáláshoz. De a "Shop floor" (gyártósor) szintre megfelelö céleszközt kell betenni.

na mivel érdekelt a dolog, megnéztem Node-Red, InfluxDB és Grafana kombóban. az elején 250ms-ként küldtem be egy értéket utána meg 100ms-ként, ez látszik a görbén. Beraktam hozzá egy telegramos értesítést is, ami így néz ki (képernyökép nincs az üzenetben, hiányzik épp az  a kiterjesztés). Mindezt egy RPI4-esen, Node-Red, InfluxDB és Grafana mind egy-egy docker konténerben fut, IOTstack installációból.
Node-Red-ben Modbus_TCP-vel vagy más módon hozzá tudsz férni a PLC adataihoz, vagy oda kell még egy célezköz + szenzor a számláláshoz.

Ha lenne a cégnek ilyen embere, biztos rá bízták volna.. De nincs. Ezért én vagyok annyira rugalmas, hogy rám bizták. Ha nem akarnak pluszba embert felvenni és nekem többet fizetni, akkor én oldom meg , mert meg kell.  Ennyi. Senki nem annyira mazohista, csak én, úgy látszik ..

Szerkesztve: 2021. 02. 05., p – 22:19

Mindenki a szoftveroldalon ragadt le.

 

Az erzekelok milyenek? Azt is te rakod ossze? Mivel erzekeled az uvegeket? Egyaltalan a palack az uveg, vagy muanyag?

A lotty befolyasolja az erzekelest? A selejt erzekeles mit takar?

 

Egyebkent a hardveroldalon vagy maradsz plc vonalon, vagy addig pakolgatod a kutyuidet, amig a 4-5bol egy tuti mukodik adott idopillanatban:))

Amugy plc+barmilyen halozat vagy barmilyen HMI ultraszopas. Komolyan, mintha visszamennel az idoben 50 evet.

Amikor ilyet kellett csinalnom, akkor a plc soros porton adta ki magabol az adatot garantalt valaszidovel, es volt egy linux gateway, ami a soros portot feltette ethernetre, es kommunikalt a szerverrel. Ilyen linux gateway egyebkent a gyar minden gepe mellett volt. De akkor meg nem volt se raspberry pi, se semmilyen sbc, igy az egy minipc volt, talan hp, x86 processzorral.

 

Amugy lattam ipari pc-vel polcrakodot (silot) megvalositva. Lehidaltam mekkora kokany. Pedig nemzetkozi multi. Eleve valami 15 percig bootolt az "ipari pc". Ahh, nem is folytatom. MSSql-be pakolta az adatot, volt valami bus interface daemon a windowsban (talan modbus?), uh, igazi kokany. Virusirto letiltva, de ugyanakkor tavoli bejelentkezes engedelyezve, ahol finnorszagbol a "mernokok" tudjak debuggolni, de a gyar halozatan keresztul.  Papir volt rola, abbol nem volt hiany. Audit is, meg mindenfele minosites. Csak neha megallt:) De a papir az volt.

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Mindenki a szoftveroldalon ragadt le.

Az erzekelok milyenek? Azt is te rakod ossze? Mivel erzekeled az uvegeket? Egyaltalan a palack az uveg, vagy muanyag?

lásd 3-al feljebb....a palack és a folyadék anyagára a tipp viszont nem rossz.

Egyebkent a hardveroldalon vagy maradsz plc vonalon, vagy addig pakolgatod a kutyuidet, amig a 4-5bol egy tuti mukodik adott idopillanatban:))

így van.

Amugy plc+barmilyen halozat vagy barmilyen HMI ultraszopas. Komolyan, mintha visszamennel az idoben 50 evet.

azért úgy látom vannak némi hiányosságaid a mai PLC-kröl...nem csak Siemens létezik...van amelyik már direkt a PLC-böl tud MySQL/Postgres/MongoDB/InfluxDB-be direkt írni...de mivel a topicindító egy 2$-os eszközzel készült neki állni, egy ~700€-s PLC-t már meg se mertem említeni.

Virusirto letiltva, de ugyanakkor tavoli bejelentkezes engedelyezve

Write filter, Whitelisting mond valamit? Bár kétlem, hogy ott alkalmazták volna, de ezekkel a beállításokkal felesleges vírusírtóval lassítani vagy akár tönkretenni a rendszert

> lásd 3-al feljebb....a palack és a folyadék anyagára a tipp viszont nem rossz.

 

Itt melyik hozzaszolasra gondolsz, a tiedre? Ott csak egy optoerzekelot emlitesz. Vajon a selejtet hogyan allapitod meg? Egyaltalan mi a selejt?

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Par eve meg leteztek olyan ipari celu alaplapok, aminek volt ISA slotja. Direkt korulneztem (egyik celfotos kamerahoz ISA kartya van, es felmerult, mi lesz, ha megdoglik). Egy keresest talan meg meger. Illetve azt is celszeru lenne megvizsgalni, hogy a hozza tartozo celprogram fut-e barmin, ami az NT-nel kicsivel ujabb (mondjuk XP). Illetve leteznek USB-s atalakitok is.

A strange game. The only winning move is not to play. How about a nice game of chess?

Ma is kapható ISA-s cucc. Például az Advantech ráállt az ilyen klasszikus ipari kártyákat fogadó alaplapokra annó és a mai napig van utánpótlás.
Érdekes felépítés: passzív ISA buszos backplane + egyik slotjába dugott CPU soc-kártya.

Aztán megjelentek olyan passzív backplane-ek, ahol van PCI busz és van ISA busz is.
Ezekbe ilyen CPU kártya kell. Ezeknek van PCI része és van ISA része. Ne feledjük, a backplane mindössze passzív NYÁK csatlakozókkal, így később nem PC-t cserélsz, csak CPU kártyát.

Itt a teljes CPU kártya kínálat a passzív backplane-ekhez:
    https://www.advantech.com/products/single-board-computers/sub_871df718-…

Szerkesztve: 2021. 02. 05., p – 23:49

Ez ipari feladat, akkor kicsit mások az elvárások és mások az eszközök (lehet buherálni, de jót még nem hozott)

A rendszer elemei:

I. Terepi rész:

  1. Pl. Siemens S7-1200 PLC - a legkisebb típus is 6db nagy sebességű számlálóval rendelkezik (3db 100kHz és 3db 30kHz). S7-1200 már tud Ethernet TC/IP-t vagy akár Modbus TCP.
  2. kapcsoló érzékelők: termék anyagától függően: optikai (fotó elektromos), induktív, kapacitív, ultrahangos.

II. PC rész (adat tárolás feldolgozás):

  Egy OPC-UA Server (OPC, Open Platform Communications  Unified Architecture) – a PLC-vel a kapcsolat és valós idejű adatok olvasása. OPC szerver van free (windows/linux).

III. Megjelenítési: ez szabadon választott, időcímkével ellátott adatsorral, amit akarsz pl. grafikon és vagy  dashborad

Fejlesztés lehet java, python, c++, (windows esetén .NET).

Cégek jobban szeretik a standard megoldásokat, mint az egyedi kivitelezést – lehet bármilyen szellemes.

Ilyen kérdések lesznek: Elromlik, hogy lesz pótolva és mikor? Elmegy a fejlesztő – ki fogja módosítani?

Ezzel egy új szakmát is megtanulsz..

1920. augusztus 01. a Magyarországi Tanácsköztársaság vége.

1918. március 21. – 1920. augusztus 01. Magyarországi Szocialista Szövetséges Tanácsköztársaság.

Nagyon nagy történelmi bűn, hogy létrejöhetett Magyarországon, 1918-ban a tanácsköztársaság.

Ilyen kérdések lesznek: Elromlik, hogy lesz pótolva és mikor? Elmegy a fejlesztő – ki fogja módosítani?

 

Egy cegtol vasarolt cuccnal pontosan ugyanezek a kerdesek, altalaban megspekelve, hogy minden az o szellemi termeke (kapcsolasi rajz, miegyeb)

 

A lenyegi kulonbseg mindosszesen annyi, hogy minel nagyobb egy ceg, annal valoszinubb, hogy itt lesz 5-10 ev mulva is, es lehet menni hozza az eladott termeke kapcsan. Mig ha tenylegesen egy ember csinalta, lehet hamarabb meghal.

 

Neha elokerul egy-egy sztori egy ilyen titanrol, aki 40 eve csinalt egy kozponti futesvezerlest iskolanak commodore-on, es most keresnek hardvert, mert beadta a kulcsot a hardware. Megprobalom eloasni a linket. De mindig van egy-egy ilyen.

 

edit: https://www.youtube.com/watch?v=oLERL4_SveI

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Csak a 30 éves működő fűtésvezérlő kapcsán: arra tippelek, hogy anno ez teljesen jó és az akkori thechnikai szintvonalnak megfelelő volt, amikor eredetileg készült. Viszont abból, hogy ebay-ről guberálnak ősi használt eszközöket, arra következtetnék, hogy nagyon túlszabályozott lehet jogilag ez és ezért kénytelenek pontosan ugyanazzal az eszközzel helyettesíteni a meghibásodott példányokat. Mert az van engedélyeztetve és lehet millió dollárokba kerülne újra engedélyeztetni valamit. Még az eredeti megoldás kapcsán is ma már sokféle modern helyettesítő ezköz van, ami képes pontosan emulálni a kivénhedt vasat. 170 millió dolláros pályázattal cserénék le a vezérlőt... 

Csak azért írtam, mert ez nem feltétlen ugyanaz, mint hogy most valaki kevés hozzáértéssel összerak valamit saját kútfőből. Lehet azt is jól csinálni, de akkor jól kell csinálni (dokumentálástól kezdve a megfelelő módszerek használatán át). Az kerület iskoláinak fűtését vezérlő rendszer simán lehetett komoly, kereskedelmi a maga idejében.

igen bíznak a cégben, hogy 10-20év  múlva is meg lesz. Egy PLC-vel megvalósított cucc standardnak mondható - egy egyedi áramkörhöz képest..

láttam már műgyantával kiöntött áramkört, vagy felírat nélküli IC-ket, mert lecsiszolták és olyat is hogy IC lábai át voltak hajtogatva, mert hasával felfelé volt beforrasztva (lehet, hogy csak elbaszták a filmet és nem akartak új nyákot csinálni :-)

PLC-hez kiegészítés:

Siemens S7-1500 -hoz van szoftver, ami közvetlenül SQL szerverbe tud adatot tolni (MSSQL, MariaDB, PostgreSQL) - csak eléggé drága 2200eur/PLC a lite 670eur - így akkor nem kell OPC szerver.

30éves fűtés vezérlés Amigával.. az már akkor is gányolás volt: Allan-Bradley, akkori PLC-i is meg tudták volna csinálni - vagy nem vezérlésre, hanem data loggernek vagy megjelenítőnek lett volna értelme Amigát/PC-t használni. felhasználni..

1920. augusztus 01. a Magyarországi Tanácsköztársaság vége.

1918. március 21. – 1920. augusztus 01. Magyarországi Szocialista Szövetséges Tanácsköztársaság.

Nagyon nagy történelmi bűn, hogy létrejöhetett Magyarországon, 1918-ban a tanácsköztársaság.

igen bíznak a cégben, hogy 10-20év  múlva is meg lesz

Volt nekem egy projektem ahol 25 éves S7 200-asok lecserélése volt a cél. Megvették az S7 1200-as CPU-kat, elkészültek a programok is rá, és vagy 5-8 éve várják a karbantartók hogy végre kipurcanjon egy 200-as. A CPU-k ipari körülmények között mennek ~25 éve és nem akarnak megdögleni. Hasonló strapabírók az OMRON és Modicon PLC-k is. Az AB-t nem ismerem sajnos, de az is megbízható márka hírében áll.

Ez egy Népszava vezér cikk volt valamikor ?

- bocs, irónia / szarkazmus bekapcsolt nálam..

1920. augusztus 01. a Magyarországi Tanácsköztársaság vége.

1918. március 21. – 1920. augusztus 01. Magyarországi Szocialista Szövetséges Tanácsköztársaság.

Nagyon nagy történelmi bűn, hogy létrejöhetett Magyarországon, 1918-ban a tanácsköztársaság.

Nekem van egy 10 éves, működő fűtésvezérlésem.
Fűtést, hűtést, HMV-t tud. 
Nincs baja, akár percenként tud kapcsolni.
OneWire alapú, már jócskán elavult.  Néhány éve megcsináltam, azóta van MQTT interfésze is, mert már akkor nyílt rendszerben gondolkoztam.

A központi 1043ND megbízhatóságán őszintén csodálkozom :) 

Az MQTT-vel megoldottam azt az absztrakciót ami a zavartalan upgrade-hez szükséges, már meg is vannak az új eszközök amik ugyanazt a funkciót ellátják (relék). A 10 éves eszközökhöz képest fillérekből.

Alapvetően nem az eszközválasztással van baj, hanem a rétegezéssel.
Ha nincsenek meg jól a rétegek nem nagyon lehet nyílt rendszert csinálni.
Ha nincs nyílt rendszer akkor szívás a csere, szívás az upgrade.

zászló, zászló, szív

Ja ...  Csak ezeken a gépeken nincs PLC.  Venni nem fognak.  "Levente, old meg! , És legyen szép, szagos  és  grafikon is kell, hogy lássam, melyik gép megy vagy nem megy éppen most !!"   <<  Ügyvezető mondata.

Egyenlőre ez van :  https://www.dropbox.com/s/g5iejz5aca2lsnf/cblnccjhjcfoegod.png?dl=0

és a plusz igények - ha működik a rendszer:

- tudja vezérelni a futószalagot vagy állítsa meg, ha x dolog teljesül..

Újra olvasva , amit írtál:

1.) "..van beépített darab számlálás. Viszont ez nem elégséges a termékek pontos követéséhez."

     Mééé ? akkor az szar - eladták x millióért és te x/1000 -ből csinálni akarsz jobbat ?

2.) SQL teljesítmény kérdésed: "...Ha jól számolok a 12 * 2 egység , másodpercenként 4 termék számolásánál eléggé megterheli , megterhelheti a szervert."

milyen vason ?? - nekünk 36ezer gép kliens küldi - véletlenszerűen - de a konkurens hozzáférés 2-4ezer /ms - persze nem SQL szerverhez - van előtte proxy, feldolgozás, memcache - rabbitMQ cluster stb..

messages queue - nélkül nem célszerű ilyen rendszereket csinálni..

1920. augusztus 01. a Magyarországi Tanácsköztársaság vége.

1918. március 21. – 1920. augusztus 01. Magyarországi Szocialista Szövetséges Tanácsköztársaság.

Nagyon nagy történelmi bűn, hogy létrejöhetett Magyarországon, 1918-ban a tanácsköztársaság.

Ja, és még egy: minek kell ide SQL? Ha belegondolsz az adatok simán lineárisan keletkeznek, egyetlen fájlba bele lehet írni sorfolytonosan. Mivel sorszámok és idő alapján van értelme visszakeresni, mindkettőre könnyen lehet bináris keresést csinálni.

Ezt az adatmennyiséget az első szériás Ráspoly is simán elbírja. De jobbat mondok! SD kártya foglalalttal megcsinálom Arduinóra is (fájlrendszer nélkül, direktben lehet loggolni SD kártyára minden cellát pontosan egyszer írva: sosem megy tönkre!). És még az sem lesz túlterhelve!

Biztos hogy nem sql-el csinálnám. Ez a pattern sokkal inkább event streaming.

Ha "brutál nagyban" gondolkozunk akkor kafka. Ha nem olyan nagyban akkor mqtt. Ide az mqtt is elég.

Nemrég - nem szándékosan - sikerült lemérnem mennyit tud egy esp8266 mqtt-n kitolni (bele egy odroid c4-be).

Nagyjából 15ezer mqtt üzenet ment át másodpercenként, az mqtt nézegető nem bírta a terhelést a másik oldalon :)

Az a jó az mqtt-ben hogy szinte semmi memória nem kell neki és miután az üzenetet kivetted belőle, az nyomtalanul eltűnik.

És az mqtt-nek mindegy hogy hányan "hallgatják" az adott queue-t.

Erre tehát építhetsz x monitoringot (én a képernyőre mondjuk angular-os vagy reactos klienssel raknám ki, az csak a klienst eszi).

Meg egy másik klienssel sql-be írogathatod ha akarod, ettől tök függetlenül.

Ha akarod az esp-ből két mqtt-be is beírhatod, meg is van a redundanciád rögtön.

zászló, zászló, szív

Én erre egy InfluxDB-t használnék.

Van is Arduino connector-a ha kell: https://docs.influxdata.com/influxdb/v1.8/tools/api_client_libraries/#arduino

Azt pont ilyen dolgokra találták ki.

Nagyon jól kezeli az ilyen jellegű dolgokat.

Minden insert kap egy timestamp-et és nagyon jó támogatás van arra, hogy adott idő alatt mennyi adat keletkezett.

https://docs.influxdata.com/influxdb/v1.8/query_language/explore-data/#group-query-results-into-12-minute-intervals

Megejelenítésre pedig van megoldás a stack-ben. Chronograf-Telegraf-os megoldás. 

https://docs.influxdata.com/chronograf/v1.8/guides/create-a-dashboard/

https://docs.influxdata.com/platform/monitoring/influxdata-platform/monitoring-dashboards/

Amiben már gyakorlati tapasztalatom van, az az, hogy a hasonló módszerrel működő számlálók használhatatlanul nagy adatbázist eredményeznek rövid időn belül. Egy soron másodpercenként 2-4 palack (számoljunk 3-al), 12 gyártósoron másodipercenként 36 sor az adatbázisban.

Ez, ha 24 órában megy a termelés, akkor 24*60*60*12*3, azaz 3 110 400 rekord naponta. Egy közepesen erős gépen 100 millió sorra a count már simán lehet 3 másodperc, 1 milliárd sorra pedig 30 másodperc.
Ezzel a tempóval pedig a 100 millió sort elérheted 32 nap alatt, az 1 milliárdot is az első évben, tehát 1 éven belül a rendszer már lassabban fog tudni neked információt adni, mint ha csak 30 másodpercenként írnál egy sort a táblába, hogy az előző 30 másodpercben mennyi volt a termelés. Arról nem is beszélve, hogy a sok GB-os táblával minden művelet nehézkesebb.

Szerintem sokkal jobban jársz, ha az ESP-ken RAM-ban számolod, hogy mennyi palack ment át, és mondjuk 5 percenként küldöd fel SQL-be az előző 5 perc termelését. Cserébe inkább az ESP-n fut valami algoritmus, ami egy másik táblába bejegyez egy sort, ha mondjuk több, mint 2 másodperce nem ment el előtte palack. Így a hibát 2 másodpercen belül detektálhatod, az adatbázis mérte pedig évekig nem lesz szűk keresztmetszet, és 5 percenként 12 insertet még egy Raspberry Pi is elvisel terhelésként. A hibákat feljegyző táblában pedig minden új sor egyből triggerelhet valami eseményt, így nem is kell másodpercenként lekérni, hogy mikor volt legutóbb hiba, és mégis azonnal értesülhetsz róla. Plusz pontos, és könnyen lekérhető hibanaplód lesz.

Nagy Péter

+1: ha belegondolunk a tábla a sorszámokkal, és időbélyegekkel iskolapéldája lenne az adat VS információ kérdéskörnek: adat az amit pénzbe kerül tárolni. Információ pedig ami hasznot hajt az adat.

Ez a tábla tele lenne egységnyi növekményű számokkal, ránézésre egy nagy halom redundancia az egész. Ezzel szemben áll az a nagy_peter által javasolt formátum, amiben csak a szummázott értékek, illetve a különleges események vannak benne. Az összes plusz információtartalma pedig annyi volna, hogy a gyártást irányító PLC-nek az óra kristálya milyen minta szerint tér el a loggolást végző PC órájától. Tehát hacsak nincsen valami számszerű mérési eredmény, amit mindenképpen tárolni kell palackonként, akkor ennek az óriási táblának a plusz üzleti értéke 0 lesz a tömörített változathoz képest. Viszont a backupja és évekig őrizgetése (feltéve, hogy szükséges), runtime vas alápakolása égetni fogja a pénzt.

Ha palackonként kellene mérési eredményeket is tárolni - például egy nyomáspróba értékét, ami egy zajjal terhelt bináris érték, tehát mindenképpen palackonként keletkezik valami adat, akkor is az a jó megoldás, hogy az értékeket binárisan egymás után írjuk (akár delta kódolással, ha van értelme), és ezeket a bináris blobokat mentjük az adatbázisba például 5 perces sorozatonként egy bejegyzébe.

Ha viszont palackonként csak valami kategória érték keletkezik (OK, NOK, kategória I, kategória II, stb), akkor ezeket már érdemes elemezni, hogy milyen eloszlás szerint jönnek, és aszerint tömöríteni. Például nyilván egy soron a darabok túlnyomó többsége OK lesz, ezért csak a NOK-okat kell tárolni. Vagy az eseményt, amikor OK->NOK vagy NOK->OK átmenet van.

az óriási táblának a plusz üzleti értéke 0 lesz a tömörített változathoz képest

Ahm, itt is látszik egy vízválasztó a mentalitásban.

Azért érdemes mindent is letárolni, mert akkor az adathalmazra rá lehet engedni gépi tanulást, ami mondjuk előre tudja jelezni, hogy meg fog hibásodni egy gyártósor, mert olyan mintával jönnek egymás után a termékek és/vagy a selejt arány adott minta szerint változik, sőt, akár azt is, hogy milyen hiba fog bekövetkezni. A storage olcsó, itt nyers adatokból ~64 MB keletkezik naponta felső becsléssel, veszteségmentes tömörítés nélkül is évente ~20 GB adat, ami lófasz mennyiség, szó szerint fillérekbe kerül még geo-mentéssel együtt is (ez a 20 GB konkrétan nagyjából bruttó ezer forint). A benne lévő adatok pedig aranyat is érhetnek, ha sikerül kiszedni összefüggéseket, amelyek leállásokat előznek meg.

Nyilván a jelen helyzetben ettől fényévekre van a kérdező, de ez egy teljesen más történet.

Hát, fontos megjegyezni, hogy én a kérdésben feltett feladatra próbáltam megoldást találni, ott sehol nem volt szó arról, hogy bármi mesterséges intelligencia figyelné a bejövő adatsort, inkább csak a mindenkor naprakész gyártási mennyiség figyelése volt a feladat, semmi előjelzés nem volt benne. Az pedig, hogy egy kijelzőn megjelenjen az elmúlt órában az adott gépsoron legyártott üvegek száma, esetleg az eltérés az elvárt mennyiségtől, vagy a selejt aránya, felesleges minden üveget egyesével rögzíteni.

Előjelzéshez is mondjuk az ESP-n gyűjteném fel az adatokat legalább 1 percen át, mire átadnám a DB szervernek, de akkor eleve a a két üveg közt eltelt időt és a gyártás eredményét írnám fel, mint sem az időbélyegzőket minden üveghez; illetve ott valószínűleg érdemes lenne más adatokat is rögzíteni a gyártott üvegekről. 

Abban viszont egyetértek, hogy ha van szándék az adatok további feldolgozására is, akkor teljesen jogos, amit írtál, több adatból pontosabb előrejelzés készíthető.
Az ML terén viszont nem vagyok elég jártas, eddig csak egyetlen helyen használtam. Ott viszont a MongoDB sokkal jobb választás volt, mint az SQL, hogy ki tudjam szolgálni adattal.

Nagy Péter

Én csak annyit írtam, hogy a feladat kapcsán egy darab legolcsóbb szerver vason fut MySQL/MariaDB is el kell viselje a terhelést, akár éveken át, ha kicsit is értelmesebb az adatok szervezése, akkor meg pláne.

Ne optimalizáljunk előre, a legegyszerűbbtől induljunk el és akkor változtassunk, amikor már fáj, hogy egyszerű.

A feladat jobb esetben ott kezdődik, hogy valaki megfoglamazza, hogy mi a valódi feladat. Itt már sokan elbuknak, mert mindenféle nem valós igényt és téves elvárásokat támasztanak. Aztán azt is rosszul valósítják meg és a végén nagy öröm van, hogy jaj éppen elmegy, amíg minden ideális. Aztán pár hét múlva meg mikor fejreáll az egész, akkor kitalálják, hogy nagyobb szerverek kellenek. Közben meg két nagyon egyszerű cél volna, jelezzen, ha baj van, legyen forgalom statisztika. Nem pedig űrrakéta milisec alapú vezérlése.

Én nem is azt vitattam egy percig sem, hogy az írást nem fogja elfogadni, hanem azt, hogy a ~100 millió sor táblánként akkor is összejön egy év alatt, ha minden gyártósor külön táblát kap. 
Márpedig 100 millió soron a count egy táblán simán eltart 2-3 másodpercig, így eléggé lelassulhat a felület egy év után. Nyilván kezelhető, optimalizálható, tucatnyi megoldást tudok rá én is, csak arra akartam felhívni a figyelmet, hogy ameddig csak a palackok számolása a feladat, addig felesleges egy Raspberry PI-nél nagyobb kapacitású gépet alá rakni, mert minimális optimalizálással azon is megoldható a feladat.

3 palackkal számolva egy gyártósoron minden palackra bejegyzés: 365*24*60*60*3 = 94 608 000 sor

Ugyanez 1 percenként reportolva: 365*24*60 = 525 600 sor

Ugyanez 5 percenként reportolva: 365*24*60/5 = 105 120 sor

Tehát az eredeti adatmennyiség 0.01%-nak eltárolásával is szinte azonos adatszolgáltatást tudunk adni éves, havi, heti, napi, műszakonkénti, óránkénti, vagy 5 perces bontásban, a meghibásodást pedig ugyanolyan gyorsan képes jelezni. 

Az aláírásodban szereplő linkből kiindulva gondolom pontosan tudod, hogy egy ESP32 mennyivel komplexebb feladatot is képes ellátni, mint amiről itt szó van, már így is nagyon le van egyszerűsítve a feladat. (szerintem egyetlen ESP32-vel is meg lehetne oldani mind a 12 gyártósor számolását + a 12 selejt futószalagon a számolást, plusz az egész napi adatot tudná tárolni a feladásig, ha 5 perces bontásban gyűjtöd szalagonként)

Nagy Péter

Márpedig 100 millió soron a count egy táblán simán eltart 2-3 másodpercig, így eléggé lelassulhat a felület egy év után.

Miért tartana? Ha nem is particionáljuk (és miért ne tennénk?), akkor is elfér memóriában, szégyen lenne, ha ilyen sokáig tartana egy lekérdezés. Ha 100 millió soron és ennyire kevés adaton 2-3 másodperc egy count, akkor ki kell rúgni a DBA-t és/vagy az architect-et.

Az aláírásodban szereplő linkből kiindulva gondolom pontosan tudod, hogy egy ESP32 mennyivel komplexebb feladatot is képes ellátni, mint amiről itt szó van, már így is nagyon le van egyszerűsítve a feladat.

Alapvetően felhős adattárolást szolgáltatok, szóval a másik oldallal is tisztában vagyok. Illetve nem egy ennél nagyobb forgalomra tervezett backend melóban vettem részt, példának okáért, mint kicsit jobban ismert dolog, az ÁNYK-ból való közvetlen doksifeltöltés szerver oldalát én csináltam, és nem ez volt a legnagyobb terhelésű munkám...

ok, és utána Influx-ban vagy Mongo-ban is, pls. Ez egy új paradigma amit el kéne fogadni, hogy ezeket az adatokat nem fogják soha többet módosítani/manipulálni ezért (sincs) szükség a klasszikus DB-rendszerekre. InfluxDB mint time series adatbázis pont ilyenre lett kitalálva, (egyszerre) nagy mennyiségü adatot mindig egy idöponttal összekapcsolva.

aztán vannak a "hibridek" mint a CrateDB, ami azt igéri, jól kombinálja a relacionális adatbázist "idösoros" adatokkal.

itt még egy poszt aminek kiváncsi leszek a második részere

Ez igaz, ha megvan az adat, akkor bármikor lehet elemzést futtatni rajta. Az általunk javasolt megoldás is meg tudja őrizni az utolsó tizedesjegyig is az információt, ha a sorszámot tartományként, az időbélyeget pedig kétszer differenciált szériaként tároljuk, akkor 16 bájt helyett kb 2 bájton bejegyzésenként átlagban, ráadásul a hozzátartozó tranzakciószám és index (ilyen kis bejegyzéseknél az index mérete összemérhető lesz az adatokéval) is sokkal kisebb lesz, az egész rendszer sokkal reszponzívabban tud működni. De belátom, hogy ezekkel a számokkal lényegében mindegy. Ezért kell a költségeket kielemezni. Elsőre szerintem valahol elnéztem egy nagyságrendet, mert nekem nagyobb számok jöttek ki.

Abban igazad van hogy érdemes lehet ezeket a cuccokat letárolni és ML-t ráengedni, tök jó feladat.

Az egyik tipikus fail big data projektek kapcsán a nem megfelelő eszközválasztás.

Az SQL adatbázis pont nem tűnik ide jó választásnak. A time series db (influxdb) sokkal inkább.

zászló, zászló, szív

Igazából nem az ML miatt érdemes tárolni, hanem azért, mert az a legegyszerűbb, hogy jön, leteszem. Ha nem kell kidobom, ha mégis kell, akkor meg ott van. Semmilyen szempontból nem túl sok az adat.

Az SQL adatbázis pont nem tűnik ide jó választásnak. A time series db (influxdb) sokkal inkább.

Ennyi adatnál teljesen jó még az SQL, pláne, hogy egyszerű eszközökkel ingyen lehet cluster-t építeni, az Influx cluster meg eléggé zsebbe nyúlós dolog, mert az ingyenesnél nincs se cluster, se HA.

azért érdemes mindent is letárolni, mert akkor az adathalmazra rá lehet engedni gépi tanulást, ami mondjuk előre tudja jelezni, hogy meg fog hibásodni egy gyártósor,

Meghibásodás előjelzését járulékos szenzorok telepítésével szokták vizsgálni: rezgés diagnosztika, hőmérséklet, áram stb. érzékelők telepítésével. Így jószerivel a meghibásodás tényét tudod detektálni.

Meghibásodás előjelzését járulékos szenzorok telepítésével szokták vizsgálni: rezgés diagnosztika, hőmérséklet, áram stb. érzékelők telepítésével.

És mivel régen úgy szokták, ezért aztán új dolgokat nem lehet használni, ugye?

Így jószerivel a meghibásodás tényét tudod detektálni.

Olvass kicsit utána a failure prediction témának machine learning tekintetében.

Lazán kapcsolódik a témához, a napokban jelent meg erről egy hír: https://bitport.hu/speci-mikrofonokkal-es-mi-vel-javitanak-a-hajszalpontos-sinkanszen-pontossagan

Ezt nem ellenérvnek szánom, el tudom képzelni, hogy mindkét módon lehet meghibásodást előre jelezni, csupán érdekességként írom.

Nagy Péter

Hogyne, minél több adat van, annál könnyebb összefüggéseket keresni közöttük, de meglepő összefüggéseket tudnak kihozni ezek a gépi tanulások, néha olyan adatsorból is, aminek látszólag nincs köze a problémához. Az előnye az, hogy jóval kevesebb szenzorból lehet jósolni a meghibásodást, ha pedig minden szenzor mérése rögzítve van, akkor a múltbeli meghibásodásokat megelőző adatokból tanítható egy algoritmus arra, hogy keresse ezt a mintát a valós idejű adatokban.

Mégis mire ülteted rá az AI-t? Egy metronomiai adatra? Azzal a hagyományos logika is megbirkózik.

Egy kicsit komplexebb dolog ez ennél, sokszor nem algoritmizálható, vagy sokkal több idő lenne algoritmizálni.

Ezért írtam, hogy ez egy mentalitásbeli vízválasztó, ahogy volt ez például a mechanikus - elektromos, a relé - elektroncső, az elektroncső - félvezető, illetve legutóbb a wired - programmable kapcsán, most épp ott tartunk, hogy a deep learning, machine learning és a többi dolog áll szemben azzal, hogy megírjuk a programot és viszonylag pontosan tudjuk, hogy mikor-mire-mit fog csinálni.

Van egy olyan érzésem, hogy te erről az Industrial 4.0 dologról vagy kompletten lemaradtál vagy pedig faszságnak tartod az egészet.

"Van egy olyan érzésem, hogy te erről az Industrial 4.0 dologról vagy kompletten lemaradtál vagy pedig faszságnak tartod az egészet."

2017 óta felelek egy viszonylag nagy gyárban a digitalizációért, inkább úgy mondanám hogy szívtam vele eleget...

Alapvetően nem az IO, NIO számlálók fognak meghibásodást előjelezni, hanem az a sok másik paraméter (kezdve a hőmérséklettől, a páratartalomig, egészen a gépkezelő fizetésnapjának a jövőbeli távolságától).

Gépi tanulást egy olyan nagy adatbázisra érdemes ráengedni, aminek felépítésének és életben tartásának költségei erősen rontják a befektetési kedvet .

Nálunk a menedzserek csak rövid időtávlatban gondolkodnak: ami 1 éven belül nem térül meg az mindig elbukik a CAR jóváhagyási folyamatában. Ennek oka, hogy egy átlagos menedzseri karrier hossza egy multi telephelyén max. 3 év, és senki sem akar az utódjának befektetni.

Ezért az Ipar 4.0 kb. gyártási adatok nyomonkövetésben, és egy elfogadható SCADA rendszerben kb. meg is áll, világszerte minden telephelyen.

2017 óta felelek egy viszonylag nagy gyárban a digitalizációért, inkább úgy mondanám hogy szívtam vele eleget...

Hát, lehet, hogy nem a közvetlen szakterületed...

Gépi tanulást egy olyan nagy adatbázisra érdemes ráengedni, aminek felépítésének és életben tartásának költségei erősen rontják a befektetési kedvet .

A gépi tanulást bármilyen kicsi adatbázisra is rá lehet engedni, nincs olyan, hogy mikortól éri meg, ott tartunk, hogy lassan IP kamerát nem tudsz venni tanítható ML/MV nélkül.

Nálunk a menedzserek csak rövid időtávlatban gondolkodnak: ami 1 éven belül nem térül meg az mindig elbukik a CAR jóváhagyási folyamatában. Ennek oka, hogy egy átlagos menedzseri karrier hossza egy multi telephelyén max. 3 év, és senki sem akar az utódjának befektetni.

Hogyne, a menedzsmentnél is van pár vízválasztó mentalitás, csakúgy, mint a mérnököknél. Látszik ez a kérdező esetén is, ahol ugye épp ingyen oldja meg sok szopással azt, amire vannak amúgy dobozos megoldások, pénzért.

Ezért az Ipar 4.0 kb. gyártási adatok nyomonkövetésben, és egy elfogadható SCADA rendszerben kb. meg is áll, világszerte minden telephelyen.

Hát, azért az i4.0 ML/MV ennél jóval előrébb jár...

Idéznék két mondatot abból, amit linkeltél: "I’m running Ubuntu 18 LTS with 16 GB RAM and a Core i7-7700" illetve "Having a table with 1billion entries results mostly from a bad database design"

Az téma kapcsán mind a kettő fontos, mert idősoros adatokat - amelyeknek amúgy nincs egymással relációjuk - alapból is hülyeség egy táblába zsúfolni, de kaphat mindegyik gyártósor külön táblát, mert azért valljuk be, nem annyira dinamikus a gyártósorok telepítése, hogy ne lehetne lekövetni az IT rendszerben, ráadásul - ha nem tesszük külön táblába, akkor a gyártósor és az idősor alapján remekül lehet particionálni is és már a lekérdezésnél meg lehet mondani, hogy melyik partícióból akarok kérdezni, ami drámai módon gyorsítja a lekérdezést.

Sajnos kevés a jó DBA és még ennél is kevesebb az adatbázishoz értő fejlesztő, mert nincsenek szokva nagy mennyiségű adathoz nagy forgalmú környezetben és már pár pár tucat tps esetén is szólnak a vészcsengők, ahogy azt látni ebben a témában sok hozzászólónál.

Ha PHP-ból kerül SQL-be az adat, akkor egyszerűen PHP-ban érdemes lekezelni, hogy mit hívjon meg, ha hiba történik. (pl küldjön e-mailt, push üzenetet, stb...) 
Általában ez az egyszerűbb megoldás.

Ha közvetlen SQL-be írunk, akkor a legtöbb SQL (pl. MySQL-ben is) vannak triggerek, amiben az INSERT-re lehet műveleteket végrehajtani. pl.:

CREATE TRIGGER trigger_name
AFTER INSERT
   ON table_name FOR EACH ROW
BEGIN
   -- variable declarations
   -- trigger code
END;

A triggerben lehet vizsgálni a beszúrt adatot, és ennek megfelelően végrehajtani tetszőleges műveleteket.
Én például e-mail küldésre használom, de mondjuk meg lehet hívni egy webcímet is, (példa) ami mondjuk push üzenetet küld, vagy akár felkapcsol egy piros lámpát (egy másik ESP-vel).
Ugyanígy lehet triggert írni a sima, jó üveget számon tartó táblára is, amivel mondjuk ha az 5 perc alatt elkészült palackok száma 90 alá esik, akkor végrehajt valami műveletet.

Itt van pár példa néhány egyszerűbb triggerre, amivel lehet ismerkedni.

Amennyiben például van cron a szerveren, elegendő, ha egy trigger egy "notification_table" táblába beírja, hogy mi a gond, majd a cron alól futó php script 15 másodpercenként elküldi mondjuk e-mailben vagy push üzenetben azt az üzenetet, amit a "notification_table"-ban talált, majd törli onnan.

Ilyesmire gondolok:

delimiter #

create trigger notification_after_error after insert on errors_table
for each row
begin
  insert into notification_table (notification_text) values (CONCAT('Hiba történt a ', gyarotsor_id ,'gépsoron.'));
end#

delimiter ;

A fenti trigger pl. minden az "errors_table" táblába beszúrt sor után beszúr egy új sort a "notification_table" táblába, beleírva az értesítésbe a errors_table-ban található gyarotsor_id mező értékét is. 

A fenti persze egy kicsit erőltetett példa, meg lehetne csinálni ezt trigger nélkül is akár, de kiindulópontnak szerintem mindenképp elegendő.

Nagy Péter

Szerkesztve: 2021. 02. 09., k – 18:50

Itt tartok most ::

A soron lévő infra érzékelők, amik a futószalagra van építve több helyen, adják a 24Voltos jelet. Ezt én egy Finder relén keresztül  kötöttem rá az ESP32-re. Ha elhalad a ternék az infra kapu előtt (eltakarja a fényt) , GND-re zár az ESP32 és növelem a számlálót. Szóval számol..

Az ESP32-re írt progi az aktuális számolt értéket kitesz a TCP 80-as portján futó webszerverre. Amíg nem nyit meg senki egy kapcsolatot a webszervere felé addig 1 másodpercenként kiírja az aktuális számolt darabot.  Az SQL-szerveren, ami a céges belső webszerver is, fut egy python script, ami CURL-al  ránéz 5 másodpercenként az ESP32-n futó weboldalra, amin az éppen összeszámolt darab érték van kiírva. Ezt az adatot pedig felírja az SQL adatbázisba. Még annyi , hogy az ESP32 -re kötve van egy RTC -modul (elemes real time clock), így a darabszámokkal kiirja a weboldalára azt az időpontot, amikor az a ternéket érzékelte, illetve a későbbi azonosítás miatt a saját IP-címét is.

Valami ilyesmit :
  ('2021-02-09 15:14:00',192.168.1.182','10'),('2021-02-09 15:14:01',192.168.1.182','9'),  ...

Ha az  ESP32 érzékeli, hogy valaki ránézett, és kiolvasa az aktuális adatokat, kiüríti a weboldalát és kiírja az addig számolt  adatokat, amíg megint rá nem néz valaki a 80-as web portjára..

Tehát az ESP32  számol, és egy másik gép (nálam maga az sql-szerver) kiolvas, és SQL-be ír. Csak az ESP32  webes kimenetét adja hozzá ehhez :

INSERT INTO tabla (datum,ip,darab) VALUES  (és ide jön az ESP32  webes kimenete, az utolsó vessző, kicserélve pontosvesszőre) 

5 mp- enként van lekérdezve  az ESP32 számoló modul a szerverről.   "('2021-02-10 09:58:02','SOR','15')"   

Ezt egy INSERT INTO table ('datum','gep','darab') VALUES  kapott string  parancsal írom be az SQL -be. Tehát 5 mp alatt 15 db termék ment át az infra kapu között. Ha ritkábban kérdezném le akkor a számolt darab persze több lenne, viszont az SQL-be írt adatok mennyisége meg kevesebb (rekord).

     Mi ebben a bizonytalan működés ??

Bármilyen kommunikáció bármikor megszakadhat. Ha például az ESP már elküldte a legutóbbi adatsort, de az valamiért nem érkezik meg a szerverre, akkor nem kerül be az adatbázisba az a néhány érték. Ennek a valószínűsége még WIFI-n is kicsi, ezért várhatóan csak nagyon ritkán fogsz ilyennel találkozni, és akkor vakarhatod a fejedet...

Bármilyen csatornát is használsz, elvileg lehetetlen biztosan ugyanazt tudni mindkét oldalon. Az SQL szerver adhat nyugtát, hogy ő már mentette is az adatokat, akkor törölheti a régi adatokat az ESP. (De ekkor meg az SQL nem tudhatja biztosan, hogy ez a törlés valóban megtörtént! Ha az SQL elküldte a törlést kívánó nyugtát, de az ESP nem kapta meg valami okból, akkor egy bejegyzés kétszer került az adatbázisba!) (A TCP stream alapú, nem üzenet alapú, de a probléma alaptermészete ugyanaz marad a felépítményektől függetlenül: az utolsó nyugtában sosem lehetünk biztosak, hogy a másik oldal megkapta, és így nem tudhatjuk, hogy megtörtént-e a régi értékek törlése, vagy az új események loggolása.)

A probléma megoldása az, hogy olyan üzeneteket kell kitalálni, amiknek az esetleges ismétlése nem okoz galibát, és az aktív oldal (esetedben a szerver) valóban ismétel, ha valami nem sikerült. Például itt a szerver elküldheti az utolsó loggolt esemény sorszámát, vagy időbélyegét. És akkor az ESP tudja, hogy addig kell törölni és az újabbakat elküldeni. (A nyugta és az új adatok lekérése egy üzenetbe van összevonva: ez egy régi jól bevált trükk.) Ez a protokoll, ha belegondolsz garantálja, hogy átmegy minden azonosító akkor is, ha közben akárhány kapcsolat is lehal. (Feltéve, hogy az ESP puffer betelés előtt azért történik legalább egy hibátlan kapcsolatfelvétel is nyilván.)

Egy másik beleköthető pont, hogy inputot nem szokás SQL-be direkben bevágni, mert SQL injectiont lehet csinálni vele. Bár tény, hogy ez a leggyorsabban lefutó megoldás, és nyilván a szenzor helyén nem kellene támadónak lenni, de mégsem szokás.

Ha például az ESP már elküldte a legutóbbi adatsort, de az valamiért nem érkezik meg a szerverre, akkor nem kerül be az adatbázisba az a néhány érték

Az ESP nem küld semmit az SQL  -felé ..  Ő csak számol, amíg valaki (a kiolvasó -gép)   rá nem néz egy GET-tel a TCP 80-as portjára. 

Ha fél óráig nem érhető el  , mert nincs net vagy Wifi, akkor addig számol. Ha visszajön a anet, és eléri őt a kiolvasó-gép , akkor az aktuális darab számot fogja látni és azt olvassa ki és már a kiolvasó gép tesz az SQL -be, ami localhost-ban van, mert egy gépen fut a kiolvasó python script és a MySQL adatbázi is.

Amikor egy TCP-be beleírunk valamit, akkor azt úgy hívják, hogy küldés. Függetlenül attól, hogy a kapcsolatot ki kezdeményezi. A kérdésre adott válasz elküldése a küldés.

Utoljára még leírom: a való életben előfordul olyan, hogy a TCP csatornába az egyik oldal beleírja, hogy kutyafüle, a másik oldal meg valami okból nem veszi ezt, de a küldő mégis azt látja, hogy ő elküldte. Például ha pont a küldés közben szakad le a hálózat valamely eleme. Ezért kiolvasó oldali nyugtázás híján nem szabad törölni a már kiolvasott logokat. Illetve a szerveren fel kell készülni esetleges duplázásra, mert ha az üzenet elveszést kezeljük, az mindig potenciális duplázással fog járni.

De ha a hálózattal nincs is probléma, az is előfordulhat, hogy az SQL szerver szakad le pont azután, hogy a GET visszatért a "kiolvasó gép"-en. Ott áll szerencsétlen processz egy adattal, ami az ő felelőssége - hiszen a mikrovezérlőről kitörölte, de nincs hová beírni! Ebben az esetben is elveszik az adott log bejegyzés.

Ha a log bejegyzések random (de ritka) elvesztése nem probléma, akkor nem szóltam, tökéletes lesz a megoldás. Nem az a baj, hogy hibás megoldást csinálsz, hanem hogy nem vagy hajlandó belegondolni sem. Ha belegondolsz és bevállalható a hiba, vagy a kockázat mértéke, akkor minden oké. Nyilván egy napi milliós nagyságrendből pár darab nem fog nagyon hiányozni, annál több hiba pedig nem lesz. De legalább gondolj bele!

 

Az a baj, hogy nagyon write only módon kommunikálsz, próbálunk segítőkészen hozzáálni, felhívni a figyelmedet a megoldásod gyengeségére, de nem vagy hajlandó gondolkodni rajta. A hozzáállásod megváltoztatásáig a magam részéről elnémulok, nem érdemelsz több segítséget.

Igazad van, kicsit fafejű voltam. Bocsánat. Amit írtál az szerencsélre ritkán fordult eddig elő, de előfordulhat, persze. Átgondolom amit írtál, és ha tudom, beépítem a projektbe. Csak félek, hogy ne menjen a hálózat terheltség rovására az ellenőrzés. Mert nem egy , hanem lehet , hogy 12*3 (36) ilyen ESP-t kell majd használni éles üzemben. És mellete még ott van egy csomó más gép is , ami szintén a LAN-t fogja terhelni...  Igaz Gigabites a belső hálónk, de az is igaz, hogy van két pár UniFi - wifi átlövő antenna is három távolabbi üzemcsarnok között. Szerinte ez lesz a gyenge láncszem ...

Semmi plusz terhelést nem okoz a kettővel fejlebb javasolt protokoll: minden adatlekérő üzenetben elküldöd, hogy hányas volt az utolsó loggolt log. 8 bájt plusz, ha bináris a protokoll és 64 bites azonosítót használsz. Egyetlen Ethernet csomaggal sem lesz több ettől a kommunikáció :-)

MÁS: Szerintem egyébként a terhelések értelmezésével is bajban vagy nagyságrendileg, hogy mi mit jelent egy rendszernek. Egy ilyen rendszer hálózati forgalma smafu, számold ki a sávszélességeket szorgalomból! Egy 9600 baudos UART-on is átférne minden adat röhögve, te meg gigás switchről beszélsz! Több nagyságrendről beszélünk!

Az is, hogy a számlálás és adatbázisba írás túl nagy falat volt a banánízű pitének erre enged következtetni. Nézted a CPU %-ot rajta? Szerintem kicsi volt, csak a várakozások miatt nem működött. Gondolom egyetlen szálon futott a program valahogy így:

 * végtelen ciklus

 ** nézd az optokaput, ha 0->1 átmenet van, akkor számlálj, azaz

 *** írd be adatbázisba -> ez eltarthat sokáig is, amikor éppen táblákat konszolidál az SQL szerver, és emiatt lemaradunk pár eseményről. De nem a banános pite a szűk keresztmetszet, hanem a worst case válaszideje az SQL-nek.

 

Ha szétszeded két szálra a programot úgy, hogy az egyik csak figyeli a kaput, a másik pedig írja az SQL-t (ráadásul több logot összevárva egyetlen kommitban), és a kettő között van egy queue (akár két program stdout és stdin-je összekötve, a Linux eleve ad hozzá egy buffert, ami elegendő is, lásd: https://man7.org/linux/man-pages/man7/pipe.7.html ), akkor máris simán elbírja a Banana PI is. Akár az összes sort is kell tudni számolni egyetlen banánossal, lehetetlen, hogy ne volna elég teljesítménye. Egy Arduino UNO-n is meg tudnám írni (bár MySQL konnektort nem akarnék csinálni, de ha nem kell titkosítás, akkor működne és el is bírná teljesítménnyel), nevetséges, hogy egy Banán PI nem elegendő.

* végtelen ciklus

 ** nézd az optokaput, ha 0->1 átmenet van, akkor számlálj, azaz

 *** írd be adatbázisba -> ez eltarthat sokáig is, amikor éppen táblákat konszolidál az SQL szerver, és emiatt lemaradunk pár eseményről.

 

Igen itt van a gond.. Erre én is csak mostanábam eszméltem rá, hogy elbasztam...  Csak eddig valamiért senkinek , még nekem sem tűnt fel a hiba.

Átírhatnám úgy, hogy egy python script számol, és egy másik sql-be tolja az első kimenetét, ha jól értem..  
De itt jön a másik ok : Ha a Banana Pi valamiért nem működik, akkor nem csak a webes konzol felület nem lesz használható a soron, hanem számolás sem lesz.  Ezért is  szeretném külön eszközön a számolást megoldani.. 
Volt hogy , eltűnt a PI-ből az SD kártya, meg az USB-s töltője egy hétvége alatt...   Hétfőn meg reklamáltak, hogy "SEMMI nem működött a hétvégén , old már meg, hogy jó legyen végre !"....   Na ekkor kicsit kiakadtam ..

Egyébként real time dolgokra illendőbb is mikrokontrollert használni, mert a Linux ütemezője nem alkalmas rá IMHO. Bár ez határeset, mert a bemenet figyelő szkriptet tippemre kb 10-szer kell ütemezni másodpercenként ahhoz, hogy megbízhatóan működjön, nem a legkeményebb real-time elvárás.

Megnéztem végül az ESP kódodat is: nekem annyi gyanúm van, hogy esetleg a TCP szerver kódban blokkoló küldést használsz, és ezért ha éppen Wifi probléma van, akkor ott is megakadhat a számlálás ameddig a TCP ismétlésre várakozik. Ebben nem vagyok biztos, a libet jobban szemügyre kellene venni ehhez.

De általánosságban érdemes a real time és a nem real time dolgokat szétválasztani. Én úgy csinálnám, hogy az input figyelést egy timer interruptra tenném, ami egy fix ütemezést ad neki. Arra kell vigyázni, hogy a számláló beírását/kiolvasását viszont akkor szinkron blokkba kell tenni. A TCP kommunikáció pedig maradhat a main loopon.

Másik megoldás a számlálóra, hogy 8 bájtos számlálót használsz, akkor sosem kell nullázni, mert az nem tud átfordulni soha, annyira sok a 2^64. A rebootot pedig a vevő oldal észreveszi onnan, hogy 0-ról indult újra a számláló.

 

Az eltűnő SD kártya problémára nem informatikai megoldást kell keresni :-). Amit te tehetsz az az hogy beraktárazol cserealkatrészből, illetve a kódot beteszed verziókezelőbe, hogy az SD eltűnésével ne vesszen el a munkád is!

Megnéztem végül az ESP kódodat is: nekem annyi gyanúm van, hogy esetleg a TCP szerver kódban blokkoló küldést használsz, és ezért ha éppen Wifi probléma van, akkor ott is megakadhat a számlálás ameddig a TCP ismétlésre várakozik. Ebben nem vagyok biztos, a libet jobban szemügyre kellene venni ehhez.

Hol ?? Pedig az nem lenne jó...  Elvileg ez Asyncron webszerver ..    Ha jól gondolom, ez a nevéből itélve nem fogja meg a futást, ha mégsem tudná kiírni a webes tartalmat ..  Vagy rosszul gondolom ..

 

De általánosságban érdemes a real time és a nem real time dolgokat szétválasztani. Én úgy csinálnám, hogy az input figyelést egy timer interruptra tenném, ami egy fix ütemezést ad neki. Arra kell vigyázni, hogy a számláló beírását/kiolvasását viszont akkor szinkron blokkba kell tenni. A TCP kommunikáció pedig maradhat a main loopon.

Segítenél ebben ?? 

Megnéztem végül az ESP kódodat is: nekem annyi gyanúm van, hogy esetleg a TCP szerver kódban blokkoló küldést használsz, és ezért ha éppen Wifi probléma van, akkor ott is megakadhat a számlálás ameddig a TCP ismétlésre várakozik. Ebben nem vagyok biztos, a libet jobban szemügyre kellene venni ehhez.

Hol ?? Pedig az nem lenne jó...  Elvileg ez Asyncron webszerver ..    Ha jól gondolom, ez a nevéből itélve nem fogja meg a futást, ha mégsem tudná kiírni a webes tartalmat ..  Vagy rosszul gondolom ..

 

De általánosságban érdemes a real time és a nem real time dolgokat szétválasztani. Én úgy csinálnám, hogy az input figyelést egy timer interruptra tenném, ami egy fix ütemezést ad neki. Arra kell vigyázni, hogy a számláló beírását/kiolvasását viszont akkor szinkron blokkba kell tenni. A TCP kommunikáció pedig maradhat a main loopon.

Az imput (bejövő jel)  nincs ütemezve, mert nem biztos, hogy állandó sebességű  a gyártó sor, Ezért tettem a main  loopba, hogy az esemény vezérelje a számolást. De lehet, hogy félre értettelek ..

> Az imput (bejövő jel)  nincs ütemezve, mert nem biztos, hogy állandó sebességű  a gyártó sor, Ezért tettem a main  loopba, hogy az esemény vezérelje a számolást. De lehet, hogy félre értettelek ..

Így is időzítve fut, csak nem tudjuk pontosan milyen periódussal: periódusonként egyszer nézel rá a bemenetre. Mivel nagyon gyors lesz a periódusidő, ezért ez így szerintem jó lesz. Esetleg ha a jelformán előfordulhat úgynevezett prellezés, akkor kellhet finomítani rajta.

Erre írtam, hogy nagyon terheli a hálót, ha sok ilyen eszköz van. Nem az adatmenyiség a sok, hanem, hogy mindenki dumálni akar. 

Amikor egy switch haldoklik az általában nem bináris, hanem csak laggolni kezd és dobja el a  csomagokat. Az általad felépített rendszer ilyenkor kitörli az esp-ket, de majd nem fog bekerülni semmi az sql-be. Emiatt kell csak visszaigazolás után törölni. Ezért nem jó, pl ha csak küldi az esp az adatokat, de választ nem vár.

> Utoljára még leírom: a való életben előfordul olyan, hogy a TCP csatornába az egyik oldal beleírja, hogy kutyafüle, a másik oldal meg valami okból nem veszi ezt, de a küldő mégis azt látja, hogy ő elküldte

Csak a teljes korrektség kedvéért, mert kissé félreérthető: a TCP megbízható, nincs olyan, hogy az egyik oldal úgy gondolta hogy jó, a másik meg nem látta. Pont azt csinálják alapvetően, amit javasoltál: sorszámozzák a packeteket, és visszajelzik, hogy mi vettek már. Ettől persze az még lehet, hogy az alkalmazás, vagy az alkalmazás TCPre illesztő rétege elbassza ezt, de magára a TCPre ez önmagában nem igaz.

"Hát ennek az egésznek másodperc pontosan kell adatokat szolgáltatnia, mert még a sor néhány másodperces megállását (illetve ha nem érkezik az érzékelőhöz termék mondjuk 2 másodperc után) is ézékelnie kell és jelezni a munkás részére, hogy gond van."

akkor ez mar nem lesz?

egy biztos, halozati hiba miatt nem fog elveszni adat ha igy olvasod ki az erzekelobol a darabszamot. en mondjuk meg egy countert beletennek. ugy ertem hogy hanyadik kiolvasas, igy ha ugrik akkor megis elveszett valami.

illetve annyit meg lehetne hogy a countert visszakuldod es csak az annal regebbi adatokat torlod az erzekelobol, nem tudom ezt miert nem irtam, en is igy csinalom csak nalam idopont van es az sem gond ha tobbszor letoltom az adatot mert az elsodleges kulcs miatt nem fogja tobbszor beszurni az adatbazisba.

neked aztan fura humorod van...

en is igy csinalom csak nalam idopont van 

Timestamp ...
Még teszek az ESP32-re egy RTC-modult , mi net nélkül is tudja a pontos időt. Így ha WiFi szakadás lenne , akor is tud számolni és tudja, hogy mikor érzékelte a terméket. Amikor meg visszajön a WiFi, leolvassa a szerver a webes 80-as portjáról, amit addig számolt.

jo csak egyreszt kuldd vissza leolvasaskor az addigi legnagyobb timestampot hogy az eszkoz tudja meddig dolgoztad fel az adatokat es mit torolhet, illetve a timestamp remelem 1/1000-es masodperc pontos

annyi kulonbseg van meg hogy en 2 sql kozott szinkronizalok, nem tudom az eszkoz milyen modon tudja tarolni az adatokat mig jon a lekerdezes

neked aztan fura humorod van...

Lehet a fájlrendszerén fájlban, de én most a memóriában tárolom a legutóbbi leolvasás óta eltelt idő alatt számolt darabokat.

Mivel  egyenlőre 3 mp -ként kérem le (lehet elég lesz  5mp is, majd meglátjuk) így egy 130 darab/perc -es gyátrósoron ezy idő  (3-5 mp) alatt max 7 -11 termék jön az érzékelő elé.  Ha a kiolvasó gép (szerver, ami egyből a MySQL-be irja, localhostban) nem érné el a WiFi-s ESP32 -t , akkor az addig számol, és összegez a memória változóban, amíg a kiolvasó el nem éri. Ez ritkán fordult elő eddig (két napja egyfolytában tesztelem 0-24 -ben).  Hála istennek azt ESP32 eszköznek elég jó WiFi  antannája van, és elég stabil  a kapcsolat rajta, de még le fogom tesztelni direkt, úgy hogy leállítom az UniFi AP -t amihez csatlakozik néhány másodpercre (Restart)  ,  szimulálva a WiFi   szakadást .. 

echo "('2021-02-09 15:14:00',192.168.1.182','10'),('2021-02-09 15:14:01',192.168.1.182','9');DELETE TABLE tabla," :)

Mi van, ha halozati zavar van, az ESP-d mar torli magabol (mert bejott a request), a DB meg nem tarolja le, ujra probalkozik, de akkor mar ures? Az egy gyartosoron levo eszkozeid kulonbozo ertekeket fognak mutatni, kerdes, hogy ez baj-e.

A strange game. The only winning move is not to play. How about a nice game of chess?

Nem, nem akkor, hanem akor, amikor a GET hatására kiküldte az adatot, függetlenül attól, hogy a túloldal alkalmazás szinten fogadta-e és feldolgozta/elrakta-e.
Hasonlat: Kérsz tőlem egy dokumentumot, papíron. Én készítek róla egy másolatot, elviszem a postára, és feladom a címedre, majd amiko r apostáskisasszony átvette tőlem a küldeményt, a dokumentum nálam lévő példányát ledarálom.
Kérdés: megbízható-e így a dokumentum továbbítása, garantált-e, hogy nálad el lesz téve?
Számora egy szabatosan fogalmazott protokoll valahogy így nézne ki:
kliens -> szerver: add ide kérlek a 123-as csomagot! - (ha adott ideig nem érkezik válasz, a kérést megismételni.)
szerver -> kliens: itt a csomag, a száma a 123-as.
kliens -> szerver: (miután letárolta a kliens az adatot) megkaptam és tároltam a 123-as csomagot (Ha a szerver nem kap ilyen választ, akkor nem törli!)
...

A lényeg, hogy a kliens a nála tárolt legutolsó csomagot követőt kéri el, és amikor azt letárolta, akkor visszajelez, hogy az adott számú csomaggal bezárólag az ESP törölheti az adatokat.

 

Valamerre elindultal es ez egy jo dolog. Rengeteg ember van, aki idejon evekig 5letel, es nem csinal semmit se.

Ha ez csak egy prototipus, es a vegen kiderul, hogy megbizhatatlan, es te mar nem tudod vagy nem akarod megcsinalni, akkor is ennek a projektnek harom oldala van:

a) hardver

b) szoftver

c) alkalmazaslogika, meg mennyire valt be (egyaltalan erdemes-e csinalni).

 

Ha masra nem, a c) pontra tuti jo a projekted, es ez alapjan a vezetoseg eldontheti, hogy hardverra vagy szoftverra akar-e kolteni es kulsos ceget felvenni, ha teged meghalad a problema (de miert haladna meg?:).

 

# Hardver

 

Ezekkel az infra erzekelokkel ne relet akarj meghajtani. Van optokapus megoldas. Csinalhatsz is, de legegyszerubb venni egy ilyet:

https://www.sparkfun.com/products/9118

 

Irhattam volna, de legalabb egy 200eFt-os keretet kerj a fonoksegre a hobbidnak. Mert gyanus, hogy sajat penzbol nyomulsz (ugyse ertekelik).

 

# Szoftver

 

Valami hibakezelest iktass be.

Pl. a szamlalot ne egy sima GET-tel torolj, hanem mondjuk legyen a get-nek egy parametere, hogy most o kiolvassa es torolheted. Igy ha valaki ranez az esp-re, akkor se torli veletlenul a szamlalot.

Legjobb lenne, ha a szerver oldal valaszt kuldene, hogy mostmar beirta -> torolheti.

De valamit csinalj, mert ez igy tenyleg kartyavar.

 

Aztan haladj tovabb a szoftverral, nezzetek meg, hogy bevalik-e, es legrosszabb esetben majd egy kulsossel megcsinaltatjak plc alapon, hogyha hasznos lesz.

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

"Pl. a szamlalot ne egy sima GET-tel torolj" - merthogy per definitem a GET idempotens, azaz 123-szor lefuttatva 123-szor ugyanazt az eredményt _kell_ visszakapnod. A szerver állapotát megváltoztatni a POST használandó, azaz lehet GET, és ha a DB-be beírta, visszaolvasta, hogy ott van, akkor mehet a POST, ami a kiszolgáló oldalon állapotváltozást (törlés) generál.

A kliens szempontjából idempotensnek _kell_ lennie, azaz a szerver állapotát a "GET" nem változtathatja meg. Azaz ha a get 123-at adott vissza, és a következőig jött még 42, akkor a következő GET-nek nem 42-t, hanem 165-öt kell visszaadnia.

akkor majd lecsereli a GET-eket POST-okra, es a POST-ban kapja vissza az adatot is.

igy a kaposzta is jollakik :)

vagy hoz egy olyan szabalyt hogy az o zart rendszereben GET=POST es POST=GET, valtoztat ez valamit is? majd azt mondja nem http protokol csak hasonlit ra :)

neked aztan fura humorod van...

De 42-nak kell lennie.

Mert az 123 -at az előző GET kiolvasta és az ESP ezt az olvasást érzékelte a webszerverén, és törölte a kimenetét,  a kiolvasó gép pedig felküldte a 123-at az SQL -be .  Így a következő kimenet az azóta érzékel darab számok lesz. Tehát 42 darab.. 

A kódot lentebb bemásoltam, ez viszont csak a lényeges rész ::

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  StartSTA();
  ////////////////// NTP /////////////
  NTP.begin ("hu.pool.ntp.org", timeZone, true);  
  NTP.setInterval (63);
  Serial.println("NTP ido :" + pontosido());
  ///////////////// NTP /////////////

  
  pinMode(4, INPUT_PULLUP);

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    if (darab > 0) {
      ido = pontosido();
      ADATOK = "('" + ido + "','SZAMOLO_IDJE','" + (String)darab + "'),";
    }
    if (darab == 0) {
      ADATOK = "";
    }
    request->send(200, "text/plain", ADATOK);
    ADATOK = "";
    darab = 0;
  });  
 
  server.begin();
  
  start_ota();

  Serial.println(van_e_log());  
  Serial.flush();

  s = 0;

  Serial.println("START");
  Serial.flush();
  timer.every(10000, wifi_ellenorzes);
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
void loop() {
  timer.tick();
  ArduinoOTA.handle();
  int g = digitalRead(4);
  if (g == 0 and s == 0) {
    s = 1;
    darab++ ;
  }
  if (g == 1) {
    s = 0;
  }
}

# HARDVER   
https://www.dropbox.com/s/roomvfc0raz5llb/1613112639190.jpg?dl=0  

Ezt nem én találtam ki, hanem a műszerészünk.  Nem is értem, hogyan működik, de működik. Ha el tudod magyarázni, megköszönném. 
Amit én csináltam :
Az ESP GPIO4  és a Ground  lábát bekötöttük a fenti Finder tokba. A sor fotoérzékelőjének kimenetét is ebbe. Ha bejövő jel magas (1) , elvileg az ESP 4 és GND lábát összekapcsolja és a 4-es láb értéke alacsony (0) lesz.  Az ESP  bootoláskor a 4-es lábat felhúzom (INPUT_PULLUP). És figyelem, hogy mikor lesz alacsony (0), ekkor számolok 1 terméket. A következő magas (1) érték utáni ismét alacsonynál (0)  számolok még egy terméket, és így tovább...
Ha egymás után több magas (1) érték jüön be, akkor a sor megállt, nem jön le rajta termék. 10 magas (1)  után jelzem a HIBA-t, TERMÉK HIÁNY-t.

Pl. a szamlalot ne egy sima GET-tel torolj, hanem mondjuk legyen a get-nek egy parametere, hogy most o kiolvassa es torolheted. Igy ha valaki ranez az esp-re, akkor se torli veletlenul a szamlalot.

Senki nem fog ránézni, mert nem is tudja, hogyan kell ..  Hidd el , ez nem lesz gond, itt nem az a USER gárda van .

Legjobb lenne, ha a szerver oldal valaszt kuldene, hogy mostmar beirta -> torolheti.

Ezt is kipróbáltam ,de felesleges, csak lassítja a dolgokat. Ha ránézett a TCP 80-as portra, az ESP ezt érzékeli... 

Aztan haladj tovabb a szoftverral, nezzetek meg, hogy bevalik-e, es legrosszabb esetben majd egy kulsossel megcsinaltatjak plc alapon, hogyha hasznos lesz.

A tesztelés most hétvégén zajlik, még keddig. Akkor ülünk le a vezetőséggel beszélgetni. Eddig is volt hasonló darab számlálás, de sajnos kiderült, hogy az úgy hibázik.
 Hogy érsd :
A sorok mellett vannak (soronként 3 darab) Banana PI gépecskék. Kezdetben az volt az elvárás, hogy ezeken fusson egy program (egy PHP - MySQL elérésű belső webprogram, amit én írtam) , amin a dolgozók a soron előforduló eseményeket (Termék váltás, gépek meghibásodása, selejt keletkezés, munkaidő szünet, gépek takarítása , ...  meg egy csomó minden) tudják rögzíteni.  Na vagy egy éve kitalálta a fönökség, hogy kéne látni , hogy a sorok végén,  hány késztermék jön le. Ha a beírt selejtekkel ez nincs összhagban, akkor vizsgálódtak ...   Én ezt úgy oldottam meg, hogy a meglévő Banana PI -kre kötöttük a sorok jeladóját, és írtam egy python scriptet ami elvégzi a számolást, és még a kapott darabszámokat köti az aktuális termék cikkszámhoz, és az adatbázisba is felküldi. Szóval kicsit túlterheltem szegényt..    Ja, a "hozzáértő emberek, akik  soron dolgoznak" rendszeresen úeltüntették , (ellopták ?)  az SD -kártáykat és az 5Voltos USB-s tápokat az eszközökből.  Csak az tűnt fel , hogy szöl a főnök, hogy "Már megint nem számol semmit a programom, és nem megy semmi !!" .   A "Nem megy semnmi" nála  értelem szerűen a BANANA PI.  Ezért (is) szeretném külön választani az adatrögzítést a darab számlálástól.  De ha már klüön választom, akkor a számolást és az SQL-be írást is ülön kéne, hogy amikor éppen SQL-be ír, addig ne szakadjon meg a számolás sem. Ugyanis ezt tapasztaltam a BANANA PI-ken mostanában.  Furcsa módon az senkinek eddig nem tűnt fel, az elmúl egy évben, hogyx a darab számok kevesk a valósághoz képest. De mindegy, most legalább észrevettük. 
A bejegyzésemet azért indítottam, hogy ötleteket kapjak az mostani megoldáshoz. Illetve megerősítést , hogy jó felé gondolkodok. 
Ahogy látom, nagyjából jó felé ...  Most hanyagoljuk a "profi" megoldásokat, meg a "külsős szakembereket", mert itt könnyű írogatni. De eddig hhárom "profi"   cég adta fel a dolgot .. Jó tudom,  ez nem egy szabványos projek, meg a cég sem  sablon-cég. Gondolom ezért nem lett ebből "profi" megoldás.
Meg hát talán egy 16 éve ott dolgozó jobban , hamarabb átlátja, hogy mi az elvárás, mint egy külsős. 

 

kovetkezo lepeskent az ERP-ben/keszlet kezeloben is lekovethetned a valtozasokat, csinalhatnal szallitoleveleket mondjuk muszakonkent amik az alapanyagot kiadjak, a kesztermeket es selejtet bevetelezik a darabonkent meghatarozott megnovelt nyilvantartasi arral.

neked aztan fura humorod van...

Vicces !! Komplett ERP-t nem akarok írni ...  

Működő ERP-nk van JDE-nek hívják. Na ehhez kell kapcsolódnia a sori daraboknak. Ja meg kapcsolódnia kell a soron, a  dolgozók által , a fent vázolt KONZOL  programba bevitt eseményekhez is. Mert a JDE-ben nincs ilyen modul, vagyis nem vettük meg. Szóval elég bonyolult a helyzet, és nekem ezt kell összehangolnom, megoldanom.

A készlet változásokat persze lekezeljük az JDE -ben, de csak ha raktárra  van véve. De előtte még meózni , csomagolni kell.
Eközben még képződhet selejt is ..  Szóval ami lejön a sorról , biztos, hogy nem készlet még.
Ezzel , hála istennek nem kell törődnöm ebben a projektben ...

> Ha el tudod magyarázni, megköszönném.

 

Bar mindig csak egy relefoglalat fotot kuldesz, de gondolom van abban egy rele is.

A rele helyett optokapus erzekelot ajanlottam (meg masok is), kuldtem egy olcso kesz aramkort is.

Gondolom a "muszeresz" tudni fogja, hogyan kell bekotni.

 

> SD -kártáykat és az 5Voltos USB-s tápokat az eszközökbő

 

A lopasra mechanika vedelem kell (normalis fem doboz), ha meg mindig fennall akkor retorzio (minden gepnek minden muszakban felelose van es ha gepbol eltunik valami az o ideje alatt, akkor le kell vonni.

 

A hibakezeles (ellenorzoosszeg, ack, miegyeb), nem azert kell bele, mert mas nem nez ra rajtad kivul, hanem hogy ne egy kartyavar legyen az egesz.

 

A kartyavar attol szunik meg, hogy minden lehetseges hibara van valasza a rendszernek, es sosincs olyan, hogy tudod hogy valamitol megborulhat, de bennehagyod mert ugyse all elo.

Igy is lesz benne epp eleg bug, amire nem gondoltal.

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Szerkesztve: 2021. 02. 10., sze – 21:47

Elastic stacket.meg nem javasolta senki.

En a helyedbe nem eroltetnem az sql szervert, hanem feltennek egy elastic clustert.amibe direktbe logolhatnak az esp-k. Grafikus feluletneknmeg tokeletes a kibana, olyan dashboardardot allitasz ossze benne amilyet csak akarsz.

Ha meg úgy latod nagy A terhelés akkor csak hozzaadsz meg par elastic node-t meg mondjuk egy load balancert.

Support Slackware: https://paypal.me/volkerdi

Itt van az ESP32  kódja. Tudom . van benne egy csomó felesleges dolog, de ez még csak a teszt...

 

#include <WiFi.h>
#include "ESPAsyncWebServer.h"
#include <ESPmDNS.h>
#include <ArduinoOTA.h>
#include <WiFiUdp.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <TimeLib.h>
#include <Wire.h>
#include "RTClib.h"
#include <NtpClientLib.h>
#include "SPIFFS.h"
#include "FS.h"
#include <arduino-timer.h>

int timeZone = 1;
RTC_DS3231 rtc;

auto timer = timer_create_default();

const char* OTAhost = "MysQL_TESZT";
IPAddress  apIP(192, 168, 182, 1);

IPAddress local_IP(192, 168, 1, 182);
IPAddress gateway(192, 168, 1, 7);
IPAddress subnet(255, 255, 255, 0);

AsyncWebServer server(80);
const char *ssid = OTAhost;

const String AP_SSID = "WIFI_SSID";
const String AP_PASSWORD = "WIFI_PASSWD";

String Wifimod = "";
String log_f = "/log.csv";
String INDEX_HTML = "";
int s = 0;
int darab = 0;
String l = "";
String ADATOK = "";
String ido = "";
String ev, ho, nap, ora, perc, mp;

////////////////// OTA /////////////
void start_ota() {
  ArduinoOTA.setHostname(OTAhost);
  //ArduinoOTA.setPassword(OTAPassword);
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    String hiba = "I"; // Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    String hiba = "I"; // Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) String hiba = "I"; // Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) String hiba = "I"; // Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) String hiba = "I"; // Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) String hiba = "I"; // Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) String hiba = "I"; // Serial.println("End Failed");
  });

  ArduinoOTA.begin();
}
////////////////// OTA /////////////
String getValue(String data, char separator, int index) {
  int found = 0;
  int strIndex[] = { 0, -1 };
  int maxIndex = data.length() - 1;
  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}


bool formazas() {
  bool F = false;
  if (SPIFFS.format()) {
    Serial.println("File system Formatted");
    F = true;
  }   else   {
    Serial.println("File system formatting error");
  }
  return F;
}

String formatBytes(size_t bytes) {
  if (bytes < 1024) {
    return String(bytes) + " B";
  } else if (bytes < (1024 * 1024)) {
    return String(bytes / 1024.0) + " KB";
  } else if (bytes < (1024 * 1024 * 1024)) {
    return String(bytes / 1024.0 / 1024.0) + "MB";
  } else {
    return String(bytes / 1024.0 / 1024.0 / 1024.0) + " GB";
  }
}


String van_e_log() {
  String R = "";
  if (!SPIFFS.begin(true)) String hiba = "I"; // Serial.println("error while mounting filesystem!");
  File f = SPIFFS.open(log_f, "r+");
  if (!f) {
    R = "";
  }  else if (f.available() <= 0) {
    String hiba = "I"; // Serial.println("file exists but available <0");
    R = "";
  }  else  {
    String ssidString = f.readStringUntil('\r');
    if (ssidString != "") {
      File root = SPIFFS.open("/");
      File file = root.openNextFile();
      while (file) {
        if ((String)file.name() == log_f) {
          Serial.print("FILE: ");
          Serial.print(file.name());
          Serial.print("  SIZE: ");
          Serial.println((String)(float(file.size() / 1024)) + " Kbyte");
          float maradek = float((SPIFFS.totalBytes() - SPIFFS.usedBytes()) / 1024);
          Serial.println("Total:" + (String)(float(SPIFFS.totalBytes() / 1024)) + "  Használt:" + (String)(float(SPIFFS.usedBytes() / 1024)) + " Maradék:" + (String)maradek);
          if (maradek < 10.00) {
            if (SPIFFS.begin(true)) {
              SPIFFS.remove(log_f);
            }
          }
        }
        file = root.openNextFile();
      }
      R = "VAN";
    } else {
      R = "";
    }
  }
  f.close();
  return R;
}


bool logWrite(String a) {
  //bool logWrite(void *) {
  bool R = false;
  float maradek = float((SPIFFS.totalBytes() - SPIFFS.usedBytes()) / 1024);
  if (maradek < 10.00) {
    if (SPIFFS.begin(true)) {
      SPIFFS.remove(log_f);
    }
  }
  if (!SPIFFS.begin(true)) {
    String hiba = "I"; // Serial.println("error while mounting filesystem!");
  } else {
    File fw = SPIFFS.open(log_f, "a+");
    if (!fw.print(a)) {
      formazas();
      fw.print(a);
    }
    fw.print("\r");
    fw.flush();
    delay(10);
    fw.close();
    R = true;
  }
  return R;
}

void log_lista() {
  INDEX_HTML = "";
  if (!SPIFFS.begin(true)) {
    String hiba = "I";
  } else {
    File fo = SPIFFS.open(log_f, "rb");
    while (fo.available()) {
      String l = fo.readStringUntil('\r');
      if (l != "") {
        INDEX_HTML  += l;
      }
    }
    fo.close();
  }
  //return logok;
}


String pontosido() {
  if (WiFi.status() != WL_CONNECTED) {
    StartSTA();
  }
  String idopont = (String)NTP.getTimeDateString ();
  ev = idopont.substring(15, 19);
  ho = idopont.substring(12, 14);
  nap = idopont.substring(9, 11);
  ora = idopont.substring(0, 2);
  perc = idopont.substring(3, 5);
  mp = idopont.substring(6, 8);
  setTime(ora.toInt(), perc.toInt(), mp.toInt(), nap.toInt(), ho.toInt(), ev.toInt());
  rtc.adjust(DateTime(ev.toInt(), ho.toInt(), nap.toInt(), ora.toInt(), perc.toInt(), mp.toInt()));
  DateTime now = rtc.now();
  return ev + "-" + ho + "-" + nap + " " + ora + ":" + perc + ":" + mp;
}


String printDigits(int digits) {
  String dd = (String)digits;
  if (digits < 10) {
    dd = "0" + (String)digits;
  }
  return dd;
}

void StartAP() {
  WiFi.disconnect();
  delay(100);
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));   // subnet FF FF FF 00
  WiFi.softAP(ssid);
  IPAddress myIP = WiFi.softAPIP();
  String hiba = "I"; // Serial.println("AP IP address: ");
  Serial.println(myIP);
  Wifimod = "AP";
}

void StartSTA() {
  // WiFi.disconnect();
  Wifimod = "STA";
  WiFi.begin(AP_SSID.c_str(), AP_PASSWORD.c_str());
  int j = 0;
  while (WiFi.status() != WL_CONNECTED) {
    j++;
    delay(1000);
    Serial.print(".");
    if (j == 10) {
      delay(500);
      ESP.restart();
      delay(500);
      while (true);
    }
  }
  if (Wifimod = "STA") {
    Serial.println();
    Serial.println(WiFi.localIP());
  }
}

bool wifi_ellenorzes (void *) {
  if (WiFi.status() != WL_CONNECTED) {
    StartSTA();
  }
  return true;
}

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  StartSTA();
  ////////////////// NTP /////////////
  NTP.begin ("hu.pool.ntp.org", timeZone, true);  
  NTP.setInterval (63);
  Serial.println("NTP ido :" + pontosido());
  ///////////////// NTP /////////////

  
  pinMode(4, INPUT_PULLUP);

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    if (darab > 0) {
      ido = pontosido();
      ADATOK = "('" + ido + "','SZAMOLO_IDJE','" + (String)darab + "'),";
    }
    if (darab == 0) {
      ADATOK = "";
    }
    request->send(200, "text/plain", ADATOK);
    ADATOK = "";
    darab = 0;
  });  
 
  server.begin();
  
  start_ota();

  Serial.println(van_e_log());  
  Serial.flush();

  s = 0;

  Serial.println("START");
  Serial.flush();
  timer.every(10000, wifi_ellenorzes);
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
void loop() {
  timer.tick();
  ArduinoOTA.handle();
  int g = digitalRead(4);
  if (g == 0 and s == 0) {
    s = 1;
    darab++ ;
  }
  if (g == 1) {
    s = 0;
  }
}

Majd valaki kijavit, ha tevednek. De en ugy latom, hogy a NTP idoszinkronizacio megakasztja az egeszet. Azaz internet is kell a mukodeshez.

Ha nincs net, akkor hulyeseg lesz a pontos idoben, probaltad, hogy csak a LAN-on van vagy fel orat a cucc, anelkul, hogy kilatna az internetre?

 

En ezt a hibalehetoseget ugy szuntetnem meg, hogy a pontosidot a GET kerestol fuggetlenul szinkronizalnam, es elmentenem a szinkronizacio idejet, es a GET-nel csak kitennem a pontos idot, es hogy boot ota hanyszor volt szinkronizalva, es mikor volt az utolso.

Termeszetesen ha nem sikerul a szinkronizacio (nincs net), akkor arra is felkeszitenem (sync since boot: 8, failed sync since boot: 0, last sync: 2021-02-13T15:15:12.187Z).

Jah es minden idot a halozaton szigoruan UTC-ben kuldozgetnek kliens szerver kozott. A localtime-ot elfelejtenem. Az csak megjelenites only.

 

De a sima GET /-et is elfelejtenem. Ezt mar en is irtam, de kb. mindenki mas is irta. Attol fuggetlenul, hogy sose fog senki se ranezni. *EGY LEHETSEGES HIBALEHETOSEG*. Tudsz rola -> szuntesd meg.

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Az ESP-hez lesz kötve egy RTC-modul, amiben van gombelem. Arra gondoltam, hogy azt tudnám távolból szinkronizálni , ha POST -tal megkülkdöm neki az időt, mondjuk egy -két naponta. Így ha le is áll a net ,vagy maga az ESP is rebootol, akkor is ki tudja olvasni az RTC -modulból a pontos időt.

Az idő formátum szerintem nem olyan gáz, hogy magyar formátumú... Vagy mi ezzel a baj ??

GET helyett mit javasolsz ?? GET /DARAB  -formát , vagy ha átteszem más portra , mondjuk TCP 90 -re    ??

Vagy mit javasolsz ?

Az ido lenyegtelen igazabol, mert azt a szerver is kuldheti, es az esp kivonhatja az addigi merest, de ez mar azert kicsit brutal hibakezeles, hogy atomtamadasra is felkeszulunk:)

Szerintem az RTC nem lenyeges. A boottol eltelt idot szamolod es a mereshez elmented azt is, meg az aktualis idot, meg az utolso szinkronizalas ota eltelt idot.

Es vagy kliens vagy szerver oldalon korrigalsz ha kell. A szerver a keresben elkuldheti a sajat idejet.

 

> Az idő formátum szerintem nem olyan gáz, hogy magyar formátumú... Vagy mi ezzel a baj ??

UTC. Ha mindig mindenhol azt mented, azzal szamolsz, akkor sose lesz problemad. Amint elkezded a lokalis idot bekavarni, elobb-utobb szopoagra futsz.

Ez amolyan okolszabaly. Kijelezni persze lokalisban jelzel ki. De a program mindig UTC-ben ment, azt kuldi es azt fogadja.

 

> GET helyett mit javasolsz ?? GET /DARAB  -formát , vagy ha átteszem más portra , mondjuk TCP 90 -re    ??

 

GET /DARAB?parameter1=value1&parameter2=value2 hogyha kell, pl:

GET /DARAB?servertime=2021-02-13T17:13:51.184Z&previous_checksum=412586

 

Erdemes egy watchdog funkciot is betenni:

GET /WATCHDOG?a=40&b=2

Es a valasz az 42. Azaz a kliens valaszol *es* nincs kifagyva, mert kiszamol valami egyszeru feladvanyt, amit te adsz fel.

 

A valaszidot is beirhatod az esp valaszaba (response_time: 123ms). Jo lenne sima json-okat adnia.

 

Nem szabvanyos port szerintem marhasag. Minden kereshez uj szerver uj porton?:) esp nem is tudja imho...

Rendes REST protokoll, GET, POST, PUT, DELETE. Ebbol kell boldogulni. Mindent jozan paraszti esszel atgondolsz es hajra.

Ha valamiben nem vagy biztos (most PUT van POST legyen), akkor szanj ra 10-15perc google idot, es azutan donts.

 

Jo lenne egy sima .md fajlba betenni a hibalehetosegeket, es arra mit csinaltal, meg az egeszet egy git projektbe.

(pl.

1. hibalehetoseg: nincs jel,

megoldas: ha x ideje nem valtozott a bemenet, akkor ERROR lesz a statusz, es minden valaszba beleirom, hogy status: normal, vagy status: error

53. hibalehetoseg: nem sikerult az idoszinkronizacio

megoldas: boot ota eltelt idot es a sikertelen (vagy sikeres) idoszinkronizaciot is mentem egy belso valtozoba.

stb, stb)

 

Es elobb utobb az osszes felmerulo problemara lesz megoldas vagy workaround. En igy szoktam programozni.

Es a legjobb minel hamarabb kikuldeni a "terepre" a programot, mert ugyis ott derul ki, hogy mit erdemes fejleszteni rajta.

 

((OFF:

Egyszer egyik cegnel 4 honapig fejlesztettem egy eleg komoly featuret (ket motort nyomatekra kellett szinkronizalni), aztan a helyszinre kimentem,

es kerdezem a munkasokat, hogy hogyan valik be az uj rakodo markologep. Hasznaljak-e a joystick tetejen a piros gombot, ami full automatan bemarkol, es a ket kotelagat egyforman terheli es ugy emeli fel (automatan). A valasz: az egy rakas szar, mert lassu. Mi csak ugy szoktuk, hogy max sebessegen az egyik kotelagat feltekerjuk es amikor csattan a markolo, akkor a masik kotelet kicsit feljebb huzzuk, hogy ne legyen laza. Mondom, hogy ugy csak az egyik kotel viszi a teljes sulyt. Valasz: oh, kibirna ez 4x ennyit, a vasuti kocsikat is meg szoktuk emelgetni vele, hogy biztos mindent kirazzunk belole.

Fasza mondom, 4 honapnyi melo. ))

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

ugy latom, hogy a NTP idoszinkronizacio megakasztja az egeszet. Azaz internet is kell a mukodeshez.

Kipróbáltam és elég egyszer szinkronizálni (akár a setup -részben)   az idót NTP-szerverről és akkor egy 
setTime(ora.toInt(), perc.toInt(), mp.toInt(), nap.toInt(), ho.toInt(), ev.toInt());  -paranccsal beállítani.

Utána nem kell többet az NTP-hez fordulni , mégis jó lesz az időkiírás.
A szinkron után kiadtam a WiFi.disconnect()  -parancsot, és lekérve az időt így  :

String ido = (String)year() + "-" + printDigits(month()) + "-" + printDigits(day()) + " " + printDigits(hour()) + ":" + printDigits(minute()) + ":" +  printDigits(second());
Serial.println(ido);

szépen kiírta wifi nélkül is. Tehát elvileg ez már nem akaszthatja meg a futást WiFi  bomláskor sem. 
Így az RTC-modul sem muszály .
Esetleg még naponta egyszer ráküldöm a szerverről az időt POST -tal.

Pipa ??

Akkor miért van benne elem ??  Véleményem szerint nem szabadna elmászni az időnek. De ha igen , naponta egyszer ráküldöm a szerverről az időt POST-tal, vagy jelzem, hogy "most kérd le az NTP-től, mert van internet !".

Vagy mit javasolsz ??

ha nincs az ESP-n az ido szinkronizalva, akkor problemasabb lesz visszakuldeni azt az idopontot hogy melyik adat van mar elteve sql-be es melyiket lehet az ESP-rol torolni.

az ESP nem tud esetleg tobb programot futtatni? egyik az NTP-t intezne, masik a szamlalast, harmadik a http szervert

neked aztan fura humorod van...

Az ESP-n egyébként van "háttértár", azaz újraindulás után is emlékezni fog a bejegyzésekre?

Erre a célra, hogy időbélyeggel azonosítsuk az eseményeket, még mindig nem kell szinkronizált óra, elegendő, ha monoton növekvő az óra, amit egy 1970-ről indított RTC is teljesít.

A szál elején szerintem azért szólt be valaki az NTP+RTC-re, mert az NTP lib, ha nem elérhető az NTP szerver, akkor blokkolni fogja a futást, és nem teljesül, hogy hálózatkimaradáskor is számlálunk. Erre jó megoldás, ha teljesen elhagyjuk az ESP idejének a szinkronizálást, mint végsősoron feleslegest. Ez csak egy lehetőség.

Nyilván elvben megoldható az NTP nem blokkoló futása is ESP-n, de ha esetleg alapból nem ilyen a lib, akkor az komoly programozással ját.

Azért, hogy tápellátási zavar esetén is menjen a beépített óra, azért van benne elem. Az, hogy szerinted nem szabadna elmásznia az időnek, az a te véleményed - ha lenne olyan megfizethetően olcsó elektronikus óra, ami nem mászik el, akkor nem kéne ntp-szerver se: egyszer a gyárban beállítanák az időt, aztán ketyegjen szépen... De sajnos ilyen elektronikus óra nincs, ezért aztán kell az ntp, ami -nem véletlenül- külön protokollt kapott - ami alkalmas arra, hogy a szinkronizálás időigényét is korrekten figyelembe vegye - ergo a "naponta egyszer ráküldöm a szerverről az időt POST-tal" nagyon nem jó ötlet (A kliensed kiolvassa az időt, összerakja belőle a request-et, elküldi, a túloldal megkapja, feldolgozza, kihámozza belőle az időt, és beállítja az óráját. És ekkor a "kiolvassa az időt" és a "beállítja az óráját" között eltelt idővel máris el vagy csúszva...

> Így az RTC-modul sem muszály .

nem muszaj

 

> Esetleg még naponta egyszer ráküldöm a szerverről az időt POST -tal.

 

NEm kell neked NTP szervert irni:) Elkuldod az idot a szerverrol, oke. De azzal ne szinkronizald az esp orajat, hanem azzal szamolj.

Az orat azert nem jo szinkronizalni, mert lazan osszejon 0.5 sec hiba. A szinkronizaciot hagyd meg az NTP protokollnak, ahol valami 3ms a max hiba (majd valaki kijavit).

 

Szoval minden kerdesben elkuldod a szerver idejet (UTC-ben), ha az esp-nek nem jo a sajat oraja (nem volt ntp szinkronizacio), akkor a szerver idejevel szamol,

de a sajat orajat nem igazitja hozza.

 

Pelda: 20210214  20:29:00 -et kuld a szerver (UTC), az esp oraja meg 19700201 12:30 -on all. Akkor az osszes meres idejet ebbol vonod ki (19700201 12:30), igy a meresek -10perc12mp-e volt, meg -10perc13mp. Igy a valaszban a 20210214 20:18:48, meg 20:18:47 -et kuldesz.

 

Egyebkent az esp-ben van eeprom, oda is menthetsz, hogy az ido ne 1970-tol induljon ha veletlenul elment volna az aram.

Saying a programming language is good because it works on all platforms is like saying anal sex is good because it works on all genders....

Szerkesztve: 2021. 02. 13., szo – 14:34

Ez meg az, amit a vezetőség figyelget ..

http://mail.matrametal.hu/konzol/kimutatasok/charts.php

( A négyszögek  - vagy mik -   kattinthatók )

Az AEROSOL H1 sor darab mérése már az ESP32 -modullal működik , a  többi még a régi Banana PI-vel, amin egy általam elbaszott sekvenciális python fut
(erre mostanában jöttem rá, hogy ezért nem stimmelnek a számok) .