Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Poznaj Spikit API - narzędzie dla prawdziwych geeków!

Program w jego najnowszej wersji coraz częściej wykorzystują osoby wdrażające w swoich czterech kątach idee inteligentnych domów i np. sterują za pomocą Spikit popularnym na polskim rynku systemem Fibaro. Nie dziwię się im. Połączenie tych dwóch technologii przynosi wiele satysfakcji (nie mówiąc o efekcie WOW!). Jednocześnie w sieci pojawiają się jak grzyby po deszczu kolejne amatorskie lub bardziej profesjonalne projekty wykorzystujące platformy Arduino lub Raspberry Pi.

Kilku nad wyraz aktywnych użytkowników wymieniło na ten temat ze mną poglądy. Osoby te podzieliły się również pasją i planami budowy własnych, zdalnie sterowanych urządzeń. Tym, co nas wszystkich łączy jest chęć wykorzystywania wszędzie interfejsu głosowego. O ile w przypadku istniejącego już systemu Fibaro, komunikacja ze specjalną centralką odbywa się za pośrednictwem protokołu HTTP i metody GET, co nie stanowi dla Spikit żadnego problemu i nie wymaga żadnych modyfikacji oprogramowania, o tyle chęć wykorzystania rozpoznanej przez Spikit mowy w kilku różniących się od siebie projektach wymagała wprowadzenia nowego mechanizmu.

Owocem wprowadzonych zmian jest możliwość komunikowania się programu z zewnętrznymi aplikacjami w bardzo przystępny sposób tj. za pomocą potoków (named pipes). Pomysł równie prosty, co wysoce skuteczny. Tym bardziej, że komunikacja może odbywać się w dwóch kierunkach :-)

Ja rozpoznam Twoją mowę, a Ty zajmij się resztą!

Osobom zaznajomionym choć trochę z problematyką komunikacji międzyprocesowej (Inter-Process Communication, w skrócie IPC) na pewno zaświeciła się stosowna żaróweczka. Idea potoków (zarówno tych anonimowych jak i posiadających nazwę) jest przecież obecna z nami już od dawna (różowe lata 70.). Mając dwa, zupełnie odseparowane od siebie programy musimy doprowadzić do sytuacji, w której wyjście jednego programu stanowić będzie wejście dla drugiego - ot, co. Różna może być jedynie implementacja tej idei między poszczególnymi środowiskami uruchomieniowymi (Windows, Linux). Niewątpliwą zaletą potoków nazwanych jest natomiast możliwość ustanowienia komunikacji między niepowiązanymi procesami przez sieć, jednocześnie nie będąc uzależnionym od konkretnego protokołu sieciowego. Inne zalety to szybkość działania, ale także możliwość wykorzystania np. uprawnień dostępu systemu Windows w procesie autoryzacji połączenia z potokiem.

W Windows mianem potoków nazywamy po prostu pewien obszar pamięci współdzielony między dwoma procesami. Komunikacja przez taki przewód (z ang. pipe) łączący dwa procesy (programy) może odbywać się w jednym kierunku lub w sposób dwukierunkowy (dupleks). Proces, który tworzy potok nazywamy serwerem, a ten, który się z nim łączy - klientem. Więcej informacji o potokach, wadach i zaletach tego rozwiązania w kontekście IPC uzyskacie w zasobach MSDN:

Jak łatwo się domyślić, w naszym przypadku Spikit jest właśnie takim serwerem i z chwilą uruchomienia tworzy potok na komputerze lokalnym o wdzięcznej nazwie... Spikit. W chwili obecnej Spikit zezwala na ustanowienie jednego połączenia w danym czasie (kolejne będą odrzucane). Zdaje się być w miarę idiotoodporny (tego nigdy za wiele!) i przekierowuje do podłączonego klienta wszystkie polecenia, którym przypisana została akcja {POTOK_NAZWANY_PRZEKIERUJ}. Użytkownik programu może przełączać tryb pracy potoku nazwanego tak, by w informacji przekazywanej klientowi Spikit uwzględniał również transkrypcję tekstu będącą rezultatem operacji dyktowania. Na aplikacji po stronie klienta spoczywa natomiast ciężar wykonania z rozpoznanym poleceniem lub fragmentem tekstu czegoś sensownego. Więc do dzieła, hulaj dusza!

Jak to ugryźć od strony programisty?

