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.

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

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

Pentru a reintroduce comenzile vocale din IFTTT, în decursului anului 2022 am încercat 3 abordări dar fără succes:
- 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.
- 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.
- 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.
Lasă un comentariu