Artykuł o sterowaniu diodą oraz odczycie stanu przycisku pokazały w jaki sposób kod może sterować urządzeniami, oraz badać ich stan. Żaden z projektów nie wykorzystywał jednak połączenia z internetem, więc ciężko mówić że były to przykłady implementacji internetu rzeczy. Czas to poprawić. Kolejny projekt będzie polegał na sterowaniu przełączaniu diody w jednym ESP po naciśnięciu przycisku podpiętego do drugiego.
Cyfrowy bliźniak
Podczas projektowania systemów IoT często wykorzystuje się wzorzec architektoniczny „Cyfrowy bliźniak”.
Polega on na stworzeniu cyfrowego modelu fizycznego przedmiotu, zawierającego jego oczekiwany stan oraz opis zachowań w reakcji na zdarzenia. Model ten może ulegać częstym zmianom i poprawkom więc umieszczenie go na serwerze dostawcy albo w chmurze obliczeniowej jest rozsądnym rozwiązaniem.
Fizyczny obiekt jest opleciony czujnikami, pozwalającymi obserwować zarówno jego samego jak i jego otoczenie, oraz elementami sterującymi (silniki, grzałki, chłodnice, diody) pozwalającymi ten obiekt zmieniać. Elementy te są połączone z kilkoma układami cyfrowymi. Kod na tych układach jest dość prosty: pobrać dane z serwera na temat oczekiwanego stanu sterowanych elementów, ewentualnie wysłać na serwer informacje o istotnych odczytach z czujników (zdarzeniach).
Kod serwera
W przypadku tego projektu kod serwera jest prosty. Serwer ma mieć dwa kanały komunikacji: jeden pozwalający lampce dowiedzieć się czy jest włączona i drugi którym przycisk przekazuje informację że został wciśnięty. Ważną zaletą tego rozwiązania jest fakt że przycisk nie wie że lampa istnieje i vice versa. Pozwala to rozszerzać układ o dodatkowe elementy (czujniki ruchu, nauczanie maszynowe) bez konieczności zmiany kodu na urządzeniach.
Serwer zrealizowałem jako aplikację web, wykorzystującą protokół http, która posiada dwa punkty końcowe: /led i /button odpowiadające urządzeniom.
Oczekiwany stan urządzenia jest zwracany jako odpowiedź na wywołanie GET, ponieważ układ z przyciskiem nie posiada oczekiwanego stanu jest on zaimplementowany tylko dla diody. Punkt /led zwraca wartość „ON” albo „OFF” w zależności od tego czy w danym momencie dioda ma być włączona czy zgaszona.
Zdarzenia są rejestrowane w obsłudze wywołań POST, która pozwala na przesłanie szczegółów zdarzenia w ciele metody. Układ z diodą LED nie generuje żadnych zdarzeń, więc punkt działa tylko dla przycisku. Wciśnięcie przycisku przycisku nie niesie ze sobą żadnych dodatkowych informacji więc ciało wywołania jest ignorowane. Stan diody jest przechowywany w pamięci RAM co ułatwia implementację.
Aplikację można zrealizować w dowolnej nowoczesnej technologii, ja zdecydowałem się ASP.Net MVC Core. Można ją jednak zaimplementować w dowolnej technologii.
Drobna uwaga dotycząca technologii PHP. Zmienne statyczne w tej technologii są dostępne w zakresie wywołania, przez co stan diody nie może być przechowywany w pamięci należy ją przechowywać w zewnętrznym magazynie np. plik, cache Redis albo baza danych.
Aplikację stworzyłem tworząc katalog Twin, otwierając w nim okno poleceń i wpisując w nią:
dotnet new webapi
Polecenie wymaga wcześniejszego zainstalowania środowiska .Net core dostępnego na stronie https://dotnet.microsoft.com/download pod przyciskiem „Download .Net Core SDK”
Następnie usunąłem klasę ValueController znajdującą się w katalogu Controllers oraz dodałem klasę IndexController.
using Microsoft.AspNetCore.Mvc;
namespace Twin.Controllers
{
[ApiController]
public class ValuesController : ControllerBase
{
private static string _ledState = "ON";
[HttpGet("led")]
public ActionResult<string> Get()
{
return _ledState;
}
[HttpPost("button")]
public void Post()
{
_ledState = _ledState == "ON" ? "OFF" : "ON";
}
}
}
Szablony w .net core domyślnie wymuszają szyfrowaną komunikację (https), co jest wskazane dla rozwiązań produkcyjnych, jednak nadmiarowo komplikuje ten przykład. Aby wyłączyć to zachowanie należy z pliku Startup.cs usunąć linijkę:
app.UseHttpsRedirection();
Natomiast w pliku Program.cs zmienić metodę CreateWebHostBuilder na:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(opt => { opt.ListenAnyIP(5000); })
.UseStartup<Startup>();
}
Ostateczna wersja programu jest do pobrania pod tym linkiem: Twin.zip. Aby go uruchomić należy rozpakować archiwum, otworzyć wiersz poleceń w katalogu gdzie je rozpakowano i wpisać:
dotnet run
Aplikacja zacznie nasłuchiwać na połączenia na porcie 5000.
Dzień dobry!
Skorzystałem z tego artykułu teraz (sty, 2023), zainstalowałem
Microsoft .NET SDK 6.0.405 (była jeszcze do wyboru 7.0).
Przy uruchomieniu Twin miałem komunikaty o potrzebie doinstalowania Microsoft ASP.NET Core 2.2.8 i Microsoft ASP.NET Core Runtime – 2.2.8, co zrobiłem.
Server ruszył, ale wcześniej pojawił się komunikat „… warning NETSDK1138: platforma docelowa „netcoreapp2.2″ nie jest już obsługiwana i w przyszłości nie będzie otrzymywać aktualizacji zabezpieczeń. …”.
Nie jestem zaznajomiony z .NET i prosiłbym o radę co i jak zmienić w projekcie Twin, żeby pracować na aktualnych wersjach platformy .NET?
Z góry dziękuję,
Andrzej Bluszcz