Nie byłbym sobą, gdybym na łamach dobrychprogramów nie zamieścił przy tej okazji stosownego dobrego kodu ;-) Niezależnie od tego, czy kod ten miałby zostać wykorzystany przez Czytelnika do ustanowienia połączenia ze Spikit i wykonania jakiejś fajnej czynności, czy też miałby wejść w skład aplikacji o zupełnie innym charakterze - jest to po prostu interesujący przykład z punktu widzenia każdego programisty .NET. Brać, póki dają.

Z racji tego, że ta funkcjonalność programu ma jeszcze charakter czysto rozwojowy i może ulec drobnym zmianom, poniższy kod API należy skompilować samodzielnie i póki co próżno szukać stosownej biblioteki DLL dołączonej do oficjalnego wydania programu Spikit. Taka biblioteka na pewno pojawi się w swoim czasie. Natomiast w pełni działający przykład odnajdziecie tu. Wystarczy uruchomić oba programy jednocześnie.

Jeden ze stałych użytkowników programu zasugerował mi, abym uzupełnił program o możliwość odczytywania godziny i bieżącej daty (wzrok z czasem płata figle). Takoż czynię, ale w formie przykładowej wtyczki. Informacją zwrotną dla Spikit będzie więc informacja o bieżącej dacie i godzinie poprzedzona kilkoma słowami. Spikit odczyta na głos każdą informację tekstową przesłaną przez zewnętrzną aplikację wbudowanym głosem syntezatora mowy lub głosem firmy trzeciej (IVONA?), oczywiście jeśli głos taki będzie zainstalowany w systemie Windows. Spikit respektuje przy tym systemowe ustawienia syntezatora mowy (szybkość, barwa, itp.) wprowadzone w systemowym oknie konfiguracyjnym 'Tekst na mowę'.

