Jedną z fajniejszych rzeczy w zawodzie programisty jest to, że można napisać sobie oprogramowanie spełniające dowolne zachcianki – na przykład, by dodać nowe funkcje do posiadanych urządzeń peryferyjnych. Dziś opisuję taką właśnie historię. Napisałem plugin, dzięki któremu Stream Deck zyskał możliwość wyświetlania statystyk bloga w czasie rzeczywistym.
Stream Deck to programowalna klawiatura, w której każdy klawisz wyświetla dowolną grafikę, wspominałem o tym gadżecie tutaj. Sprzęt jest pomocny podczas szkoleń i prezentacji, ale… na co dzień leżałby nieużywany. Dzięki pluginowi może służyć do ciągłego podglądu ważniejszych parametrów pracy serwisu.
Dwa lata temu opisałem, jak śledziłem bieżącą liczbę czytelników bloga za pomocą zestawu kolorowych LED-ów podłączonych przez USB. Był to model BlinkStick Strip z oferty marki BlinkStick. Metoda sprawdzała się fajnie, ale w danej chwili widziałem tylko jedną wartość liczbową.
Oczywiście dałoby się wymyślić sposób na kodowanie informacji o bieżącym trendzie, np. przeznaczyć jedną diodę na informację „odwiedzalność rośnie/spada szybko/wolno”, ale raczej niewiele ponad to.
Skoro jednak teraz mam do dyspozycji piętnaście małych ekraników, to może by coś z nimi zrobić? No więc siadłem i zrobiłem – oto, co pokazuje mój Stream Deck, gdy tylko nie prowadzę zdalnej prezentacji ani szkoleń.
Oczywiście aranżacja funkcji może być dowolnie modyfikowana. Wystarczy w programie konfiguracyjnym przeciągnąć treść do innej ramki, by Stream Deck od razu odwzorował taką zmianę. Możliwe jest też stronicowanie widżetów i grupowanie ich pod jednym klawiszem.
Opis zawartości ekraników
Gdy piszę ten tekst, układ klawiszy wygląda u mnie następująco. Poniżej opiszę poszczególne bloki funkcjonalne.
Social media
Podstawową funkcją dolnego bloku klawiszy jest prezentacja liczby fanów Informatyka Zakładowego na Twitterze, Facebooku, LinkedInie oraz YouTube (lajkujcie i obserwujcie bez wahania!). Wyświetlam też liczbę abonentów newslettera.
Przy okazji – przycisk Facebooka pokazuje nie tę wartość, którą powinien. Chciałbym prezentować liczbę obserwujących (ok. 3800) zamiast lubiących profil (ok. 3400), ale API Facebooka zwraca w obu przypadkach mniejszą wartość. Błąd czeka na poprawkę od czterech miesięcy.
Ponieważ nie wgapiam się w Stream Decka non-stop, raczej nie zauważyłbym zmian w prezentowanych cyferkach. Postanowiłem więc skorzystać ze sposobu, w jaki systemy pokładowe Boeingów zwracają uwagę pilotów na sytuacje wymagające uwagi – jest to tzw. Master Caution system.
Gdy liczba na danym przycisku wzrośnie, obwódka zaczyna mrugać na żółto. Jednokrotne wciśnięcie klawisza kasuje alert – aż do kolejnej zmiany.
Co jednak robić, gdy jakiś tweet pójdzie wiralem i nowy obserwujący pojawia się co kilka minut? Albo tweeta zacytuje Niebezpiecznik, co oznacza setkę followersów w godzinę lub dwie? Wówczas należy wcisnąć i przytrzymać przycisk, by do odwołania zablokować wyświetlanie alertów w danym panelu. O blokadzie informuje ikonka.
Statystyki czasu rzeczywistego
Źródłem danych dla tego bloku przycisków jest Google Analytics. Kiedyś sprawdzałem, na ile wartości tam prezentowane odwzorowują rzeczywistość – nie jest najgorzej, choć im więcej adblokerów, tym bardziej niedoszacowania liczba czytelników. Podobnym ograniczeniom podlegają zresztą i samodzielnie hostowane skrypty pokroju Matomo, bo adblockery tną wszystko jak leci.
Panel po lewej to wykres pokazujący pomiary oglądalności z minionego kwadransa. Skala jest automatyczna, rozciąga się od zera do maksymalnej wartości z prezentowanego interwału. Środkowy panel to liczba osób odwiedzających bloga obecnie. Po prawej stronie widać źródła ruchu, czyli: wejścia bezpośrednie, wyszukiwarka Google, Facebook, Twitter oraz LinkedIn. Rozmiar słupków jest skalowany względem sekcji z największą wartością.
Obciążenie systemu
Ten blok przycisków nie ma przełożenia na działanie bloga, wyświetla najważniejsze parametry pracy komputera. Dawniej miałem tylko XMeters oraz Process Explorera, teraz doszedł Stream Deck.
Dwa panele po lewej stronie zapewniają podgląd obciążenia poszczególnych rdzeni procesora. Na desktopie z 16-wątkowym procesorem (Ryzen 3700X, 8C/16T) wyświetlam obciążenie ośmiu fizycznych rdzeni; na laptopie (Core i7-1195G7, 4C/8T) prezentuję raportowane obciążenie z podziałem na wątki. Czerwony segment każdego słupka to zadanie realizowane na rzecz jądra systemu operacyjnego.
Dwa panele po prawej stronie prezentują łączne obciążenie procesora (CPU) oraz zajętość pamięci (RAM). Słupek pokazuje bieżące statystyki, odjeżdżająca w lewo wstęga daje wgląd w wartości z ostatnich 20 sekund.
Najmniej intuicyjnym wskaźnikiem jest „queue” czyli rozmiar kolejki procesów gotowych do wznowienia pracy. Jeśli wartość ta jest większa od zera, to – mówiąc kolokwialnie – procesor „nie nadąża”. Zdarzało się to znacznie częściej w czasach, gdy pamięci RAM było mniej a tzw. plik wymiany rezydował na dysku talerzowym. Na tym wykresie wyróżniam tylko dwa stany – kolejkę zerowej długości (pasek zielony) oraz kolejkę większą od zera (kolor czerwony). Kolor czerwony trwający dłużej niż pół sekundy widuję jednak na dobrą sprawę tylko przy montażu wideo albo kompilacji dużych projektów.
Puste miejsca
Co wstawić w puste miejsca? Chwilowo w jednym z nich mam funkcję wyciszania dźwięków, ale po odpaleniu kolejnego kursu pojawi się tam zapewne podgląd wartości sprzedaży albo czegoś w tym rodzaju.
Stos technologiczny i przykładowy kod
Oprogramowanie Stream Decka działa pod Windows i MacOS, interfejs programistyczny (SDK) jest oparty o komunikację przez WebSockety i komunikaty w formacie JSON. W teorii istotnie ułatwia to tworzenie pluginów, które będą niezależne od platformy – szczególnie gdy sam plugin będzie napisany w Javascripcie.
Moim ulubionym językiem programowania jest jednak C#, więc mój plugin ma formę pliku EXE. Czy zadziała pod MacOS? Nie do końca – mimo, że środowisko .NET od dawna pozwala na tworzenie oprogramowania działającego na makach. Liczniki social mediów oraz analityki czasu rzeczywistego są oparte na wywołaniach API, tu nie byłoby problemu. Jednak w przypadku statystyk działania CPU i RAM-u, dane zbierane są z metryk systemu operacyjnego i zadziałają tylko pod Windows.
Przykładowy kod pobierający dane z Facebooka wygląda tak:
var s = await new HttpClient().GetStringAsync(
"https://graph.facebook.com/v12.0/me?fields=id%2Cname_with_location_descriptor%2Cfollowers_count%2Cfan_count&access_token=TOKEN");
var doc = JsonNode.Parse(s);
fbFollowers = (int)doc["followers_count"];
Podczas pisania plugina skorzystałem z już istniejącej biblioteki SharpDeck – dzięki niej komunikacja ze Stream Deckiem to bułka z masłem.
Zawartość przycisku to bitmapa 72×72 piksele, po której rysuję standardowymi metodami klasy System.Drawing.Graphics
, czyli FillRectangle
, DrawImageUnscaled
albo DrawString
. Przekazanie obrazka do urządzenia zapewnia następujący fragment kodu:
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Png);
byte[] byteImage = ms.ToArray();
var str = Convert.ToBase64String(byteImage);
SetImageAsync("data:image/png;base64," + str);
Obsługa wciskania klawiszy jest jeszcze prostsza, np. kod resetujący alert to:
protected async override Task OnKeyPress(ActionEventArgs<KeyPayload> args)
{
blinking = false;
}
Chcesz kupić Stream Decka?
Jeśli nosisz się z zamiarem kupna Stream Decka, będzie mi miło, jeśli zechcesz skorzystać linków afiliacyjnych – otrzymam niewielki procent od kwoty, którą wydasz.
Oto linki do sklepu x-kom.pl: Stream Deck Mini, Stream Deck MK.2, Stream Deck XL.
O zyskach z tego typu akcji piszę regularnie w tekstach z serii „Kulisy bloga”, na przykład tutaj. W ciągu dwóch lat blogowania linki afiliacyjne Ceneo przyniosły mi 195 zł, szału nie ma. Dziś testuję więc, jak sprawy będą się miały przy współpracy ze sklepem x-kom – jeden procent od zakupu Stream Decka to więcej, niż kilkanaście przeklików w Ceneo.
Jeśli chodzi o model Stream Decka, to zacząłem od modelu Mini (6 przycisków). Wystarczał do przełączania widoków podczas szkoleń, ale nie mieścił widżetów opisanych w tym artykule. Zmieniłem go więc na model MK.2 (15 przycisków) i ten rozmiar spełnia oczekiwania. Na razie nie mam potrzeby inwestowania w Stream Decka XL.
Dlaczego nie open-source?
Odpowiedź na powyższe pytanie jest przeznaczona dla osób, które nie mają na co dzień do czynienia z rozwojem i utrzymaniem oprogramowania.
Oto główny powód, który przesłania wszystko inne: tworzenie opisanych wyżej funkcji i patrzenie, jak działają, niosło radość. Aby z plugina zrobić produkt, którego będą mogły użyć inne osoby, trzeba dodatkowo sporo pracy żmudnej i nudnej. Gdy piszę coś tylko dla siebie, mogę te nieprzyjemne obszary zwyczajnie pominąć.
Co wymagałoby dodatkowej pracy?
Po pierwsze – musiałbym udokumentować, w jaki sposób zdobyć klucze API do pobierania danych z serwisów społecznościowych. W przypadku Facebooka pozyskanie tokena o przedłużonej ważności jest procedurą złożoną, niezrozumiałą i na dodatek zmieniającą się wraz z ewolucją serwisu. W przypadku Google Analytics korzystam z przestarzałego mechanizmu, niedostępnego już chyba dla nowych kont. Słowem – problem.
Po drugie – musiałbym zadbać o to, aby klucze API dało się podać w oknie konfiguracyjnym widżetów Stream Decka, odpowiednio je walidować i przechowywać. Teraz są osadzone w kodzie źródłowym.
Po trzecie – w kodzie nadal jest kilka usterek trudnych do odtworzenia i debugowania, np. czasem przy wybudzeniu komputera z uśpienia plugin przestaje działać prawidłowo. Nie ma też obsługi innych konfiguracji rdzeni/wątków, niż moja – tymczasem procesory na rynku mają od 2 do 64 rdzeni. To wymagałoby zaprojektowania nowych kontrolek prezentujących rozmaite kombinacje słupków.
Po czwarte – w wielu miejscach poszedłem na skróty, np. wszystkie bitmapy przygotowałem z myślą o klawiszach mających rozdzielczość 72×72 piksele. W modelu Stream Deck XL jest to 96×96 pikseli, dla optymalnego efektu wizualnego wymagane byłyby dodatkowe zasoby graficzne.
I to wszystko bez gwarancji, że komukolwiek przyda się taki plugin – przecież wszystko w nim robiłem pod siebie…
Weźmy się i zróbcie!
Opublikowanie kodu pod licencją Open Source sprawia, że w opinii wielu osób autor zobowiązuje się do wieczystego utrzymania projektu. Już zawsze odpowiedzialny będzie za poprawianie zgłoszonych błędów, dostosowanie kodu do nowych wersji bibliotek i frameworków, tworzenie nowych funkcji zgodnie z zapotrzebowaniem użytkowników – i nie tylko. W wielu przypadkach realizacja takich życzeń (lub wręcz żądań) kończy się wypaleniem. Polecam lekturę blogonotki Dennisa Schuberta, opisał on dokładnie taką sytuację.
Mój plugin nie jest żadnym cudem, kompetentny programista byłby w stanie zaimplementować jego funkcje od zera w ciągu kilku dni. Z tego właśnie powodu nie uważam, by otworzenie kodu w jego obecnej postaci przyniosło światu szczególną korzyść. Na pewno byłoby powodem do wstydu dla mnie, bo programując na własne potrzeby, na szybko i na brudno, złamałem wiele dobrych praktyk.
Zróbmy więc tak: jeśli ktoś chciałby pociągnąć temat, może dostać e-mailem źródła w obecnym kształcie – bez moich kluczy API i bez gwarancji, że kod przyda mu się do czegokolwiek. A jeśli powstanie z tego jakiś plugin z prawdziwego zdarzenia, chętnie go tu podlinkuję.
A (prawie) wszystko dzięki… Hack Friday w DeepL
Aby było jasne – ten tekst nie jest sponsorowany i nie jest płatną promocją akcji rekrutacyjnej. Uczciwość wymaga jednak, by wspomnieć, że znacząca część kodu mojego plugina powstała podczas Hack Friday – jednego dnia w miesiącu, podczas którego pracownicy DeepL mogą rozwijać swoje zainteresowania i pasje w godzinach pracy. A to tylko jeden z bonusów w firmie, które dostarcza najlepszy na świecie system do automatycznego tłumaczenia tekstów między 26 językami.
Pracuję w tej firmie od trzech kwartałów i jestem bardzo zadowolony. Jeśli programujesz, rozglądasz się za zmianą i rozważasz pracę zdalną – zerknij na stronę deepl.com/jobs. Gdy znajdziesz coś ciekawego, przed wysłaniem CV-ki możesz odezwać się mailem i podlinkować swój profil w LinkedIn, powody wyjaśnię osobiście.
O autorze: zawodowy programista od 2003 roku, pasjonat bezpieczeństwa informatycznego. Rozwijał systemy finansowe dla NBP, tworzył i weryfikował zabezpieczenia bankowych aplikacji mobilnych, brał udział w pracach nad grą Angry Birds i wyszukiwarką internetową Microsoft Bing.
12 odpowiedzi na “Centrum sterowania blogiem”
Bardzo dobry wpis. Jak na te 15 min, które poświęciłeś dzisiaj (Hack Friday) na jego wykreowanie.
Merytoryczna krytyka:
1) do kogo ten tekst jest skierowany? Ilu czytelników posiada Stream Deck? Ilu kupi go po coś więcej niż wciskanie przycisków z domyślnymi funkcjami?
2) nieumieszczenie kodu wtyczki (jako linku do pobrania) dałoby Ci aż dwa plusy dodatnie – zainteresowany czytelnik (czyli na oko jeden dziwak) ściągnąłby gotowca i jeśli by go nie użył po dostosowaniu pod siebie to przynajmniej przejrzał i zobaczył rozwiązania jakie zastosowałeś (przecież po to upublicznia się kody żeby inni nie wyważali otwartych drzwi), a dla Ciebie plus taki, że ten nieużywany przycisk zaprogramowałbyś do wyświetlania pobrań kodu wtyczki w czasie rzeczywistym, co dałoby Ci zajęcie na piętnaście następnych Hack Friday’ów 🙂
3) najważniejsze – grafiki wyświetlane na przyciskach wyglądają po prostu nieestetycznie. Tu coś się rozjeżdża, a tam jest krzywo, a poza tym to tak naprawdę wyświetlane dane są nieprawdziwe i w sumie to mogłeś te dane zawrzeć „na sztywno” w samym kodzie źródłowym (pewnie dlatego go nie udostępniasz, przyznaj się).
Na zakończenie, z okazji Fun Friday (u mnie) życzę udanego weekendu i jak najmniej Hack Friday’ów bo notki pisane w pracy na użytek prywatny są słabsze niż ten Twój laptopowy Core i7-1195G7 z wyprzedaży.
Wpis to dwie reklamy – Stream Decka oraz samego siebie jako headhuntera blogowego.
Daję znać, że krytykę przeczytałem, przyjąłem, ale nie mogę powiedzieć, że w pełni zrozumiałem. Może z wyjątkiem fragmentu o nieestetycznych przyciskach – tu się w pełni zgadzam 🙂
(do usunięcia)
Strasznie nieczytelny jest mój wcześniejszy komentarz. Jeśli w komentarzach można stosować BBCode lub jakieś inne formatowanie tekstu to mógłbyś dodać taką informację widoczną przy dodawaniu komentarza?
Pozdrawiam.
Nie zgodzę się z Hello World.
Rozważam zakup Stream Deck MK.2 od jakiegoś czasu. Takie artykuły które pokazują, że można samemu programować wymyślone funkcje są kolejnym argumentem za.
Również nie zgodzę się z Hello World.
Artykuł stanowi świetną inspirację do własnych projektów. Do tej pory nawet nie wpadłem na to, że akcesoria do streamingu nie muszą służyć do streamingu. Mogą być to wszelkiej maści panele kontrolne, a ogranicza nas tylko wyobraźnia.
Kiedyś by wykonać takie cuda trzeba było projektować płytki, lutować, wymyślać interfejsy komunikacyjne. A teraz – wystarczy podłączyć gotowe urządzenie do USB i napisać troszkę kodu w C#. Jest nawet aplikacja na Linuxa (nieoficjalna), więc może da radę wykorzystać SDK też na Linuxie, choćby Raspberry Pi. Po prostu niezwykłe możliwości.
Ja się zgodzę z „niepopularną” opinią. Za bardzo nie wiem, dlaczego miałbym kupić tego StreamDecka, jeszcze jakbym strimował to miałoby jakiś sens. Te wszystkie informację, mogę odczytać z kolejnego monitora obok.
Fajny tekst, dzięki.
Po jego przeczytaniu też zapragnąłem mieć takie cudo, ale to tylko zakupoholizm mnie do tego popycha, więc mam nadzieję się powstrzymać 🙂
Natomiast zupełnie nie szanuję komentarza Hello World, na początku myślałem, że krytykujesz fakt napisania tego kodu w trakcie pracy (w sumie nie rozumiałbym po co, ale spoko haters gonna hate), ale po przeczytaniu tego komentarza po raz drugi wnioskuję, że krytykujesz bo… uważasz, że takie urządzenie jest niepotrzebne?
Matko bosko, to w takim razie co musisz czuć zaglądając na aliexpress czy dajmy na to – na elektroda pl? Tyle rzeczy, których nie potrzebujesz, oszaleć można!
Ja się zawsze zastanawiałem czy StreamDecka nada się jako konsola do stanowiska CCTV, tu pokazujesz iż jak najbardziej tak. Tylko zapewnię nie prosto z pudełka. Ale pokazuje, iż się da.
Do tego ciekawy pomysł z wykorzystaniem idei Master Caution system.
„(..) samodzielnie hostowane skrypty pokroju Matomo, bo adblockery tną wszystko jak leci.” – jeżeli samodzielnie hostujemy dane oprogramowanie to możemy dowolnie podmieniać nazwy subdomen i endpointów (np. pozbycie się słów „analytics”, „tracker”, „count” itp). Powinno wystarczyć do zliczania czytelników z adblockiem. Takie rozwiązanie ma jeszcze jedną zaletę – nie przekazujemy danych naszych użytkowników do podmiotów zewnętrznych i najprawdopodobniej zakres danych, które zbieramy nie stanowi danych osobowych (w przypadku Google są one korelowane z informacjami pozyskanymi z baz Google i aktywności na innych stronach wczytujących skrypt Analytics, więc nie ulega wątpliwości że są to dane osobowe). A do przetwarzania danych osobowych w tym przypadku trzeba mieć zgodę użytkownika – część takiej nie wyrazi więc efekt podobny jak z adblockiem.
W sumie z innej beczki, a po części odnośnie posta @TJ, to czy nie ma systemów statystyk, który mógłby się opierać o pliki logów serwera www? Zdawało mi się, iż Piwik był takim systemem. Ale nie jestem pewien czy Matomo dalej ma tą funkcję.
Cześć. Czy jest możliwość, aby dodatek do Stream Decka wywoływał okno dialogowe celem wprowadzenia przez użytkownika jakichś danych przekazanych następnie do pluginu? Choćby parametry do zapytania w API innej usługi.
W standardowych kontrolkach tego nie ma, w API Javascriptowym też nie. Nie ma natomiast problemu w przypadku natywnych pluginów – one mogą robić co chcą, np. w reakcji na wciśnięcie guzika otworzyć okienko dialogowe.