andreidiaconescu.wordpress.com
Open in
urlscan Pro
192.0.78.12
Public Scan
URL:
https://andreidiaconescu.wordpress.com/
Submission: On November 25 via api from US — Scanned from GB
Submission: On November 25 via api from US — Scanned from GB
Form analysis
2 forms found in the DOMPOST https://subscribe.wordpress.com
<form method="post" action="https://subscribe.wordpress.com" accept-charset="utf-8" style="display: none;">
<div>
<input type="email" name="email" placeholder="Introdu adresa ta de email" class="actnbr-email-field" aria-label="Introdu adresa ta de email">
</div>
<input type="hidden" name="action" value="subscribe">
<input type="hidden" name="blog_id" value="66740030">
<input type="hidden" name="source" value="https://andreidiaconescu.wordpress.com/">
<input type="hidden" name="sub-type" value="actionbar-follow">
<input type="hidden" id="_wpnonce" name="_wpnonce" value="e0ca1a2387">
<div class="actnbr-button-wrap">
<button type="submit" value="Înregistrează-mă "> Înregistrează-mă </button>
</div>
</form>
<form id="jp-carousel-comment-form">
<label for="jp-carousel-comment-form-comment-field" class="screen-reader-text">Scrie un comentariu...</label>
<textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Scrie un comentariu..."></textarea>
<div id="jp-carousel-comment-form-submit-and-info-wrapper">
<div id="jp-carousel-comment-form-commenting-as">
<fieldset>
<label for="jp-carousel-comment-form-email-field">Email (obligatoriu)</label>
<input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field">
</fieldset>
<fieldset>
<label for="jp-carousel-comment-form-author-field">Nume (obligatoriu)</label>
<input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field">
</fieldset>
<fieldset>
<label for="jp-carousel-comment-form-url-field">Site web</label>
<input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field">
</fieldset>
</div>
<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="Publică comentariul">
</div>
</form>
Text Content
Sari la conținut ANDREI DIACONESCU MENIU PRINCIPAL Meniu * Prima pagină * Din viața de zi cu zi * Când mă chinuie talentul * Tehnologie * Foto & Video * Poezie & Proză * PiXeL Ne0XiS * Colecția de monede * Monede cu povești * Despre mine JURNAL 14.08.2024 14 august 2024Andrei Diaconescu Lasă un comentariu A trecut un an de când scriam această filă de jurnal și dacă mă uit la întrebările pe care mi le puneam atunci aș putea spune că unele au răspuns, altele nu dar au mai apărut alte întrebări între timp. A trecut un an și nu am mai purtat acea discuțe. Mi-a luat ceva timp să îmi accept și eu partea mea de vină în tot acel conflict. Un lucru pe care pe care l-am avut a fost orgoliul, poate puțin cam mare și nu m-a ajutat deloc atunci. Partea bună e că în ultimul an am mai lucrat la el. Nu pot să schimb ce a fost, ce-am făcut pot doar să învăț, să accept și să merg înainte fără a repeta greșelile pe care le-am făcut. Cel mai important lucru pe care l-am învățat este acela de a gândi în nuanțe de gri – adevărul este undeva la mijloc în relațiile și conflicetele interumane și nimic nu este doar alb sau negru, bun sau rău, doar o parte greșește și cealaltă nu are absolut nici o vină, etc. Aș vrea să spun poate mai multe, dar vreau mai întâi să îmi fac ordine în gânduri iar lucruri pe care le spun să fie comunicate într-o manieră cât mai asertivă. P.S. Dacă ajungi să citești aceste rânduri, cu toate că nu am purtat discuția, îți mulțumesc și îți doresc multă fericire și să ai pace interioară. JURNAL 01.05.2024 1 mai 2024Andrei Diaconescu Lasă un comentariu Au trecut 5 luni și nu m-am simțit pregătit să discut acest subiect dar cred că este timpul să o fac. Am crezut că dacă îmi văd de viață o să am liniște dar se pare că nu e așa. S-au scris multe, s-au zis multe, s-a creat „artă” din tot ce am zis, ce am făcut ca într-un final să îți câștigi imaginea de artist. Cred că e timpul să îmi spun și eu povestea mea, versiunea mea a poveștii pentru că până acuma am tăcut și nu mi-a păsat de „arta” ta, dar observ că în continuare, dacă nu ai tu ultimul punct de vedere nu se poate încheia discuția. Știu că sunt un bau-bau pentru tine și pentru urmăritorii artei tale că doar așa am fost portretizat de către tine. Nu știu dacă ți-ai făcut prieteni cu această artă și câtă apă îți dau la moară dar mă bucur că ți-ai găsit fani. O să îi numesc fani în continuare pentru că totul este doar la suprafață(În opinia mea! Preceizez asta că altfel ies interpretări), îi întâlnești doar după cele 3 minute de glorie pe care le ai pe scenă și după uită de tine sau în primele 3 zile după ce publici ceva nou(aș fi zis inițial o zi dar îmi apare că ai platit pentru reclamă așa că o să zic 3). Dragă cititorule, Dacă ai citit până aici și crezi că sunt hater să știi că sunt în acest context și pe acest subiect. Este în regulă dacă nu vrei să citești mai departe, o să vină și alte articole mai interesante. În continuare o să fac o analiză a cuvintelor „context” și „subiect” raportat la artistul nostru. Îți acord premiul întâi pentru scoaterea din context a mai multor discuții avute cu mine și mixarea subiectelor. Pe baza acestui mix ai creat un personaj pe care l-ai folosit în arta ta, cu toate că nu i-ai dat un nume, au fost destui oameni care l-au asociat cu mine, cu ce am făcut în trecut, cum sunt eu, etc. Nu spun că am făcut doar lucruri bune că am făcut și eu o prostii acum 10 ani, dar nu o să le tot folosesc de dragul artei(o să revin la acest subiect puțin mai jos). Ți-am spus atunci că mă deranjează lucrul acesta iar într-un final mi-a zis următoarea replică: „Dacă oamenii sunt proști și își fac o părere despre tine raportat la ce scriu, nu este problema mea…”. Ironia a făcut că la momentul publicării unei astfel de postări, nici nu apucasem să citesc postarea dar deja aveam un mesaj pe messenger care suna cam așa: „…X avea dreapte, trebuia să îți dau block…” și ce a fost dureros a fost faptul că venea de la persoană la care țineam mult de tot. Revenind la prostiile pe care le-am făcut acum mai bine de 10 ani, sunt lucruri de care nu sunt mândru și nu are rost să le enumăr aici; am făcut oameni să sufere, am trecut dintr-o extremă în alta în ceea ce privește empatia(de la prea multă la mi se rupe de toți și toate). Nu pot să șterg ce am făcut, pot doar să învăț să nu mai repet aceleași greșeli. Am avut multe momente când eram frustrat și mai am și acuma uneori dar nu le mai transform în „artă” pentru că nu mai rezoz cu asta. Acum o lună, povesteam cu cineva referitor la poeziile pe care le-am scris și sunt postate aici pe blog și am spus că nu este ceva ce aș mai scrie. Am ceva drafturi legate de ceva proze de prin 2019 pe care am vrut să le public vara trecută în august dar simțeam că dacaă fac asta, o fac doar din durere. Ultima poezie pe care am scris-o a fost acum 4 ani și a fost o dedicație așa că nu cred că o voi publica vreodată. Închei aici capitolul acesta, poate o să revin ma încolo cu o continuare sau poate nu, depinde cum vor evolua lucrurile. Dacă are cineva de adăugat ceva, îl aștept în secțiunea de comentarii. JOACA CU GOOGLE ASSISTANT(4) 31 martie 202431 martie 2024Andrei Diaconescu Lasă un comentariu Cum ziceam în partea a treia(link aici) în această ultimă parte am să vă prezint cele 2 abordări cu ajutorul cărora mi-am rezolvat problema. Pentru prima abordare m-am gândit în felul următor: dacă nu pot să inițiez o conexiune securizată dispre IFTTT către serverul meu de Django, atunci să țin o comunicație deschisă dispre rețeua mea către un server de pe internet. Ce era important la această comunicație era să se realizeze automat inclusiv atunci când se lua curentul și se repornea Raspberry Pi-ul. Pe la mijlocul lui septembrie 2023 lucram la job la un PoC care implica GitLab CI/CD ca build server iar GitLab Runner-ul era un workstation fizic. Un lucru fain la runneri de Gitlab este acela că îi poți avea hostați la tine local în rețea. După ce ai înregistrat un runner, îl poți instala ca și serviciu iar acesta se va connecta automat la serverul de Gitlab chiar și după un restart al PC-ului. Pornind de la cele menționate anterior am dezvoltat următoarea soluție: 1. Am configurat ca și Gitlab runner unul din Raspberry Pi-uri. 2. Comanda vocală dată cu Google Assistant era preluată de IFTTT, iar ca și răspuns executa un POST request către Gitlab, mai precis un trigger al unui pipeline. 3. Pipeline-ul triggeruit anterior executa un script python pe runnerul configurat la pasul 1. .gitlab-ci.yml stages: - build build-job: tags: - rapi stage: build script: - echo "Run script..." - python turn_on_pc.py turn_on_pc.py from wakeonlan import send_magic_packet import tinytuya send_magic_packet("MAC_ADDRESS", ip_address=BROADCAST_ADDRESS) outlet=tinytuya.OutletDevice("DEVICE_ID", "IP_ADDRESS", "LOCAL_KEY") outlet.set_version(3.3) outlet.turn_on() În scriptul de mai sus se poate observa că pe lângă PC, pornesc și boxele. Arhitectura soluției Soluția de mai sus a funcționat dar avea o mică problemă: între momentul în care era programat să se execute pipeline-ul și execuția propriu zisă era o întârziere de 5-10 secunde. După aproape două săptămâni de la rulat soluția anterioară în urma unei discuții foarte interesante cu un coleg de la birou, acesta mi-a sugerat să folosesc soluția Zero Trust a celor de la Cloudflare. O descriere în mare a soluției pentru problema mea presupune ca toate requesturile făcute către un domeniu să ajungă la Cloudflare, iar acestea să fie redirectate către rețeua mea privată printr-un tunel. Pentru implementarea soluției și accesarea aplicației în mod securizat am urmat următorii pași: 1. Mi-am cumpărat un domeniu .cloud cu 1$/an de la Hostinger. În setările am adăugat 2 intrări pentru DNS/Nameservers de la Cloudflare. 2. Am instalat softul pentru tunel inițial pe NUC și după pe Raspberry Pi. Cel mai important lucru este acela ca device-ul pe care îl instalezi să fie pornit tot timpul. 3. După ce m-am asigurat în platforma Zero Trust că tunelul era accesibil am adăugat pe rând Public Hostname. Poți adăuga un întreg domeniu pentru o aplicație sau poți adăuga un subdomeniu și astfel poți expune public mai multe aplicații. 1. Un lucru foarte important de reținut este atenția la tipul serviciului expus, respectiv setările suplimentare pentru anumite servicii. 4. Pentru fiecare aplicație de la pasul anterior am adăugat politci de securtitate și acces. Pentru KADMA am adăugat 2 politici de acces: prima bazată pe email iar cea de-a doua bazată pe un service token. Acestui token i se poate seta o perioada de valabilitate. Pentru a face requesturi de tipul POST folosind tokenul, se adaugă Additional Headers sub forma: CF-Access-Client-Id: f4fc170ecc34ac78b34815d4e1e956eec3d.access CF-Access-Client-Secret: 0236235236a5a8981eeb29f4e55819c25e7cbe42c54979683c179704ec2e și astfel doar serviciile autorizate pot să execute requesturile către server. Arhitectura aplicației folosind soluția Zero Trust de la Cloudflare Un lucru pe care mai doresc să îl menționez este faptul că acum o lună am migrat toate aplicațiile de pe Raspberry Pi în containere de Docker care rulează pe NUC, poate o să detaliez într-un alt articol. În continuare o vă prezint un mic demo: CUM AM REZOLVAT PROBLEMA CU WAKE-ON-LAN LA PC? 26 decembrie 202326 decembrie 2023Andrei Diaconescu Un comentariu Spuneam în articolul Joaca cu Google Assistant(2) de faptul că Wake-on-LAN(WoL) nu funcționa corespunzător pe PC. PC-ul se „trezea” când venea Magic Packet doar dacă era în sleep. De menționat este faptul că PC-ul are în componența sa o placă de bază Asus TUF GAMING Z590-PLUS WIFI iar criteriile pentru care am ales-o în 2021 au fost următoarele: * suporta procesoare Intel din generația a 11-a; * are Wifi/Bluetooth – îmi este mult mai ușor să conectez căști bluetooth fără dongle sau să conectez PC-ul pe Wifi la o rețea diferită(pe atunci mă jucam cu un VM cu Kali Linux și mă jucam cu 2 routere); * are porturi SATA suficiente; * placa de rețea este mai mare de 1Gb în contextul în care doresc să îmi fac rețea 10Gb, iar placa aceasta este de 2.5Gb. Am asamblat PC-ul, am făcut toate setările prin BIOS, am instalat un Windows 10 Pro cu toate driverele, am făcut toate setările prin Windows pentru WoL și când testez WoL nu pornea. Am verificat din nou IP-ul asignat, adresa MAC, setările din Windows, setările din Bios și nimic. I-am făcut update de BIOS la ultima versiune de pe site-ul producătorului, am reinstalat driverul pentru placa de rețea de pe site-ul producătorului de data aceasta și tot degeaba. Pe un forum am găsit că era o problemă de driver și că să încerc un driver mai vechi și am încercat și asa dar degeaba. Dacă scoteam PC-ul din priză, îl puneam înapoi îl puteam porni din WoL dar după dacă îi dădeam shutdown și încercam să îl pornesc nu mai pornea. Din sleep pornea fără nici o problemă și să las PC-ul pe sleep mereu când sunt plecat de acasă sau din oraș nu prea era o soluție care să mă încânte. Verificam odată la câteva luni dacă apărea un driver nou sau un update nou de BIOS, îl făceam și aveam speranță că o să se rezolve problema dar degeaba, mereu același comportament. În toamna aceasta în septembrie, într-o zi nu eram acasă dar îmi trebuia un document din PC și m-am frustrat destul de tare să accesez documentul și am hotărât să caut o soluție definitivă. Am mai încercat toate artificiile din BIOS și din drivere pe care le mai văzusem pe forumurile de la Asus și Intel și am ajuns la concluzia că placa de rețea de pe placa de bază are o problema și am hotărât să îmi cumpăr o placă de rețea externă. După ce m-am uitat peste mai multe plăci am comandat-o pe aceasta: TP-Link TG-3468 pentru că avea recenezii bune iar prețul destul de bun(53 lei la vremea aceea). Am conectat placa în portul PCIe x1 cel mai de jos al plăcii de bază și i-am instalat driverul pentru Windows 10. Pentru WoL i-am asiganat un IP static pe router și am adăugat-o în aplicația KADMA. Am testat-o atunci de cel puțin 10 ori, pornire din shutdown, din sleep și în sfarșit după atâta timp PC-ul pornea așa cum trebuie. De atunci, dacă am nevoie de ceva din PC și nu sunt acasă tot ce trebuie să fac este să îi dau drumul din KADMA și după Remote Desktop de pe telefon. JOACA CU GOOGLE ASSISTANT(3) 19 noiembrie 202326 decembrie 2023Andrei Diaconescu Un comentariu După problema prezentată în partea a doua(link aici) am vrut să folosesc soluții de home automation care să permită atât integrări cu producători de device-uri smart cât și să pot rula scripturi personalizate cu care pot interacționa cu diferite device-uri conectate la Arduino/Raspberry Pi(cum era neopixelul). Prima soluție pe care am testat-o a fost Home Assistant. Cu toate că am instalat-o ușor, mi-am bătut capul 3 zile și nu am reușit nici cum să o fac să îmi ruleze scripturilepersonalizate scrise în python. A doua soluție pe care am testat-o a fost openHAB și din nou m-am bătut de aceleași probleme ca și în cazul Home Assistant așa că am renunțat și la aceasta. Țin să precizez faptul că ambele soluții menționate mai sus le-am testat în perioada octombrie-noiembrie 2021 și între timp nu știu ce schimbări și îmbunătățiri au fost aduse de către comunitățile lor. Tot în perioada aceea mi-am cumpărat o priză inteligentă și un set de 3 becuri inteligente de la LEDVANCE. Configurarea lor a fost destul de ușoară: instalezi pe telefon aplicația LEDVANCE SMART+ WiFi, îți faci un cont , în momentul în care le dai curent la dispozitive prima dată intră în modul de configurare și o să fie detectate în aplicație, le adaugi, selectezi Wifi-ul și merge direct. Am adăugat contul de LEDVANCE și în aplicația Home de la Google și îmi apăreau device-urile și în aceasta și le puteam controla de aici, inclusiv vocal cu Google Assistant. Am avut nevoie de becuri pentru lampa de la birou pentru funcțiile de setare ale intensității și temperaturii luminii deoarece sunt momente când am nevoie de o lumină mai caldă, alteori mai rece. Priza am cumpărat-o pentru boxele de la PC, pentru că era foarte enervant să mă tot aplec de fiecare dată să le dau drumul și după să le opresc pentru că butonul de pornit oprit se află pe Subwoofer. Priza și becurile mi-au rezolvat problemele doar pe jumătate pentru că pentru a putea porni/opri device-urile fie dădeam comanda vocală, fie din aplicația Home sau LEDVANCE. Lucrul acesta mă facea dependent de internet și de telefonul mobil(da, atât aplicația Home cât și LEDVANCE nu aveau varianta disponibilă pentru Desktop/Web). Pentru a nu fi dependent de telefonul mobil am incercat să folosesc un emulator pentru Android pentru PC dar mergea destul de greu și am renunțat. Am folosit folosit doar comanda vocală și aplicația Home până prin luna februarie 2022. În anul universitar 2021-2022 în semestrul 1 am predat prima dată laboratorul de Administrarea Sistemelor de Operare iar la acest laborator era și o parte de proiect ce presupunea dezoltarea unei aplicații Web în Django. Eu nu mai lucrasem cu Django și nici mulți dintre studenții mei iar la final de semestru văzând că au dus la capăt proiectele am hotărât două lucruri: să învăț Django și să fac o schimbare în carieră trecând de la echipa de Local IT la echipa de DevOps. Am stat o săptămână și m-am jucat cu Django ca să înțeleg puțin cum trebuie organizat un proiect, aplicațiile din el, pachete, etc. iar lucrul acesta m-a făcut să iau o decizie: o să dezvolt aplicația web de home automation în Django, pentru că pot interacționa atât cu device-uri smart cât și cu scripturi personalizate scrise de mine în python. În luna februarie a anului 2022 am început să dezvolt împreună cu prietena mea de atunci(Mulțumesc mult!), proiectul KADMA, o aplicație Django pentru home automation. Aplicația suportă autentificarea basic din Django și permite interacțiuni cu 2 tipuri de componente: * Devices – reprezintă computerele din rețeua mea. Cu toate că în imaginea de mai jos sunt prezente atât butoane de Start cât și de Sleep, doar Startul a fost implementat folosind scriptul de Wake-on-LAN din partea a doua. KADMA – Devices * Smart things – reprezintă device-urile smart din casă(becuri, prize, etc). Când am dezolvat componenta aceasta am ținut cont de faptul că o să am device-uri de la diferiți producători de aceea requesturile trebuie să fie cât mai generice. KADMA – Smart Things În baza de date am stocat producătorul ca și câmp text așa cum se poate vedea mai jos. from django.db import models # Create your models here class SmartThing(models.Model): class Vendor(models.TextChoices): UNKNOWN = "UNKNOWN" LEDVANCE = "LEDVANCE" TPLINK = "TPLINK" PHILIPS = "PHILIPS" class Type(models.TextChoices): BULB = "BULB" OUTLET = "OUTLET" OTHER = "OTHER" name = models.CharField(max_length=20) ip_address = models.GenericIPAddressField() mac_address = models.CharField(max_length=17) vendor = models.CharField(max_length=20,choices=Vendor.choices,default=Vendor.UNKNOWN) type = models.CharField(max_length=20,choices=Type.choices,default=Type.OTHER) device_id = models.CharField(max_length=30) local_key=models.CharField(max_length=30) description = models.CharField(max_length=100) În operațiile cu aceste device-uri m-am folosit Factory Method pentru a putea crea obiecte în funcție de producător, iar pe baza producătorului metodele specifice în funcție de biblioteci. class Vendor(): def __init__(self): pass import tinytuya from smart_things.vendors import vendor from smart_things.models import SmartThing class Ledvance(vendor.Vendor): def __init__(self,smart_thing): self.smart_thing=smart_thing if self.smart_thing.type == SmartThing.Type.OUTLET: self.device = tinytuya.OutletDevice(self.smart_thing.device_id, self.smart_thing.ip_address, self.smart_thing.local_key) elif self.smart_thing.type == SmartThing.Type.BULB: self.device = tinytuya.BulbDevice(self.smart_thing.device_id, self.smart_thing.ip_address, self.smart_thing.local_key) else: self.device = None self.device.set_version(3.3) def turn_on_outlet(self): self.device.turn_on() def turn_off_outlet(self): self.device.turn_off() def turn_on_light(self): self.device.turn_on() def turn_off_light(self): self.device.turn_off() def get_color(self): info = self.device.state() if info['mode']=='colour': (r, g, b) = self.device.colour_rgb() else: (r, g, b) = (255,255,255) return (r, g, b) def set_color(self,rgb): self.device.set_mode("colour") self.device.set_colour(rgb[0],rgb[1],rgb[2]) def get_white(self): return self.device.colourtemp() def set_white(self,white): self.device.set_mode("white") self.device.set_white(colourtemp=white,brightness=self.device.brightness()) def get_brightness(self): info = self.device.state() if info["mode"] == "white": brightness = self.device.brightness() else: (h,s,v) = self.device.colour_hsv() brightness = int(v*1000) b = int(((brightness) * 100) / 990) return b def set_brightness(self,brightness): self.device.set_brightness_percentage(brightness) def get_state(self): if self.smart_thing.type == SmartThing.Type.OUTLET: data = self.device.status() return data['dps']['1'] elif self.smart_thing.type == SmartThing.Type.BULB: data = self.device.state() return data['is_on'] else: return False from smart_things.models import SmartThing from smart_things.vendors.ledvance import Ledvance class VendorFactory(): def __init__(self): pass def getVendor(name): smart_thing = SmartThing.objects.get(name=name) if smart_thing.vendor == SmartThing.Vendor.LEDVANCE: return Ledvance(smart_thing) return None VendorFactory.getVendor = staticmethod(VendorFactory.getVendor) Partea bună la produsele de la LEDVANCE o reprezintă faptul că sunt bazate pe platforma de la Tuya, deci pot fi programate ușor din python prin biblioteca tinytuya. Pentru a le programa ai nevoie de DEVICE_ID, IP_ADDRESS și LOCAL_KEY. Dacă îți legi contul de la aplicația Tuya Smart la platforma de developement ar trebui să poți obține Device ID-ul și Local Key-ul device-urilor pe care le-ai adăugat în aplicație. Partea proastă e că cei de la LEDVANCE au modificat device-urile în așa fel încât să nu le poți adăuga în aplicația celor de la Tuya și implicit nu ai acces la Device ID și Local Key. Ca să obțin Device ID si Local key m-am folosit de tutorialul acesta. În timp ce scriam la articol am găsit și repoul acesta și soluția propusă aici mi-a dat atât Device ID-ul cât și Local Key-urile. Odată ce am terminat de dezvoltat aplicația, am hostat-o pe un Raspberry 3 unde rulează și astăzi. Arhitectura rețelei utilizând KADMA ca și aplicație de home automation Pentru a reintroduce comenzile vocale din IFTTT, în decursului anului 2022 am încercat 3 abordări dar fără succes: 1. Să deschid un port random pe router și să încerc să îi pun regulă să poată fi accesat doar de IP-ul de la IFTTT dar IP-ul de la care veneau requesturile se schimba. 2. Să folosesc aplicația TriggerCMD dar nu am reușit sa o configurez și nici nu mi-am bătut capul prea tare cu ea. 3. Să fac requesturile din IFTTT într-o manieră secure – am căutat dacă pot adăuga un layer de securitate din IFTTT dar din păcate nu suportă lucrul acesta. Singura soluție care îmi rămăsese era să modific aplicația astfel încât layerul de securitate să fie în aceasta dar din diferite motive am tot amânat să mai fac vreo modificare. Între timp mi-am pus server de VPN pe router ca să pot accesa resursele din rețea când eram plecat de acasă. După ce am rezolvat problema cu Wake-on-LAN la PC în septembrie 2023 am mai încercat două abordări pentru comenzile vocale care au funcționat, dar despre acestea o să vorbesc în partea a 4-a. JOACA CU GOOGLE ASSISTANT(2) 29 octombrie 202326 decembrie 2023Andrei Diaconescu 2 comentarii Au trecut aproape 2 ani și jumătate de când am scris prima parte(link aici) iar în această perioadă s-au întâmplat multe în ceea ce privește automatizările pe care le-am făcut în casă. Vă recomand să citiți și prima parte pentru a avea mai mult context pentru ceea ce urmează. După ce m-am distrat cu neopixelul, am vrut să îmi pornesc și să îmi opresc PC-ul tot așa folosind comenzi vocale. Am analizat întâi ce implementări erau pe IFTTT pentru acest lucru și soluțiile propuse erau următoare: * Pentru pornire: 1. Comanda vocală dată cu Google Assistant era preluată de IFTTT, iar ca execuție îți dădea trigger la o aplicație pe care trebuia să o ai instalată în telefon. 2. Aplicația din telefon făcea la rândul ei trigger către o altă aplicație din telefon pentru Wake-on-LAN(WoL). Limitarea acestei soluții presupunea să ai telefon conectat la același WiFi în care se afla și PC-ul. * Pentru oprire: 1. Comanda vocală dată cu Google Assistant era preluată de IFTTT, iar ca execuție îți scria un fișier în contul de Google Drive sau One Drive. 2. Mai trebuia să ai o aplicație custom pe PC care rula ca și serviciu și îți monitoriza locul unde se sincroniza Google Drive sau One Drive. Când detecta un fișier într-un folder specific, apela în spate shutdown. Soluțiile propuse atât pentru pornire cât și pentru oprire mi se păreau limitate și greoaie de aceea am luat decizia să îmi dezvolt propriile soluții. Pentru pornire m-am folosit următoarele lucruri: * Aveam deja experința de la neopixel cu apelatul scriptului în python, deci râmanea doar să fac Wake-on-LAN via python. Wake-on-LAN este un protocol pentru pornirea calculatoarelor aflate în sleep sau complet oprite. Pentru a putea fi „trezit” calculatorul este nevoie să fie activată din BIOS funcția de Wake-on-LAN și pe PC-urile cu Windows mai trebuie făcute ceva setări în plus la placa de rețea. Principiul după care funcționează este următorul – calculatoarele oprite așteaptă să primească un Magic Packet pe portul LAN. Pachetele de genul pot fi trimise de pe routere sau diferite softuri. Pachetul se trimite ca și broadcast în rețea și conține adresa MAC a plăcii de rețea a PC-ului pe care dorim să îl pornim. * Nu am vrut să implementez de la 0 trimiterea pachetului magic în python așa că am folosit pachetul python wakeonlan în scriptul meu. from wakeonlan import send_magic_packet send_magic_packet("F0.2F.AA.DB.63.AA") Pentru oprire am stat mai mult ca să găsesc o soluție care să nu implice softuri externe și singura soluție la care am ajuns a fost să am o conexiune prin SSH între Raspberry Pi și PC, iar de pe Raspberry să vină comanda de shutdown. Pașii pentru dezvoltarea acestei soluții au fost următorii: * Mi-am instalat pe PC serverul de SSH default de la Microsoft. * Mi-am modificat autentificarea pe bază de utilizator/parolă în autentificare pe bază de chei. * Cheile generate la pasul anterior le-am mutat și pe Raspberry Pi. * Când venea un request pe server web, se apela următorul script în bash. #!/bin/bash ssh andrei@192.168.1.50 "shutdown 0" & exit; După câteva ore și teste m-am gândit că decât să oprească PC-ul mai bine să îl pună pe sleep. ssh andrei@192.168.1.50 "rundll32.exe powrprof.dll,SetSuspendState 0,1,0" & exit; Un lucru important pe care vreau să îl menționez este faptul că eu în rețeaua mea folosesc IP-uri statice pentru PC-uri, Raspberry Pi și cam orice este legat pe fir, deoarece uneori nu mergea conectarea prin ssh folosind numele device-ului. Arhitectura soluției În imaginea de mai sus se mai pot observa două lucruri: 1. Un POST request de la IFTTT către ISP. ISP-ul meu este Digi iar conexiunea mea la internet este de tipul PPPoE. Asta înseamnă că IP-ul pe care mi-l asignează este dinamic iar la o conectare ulterioară(în cazul unui restart al routerului din varii motive) să fie altul decât acela pe care l-am avut. Dacă totuși vrei o conexiune către rețeaua ta de acasă, cei de la Digi îți oferă gratuit serviciul de Dynamic Domain Name System(DDNS). Tot ce trebuie să faci este să intri în contul tău Digi și să îți alegi un nume pentru subdomeniu și vei putea folosi acest subdomeniu ca să îți poți accesezi resursele din rețeua internă. Subdomeniile oferite de Digi sunt de forma: numeAles.go.ro unde numeAles este subdomeniul ales de mine. Mecanismul din spatele DDNS într-o explicație mai simplă este următorul: în loc să folosești IP-ul, folosești subdomeniu iar de traducerea din subdomeniului în IP se ocupă serverul de DDNS. ex: GET request către http://numeAles.go.ro/pagina1.html va face în spate un request către http://86.125.142.34/pagina1.html. 2. Un port forwarding de pe portul 80 al routerului pe portul 80 al Raspberry Pi-ului. Pentru accesa o resursă privată din internet va fi nevoie ca requestul care va veni pe router să fie redirecționat către device-ul din rețea care conține resursa. Redirecționarea presupune deschiderea unui port extern pe router unde vor ajunge requesturile iar pachetele de date care vor ajunge pe router la acel port vor fi trimise către un anumit IP și port din rețeaua privată. ex: GET requestul http://86.125.142.34/pagina1.html ajunge pe router. Portul 80 este deschis și este setat în router să facă redirecționare către Raspberry Pi tot pe portul 80, deci requestul nostru va fi ca și requestul http://192.168.1.20/pagina1.html făcut din rețeaua privată. Soluția descrisă mai sus a funcționat fără nici o problemă pe NUC pentru că pe el am făcut dezvoltarea ei(februarie 2021) dar nu a funcționat cum trebuie partea de pornire pentru PC(PC-ul l-am construit în aprilie 2021 și problema era că nu voia să se „trezească” când venea Magic Packet decât dacă era în sleep. O să detaliez într-un alt articol cum am rezolvat problema pentru că mi-am bătut capul cu ea aproape 2 ani – Update: link articol). În luna iulie 2021 am revenit la Cluj ca să îmi susțin disertația, pe atunci încă stăteam la cămin iar device-urile au rămas la Sighișoara. La începutul lunii septembrie m-am mutat în chirie, mi-am făcut abonament la Digi și mi-am adus cam toate device-urile la Cluj. Mi-am luat un router nou și am asignat IP-urile private la device-uri în așa fel încât să fie ca pe cel din Sighișoara. Pe abonamentul nou creat mi-am activat DDNS iar în POST requesturile făcute de IFTTT am schimbat subdomeniul. Totul era funcțional și mergea cum trebuie până într-o dimineață(octombrie 2021) când m-am trezit și am observat că NUC-ul era pornit(pe atunci nu puteam să îl pornesc din buton pentru că se oxidase ceva contact la el și singurul mod de pornire era WoL) și neopixelul era aprins și lumina foarte puternic în ceva culoare aleatoare. Mă gândeam dacă am vorbit ceva în somn și Google a interpretat dar am zis că mai bine să verific logurile serverului de Apache. Am văzut acolo în listă o grămadă de încercări de POST/GET request-uri de la diferite IP-uri de prin Asia și după mi-a picat fisa că am fost atacat. Site-ul așa cum arăta în ziua atacului. Site-ul meu web era ceva simpluț un pic de html cu php, ceva butoane și cam atât. Ce nu m-am gândit să îi pun a fost o metodă de autentificare și de aici faptul că oricine din internet putea să facă requesturi către el. Cel mai probabil cineva a scanat întreg subnetul din care făcea parte și IP-ul pe care îl aveam de la ISP și găsind portul 80 deschis a dat în el cu tot ce a putut(prin loguri se vedeau încercări cu diferite tooluri din Metasploit). Văzând cele întâmplate am dezactivat port fordwaring de pe portul 80 și am hotărât să caut o altă soluție care să fie sigură atunci când se fac requesturi dinspre IFTTT spre rețeaua mea. În următoarele părți ale acestei serii o să vă prezint ce soluții am mai încercat și cum am ajuns la o soluție finală. JURNAL 13.08.2023 13 august 202314 august 2024Andrei Diaconescu Un comentariu A trecut o noapte și încerc să îmi revin, să mă pun pe picioare și să cred că a fost un vis dar nu a fost. Nici nu știu cum să încep așa că o să spun lucrurile așa cum îmi vin în minte. Eu sunt o persoană impulsivă și care știu că dacă aș răspunde la fierbinte aș regreta atât eu cât și cealaltă persoană de aceea încerc să răspund la cald. Raspunsul la cald am încercat să îl dau și eu zilele trecute în urma unui eveniment neplăcut dar într-un final am ajuns să trăiesc tot eu cu sentimentul de vinovăție pentru faptul că încă nu puteam să port discuția la cald iar persoana cealaltă nu înțelegea lucrul acesta. Am fost prins între a răspunde la fierbinte și a nu răspunde pe moment sau a răspunde sec doar pentru a nu detona bomba. Am ales a doua variantă, am răspuns sec pentru că îmi doream să mă liniștesc, să pot să port o discutie normală dar într-un final nu va mai avea acea discutie iar asta din motive ce nu țin de mine. Și acuma îmi pun întrebările: Sunt eu un om rău? De ce mă simt așa groaznic? Mai pot să fac ceva? Nu știu răspunsurile la întrebările de mai sus. Tot ce îmi doresc este să nu mă mai doară. NODEMCU & DHT11 17 februarie 2023Andrei Diaconescu Lasă un comentariu Inițial mi-am cumpărat plăcuța NodeMCU după ce am văzut acest demo despre Wifi Deauther dar mai mult am vrut să mă joc cu serverul web ce poate fi expus în interiorul rețelei de acasă de către această plăcuță. În trecut am mai folosit module ESP8266 simple dar mi se pare destul de greu de lucrat cu ele(mereu să ai grijă cum legi pinii, comenzile AT pe care le poți da, etc). Logica acestui proiect presupune citirea la fiecare 5 secunde a valorii temperaturii și umiditații folosind un senzor DHT11 iar cele mai recente 50 de valorile citite sunt stocate într-un buffer circular. Când se face un request de tipul POST de către un client, valorile din buffer sunt folosite pentru a genera pagina web care va fi servită clientului. Ca și dificulte pe care am întâlnit-o la realizarea acestui proiect a fost să găsesc o bibliotecă pentru senzorul DHT care să fie compatibilă cu NodeMCU. Pentru generarea graficului am folosit Google Charts iar pentru obținerea datei și orei am folosit biblioteca NTPClient. Codul sursă se găsește aici. Un mic demo se regăsește în videoul de mai jos. MACRO-KEYBOARD 24 ianuarie 202216 februarie 2023Andrei Diaconescu Lasă un comentariu Folosesc o tastatură mecanică de 1 an si jumătate si un lucru care îmi place mult la ea este faptul că am butoane dedicate pentru macro-uri. Le-am folosit pentru combinații simple de taste, dar utile pentru mine – Cut, Copy, Paste, Win+Shift+S , Enter – e mult mai usor după ce faci un copy-paste de undeva să dai enter tot cu mâna stângă. După ce mi-am legat neopixelul la Google Assistant, mă gândeam cum aș putea să am o consolă din care să pot controla luminile, respectiv celelate device-uri conectate în rețea fără să folosesc Google Assistant și dacă se poate dintr-un singur buton, cum sunt macro-urile. După ce am analizat mai multe posibilități am ajuns la concluzia că pentru a putea construi consola aș avea nevoie de o tastatură pe care să o pot reprograma astfel încât fiecare tastă să execute una sau mai multe comenzi. Codul sursă se găsește aici. Detalii despre cum am făcut o tastatură clasică să execute una sau mai multe comenzi se regăsesc în video-ul de mai jos. JOACA CU GOOGLE ASSISTANT(1) 2 februarie 202119 aprilie 2022Andrei Diaconescu 2 comentarii Acum aproximativ 3 săptămâni m-am apucat să fac ordine printre arduino și senzori și am găsit un NeoPixel de care și uitasem că îl am am zis hai totuși să mă joc cu el, cine știe ce idee îmi mai vine. Am reușit să îl fac să lumineze, am găsit si diferite moduri de iluminare și m-am jucat cu el câteva ore. Am zis că dacă tot nu am o lampă mai inteligentă prin casă, hai că îl fac să lumineze și eventual să îi pun un buton ca să îl opresc, dar nu am mai adăugat butonul. A mai trecut o zi și m-am gândit că: ce ar fi dacă aș putea să îl controlez pe interfața serială printr-un script python; că și așa mă jucasem cu interfața serială în python acum 3 ani când controlam laptopul printr-un arduino la care avem legată o telecomandă. Mi-am bătut capul cu transmisia de date din python către arduino prin faptul că am uitat să adaug un mic delay imediat după deschiderea interfeței seriale iar informațiile care se scriau nu ajungeau pe arduino. L-am implementat inițial cu două comenzi, una pentru a porni neopixelul(care rulează un curcubeu pe acesta) si una pentru a opri neopixelul. După ce am testat codul l-am mutat pe Raspberry Pi deoarece le el voiam să leg arduino și dacă tot l-am mutat pe Raspberry de ce să nu încerc să pot porni și opri neopixelul dintr-o pagină web că și așa aveam un server de apache cu care mă mai jucam și rula pe Raspberry. Aici începe adevărata distracție pentru că nu înțelegeam de ce nu se rula scriptul python din php. După o oră de debug pe toate părțile și încercat metode diferite de rulat, verific logurile de eroare din apache și eroarea era de la faptul că userul sub care rulam scriptul python nu avea drepturi să deschidă interfața serială către arduino. Reușesc într-un final să rezolv această problemă și în sfârșit puteam să aprind și să stâng neopixelul din interfața web atât de pe PC cât și de pe telefon. Între timp, pe lângă pornit și oprit am mai adăugat ca și funcționalități să pot seta intensitatea luminoasă respectiv culoarea în care să lumineze neopixelul. Acum că am terminat cu introducerea, de unde până unde joaca cu Google Assistant? La câteva zile după ce îmi funcționa să aprind și să sting neopixelul, într-o seară mă gândeam că mi-ar fi m-ai comod să am un asistent care să îl pornească și să îl oprească pentru mine. Aici a intervenit următoarea dilemă pentru mine: Google Assistant sau Amazon Alexa? Am cerut și eu sfaturi, ce să aleg și dintre Google Nest Mini și Echo Dot gen 3 și după ce am cântărit argumentele am optat pentru Google Nest Mini. Mă bucură tare faptul că Nest-ul meu a venit cu încărcător pentru România doar că după ce l-am băgat în priză mă salută în italiană. Chiar râdeam cu un prieten când desfăceam cutia, că e scris în italiană pe ea la care el: „O să îți zică: Ciao… când o bagi în priză” și fix așa a și fost. În continuare o să prezint partea tehnică a magiei din spatele comenzilor pentru a porni și opri cu Google Assistant neopixelul. * Pentru a prelua comanda vocală am folosit IFTTT. Platforma IFTTT îți permite ca având un trigger să se execute o comandă – If This(<trigger>) Then That(<comandă>) . Deci am folosit ca și trigger Google Assitant iar comanda pe care am vrut să o execute a fost un request de tipul POST către serverul meu de apache. * Pe server, în funcție de comanda care se afla în body-ul requestului, se apelează scriptul de python cu parametrii corespunzători. * Scriptul python trimite comanda mai departe către arduino care aprinde sau stinge neopixelul. Ce este comun atât pentru comenzile din browser cât și pentru cele date vocal sunt pașii începând cu POST requestul care se face. Am optat pentru acest mod de structurare a aplicației pentru a putea face cât mai puține modificări în dezvoltările ulterioare. În continuare vă prezint un mic demo: În perioada următoare o să vă prezint și alte comenzi pe care le-am implementat cu Google Assistant. P.S. Aș dori să le mulțumesc studenților mei pentru că m-au inspirat să mă apuc de acest proiect. NAVIGARE ARTICOLE ← Articole mai vechi * Facebook * Instagram * Youtube * Github * Linkedin Un site web WordPress.com. Tema: Wilson de Anders Noren. Andrei Diaconescu Un site web WordPress.com. * Abonează-te Abonat * Andrei Diaconescu Înregistrează-mă * Ai deja un cont WordPress.com? Autentifică-te acum. * Confidențialitate * * Andrei Diaconescu * Personalizare * Abonează-te Abonat * Înregistrare * Autentificare * Raportează acest conținut * Vezi site-ul în Cititor * Administrează abonamente * Restrânge această bară Încarc comentariile... Scrie un comentariu... Email (obligatoriu) Nume (obligatoriu) Site web Proiectează un site ca acesta, cu WordPress.com Începe