SpikitAPI.PipeClient

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SpikitAPI { public class PipeClient { private bool running = true; private System.Threading.AutoResetEvent messageEvent = new System.Threading.AutoResetEvent(true); private System.IO.Pipes.NamedPipeClientStream client = null; public event EventHandler Disconnected; protected virtual void OnDisconnected(EventArgs e) { var temp = Disconnected; if (temp != null) temp(this, e); } public event EventHandler Connected; protected virtual void OnConnected(EventArgs e) { var temp = Connected; if (temp != null) temp(this, e); } public delegate void MessageReceivedEventHandler(object sender, PipeClientEventArgs e); public event MessageReceivedEventHandler MessageReceived; protected virtual void OnMessageReceived(PipeClientEventArgs e) { var temp = MessageReceived; if (temp != null) temp(this, e); } public class PipeClientEventArgs : EventArgs { public readonly string Message; public PipeClientEventArgs(string message) { Message = message; } } public bool SendToServer(string message) { bool success = false; if (client != null && client.IsConnected && client.CanWrite) // Wyślij wiadomość do serwera tylko, gdy jest taka możliwość (połączony z możliwością przesyłania danych) { try { byte[] output = System.Text.Encoding.UTF8.GetBytes(message); client.Write(output, 0, output.Length); success = true; } catch { } } Console.WriteLine(success ? string.Format("Wiadomość zwrotna została wysłana: {0}", message) : "Wystąpił błąd podczas przesyłania odpowiedzi"); return success; } public void Stop() // Zakończ pracę klienta. Wątek zakończy pracę w normalny, niezakłócony sposób (wyjście z pętli do-while). { running = false; messageEvent.Set(); } public PipeClient(string serverName = ".", System.Security.Principal.TokenImpersonationLevel impersonationLevel = System.Security.Principal.TokenImpersonationLevel.None) { System.Threading.Thread t = new System.Threading.Thread(() => { do { try { if (client == null) // Utwórz instancję klasy NamedPipeClientStream client = new System.IO.Pipes.NamedPipeClientStream(serverName, "Spikit", System.IO.Pipes.PipeDirection.InOut, System.IO.Pipes.PipeOptions.Asynchronous, impersonationLevel); client.Connect(5000); // Nawiąż połączenie z potokiem Spikit na komputerze lokalnym (serverName = ".") lub w sieci (serverName = "NAZWA_PC") Console.WriteLine("Połączyłem się"); OnConnected(EventArgs.Empty); while (messageEvent.WaitOne() && client.IsConnected) // Jeśli obiekt zasygnalizowany i gdy klient połączony, w przeciwnym razie blokuj wątek { if (!running) // Jeśli wywołana metoda Stop(), wyjdź z pętli break; Console.WriteLine("Czekam na wiadomość..."); byte[] buffer = new byte[4096]; // Domyślna wielkość bufora danych przesyłanych przez Spikit client.BeginRead(buffer, 0, buffer.Length, callback => // Wywołaj asynchroniczną metodę BeginRead i obsłuż wywołanie funkcji 'callback', gdy w potoku pojawią się nowe dane { bool error = false; try { int count = client.EndRead(callback); // Zakończ asynchroniczną operację odczytywania danych if (count > 0) { string input = System.Text.Encoding.UTF8.GetString(buffer, 0, count); Console.WriteLine("Otrzymałem wiadomość ({0}): {1}", count, input); OnMessageReceived(new PipeClientEventArgs(input)); } else { error = true; client.Close(); // Zamknij strumień, jeśli ilość przesłanych danych jest równa zeru (możliwe zerwanie połączenia po stronie serwera) Console.WriteLine("Brak wiadomości/Zerwane połączenie"); } } catch { error = true; } finally { if (error) { OnDisconnected(EventArgs.Empty); } messageEvent.Set(); // Sygnalizuj nadejście wiadomości lub zerwania połączenia (count == 0), zasygnalizuj konieczność odblokowania wątku w pętli while } }, null); } } catch (Exception e) { Console.WriteLine("Błąd/Brak połączenia: {0}", e.Message); messageEvent.Set(); // Zasygnalizuj obiekt messageEvent, umożliwiając wejście do pętli while, gdy tylko klient nawiąże połączenie z potokiem if (client != null) // Zwolnij nieużywane zasoby { client.Dispose(); client = null; } System.Threading.Thread.Sleep(5000); // Zatrzymaj wykonywanie kodu na jakiś czas przed podjęciem kolejnej próby } } while (running); if (client != null) // Zwolnij nieużywane zasoby { client.Dispose(); client = null; } }); t.Start(); } } }

Przykład aplikacji konsolowej - dla początkujących

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace NamedPipeTest { class Program { static void Main(string[] args) { SpikitAPI.PipeClient client = new SpikitAPI.PipeClient(); // Wystarczy utworzyć instancję klasy PipeClient i gotowe client.MessageReceived += new SpikitAPI.PipeClient.MessageReceivedEventHandler(client_MessageReceived); // Obsługa przychodzących wiadomości odbywa się w zdarzeniu 'MessageReceived' } static void client_MessageReceived(object sender, SpikitAPI.PipeClient.PipeClientEventArgs e) { // e.Message zawiera treść rozpoznanego polecenia głosowego lub rozpoznanej mowy (funkcja dyktowania) string message = e.Message.Trim(); // Dla pewności usuniemy wszelkie białe znaki przed oraz po wiadomości if (string.IsNullOrEmpty(message)) // Dobre przyzwyczajenie, a sytuacja mało prawdopodobna return; string reply = null; // Wykorzystamy podejście staromodne i oczywiste: if/else if/else. Dlaczego nie instrukcji 'switch'? Z uwagi na porównywanie łańcuchów 'OrdinalIgnoreCase', czyli bez rozróżniania wielkości znaków if (message.Equals("która godzina", StringComparison.OrdinalIgnoreCase)) { reply = string.Format("jest godzina {0}", DateTime.Now.ToShortTimeString()); // godzina } else if (message.Equals("jaki dziś dzień", StringComparison.OrdinalIgnoreCase)) { System.Globalization.CultureInfo locale = new System.Globalization.CultureInfo("pl-PL"); reply = string.Format("dziś jest {0} {1}", DateTime.Now.ToString("dddd", locale), DateTime.Now.ToString("d", locale)); // dzień tygodnia i data } else if (message.Equals("o co mogę zapytać", StringComparison.OrdinalIgnoreCase)) { StringBuilder result = new StringBuilder(); result.Append("Słucham następujących poleceń"); result.Append(". "); result.Append("która godzina"); result.Append(". "); result.Append("jaki dziś dzień"); result.Append(". "); result.Append("o co mogę zapytać"); result.Append(". "); result.Append("wyłącz się"); result.Append(". "); reply = result.ToString(); } else if (message.Equals("wyłącz się", StringComparison.OrdinalIgnoreCase)) { Environment.Exit(0); } else { reply = "niestety, chyba mówimy różnym językiem, bo naprawdę nie rozumiem o co tobie chodzi"; // każda inna komenda przesłana do klienta zwróci ten wynik } if (!string.IsNullOrEmpty(reply)) // Jeśli odpowiedź została przez nas określona { SpikitAPI.PipeClient client = sender as SpikitAPI.PipeClient; client.SendToServer(reply); // Wyślij odpowiedź z powrotem do programu } } } }

Przykład aplikacji konsolowej - dla średniozaawansowanych

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace NamedPipeTest { class Program { static Dictionary<string, Func<string>> dictionary = null; static void Main(string[] args) { dictionary = new Dictionary<string, Func<string>>(StringComparer.OrdinalIgnoreCase); dictionary.Add("która godzina", () => { return string.Format("jest godzina {0}", DateTime.Now.ToShortTimeString()); } ); dictionary.Add("jaki dziś dzień", () => { System.Globalization.CultureInfo locale = new System.Globalization.CultureInfo("pl-PL"); return string.Format("dziś jest {0} {1}", DateTime.Now.ToString("dddd", locale), DateTime.Now.ToString("d", locale)); } ); dictionary.Add("wyłącz się", () => { Environment.Exit(0); return null; // duh... ;-) } ); dictionary.Add("o co mogę zapytać", () => { StringBuilder result = new StringBuilder(); result.Append("Słucham następujących poleceń"); result.Append(". "); result.Append("która godzina"); result.Append(". "); result.Append("jaki dziś dzień"); result.Append(". "); result.Append("o co mogę zapytać"); result.Append(". "); result.Append("wyłącz się"); result.Append(". "); return result.ToString(); } ); SpikitAPI.PipeClient client = new SpikitAPI.PipeClient(); // Wystarczy utworzyć instancję klasy PipeClient i gotowe client.MessageReceived += new SpikitAPI.PipeClient.MessageReceivedEventHandler(client_MessageReceived); // Obsługa przychodzących wiadomości odbywa się w zdarzeniu 'MessageReceived' } static void client_MessageReceived(object sender, SpikitAPI.PipeClient.PipeClientEventArgs e) { // e.Message zawiera treść rozpoznanego polecenia głosowego lub rozpoznanej mowy (funkcja dyktowania) string message = e.Message.Trim(); // Dla pewności usuniemy wszelkie białe znaki przed oraz po wiadomości if (string.IsNullOrEmpty(message)) // Dobre przyzwyczajenie, a sytuacja mało prawdopodobna return; string reply = null; if (dictionary != null && dictionary.ContainsKey(message)) reply = dictionary[message].Invoke(); else reply = "niestety, chyba mówimy różnym językiem, bo naprawdę nie rozumiem o co tobie chodzi"; if (!string.IsNullOrEmpty(reply)) // Jeśli odpowiedź została przez nas określona { SpikitAPI.PipeClient client = sender as SpikitAPI.PipeClient; client.SendToServer(reply); // Wyślij odpowiedź z powrotem do programu } } } }

Jak to wygląda w praktyce? Jak na załączonym poniżej filmie:

Niespodzianka

Wszystkim, którzy dotarli do końca szczerze gratuluję i dziękuję. By umilić niektórym Czytelnikom kolejny majowy weekend proponuję następującą zabawę:

Utwórz ciekawą aplikację wykorzystującą Spikit lub dowolną wtyczkę rozszerzającą możliwości programu. Do komunikacji z programem użyj klasy PipeClient z przestrzeni nazw SpikitAPI (w oryginale lub zmodyfikowanej do własnych potrzeb). Link do swojej aplikacji wraz z krótkim opisem zamieść w komentarzu do tego wpisu.

Linki do podstawowych narzędzi programistycznych:

Osoba, które wykaże się świetnym pomysłem, zrealizuje go w ciekawy sposób i udokumentuje swoją pracę krótkim filmem w YouTube, otrzyma ode mnie licencję. Klucz licencyjny likwiduje sztuczne opóźnienie (od 1 do 8 sekund) znane z bezpłatnej edycji programu i uprawnia do późniejszych aktualizacji. Na zgłoszenia czekam przez tydzień. Nie czekaj na polską Cortanę, weź sprawy w swoje ręce!

Oczywiście z miłą chęcią poznam Wasze komentarze i spostrzeżenia dotyczące całego wpisu oraz nowej, jakże istotnej funkcji. 

porady programowanie

Komentarze

0 nowych
  #1 10.05.2014 18:03

Podoba mi się! Spróbuję swoich sił, widzę duży potencjał w programie. Z tego, co rozumiem, można by sterować tym jakimis urządzeniami przez sieć czy tak?

Jim1961   7 #2 10.05.2014 21:19

10-ty poziom zagnieżdżenia w kodzie ... nice :P

alucosoftware   7 #3 10.05.2014 21:47

@Jim1961
Z czystej oszczędności miejsca i czasu (całość można ogarnąć jednym spojrzeniem). Zobacz przy tym ile ciekawych rzeczy tam się dzieje! Wyrażenia lambda i metody anonimowe po to właśnie istnieją, aby ułatwiać życie programisty. Z drugiej strony, patrzysz na część (SpikitAPI.PipeClient), której osoby dopiero rozpoczynające przygodę z programowaniem dotykać nie powinny, a jedynie skopiować i wkleić ;-)

alucosoftware   7 #4 10.05.2014 22:01

@michałavr
Dzięki, czekam na wyniki, a w razie problemów postaram się doradzić.

Tak, wystarczy, że dwa komputery (do jednego z nich podłączysz stosowne urządzenie np. mikrokontroler) znajdować się będą w tej samej sieci.

  #5 11.05.2014 15:01

człowieku, ten program powinien być na pierwszej stronie jakieś dużej gazety albo na reddicie!! przecież takich możliwości nie ma żaden inny soft jaki jest w sieci. dziwne, że jeszcze MS się tym nie zainteresował :-O a może???

cały komp sterowany spikitem to jest to!

jak mogę w kwestii konkursu, czy ktoś szykuje jakiś czytnik newsów, na przykład nagłówki z rss'a, to było by coś wielkiego! (newsy czytane przez głos spikita). mogę spróbować, ale nie wiem czy dam radę zrobić to dobrze, bardziej siedzę w VB

enedil   9 #6 11.05.2014 19:59

Szkoda, że C#, bo automatycznie "przygwoździłeś" soft do Windowsa.

enedil   9 #7 11.05.2014 20:00

Szkoda, że C#, bo automatycznie "przygwoździłeś" soft do Windowsa.

pawcio1212   7 #8 11.05.2014 20:38

@enedil
Z oficjalnej strony
"Czy istnieje wersja programu Spikit przeznaczona dla systemu Linux?
W chwili obecnej nie istnieje wersja programu Spikit dedykowana na system operacyjny z rodziny Linux. Instalacja programu nie powiedzie się także na systemie Linux z zainstalowanym pakietem Wine."

Nawet jeżeli autor użyłby innego języka programowania to i tak zostałeś uczepiony windowsa.
Tutaj c# jest translatorem(nie wiem czy można go tak nazwać)
Tłumaczy polecenia od spikit na twoje zamierzenia np może wysyłać polecenia przez porty albo komunikatory a program docelowy nawet na innym urządzeniu(rasperry pi który zapala światło gdzie powiesz).
A jak każdy wie translatora można użyć innego :P

Minusem programu jest brak wersji na linuksa(może program nie jest zasobożerny ale windows tak)
Jedyna wada tego cudnego programu.

alucosoftware   7 #9 11.05.2014 20:41

@enedil
Możesz rozwinąć ten wątek?

alucosoftware   7 #10 11.05.2014 21:18

@pawcio1212
Przedstawiony tutaj kod napisany jest w języku C# (platforma .NET). W Spikit wbudowałem mechanizm, dzięki któremu zewnętrzne aplikacje mogą podłączyć się do Spikit i słuchać (w sposób pośredni) wybranych poleceń.

Gdy tylko Spikit rozpozna wypowiadane przez Ciebie słowa, sprawdzi też co ma zrobić po ich usłyszeniu. Jeśli do słów przypisałeś akcję {POTOK_NAZWANY_PRZEKIERUJ}, Spikit uzna, że słowa, które właśnie usłyszał nie są przeznaczone dla niego, a dla zupełnie innej aplikacji i skieruje je do specjalnego "kanału" komunikacyjnego. Jeżeli ktoś będzie nasłuchiwał na tym samym kanale - otrzyma wiadomość o rozpoznanej komendzie.

We wpisie znajduje się gotowiec, który można przekleić do swojej aplikacji w C# (są to po prostu reguły komunikacji z programem). Jeśli programista-amator przeklei ten kod, to do wykorzystania Spikit we własnych projektach (włączanie lampki, sterowanie robotem) będzie musiał wykonać tylko dwie rzeczy:
1. Utworzyć specjalny obiekt
SpikitAPI.PipeClient client = new SpikitAPI.PipeClient();
client.MessageReceived += new SpikitAPI.PipeClient.MessageReceivedEventHandler(client_MessageReceived);
2. Obsłużyć nadchodzące komunikaty/komendy
static void client_MessageReceived(object sender, SpikitAPI.PipeClient.PipeClientEventArgs e)
{
if (e.Message == "jakieś słowa")
{
}
}

Proste, prawda? We wpisie wskazuję także drogę dla osób, które lubią kod natywny. .NET to i tak tylko zgrabne "opakowanie" kodu natywnego. Sposób postępowania jest dokładnie taki sam w przypadku C++ lub innego języka korzystającego z funkcji systemu Windows (CreateNamedPipe).

Dziękuję za dobre słowo :)

@enedil
@pawcio1212
To co zrobi użytkownik po otrzymaniu komunikatu nie leży już tak naprawdę w mojej gestii. Najlepszym wyborem byłoby utworzenie drobnej usługi systemu Windows (to tylko kilka linijek kodu), działającej sobie w tle i nasłuchującej wybranych komunikatów od Spikit. Usługa ta może sobie komunikować się z Linuxami/Androidami i różnorakimi mikrokontrolerami w znany tylko sobie sposób i przy użyciu znanych tylko sobie protokołów komunikacyjnych (ile różnych projektów, tyle też różnych sposobów na ich zrealizowanie)

Dla mnie jako dewelopera ważne jest to, że idąc z tabletem z Windows 8 i mówiąc do niego, moje polecenia głosowe mogą być - w czasie rzeczywistym - interpretowane przez komputer znajdujący się na drugim końcu Polski i np. sterujący automatyką w domu. Mając powyższy gotowiec, czas potrzebny do napisania aplikacji współpracujących ze Spikit i wykorzystujących jego zalety jest zwyczajnie pomijalny.

Z drugiej strony, nie muszę już rozbudowywać bazy akcji (tj. możliwości) w Spikit (wolę dopracować istniejące rozwiązania), ponieważ od teraz do rozwiązywania ludzkich problemów mogę użyć malutkich programów-pomocników. Chcesz wiedzieć co właśnie dzieje się na świecie - napisz program, który pobierze nagłówki z kanałów RSS i wyśle je Spikitowi. Program je odczyta i po kłopocie :)

@vb-guru
Dzięki za sugestię z RSS, bardzo fajny pomysł! Microsoft jeszcze milczy, może masz tam jakieś znajomości? ;-)

nie_lubie_informatyki   3 #11 13.05.2014 07:29

ten program (spikit) mógłby mieć spore znaczenie dla osób niepełnosprawnych, znam osobę na wózku która mogłaby być zainteresowana. Takim osobom nie zawsze łatwo jest operować klawiaturą/myszką, a tutaj byłoby wygodniej

alucosoftware   7 #12 13.05.2014 09:16

@nie_lubie_informatyki
Mógłby, ale nie wpasowuje się w politykę wspierania osób niepełnosprawnych, ponieważ dożywotni koszt licencji (w tym aktualizacje i opieka techniczna) nie przekracza 250 zł.

W Polsce koszt urządzeń i oprogramowania dla osób niepełnosprawnych musi mieścić się w przedziale 3000-15000 zł, aby pojawiło się na nie zainteresowanie ze strony rozmaitych fundacji i stowarzyszeń. Sam nie jestem w stanie dotrzeć do zainteresowanych (często nie mają oni nawet jak komunikować się ze światem), a sytuację znam z osobistych doświadczeń (mnie i mój pomysł "olało" ponad 2 tysiące fundacji).

#takasytuacja

  #13 13.06.2014 02:15

@alucosoftware: a pomyślałeś że może Twoje rozwiązanie jest beznadziejne lub fundacje nie chcą takiej tandety. Na ilu niepełnosprawnych to testowałeś ?? Jak rozwiązałes temat osób które nie potrafią już wyraźnie mówić ??
Twoje rozwiązanie oferuje operowanie policzkami, mruganiem, grymasami ?
Rozpoznawanie mowy to najmniejszy problem w systemach dla osób niepełnosprawnych.
Proszę nie siej zamętu bo nie masz o tym najmniejszego pojęcia. Wyklikanie w C# prostego programu na kogoś technologii nie daje Ci prawa do takich osądów.
Opracuj cały system od zera, który naprawdę będzie wspierał niepełnosprawnych i będzie lepszy od tych co są na rynku to pokłonię Ci się w pas a jak na razie to jesteś tylko i wyłącznie szkodnikiem.

alucosoftware   7 #14 13.06.2014 12:23

@Sztywniak.
Rozumiem, że jesteś ekspertem w każdej dziedzinie.

  #15 14.06.2014 15:13

@sztywniak ty tak na serio? daj coś od siebie nim zaczniesz jechać po kimś kto jednak wykonuje kawał dobrej roboty i solidnie pomaga. typowy polaczek. skąd wy sie bierzecie? i co ma sterowanie głosem do grymasów lub mrugania? czytałeś podręcznik z programu czy tylko plujesz dla plucia?

  #16 12.11.2014 00:19

Szkodnik pewnie jest z firmy która się zajmuje softem dla niepełnosprawnych i może poczuł zagrożenie, że jedna osoba stworzyła coś co oni tworzą w sztabie informatyków. Btw, może i spikit nie nadaje się jeszcze w 100% dla wszystkich niepełnosprawnych, ale nie od razu Rzym zbudowano ! A tobie szkodnik życze powodzenia w hejtowaniu wszystkiego co ludzie dają innym ludziom !

  #17 05.12.2014 23:53

Lipa! Nie można przekierowywać wszystkich rozpoznanych przez ten program słów. Trzeba wypowiadać jakieś zaklęcia...

alucosoftware   7 #18 06.12.2014 13:22

@up Dzięki za konstruktywny komentarz (to taka "nowa" narodowa tradycja?). Mechanizm komunikacji z aplikacją działa zgodnie z przeznaczeniem i ma być pomocny dla tych użytkowników programu, którzy chcą czegoś więcej niż Spikit może im w tej chwili zaoferować. A oferuje całkiem sporo.

  #19 13.05.2015 05:37

@michałavr (niezalogowany): true... true... chociaż sam na codzień korzystam z linuxów i pseudo windowsa do gier (niech bóg wybaczy Gates'owi za to że to stworzył) to nie powiem mam trochę obycia z terminalem i wygląda ten program kosmicznie dla szaraków to nie jestem pewien czy 95% z urzytkowników nie będą potrafili nawet z niego raz skorzystaćchyba że mowa o uruchomieniu i powiedzeniu "aha" ale samemu do siebie przed wyłączeniem go jak ja dokłądnie tak zrobiłem chociaż spróbuje do tego podejść ale z tym sporo zabawy a wiadomo że większość urzytkowników kompów którzy z nich korzystają bo muszą to nawet wygaszacz ekranu przerasta więc niech dziękują że ten progam dużo nie zajmuje :) Pozdrawiam

  #20 26.10.2015 01:41

Witam, gdzie mozna zakupic licencje do tego cudownego programu(nigdzie nie moge tego znalesc), chyba ze mozna dostac ja za free.Prosze o kontakt na e-mail razorxx100@o2.pl

  #21 04.01.2016 23:26

Mam Spikit 1.9.4.0 na Windows 10. Gdy w oknie spikita w karcie Moje polecenia wpisze :
(
test potoku {POTOK_NAZWANY_PRZEKIERUJ}
)
to przy probie wlaczenia karty otrzymuje czerwona czcionka komunikat "Niepoprawnie skonstruowany kontekst wypowiedzi {POTOK_NAZWANY_PRZEKIERUJ}".

O co chodzi?

  #22 13.02.2016 18:31

Witam, mam problem z kodem powyżej. Udaje mi się połączyć z pipem spikit (aplikacja Spikit pokazuje, że się połączyła z programem, jak i mój program). Jednakże nigdy nie dostaję wiadomości nawet jeśli została przetworzona przez aplikację. Mój program stoi na asynchronicznym zczytywaniu wiadomości i nigdy nie wywołuje callback'a, jakieś pomysły, albo naprowadzenie co mógłbym w tym przypadku sprawdzić? :/.