Ten wpis jest rozwinięciem wpisu dotyczącego celu projektu. Tu skupię się na konkretach – konkretnych wymaganiach, konkretnych technologiach i przypadkach użycia. Opisane technologie są tymi, które na ten moment mam w głowie do realizacji danego zadania. Wynikły z researchu dokonanego przeze mnie, wcześniejszych doświadczeń i trochę z popularności danego rozwiązania oraz chęci zapoznania się z nim. Zapraszam do czytania.
Jako, że wykonując ten projekt chcę poszerzyć wiedzę, którą już posiadam, główna aplikacja zarządzająca będzie napisana w C#. Założenie jest takie, że główna aplikacja ma działać na małym komputerku SoC (prawdopodobnie z linuxem) typu Raspberry Pi, Orange Pi lub Odroid. Test możliwości i porównanie systemów operacyjnych dostępnych na takie płytki prawdopodobnie pojawi się niedługo. Oczywiście takie testy można znaleźć w internecie, ale ten będzie bardziej pod kątem praktycznego wykorzystania danego systemu w tym projekcie. Dla linuxa sprawdzone zostaną możliwości Mono i jak to wygląda odkąd zostało wypuszczone .NET Core. Drugim systemem będzie Windows 10 IoT Core.
Nie obejdzie się bez pisania w C/C++ w przypadku aplikacji na mikrokontrolery – Atmel AVR i ESP8266 – najprawdopodobniej w środowisku Arduino. C/C++ znam ze studiów – powiedziałbym, że nawet dobrze. Jednak brakuje mi doświadczenia. Ostatnio w C++ pisałem (a właściwie poprawiałem) grę, którą kiedyś napisałem na studiach. Było to zaraz po tym jak pojawił się standard C++11. W tym miejscu jednym z ciekawych problemów do rozwiązania będzie zapewnienie modułowości rozwiązania. W C++ nie ma refleksji (a może już jest?), a dodatkowo trzeba uporać się z problemem małej ilości pamięci – zwłaszcza w przypadku mikrokontrolerów Atmel AVR. Niedługo pojawi się wpis opisujący moje pierwsze kroki z AVR’ami, który będzie także częściowo omawiał ten problem.
Posiadam także płytkę Intel Galileo Gen1, ale najprawdopodobniej nie wykorzystam jej do niczego – z Arduino działa słabo, a w roli serwera aplikacji Raspberry Pi (lub inna tego typu płytka) nada się bardziej. Być może napiszę coś więcej o tym, dlaczego zdecydowałem się jej nie używać lub może coś się zmieni w tym temacie.
Wymagania
Poniżej opiszę wymagania jakie chciałbym, żeby projekt implementował. Wszystkie z nich są technicznie realizowalne, jednak w realnym środowisku mogą okazać się niepraktyczne lub mogą po prostu nie realizować funkcji jaka została zamierzona np. wykrywanie osoby przy wejściu do mieszkania na podstawie twarzy – może się okazać, że czas potrzebny do wykrycia twarzy będzie dłuższy niż czas w jakim twarz jest widoczna w kamerze, co w konsekwencji spowoduje że dana funkcja nie będzie działać. Drugim przykładem może być wymaganie do działania funkcji rozpoznawania mowy usytuowania mikrofonów bezpośrednio przy twarzy – gdy będą one np. zamontowane w ścianie, to rozpoznawanie mowy nie będzie działać.
Wymagania niefunkcjonalne
Są to wymagania niezwiązane bezpośrednio z żadną z funkcji systemu. Jednak niektóre wymagania funkcjonalne oraz decyzje techniczne są bezpośrednio związane z danym wymaganiem. Większość poniższych wymagań będzie miało osobne wpisy opisujące konkretne decyzje projektowe jakie zostały w związku z danym wymaganiem podjęte wraz z opisem powodów tych decyzji.
Modułowość / Uniwersalność
Jest to wymaganie, które bezpośrednio wynika z celu projektu. W praktyce będzie polegało na tym, że będzie można dołączać pluginy. Architektura powinna być odpowiednio zaprojektowana, żeby było to możliwe. Powinna być otwarta na rozszerzanie i zablokowana na modyfikacje. – coś w stylu Open Closed Principle, ale na poziomie aplikacji (zamiast klasy).
Bezpieczeństwo
Dostęp do systemu powinien być zabezpieczony hasłem (logowanie), aby osoby niepowołane, które uzyskają dostęp do sieci lokalnej w mieszkaniu nie mogły z niego korzystać. Dodatkowo warto by było zaimplementować proste mechanizmy wykrywania niepożądanych zdarzeń oraz potencjalnych błędów konfiguracyjnych.
Łatwość instalacji i konfiguracji
Intuicyjny interfejs
Wymagania funkcjonalne
Poniższych wymagań jest już sporo i większości z nich nie uda mi się szybko zaimplementować. Po pierwsze wymaga to czasu, a po drugie brakuje mi sprzętu do tego potrzebnego. Tematy, które rozpoznam lub zaimplementuje opiszę szczegółowo na blogu.
- Mixer audio – X wejść liniowych i X wyjść liniowych. Możliwość łączenia wyjść z wejściami. Pre i post processing danych dźwiękowych. Efekty dźwiękowe.
- Streaming audio – DLNA Player i Receiver, bluetooth (w tym odbieranie połączeń) oraz inne (np. internetowe audio).
- Sterowanie oświetleniem, wentylacją – X wejść i X wyjść. Sterowanie przez przekaźniki. Jako osobny moduł Controllino PLC, ale także jako przekaźniki podłączane bezpośrednio do RPI lub mikrokontrolera.
- Sterowanie listwami LED. Predefiniowane animacje m.in. na podstawie aktualnie odtwarzanego dźwięku (VU Meter). Animacje można podpiąć pod każde zdarzenie (patrz wstępne cechy architektury).
- Dzwonek mp3 – możliwość odtworzenia dźwięku na zajście zdarzenia. Możliwość przyciszenia obecnie odtwarzanego dźwięku.
- Centrum wideo – kamery, sterowanie, nagrywanie. Wykrywanie ruchu (nawet jak kamera tego nie wspiera).
- Wykrywanie twarzy i identyfikacja osób – kamera przy wejściu.
- Wykrywanie ruchu – czujki PIR.
- Sterowanie głosem – mikrofony w kontaktach, może w suficie.
- Informacje głosowe – na niektóre zdarzenia zostanie odtworzona informacja głosowa np. „Witaj Czesio” jak w Jetsonach.
- Sterowanie ogrzewaniem – bezprzewodowe głowice termostatyczne.
- Sterowanie na pilota – moduły pilota w suficie i w różnych miejscach np. sterowanie TV, wentylatorem.
- Bezprzewodowe przyciski – jako dodatkowe wejścia.
- Wykrywanie obecności – m.in. sprawdzanie czy jego telefon jest połączony z siecią domową.
- Powiadamianie – różne sposoby: dźwięk, oświetlenie, email, na telefon.
- Centrum pluginów – do łatwego ściągania i instalacji. Mniej więcej coś takiego w WordPressie. Być może przy użyciu NuGeta i konwencji tagów.
- Statystyki – zapisywanie zdarzeń pozwoli na wygenerowanie wykresów – jednak to późniejszy etap.
Wstępne cechy architektury
- Zdarzeniowa – przyciśniecię przycisku wywołuje odpowiednie zdarzenie, które może być złapane przez różne handlery. Z każdym zdarzeniem są wysyłane parametry urządzenia, który wygenerowało zdarzenie (identyfikator, data, inne). Zdarzenie może być przetworzone przez różne handlery, ale może też być zablokowane jego dalsze procesowanie.
- Identyfikatory – wszystkie urządzenia mają identyfikatory i nazwy. Istnieją zależności między urządzeniem, a jego lokalizacją (Pokój 1, 2 itd.), która nie jest wymagana.
- Logowanie zdarzeń – każde zdarzenie będzie logowane (do statystyk). Dodatkowo będą zdarzenia „specjalne” (jaki typ będą miały jeszcze nie wiem np. Important), które będą działać tak, że będą wyświetlane w panelu dashboard i będą posiadać informacje o nowo podłączanych urządzeniach np. nowo podłączony komputer do sieci, nowo dodane urządzenie (wraz z jego identyfikatorem), żeby łatwo odnaleźć te informacje.
- Plug & Play – automatyczne wykrywanie nowo podłączonych urządzeń.
W kolejnych wpisach opiszę bardziej szczegółowo projekt architektury, podjęte decyzje projektowe oraz wyniki przeprowadzonych testów, które wpłynęły na daną decyzję – głównie związanych z możliwościami spełnienia danego wymagania.