Pokazywanie postów oznaczonych etykietą Variable Set. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą Variable Set. Pokaż wszystkie posty

11 grudnia 2014

Tasker i OpenVPN czyli dbamy o bezpieczeństwo

Jako, że od zawsze staram się dbać o bezpieczeństwo swoich danych i prywatności (przynajmniej na ile to możliwe w dzisiejszych czasach) unikam łączenia telefonu z nieszyfrowanymi sieciami WiFi. Niestety zdarzają się sytuacje, w których, trzeba z takich sieci skorzystać. Nie ma wtedy pewności czy hasła i loginy nie wpadną w łapy jakiegoś domorosłego "hakiera" bawiącego się w podszywanie pod punkt dostępowy. Rozwiązaniem tego problemu jest zastosowanie wirtualnych połączeń prywatnych czyli VPN, które tworzą szyfrowany tunel do serwera VPN i dane, które urządzenie przesyła są bezpieczne. Aby zdobyć dostęp do serwera VPN można wykupić sobie taką usługę, znaleźć darmowego dostawcę lub zrobić wszystko samemu, którą to opcję polecam. Coraz więcej nowoczesnych routerów posiada możliwość uruchomienia serwera OpenVPN w oprogramowaniu firmowym. Osobiście preferuję alternatywne oprogramowania dla routerów i praktycznie każdy z dostępnych (DD-WRT/Tomato/ OpenWRT/Gargoyle) udostępnia taką funkcjonalność. O konfiguracji usługi na routerze bądź wgrywaniu alternatywnego oprogramowania nie będę się tu rozpisywał ale jakby było zapotrzebowanie to chętnie pomogę. Należy tylko pamiętać, że konfigurując serwer należy wybrać opcję przesyłania pełnego ruchu sieciowego przez serwer.

Wymagania

Zakładam więc, że masz skonfigurowany serwer OpenVPN w routerze i utworzony profil dla telefonu. Co teraz? Potrzebny Ci będzie klient usługi OpenVPN, plugin do Taskera umożliwiający sterowanie połączeniem VPN oraz mój profil, który automatycznie będzie uruchamiał szyfrowany tunel w momencie połączenia z nieszyfrowaną siecią WiFi.
Jako klienta usługi stosuję OpenVPN for Android, a OpenVPN Tasker Plugin zapewnia mi współpracę z Taskerem. Konfiguracja OpenVPN for Android polega na imporcie pliku z rozszerzeniem ovpn po naciśnięciu klawisza Wczytaj.

OpenVPN Tasker Plugin nie wymaga konfiguracji. Po uruchomieniu wtyczka wyświetla status Aplikacji OpenVPN for Android i Taskera.

Opis wykonania

Jako, że połączenie z serwerem OpenVPN ma następować w momencie połączenia z niezabezpieczoną siecią WiFi do realizacji tego zadania wykorzystam profil Tost z danymi sieci WiFi po połączeniu.
Mam więc profil aktywowany poprzez WiFi Connected. W jego tasku wejściowym wartość zmiennej %WIFII przekazywana jest do zmiennej lokalnej %wifiinfo, za pomocą akcji Variable Search Replace z warunkiem RegEx (?<=(\n)).* wpisanym w pole Search i odznaczoną opcją Replace Matches zawartość zmiennej zostaje podzielona na poszczególne linie, które zostają zachowane w zmiennej %wifiinfo tworząc macierz. Użyte wyrażenie regularne wyszukuje tekst, po którym występuje znak \n czyli znak końca linii. Po tej operacji dostęp do poszczególnych linii jest możliwy poprzez podanie w parametrze numeru elementu macierzy np. %wifiinfo(3) lub %wifiinfo3. Następnie, znów za pomocą akcji Variable Search Replace, tym razem z zaznaczoną opcję Replace Matches i pustą zawartością pola Replace With czyszczę poszczególne linie z niepotrzebnych znaków " i tekstów by za moment wyświetlić tost z danymi sieci WiFi jeśli ekran jest włączony.

W kolejnym kroku sprawdzane jest czy sieć WiFi, do której właśnie podłączyło się urządzenie jest siecią domową (lub inną, dla której nie chcesz włączać połączenia VPN). Oczywiście możesz podać nazwy kilku sieci oddzielone znakiem / oraz podać maskę co zapewni omijanie wszystkich sieci, do których masz zaufanie.
Nastepnie za pomocą komend powłoki systemu umieszczonych w akcji Run Shell kopiowany jest plik wpa_supplicant.conf do tymczasowego katalogu Taskera. W pliku tym system przechowuje dane wszystkich znanych mu sieci. Dla akcji tej konieczne jest zaznaczenie opcji Use Root, a więc właściciele urządzeń bez dostępu do root nie skorzystają z tego profilu. Po wczytaniu zawartości pliku do zmiennej %wpa_supplicant za pomocą akcji Read File plik jest kasowany z katalogu tymczasowego za pomocą akcji Delete File.
Następnym zadaniem jest wyłuskanie z pliku listy nazw zapamiętanych sieci oraz sposobu ich zabezpieczenia. Wykonywane jest to za pomocą akcji Variable Search Replace bez zaznaczonej opcji Replace Matches. W pierwszym przypadku użyto wyrażenia regularnego (?<=(ssid=").*(?=("\n)), które wyszukuje teksty znajdujące się pomiędzy ssid=", a "\n i przekazuje je w formie macierzy do zmiennej %lista_ssid. W drugim przypadku wyrażenie regularne (?<=(key_mgmt=)).*(?=(\n)) wyszukuje teksty znajdujące się pomiędzy key_mgmt=, a znakiem końca linii i przekazuje je w formie macierzy do zmiennej %typy_kluczy.
Teraz można już za pomocą akcji Variable Set ustalić jaką pozycję na liście ma sieć, do której podłączone jest urządzenie. Wykonywane to jest za pomocą zapisu %lista_ssid(#?%wifiinfo2), który zwraca z macierzy %lista_ssid numer wartości odpowiadający %wifiinfo2 czyli nazwy aktualnie podłączonej sieci. Wartość ta zapisywana jest do zmiennej %indeks.

W tym momencie dostępne są już wszystkie dane niezbędne do sprawdzenia czy obecne połączenie jest szyfrowane. Warunkiem if sprawdzane jest czy %typy_kluczy(%indeks) jest różne od WPA-PSK czyli oznaczenia szyfrowania połączenia kluczem WPA. Jeśli tak task uruchamia połączenie OpenVPN za pomocą wtyczki ze skonfigurowaną siecią (w moim przypadku nazywa się ona Dom) oraz nadaje zmiennej %OpenVPN wartość 1.
Profil wymaga jeszcze tasku wyjściowego, w którym jeśli wartość %OpenVPN jest równa 1 wtyczka rozłącza połączenie z serwerem i następnie czyszczona jest zmienna %OpenVPN.
Cały profil wygląda następująco:

Rozpisany profil

Profile: Połączone WiFi (177)
State: Wifi Connected [ SSID:* MAC:* IP:* ]
Enter: Anon (178)
A1: Variable Set [ Name:%wifiinfo To:%WIFII Do Maths:Off Append:Off ]
A2: Variable Search Replace [ Variable:%wifiinfo Search:(?<=(\n)).* Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%wifiinfo Replace Matches:Off Replace With: ]
A3: Variable Search Replace [ Variable:%wifiinfo2 Search:" Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%wifiinfo2 Replace Matches:On Replace With: ]
A4: If [ %SCREEN ~ on ]
A5: Variable Search Replace [ Variable:%wifiinfo5 Search:IP : Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%wifiinfo5 Replace Matches:On Replace With: ]
A6: Variable Search Replace [ Variable:%wifiinfo7 Search:Spd: Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%wifiinfo7 Replace Matches:On Replace With: ]
A7: Flash [ Text:Połączono z siecią %wifiinfo2
Adres IP: %wifiinfo5
Prędkość: %wifiinfo7 Long:On ]
A8: End If
A9: If [ %wifiinfo2 !~ Siec_domowa ]
A10: Run Shell [ Command:mkdir -p /sdcard/Tasker/tmp
cp /data/misc/wifi/wpa_supplicant.conf /sdcard/Tasker/tmp Timeout (Seconds):0 Use Root:On Store Output In: Store Errors In: Store Result In: Continue Task After Error:On ]
A11: Read File [ File:/sdcard/Tasker/tmp/wpa_supplicant.conf To Var:%wpa_supplicant ]
A12: Delete File [ File:/sdcard/Tasker/tmp/wpa_supplicant.conf Shred Level:0 Use Root:Off ]
A13: Variable Search Replace [ Variable:%wpa_supplicant Search:(?<=(ssid=")).*(?=("\n)) Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%lista_ssid Replace Matches:Off Replace With: ]
A14: Variable Search Replace [ Variable:%wpa_supplicant Search:(?<=(key_mgmt=)).*(?=(\n)) Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In:%typy_kluczy Replace Matches:Off Replace With: ]
A15: Variable Set [ Name:%indeks To:%lista_ssid(#?%wifiinfo2) Do Maths:Off Append:Off ]
A16: If [ %typy_kluczy(%indeks) !~ WPA-PSK ]
A17: OpenVPN [ Configuration:Connect (Dom) Package:com.ffrog8.openVpnTaskerPlugin Name:OpenVPN Timeout (Seconds):0 ]
A18: Variable Set [ Name:%OpenVPN To:1 Do Maths:Off Append:Off ]

Exit: Anon (258)
A1: If [ %OpenVPN = 1 ]
A2: OpenVPN [ Configuration:Disconnect Package:com.ffrog8.openVpnTaskerPlugin Name:OpenVPN Timeout (Seconds):0 ]
A3: Variable Clear [ Name:%OpenVPN Pattern Matching:Off ]

Pobieranie profilu

WiFi połączone / OpenVPN [Tasker 4.6b7]

Podziękowania

Dziękuję Mariuszowi "mrtur" Turkowi za pomoc przy testowaniu wykrywania przez Taskera niezabezpieczonych sieci WiFi.

5 listopada 2014

Profil: Głosowe wysyłanie wiadomości SMS

Dziś przedstawię kolejny profil, w którym główne skrzypce odgrywa komunikacja głosowa z urządzeniem. Dokładnie chodzi o podyktowanie i wysłanie wiadomości SMS tylko za pomocą głosu.
Profil uruchamia się następującymi komendami głosowymi:

  • wyślij wiadomość do Jan Kowalski
  • wyślij sms do Jan Kowalski
  • wyślij smsa do Jan Kowalski
  • wiadomość do Jan Kowalski
  • sms do Jan Kowalski
przy założeniu, że wysłać ma wiadomość do kontaktu Jan Kowalski.
Po uruchomieniu profil sprawdza czy w kontaktach znajduje się kontakt o podanej nazwie oraz czy kontakt ten ma wpisany numer telefonu komórkowego następnie prosi użytkownika o podyktowanie treści wiadomości i jeśli użytkownik zatwierdzi jej poprawność wysyła ją do odbiorcy. W przypadku braku zatwierdzenia poprawności treści wiadomości profil proponuje ponowne jej podyktowanie.

Wymagania

  • wtyczka AutoVoice w wersji płatnej
  • wtyczka AutoContacts w wersji płatnej
  • generator głosu Text-To-Speech, przykładowo IVONA lub Google TTS
  • do poprawnego działania profilu niezbędny jest porządek w książce adresowej tzn. numery telefonów komórkowych muszą być opisane jako komórka

Opis wykonania

Profil uruchamiany jest za pomocą kontekstu AutoVoice Recognized z zaznaczoną opcją Event Behavior, Use Regex i filtrem komendy ustawionym na (?:wyślij )?(?:wiadomość|sms[a]?) do (?<contact>.*).

W tym miejscu spróbuję rozszyfrować ten zapis. Jest to wyrażenie regularne, które pozwala wywołać uruchomienie profilu kilkoma komendami głosowymi według powyższego schematu.
Wyrażenie (?:wyślij )? oznacza, że w komendzie może ale nie musi pojawić się słowo wyślij ze spacją po nim. Ostatni znak zapytania gwarantuje to, że słowo wyślij nie jest obligatoryjne. Dzięki temu profil można uruchomić komendą wyślij wiadomość do Jan Kowalski ale również wiadomość do Jan Kowalski.
Zestaw znaków (?: ) tworzy grupę, która w tym przypadku ma tylko jeden element czyli wyślij .
Następna część wyrażenia regularnego (?:wiadomość|sms[a]?) tworzy kolejną grupę, która ma dwa elementy oddzielone znakiem |. Zapis sms[a]? oznacza słowo sms oraz jeden znak a, który może ale nie musi wystąpić. Dzięki temu profil zostanie uruchomiony komendą wyślij sms do Jan Kowalski ale także wyślij smsa do Jan Kowalski.
W końcu wyrażenie (?<contact>.*) tworzy parametr, który zostanie przekazany do Taskera w postaci zmiennej %contact czyli w tym przypadku w tej zmiennej znajdzie się wartość Jan Kowalski.
Task zadania zaczyna się od akcji AutoContacts ze zmienną %contact wpisaną w pole Contact Name or Nickname. Dzięki temu wtyczka wyszukuje w kontaktach przykładowego Jana Kowalskiego i wypełnia zmienne danymi jego kontaktu.
Następnie sprawdzana jest zmienna %acnumber, która powinna otrzymać wartość pierwszego numeru telefonu kontaktu. Jeśli nie ma nadanej wartości oznacza task powiadamia głosowo użytkownika o nieznalezieniu kontaktu i zatrzymuje dalsze akcje.
Kolejnym krokiem jest ustalenie, który numer telefonu jest numerem komórkowym. Jeśli numer komórkowy nie zostanie odnaleziony generowana jest głosowa informacja o błędzie, a task zostaje zatrzymany.

Następnie task głosowo prosi o podyktowanie treści wiadomości i za pomocą akcji AutoVoice Recognize rejestruje co powiedział użytkownik. Kolejnym krokiem jest głosowe odczytanie podyktowanej treści i pytanie czy treść jest poprawna. Jeśli użytkownik potwierdzi poprawność, wiadomość jest wysyłana za pomocą akcji Send SMS, w której w polu Number należy podać zmienną %komórka, a w polu Message %sms. Jeśli użytkownik nie potwierdzi poprawności smsa, task proponuje ponowne podyktowanie wiadomości i wraca do prośby o podyktowanie jej treści.

Rozpisany profil

Profile: Wyślij SMS (193)

State: AutoVoice Recognized [ Configuration:Event Behaviour: true
Command: "(?:wyślij )?(?:wiadomość|sms[a]?) do (?<contact>.+) (regex)" ]
Enter: Anon (200)
A1: AutoContacts [ Configuration:Contact Name or Nickname: %contact Package:com.joaomgcd.autocontacts Name:AutoContacts Timeout (Seconds):1000 Continue Task After Error:On ]
A2: If [ %acnumber !Set ]
A3: Say [ Text:Nie znaleziono kontaktu %contact Engine:Voice:default:default Stream:3 Pitch:5 Speed:5 Respect Audio Focus:Off Network:Off Continue Task Immediately:Off ]
A4: Stop [ With Error:Off Task: ]
A5: End If
A6: Variable Split [ Name:%acallnumbers1 Splitter:, Delete Base:Off ]
A7: Variable Split [ Name:%acallnumbertypes1 Splitter:, Delete Base:Off ]
A8: Variable Set [ Name:%index To:%acallnumbertypes1(#?Komórka) Do Maths:Off Append:Off ]
A9: Variable Split [ Name:%index Splitter:, Delete Base:Off ] If [ %index !~ 0 ]
A10: Variable Set [ Name:%komórka To:%acallnumbers1(%index1) Do Maths:Off Append:Off ] If [ %index !~ 0 ]
A11: If [ %komórka !Set ]
A12: Say [ Text:Nie znaleziono numeru komórkowego kontaktu %acname Engine:Voice:default:default Stream:3 Pitch:5 Speed:5 Respect Audio Focus:Off Network:Off Continue Task Immediately:Off ]
A13: Stop [ With Error:Off Task: ]
A14: End If
<podyktuj>
A15: Say [ Text:Podyktuj wiadomość po sygnale. Engine:Voice:default:default Stream:3 Pitch:5 Speed:5 Respect Audio Focus:Off Network:Off Continue Task Immediately:Off ]
A16: Variable Clear [ Name:%avcomm Pattern Matching:Off ]
A17: AutoVoice Recognize [ Configuration:
Voice command without headset
Command: "all" Package:com.joaomgcd.autovoice Name:AutoVoice Recognize Timeout (Seconds):120 ]
A18: Goto [ Type:Action Label Number:1 Label:podyktuj ] If [ %avcomm !Set ]
A19: Variable Set [ Name:%sms To:%avcomm Do Maths:Off Append:Off ]
A20: Say [ Text:Czy chcesz wysłać wiadomość do %acname o treści: %sms? Engine:Voice:default:default Stream:3 Pitch:5 Speed:5 Respect Audio Focus:Off Network:Off Continue Task Immediately:Off ]
A21: AutoVoice Recognize [ Configuration:
Voice command without headset
Command: "all" Package:com.joaomgcd.autovoice Name:AutoVoice Recognize Timeout (Seconds):120 ]
A22: If [ %avcomm ~ tak ]
A23: Send SMS [ Number:%komórka Message:%sms Store In Messaging App:On ]
A24: Say [ Text:Wiadomość wysłana. Engine:Voice:default:default Stream:3 Pitch:5 Speed:5 Respect Audio Focus:Off Network:Off Continue Task Immediately:Off ]
A25: Else
A26: Say [ Text:Czy chcesz poprawić wiadomość? Engine:Voice:default:default Stream:3 Pitch:5 Speed:5 Respect Audio Focus:Off Network:Off Continue Task Immediately:Off ]
A27: AutoVoice Recognize [ Configuration:
Voice command without headset
Command: "all" Package:com.joaomgcd.autovoice Name:AutoVoice Recognize Timeout (Seconds):120 ]
A28: Goto [ Type:Action Label Number:9 Label:podyktuj ] If [ %avcomm ~ tak ]
A29: End If

Pobieranie profilu

Profil Głosowe wysyłanie wiadomości sms [Tasker 4.5u1]

18 października 2014

Tasker przypomni Ci o urodzinach, imieninach i rocznicach

Odkąd pamiętam mam problem z zapamiętywaniem dat. Z tego powodu zdarza mi się zapomnieć o urodzinach lub imieninach bliskich mi osób. Wpisanie dat do kalendarza częściowo rozwiązuje problem ale zawsze brakowało mi w telefonie przypominajki, którą trudno zignorować. W ten sposób powstał pomysł na projekt Taskera przypominający o urodzinach, imieninach i rocznicach osób z książki adresowej. Projekt codziennie rano i wieczorem wyszukuje w książce adresowej daty urodzin, imienin, rocznic ślubu i rocznic śmierci i jeśli takie występują dla danego dnia wyświetla powiadomienie umożliwiające wysłać wiadomość SMS, zadzwonić lub napisać wiadomość Hangouts do kontaktu. Prezentuje się to następująco.

Jest to trzecia wersja tego projektu. Poprzednie miały braki w funkcjonalności i nie umiały obejść niedoskonałości wtyczki AutoContacts. Ta wersja zdaje się być kompletna i nie zawierać błędów.
Jeśli coś z opisu lub samego projektu wyda Ci się niezrozumiałe to zachęcam do zadawania pytań. Postaram się na wszystkie odpowiedzieć.

Wymagania

Wtyczka AutoNotification

Wtyczka AutoNotification służy do generowania powiadomień. Oczywiście sam Tasker to potrafi za pomocą akcji Notify jednak wtyczka ma dużo większe możliwości konfiguracji tworzonego powiadomienia dlatego ja zdecydowanie wolę z niej korzystać. Poza generowaniem powiadomień wtyczka potrafi przechwytywać notyfikacje innych aplikacji co umożliwia np. zamykanie niechcianych powiadomień, przechwytywanie treści z powiadomień, uruchamianie profili w momencie pojawienia się notyfikacji z danego programu itp.

Instalacja i konfiguracja

Wtyczkę AutoNotification można pobrać ze sklepu Google Play. Po instalacji i wykupienia wersji Pro wtyczka jest gotowa do działania.

Konfiguracja

W dwóch pierwszych akcjach tasku AC Daty z kontaktów należy podać ścieżkę dostepu do plików graficznych oraz wybrany dxięk powiadomienia, który ma być odgrywany w momencie pojawienia się przypomnienia.

Opis wykonania

Projekt składa się z 6 profili. Dwa główne AN Przypomnienie o urodzinach [ranek] i AN Przypomnienie o urodzinach [wieczór] uruchamiają ten sam task AC Daty z kontaktów. Profil ranny uruchamiany jest o godzinie 10tej, wieczorny o 19tej pod warunkiem, że zmienna %BIRTHDAYR ma wartość 1. Zmienna ta ma wartość 1 jeśli użytkownik naciśnie poranne powiadomienie (nie odrzuci).

Task AC Daty z kontaktów zaczyna się od konfiguracji ścieżki dostępu do grafik oraz dźwięku powiadomienia, która użytkownik po imporcie projektu musi samemu dostosować do własnego systemu.
Następnie task sprawdza czy danego dnia są jakieś zdarzenia do obsłużenia (zmienna %daystoeventc) i jeśli tak odczytuje za pomocą akcji Run Shell i komend powłoki datę. Później w pętli pętla dane kontaktówporównując datę do listy dat jakie w zmiennej %acallevents otrzymuje od wtyczki AutoContacts task ustala ile dat należy obsłużyć danego dnia i dla tych dat odczytuje nazwiska, daty i typy dat i zapisuje je oddzielając przecinkami do zmiennych odpowiednio %nazwy_kontaktów, %daty_kontaktów i %typy_dat. Po tych operacjach wiadomo jest ile dat trzeba obsłużyć i otrzymuję zmienne macierzowe z wszystkimi niezbędnymi danymi.

Pętla powiadomienia odpowiedzialna jest za kolejno dla każdej daty ze zmiennej %daty_kontaktów wyciągnięcie z AutoContacts zdjęcia kontaktu i numerów telefonów i danych czatu Hangouts, przygotowanie tekstów dla powiadomienia i w końcu wyświetlenie powiadomienia. Przygotowanie tekstów i wyświetlanie powiadomień rozdzielone jest na cztery grupy, które kolejno obsługuję urodziny, imieniny, rocznice ślubów i rocznice śmierci. Oczywiście można stworzyć dodatkowe kategorie i obsłużyć je odpowiednimi powiadomieniami.

Do poprawnego działania projektu potrzebne są jeszcze profile odpowiedzialne za naciśnięcie powiadomienie przez użytkownika oraz obsługujące naciśnięcie klawiszy powiadomień.
Profil AN Przypomnij o urodzinach ma zadziałać w momencie naciśnięcie przez użytkownika powiadomienia. Dzięki kontekstowi AutoNotification oczekuje on na komendę o składni remind birthday=:=. Komendy takie są specyficzne dla wtyczek AutoNoticifation, AutoVoice, AutoRemote i innych tego samego autora. Zestaw znaków =:= rozdziela na części parametry komendy (może być ich więcej niż 2). W tym przypadku naciśniecie na notyfikacje wysyła komendę remind birthday=:=1, a parametr 1 komendy zostaje przekazany do zmiennej %ancomm dostępnej w tasku, dzięki temu możemy go przekazać do naszej zmiennej %BIRTHDAYR co zaowocuje ponownym przypomnieniem wieczorem (jeśli taka akcja miała miejsce rano).

Profil AN Wyślij wiadomość ma za zadanie przygotować wiadomość SMS do wysłania po naciśnięciu przycisku Wyślij wiadomość na powiadomieniu. W tym przypadku naciśnięcie przycisku przekazuje komendę composesms=:=%komórka gdzie %komórka zawiera numer telefonu komórkowego kontaktu.

Profil AN Zadzwoń ma za zadanie zadzwonić na numer kontaktu po naciśnięciu przycisku Zadzwoń na powiadomieniu. W tym przypadku naciśnięcie przycisku przekazuje komendę call=:=%komórka lub call=:=%dom (w zależności od dostępności numeru kontaktu).

Profil AN Hangouts ma za zadanie rozpocząć czat Hangouts z kontaktem po naciśnięciu przycisku Hangouts na powiadomieniu. W tym przypadku naciśnięcie przycisku przekazuje komendę browse=:=%achangouturi.

Rozpisany profil

Profile: AN Przypomnienie o urodzinach [wieczór] (45)
Time: 19:00
State: Variable Value [ %BIRTHDAYR = 1 ]
Enter: AC Daty z kontaktów (220)
<ścieżka do grafik>
A1: Variable Set [ Name:%scieżka_do_grafik To:/storage/emulated/0/Tasker/pictures Do Maths:Off Append:Off ]
<ścieżka do dźwięku>
A2: Variable Set [ Name:%scieżka_do_dźwięku To:content://media/internal/audio/media/246 Do Maths:Off Append:Off ]
A3: Variable Clear [ Name:%BIRTHDAYR Pattern Matching:Off ]
A4: AutoContacts [ Configuration:Order By: Next Event Date Package:com.joaomgcd.autocontacts Name:AutoContacts Timeout (Seconds):1000 ]
A5: Stop [ With Error:Off Task: ] If [ %acdaystoeventc != 0 ]
A6: Variable Set [ Name:%indeks To:1 Do Maths:Off Append:Off ]
A7: Run Shell [ Command:DATUM=$(date "+%m-%d")
echo $DATUM Timeout (Seconds):1 Use Root:Off Store Output In:%dzisiaj_md Store Errors In: Store Result In: ]
A8: Run Shell [ Command:DATUM=$(date "+%Y")
echo $DATUM Timeout (Seconds):1 Use Root:Off Store Output In:%dzisiaj_r Store Errors In: Store Result In: ]
<pętla dane kontaktów>
A9: If [ %acallevents(%indeks) ~ *%dzisiaj_md* ]
A10: If [ %acallevents(%indeks) ~ *,* ]
A11: Variable Set [ Name:%daty To:%acallevents(%indeks) Do Maths:Off Append:Off ]
A12: Variable Split [ Name:%daty Splitter:, Delete Base:Off ]
A13: Variable Set [ Name:%licznik To:%daty(#) Do Maths:Off Append:Off ]
<podwójna data>
A14: If [ %daty(%licznik) ~ *%dzisiaj_md* ]
A15: Variable Set [ Name:%nazwy_kontaktów To:%acnames(%indeks), Do Maths:Off Append:On ]
A16: Variable Set [ Name:%daty_kontaktów To:%daty(%licznik), Do Maths:Off Append:On ]
A17: Variable Set [ Name:%typy_dat_temp To:%acalleventtypes(%indeks) Do Maths:Off Append:Off ]
A18: Variable Split [ Name:%typy_dat_temp Splitter:, Delete Base:Off ]
A19: Variable Set [ Name:%typy_dat To:%typy_dat_temp(%licznik), Do Maths:Off Append:On ]
A20: Variable Add [ Name:%ile_dat Value:1 Wrap Around:0 ]
A21: Variable Subtract [ Name:%licznik Value:1 Wrap Around:0 ]
A22: Goto [ Type:Action Label Number:1 Label:podwójna data ] If [ %licznik > 0 ]
A23: Else
A24: Variable Subtract [ Name:%licznik Value:1 Wrap Around:0 ]
A25: Goto [ Type:Action Label Number:1 Label:podwójna data ] If [ %licznik > 0 ]
A26: End If
A27: Else
A28: Variable Set [ Name:%nazwy_kontaktów To:%acnames(%indeks), Do Maths:Off Append:On ]
A29: Variable Set [ Name:%daty_kontaktów To:%acallevents(%indeks), Do Maths:Off Append:On ]
A30: Variable Set [ Name:%typy_dat To:%acalleventtypes(%indeks), Do Maths:Off Append:On ]
A31: Variable Add [ Name:%ile_dat Value:1 Wrap Around:0 ]
A32: End If
A33: Variable Add [ Name:%indeks Value:1 Wrap Around:0 ]
A34: Goto [ Type:Action Label Number:1 Label:pętla dane kontaktów ]
A35: End If
A36: Variable Split [ Name:%daty_kontaktów Splitter:, Delete Base:Off ]
A37: Variable Split [ Name:%typy_dat Splitter:, Delete Base:Off ]
A38: Variable Split [ Name:%nazwy_kontaktów Splitter:, Delete Base:Off ]
<pętla powiadomienia>
A39: If [ %typy_dat(%ile_dat) ~ imieniny/urodziny/birthday/ślub/zgon ]
A40: Variable Clear [ Name:%dom Pattern Matching:Off ]
A41: Variable Clear [ Name:%komórka Pattern Matching:Off ]
A42: Variable Clear [ Name:%acpicturefile Pattern Matching:Off ]
A43: Variable Clear [ Name:%achangouturi Pattern Matching:Off ]
A44: AutoContacts [ Configuration:Contact Name or Nickname: %nazwy_kontaktów(%ile_dat) Package:com.joaomgcd.autocontacts Name:AutoContacts Timeout (Seconds):1000 ]
A45: AutoContacts Details [ Configuration:Contact Id: %acid
Get Picture: true
Full size: true Package:com.joaomgcd.autocontacts Name:AutoContacts Details Timeout (Seconds):1000 ]
A46: Variable Set [ Name:%telefony To:%acallnumbers(1) Do Maths:Off Append:Off ]
A47: Variable Set [ Name:%typy_telefonów To:%acallnumbertypes(1) Do Maths:Off Append:Off ]
A48: Variable Split [ Name:%telefony Splitter:, Delete Base:Off ]
A49: Variable Split [ Name:%typy_telefonów Splitter:, Delete Base:Off ]
<komórka>
A50: Variable Set [ Name:%licznik To:%typy_telefonów(#?Komórka) Do Maths:Off Append:Off ]
A51: Variable Split [ Name:%licznik Splitter:, Delete Base:Off ] If [ %licznik !~ 0 ]
A52: Variable Set [ Name:%komórka To:%telefony(%licznik1) Do Maths:Off Append:Off ] If [ %licznik !~ 0 ]
<dom>
A53: Variable Set [ Name:%licznik To:%typy_telefonów(#?Domowy) Do Maths:Off Append:Off ]
A54: Variable Split [ Name:%licznik Splitter:, Delete Base:Off ] If [ %licznik !~ 0 ]
A55: Variable Set [ Name:%dom To:%telefony(%licznik1) Do Maths:Off Append:Off ] If [ %licznik !~ 0 ]
<urodziny>
A56: If [ %typy_dat(%ile_dat) ~ urodziny/birthday ]
A57: Variable Set [ Name:%data To:%daty_kontaktów(%ile_dat) Do Maths:Off Append:Off ]
A58: Variable Split [ Name:%data Splitter:- Delete Base:Off ]
A59: Variable Set [ Name:%urodziny To:%dzisiaj_r-%data(1) Do Maths:On Append:Off ]
A60: Variable Set [ Name:%nottitle To:Urodziny %nazwy_kontaktów(%ile_dat) Do Maths:Off Append:Off ]
A61: Variable Set [ Name:%nottext To:%nazwy_kontaktów(%ile_dat) świętuje dziś %urodziny urodziny. Do Maths:Off Append:Off ]
A62: If [ %komórka Set & %achangouturi Set ]
A63: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/birthday.jpg
Text Expanded: %nottext
Button 1: call=:=%komórka
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: composesms=:=%komórka
Label 2: Wyślij wiadomość
Icon 2: ic_action_sms
Button 3: browse=:=%achangouturi
Label 3: Hangouts
Icon 3: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A64: Else If [ %dom Set & %achangouturi Set ]
A65: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/birthday.jpg
Text Expanded: %nottext
Button 1: call=:=%dom
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: browse=:=%achangouturi
Label 2: Hangouts
Icon 2: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A66: Else If [ %komórka Set ]
A67: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/birthday.jpg
Text Expanded: %nottext
Button 1: call=:=%komórka
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: composesms=:=%komórka
Label 2: Wyślij wiadomość
Icon 2: ic_action_sms
Icon 3: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A68: Else If [ %dom Set ]
A69: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/birthday.jpg
Text Expanded: %nottext
Button 1: call=:=%dom
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Icon 2: ic_action_phone_start Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A70: Else If [ %achangouturi Set ]
A71: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/birthday.jpg
Text Expanded: %nottext
Button 1: browse=:=%achangouturi
Label 1: Hangouts
Icon 1: ic_action_dialog
Icon 2: ic_action_phone_start Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A72: Else
A73: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/birthday.jpg
Text Expanded: %nottext Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A74: End If
A75: End If
<imieniny>
A76: If [ %typy_dat(%ile_dat) ~ imieniny ]
A77: Variable Set [ Name:%nottitle To:Imieniny %nazwy_kontaktów(%ile_dat) Do Maths:Off Append:Off ]
A78: Variable Set [ Name:%nottext To:Nie zapomnij złożyć życzeń. Do Maths:Off Append:Off ]
A79: If [ %komórka Set & %achangouturi Set ]
A80: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: imieniny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/imieniny.jpg
Text Expanded: %nottext
Button 1: call=:=%komórka
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: composesms=:=%komórka
Label 2: Wyślij wiadomość
Icon 2: ic_action_sms
Button 3: browse=:=%achangouturi
Label 3: Hangouts
Icon 3: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A81: Else If [ %dom Set & %achangouturi Set ]
A82: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: imieniny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/imieniny.jpg
Text Expanded: %nottext
Button 1: call=:=%dom
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: browse=:=%achangouturi
Label 2: Hangouts
Icon 2: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A83: Else If [ %komórka Set ]
A84: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: imieniny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/imieniny.jpg
Text Expanded: %nottext
Button 1: call=:=%komórka
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: composesms=:=%komórka
Label 2: Wyślij wiadomość
Icon 2: ic_action_sms
Icon 3: ic_launcher Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A85: Else If [ %dom Set ]
A86: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: imieniny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/imieniny.jpg
Text Expanded: %nottext
Button 1: call=:=%dom
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Icon 2: ic_action_phone_start Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A87: Else If [ %achangouturi Set ]
A88: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: imieniny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/imieniny.jpg
Text Expanded: %nottext
Button 1: browse=:=%achangouturi
Label 1: Hangouts
Icon 1: ic_action_dialog
Icon 2: ic_action_phone_start Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A89: Else
A90: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: imieniny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/imieniny.jpg
Text Expanded: %nottext Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A91: End If
A92: End If
<ślub>
A93: If [ %typy_dat(%ile_dat) ~ ślub ]
A94: Variable Set [ Name:%data To:%daty_kontaktów(%ile_dat) Do Maths:Off Append:Off ]
A95: Variable Split [ Name:%data Splitter:- Delete Base:Off ]
A96: Variable Set [ Name:%ślub To:%dzisiaj_r-%data(1) Do Maths:On Append:Off ]
A97: Variable Set [ Name:%nottitle To:Rocznica ślubu %nazwy_kontaktów(%ile_dat) Do Maths:Off Append:Off ]
A98: Variable Set [ Name:%nottext To:%nazwy_kontaktów(%ile_dat) świętuje dziś %ślub rocznicę ślubu. Do Maths:Off Append:Off ]
A99: If [ %komórka Set & %achangouturi Set ]
A100: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/wedding.jpg
Text Expanded: %nottext
Button 1: call=:=%komórka
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: composesms=:=%komórka
Label 2: Wyślij wiadomość
Icon 2: ic_action_sms
Button 3: browse=:=%achangouturi
Label 3: Hangouts
Icon 3: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A101: Else If [ %dom Set & %achangouturi Set ]
A102: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/wedding.jpg
Text Expanded: %nottext
Button 1: call=:=%dom
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: browse=:=%achangouturi
Label 2: Hangouts
Icon 2: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A103: Else If [ %komórka Set ]
A104: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/wedding.jpg
Text Expanded: %nottext
Button 1: call=:=%komórka
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Button 2: composesms=:=%komórka
Label 2: Wyślij wiadomość
Icon 2: ic_action_sms
Icon 3: ic_action_dialog Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A105: Else If [ %dom Set ]
A106: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/wedding.jpg
Text Expanded: %nottext
Button 1: call=:=%dom
Label 1: Zadzwoń
Icon 1: ic_action_phone_start
Icon 2: ic_action_phone_start Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A107: Else If [ %achangouturi Set ]
A108: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/wedding.jpg
Text Expanded: %nottext
Button 1: browse=:=%achangouturi
Label 1: Hangouts
Icon 1: ic_action_dialog
Icon 2: ic_action_phone_start Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A109: Else
A110: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_balloon
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik/wedding.jpg
Text Expanded: %nottext Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A111: End If
A112: End If
<zgon>
A113: If [ %typy_dat(%ile_dat) ~ zgon ]
A114: Variable Set [ Name:%data To:%daty_kontaktów(%ile_dat) Do Maths:Off Append:Off ]
A115: Variable Split [ Name:%data Splitter:- Delete Base:Off ]
A116: Variable Set [ Name:%zgon To:%dzisiaj_r-%data(1) Do Maths:On Append:Off ]
A117: Variable Set [ Name:%nottitle To:Rocznica śmierci %nazwy_kontaktów(%ile_dat) Do Maths:Off Append:Off ]
A118: Variable Set [ Name:%nottext To:Dziś jest %zgon rocznica śmierci %nazwy_kontaktów(%ile_dat). Do Maths:Off Append:Off ]
A119: AutoNotification [ Configuration:Title: %nottitle
Text: %nottext
Ticker: %nottitle
Action on Touch: cancel=:=birthday
Action on Dismiss: remind birthday=:=1
Icon: %acpicturefile
Status Bar Icon: ic_action_basket
Id: urodziny_%acid
Dismiss on Touch: true
Priority: 1
Sound: %scieżka_do_dźwięku
Picture: %scieżka_do_grafik

/rip.jpg
Text Expanded: %nottext Package:com.joaomgcd.autonotification Name:AutoNotification Timeout (Seconds):0 ]
A120: End If
A121: Variable Subtract [ Name:%ile_dat Value:1 Wrap Around:0 ]
A122: Goto [ Type:Action Label Number:1 Label:pętla powiadomienia ] If [ %ile_dat > 0 ]
A123: End If

Profile: AN Przypomnij o urodzinach (42)
State: AutoNotification [ Configuration:Event Behaviour
Filter: remind birthday=:= ]
Enter: Anon (43)
A1: AutoNotification Cancel [ Configuration:Id: %anpar2 Package:com.joaomgcd.autonotification Name:AutoNotification Cancel Timeout (Seconds):0 ]
A2: Variable Set [ Name:%BIRTHDAYR To:%ancomm Do Maths:Off Append:Off ]

Profile: AN Wyślij wiadomość (27)
State: AutoNotification [ Configuration:Event Behaviour
Filter: composesms=:= ]
Enter: Anon (39)
A1: Status Bar [ Set:Collapsed ]
A2: Compose SMS [ Recipient(s):%ancomm Message: ]
A3: AutoNotification Cancel [ Configuration:Id: %anpar2 Package:com.joaomgcd.autonotification Name:AutoNotification Cancel Timeout (Seconds):0 ]

Profile: AN Zadzwoń (40)
State: AutoNotification [ Configuration:Event Behaviour
Filter: call=:= ]
Enter: Anon (41)
A1: Status Bar [ Set:Collapsed ]
A2: Call [ Number:%ancomm Auto Dial:On ]
A3: AutoNotification Cancel [ Configuration:Id: %anpar2 Package:com.joaomgcd.autonotification Name:AutoNotification Cancel Timeout (Seconds):0 ]

Profile: AN Hangouts (192)
State: AutoNotification [ Configuration:Event Behaviour
Filter: browse=:= ]
Enter: Anon (201)
A1: Status Bar [ Set:Collapsed ]
A2: Browse URL [ URL:%ancomm ]
A3: AutoNotification Cancel [ Configuration:Id: %anpar2 Package:com.joaomgcd.autonotification Name:AutoNotification Cancel Timeout (Seconds):0 ]

Pobieranie profilu

Projekt Urodziny [Tasker 4.5u1]
Pliki JPG należy umieścić w folderze /sdcard/Tasker/pictures/.

4 października 2014

Profil: Głosowe wybieranie numerów

Dziś mniej teorii, a więcej praktyki. Zajmiemy się profilem, który umożliwi głosowe wybieranie numerów kontaktów i inicjowanie połączenia głosowego. Niestety sam Tasker nie pozwoli zrealizować takiego profilu. Pomocne będą wtyczki AutoContacts i AutoVoice.
Profil ma za zadanie odnaleźć dany kontakt w książce adresowej, odczytać jego numery telefonów, zapytać użytkownika, na który numer chce zadzwonić i wywołać połączenie.

Wymagania

  • wtyczka AutoVoice w wersji płatnej
  • wtyczka AutoContacts w wersji płatnej
  • generator głosu Text-To-Speech, przykładowo IVONA lub Google TTS
  • do poprawnego działania profilu niezbędny jest porządek w książce adresowej tzn. numery telefonów muszą być opisane jako komórka, domowy lub służbowy

Wtyczka AutoVoice

Wtyczka AutoVoice, w wielkim skrócie, pozwala na uruchamianie tasków Taskera za pomocą komend głosowych. Dzięki niej możemy oprogramować głosowo praktycznie wszystkie funkcje telefonu lub tabletu. Do prawidłowego działania wtyczka wymaga połączenia z internetem.

Instalacja i konfiguracja

Wtyczkę AutoVoice można pobrać ze sklepu Google Play. Po instalacji i wykupienia wersji Pro pozostaje wybór sposobu uruchamiania komend głosowych. Najprostszym rozwiązaniem jest dodanie na pulpit skrótu Recognize.

Trochę wygodniejszym rozwiązaniem jest uruchamianie tego skrótu gestem co można osiągnąć stosując alternatywne launchery np. Nova Launcher

Wtyczka AutoContacts

Wtyczka AutoContacts daje dostęp Taskerowi do kontaktów z książki adresowej. Dzięki niej możemy dotrzeć do numerów telefonów kontaktu, do którego chcemy zadzwonić.

Instalacja i konfiguracja

Wtyczkę AutoContacts można pobrać ze sklepu Google Play. Po instalacji i wykupienia wersji Pro należy w konfiguracji wtyczki uruchomić opcję Force Refresh Contacts co pozwoli odczytać z książki adresowej dane wszystkich kontaktów.
Aby łatwiej wybierać głosowo kontakty dobrze jest najczęściej używanym nadać ksywki. Po naciśnięcie opcji Manage Contacts w konfiguracji wtyczki i przytrzymaniu dłużej wybranego kontaktu możemy nadać mu ksywkę (opcja Set Nickname). Przykładowo kontaktowi Jan Kowalski nadanie ksywki Janka pozwoli na wykonanie połączenia telefonicznego do tego kontaktu poprzez wypowiedzenie komendy zadzwoń do Janka zamiast zadzwoń do Jan Kowalski.

Opis wykonania

Kontekstem uruchamiającym profil jest State / Plugin / AutoVoice Recognized. W konfiguracji kontekstu należy zaznaczyć opcję Event Behavior oraz Use Regex natomiast w polu Command Filter wpisać zadzwoń do (?<contact>.+). Taki zapis oznacza, że wszystko co zostanie wypowiedziane po zadzwoń do zostanie przekazane do tasku profila w postacie zmiennej %contact.

W edycji tasku zaczynamy od akcji Plugin / AutoContacts. W konfiguracji akcji w polu Contact Name or Nickname wpisujemy %contact czyli każemy wtyczce wyszukać dane kontaktu, którego nazwę/ksywkę dostarczymy w komendzie głosowej.
Następnie sprawdzamy za pomocą akcji If czy zmienna %acnunmber (czyli przechowująca numer telefonu odnalezionego kontaktu) ma wartość. Jeśli nie za pomocą akcji Say informujemy użytkownika o błędzie. Akcja Say używa generatora głosu Text-To-Speech by tekst zamienić na mowę.

Następnie musimy użyć akcji Variable Split, które dzielą ciągi tekstowe na części tworząc zmienną typu macierz. Jako, że AutoContacts poszczególne wartości oddziela przecinkami to w akcji Variable Split jako separatora użyjemy właśnie przecinka.
Zmienne %acallnumbers (wszystkie numery telefonów danego kontaktu) i %acallnumbertypes (typy numerów telefonów) są zmiennymi macierzowymi i mogą zawierać wyniki pochodzące od więcej niż jednego kontaktu. Dlatego odczytujemy tylko pierwsze rekordy podając parametr 1 lub (1).

Kolejnym krokiem jest przekazanie do zmiennej %index pozycji, na której znajdują się poszczególne typy numerów telefonów. W przypadku telefonu komórkowego będzie to %acallnumbertypes1(#?Komórka). Dalej za pomocą wyznaczonej wartości przekazujemy do zmiennej %komórka numer telefonu komórkowego za pomocą składni %acallnumbers1(%index1). Następnie powtarzamy te operacje dla telefonu domowego oraz służbowego.
Należy pamiętać, że w różnych wersjach producenckich systemu Android inaczej mogą być oznaczane typy numerów telefonów. W przypadku "czystego" Androida oraz wszelkich wersji bazujących na AOSP/CM będzie to odpowiednio: Komórka, Służbowy, Domowy. Jeśli w danym systemie oznaczenie te są inne (przykładowo w telefonach Samsunga numer telefonu komórkowego opisywany jest jako Komórkowy) należy zmienić je w akcjach numer 8, 11 i 14.
Kolejnym krokiem jest połączenie numerów telefonów ze zmiennych %komórka, %dom, %praca (pod warunkiem, że mają wartości) oddzielonych przecinkami do zmiennej %telefony za pomocą akcji Variable Set z zaznaczoną opcją Append. Teraz możemy zamienić tą zmienną w macierz i ilość jej elementów przekazać do zmiennej %index.

Jeśli wartość %index ma wartość 1 czyli kontakt ma tylko jeden numer telefonu za pomocą akcji Call wywołujemy połączenie głosowe pod dany numer.
Jeśli zmienna %index ma wartość większą od 1 za pomocą akcji Say pytamy użytkownika, na który numer ma być wykonane połączenie. Odpowiedź głosową rejestrujemy akcją AutoVoice Recognize, która trafia do zmiennej %avcomm. Następnie wywołujemy akcję Call pod wybrany numer w zależności od zawartości tej zmiennej.

I to już koniec. Profil gotowy. Na zrzutach ekranu powinien on wyglądać następująco:

Aby w przyszłości AutoContacts miał dostęp do dodanych i zmienionych kontaktów należy stworzyć profil, który będzie odświeżał dane wtyczki. U mnie taki profil uruchamia się codziennie o drugiej godzinie w nocy pod warunkiem podłączneia telefonu do ładowarki. W tasku tego profilu należy dodać akcję AutoContacts z zaznaczoną opcją Refresh.

Rozpisany profil

Profile: Zadzwoń do (195)
State: AutoVoice Recognized [ Configuration:Event Behaviour: true Command: "zadzwoń do (?<contact>.+) (regex)" ]
Enter: Anon (196)
A1: AutoContacts [ Configuration:Contact Name or Nickname: %contact Package:com.joaomgcd.autocontacts Name:AutoContacts Timeout (Seconds):1000 Continue Task After Error:On ]
A2: If [ %acnumber !Set ]
A3: Say [ Text:Nie znaleziono kontaktu %contact Engine:Voice:default:default Stream:5 Pitch:5 Speed:5 Respect Audio Focus:On Network:Off Continue Task Immediately:Off ]
A4: Stop [ With Error:Off Task: ]
A5: End If
A6: Variable Split [ Name:%acallnumbers1 Splitter:, Delete Base:Off ]
A7: Variable Split [ Name:%acallnumbertypes1 Splitter:, Delete Base:Off ] <komórka>
A8: Variable Set [ Name:%index To:%acallnumbertypes1(#?Komórka) Do Maths:Off Append:Off ]
A9: Variable Split [ Name:%index Splitter:, Delete Base:Off ] If [ %index !~ 0 ]
A10: Variable Set [ Name:%komórka To:%acallnumbers1(%index1) Do Maths:Off Append:Off ] If [ %index !~ 0 ] <praca>
A11: Variable Set [ Name:%index To:%acallnumbertypes1(#?Służbowy) Do Maths:Off Append:Off ]
A12: Variable Split [ Name:%index Splitter:, Delete Base:Off ] If [ %index !~ 0 ]
A13: Variable Set [ Name:%praca To:%acallnumbers1(%index1) Do Maths:Off Append:Off ] If [ %index !~ 0 ] <dom>
A14: Variable Set [ Name:%index To:%acallnumbertypes1(#?Domowy) Do Maths:Off Append:Off ]
A15: Variable Split [ Name:%index Splitter:, Delete Base:Off ] If [ %index !~ 0 ]
A16: Variable Set [ Name:%dom To:%acallnumbers1(%index1) Do Maths:Off Append:Off ] If [ %index !~ 0 ]
A17: Variable Set [ Name:%telefony To:komórka, Do Maths:Off Append:Off ] If [ %komórka Set ]
A18: Variable Set [ Name:%telefony To:dom, Do Maths:Off Append:On ] If [ %dom Set ]
A19: Variable Set [ Name:%telefony To:praca, Do Maths:Off Append:On ] If [ %praca Set ]
A20: Variable Split [ Name:%telefony Splitter:, Delete Base:Off ]
A21: Variable Set [ Name:%index To:%telefony(#) Do Maths:Off Append:Off ]
A22: If [ %index = 1 ]
A23: Call [ Number:%komórka Auto Dial:On ] If [ %komórka Set ]
A24: Call [ Number:%dom Auto Dial:On ] If [ %dom Set ]
A25: Call [ Number:%praca Auto Dial:On ] If [ %praca Set ]
A26: Else
A27: Say [ Text:Na który numer %acname chcesz zadzwonić: %telefony Engine:Voice:default:default Stream:3 Pitch:5 Speed:5 Respect Audio Focus:On Network:Off Continue Task Immediately:Off ]
A28: AutoVoice Recognize [ Configuration: Voice command without headset Command: "all" Package:com.joaomgcd.autovoice Name:AutoVoice Recognize Timeout (Seconds):120 ]
A29: Call [ Number:%komórka Auto Dial:On ] If [ %avcomm ~ *komórka* ]
A30: Call [ Number:%dom Auto Dial:On ] If [ %avcomm ~ *dom* ]
A31: Call [ Number:%praca Auto Dial:On ] If [ %avcomm ~ *praca* ]
A32: End If

Profile: Odświeżanie kontaktów (197)
Time: 02:00
State: Power [ Source:AC ]
Enter: Anon (198)
A1: AutoContacts [ Configuration:Refresh: true Package:com.joaomgcd.autocontacts Name:AutoContacts Timeout (Seconds):1000 ]

Pobieranie profilu

Profil Głosowe wybieranie połączenia telefonicznego [Tasker 4.5u1]

16 sierpnia 2014

Profil: Tost z danymi sieci WiFi po połączeniu

Mimo, że nie przepadam za nakładką TouchWiz autorstwa Samsunga ma ona kilka ciekawych i przydatnych elementów. Jednym z nich jest tost wyświetlający dane sieci WiFi i szybkość połączenia zaraz po jego nawiązaniu. Dziś zademonstruję w jaki sposób uzyskać podobną funkcjonalność w Taskerze.

Opis wykonania

Na ekranie głównym Taskera, w zakładce Profile naciskamy klawisz +, z listy kontekstów wybieramy State / Net / WiFi Connected. Na ekranie edycji kontekstu nic nie zmieniamy bo chcemy by tost był wyświetlany przy połączeniu z każdą siecią. Jeśli wypełnimy na tym ekranie pola SSID, MAC lub IP to profil będzie uruchamiany tylko po połączeniu z siecią spełniającą wpisane warunki. Przykładowo podanie nazwy SSID sieci PRZYKLADOWE-WIFI spowoduje, że połączenie tylko z tą siecią uaktywni profil.
Wciskamy klawisz wstecz, następnie wybieramy New Task i przechodzimy do edycji tasku wejściowego profilu.
Wyświetlanie tostu ma sens tylko w przypadku gdy urządzenie ma włączony ekran. Dlatego zaczniemy task od sprawdzenia jego statusu. Tasker przechowuje dane na temat statusu ekranu w zmiennej %SCREEN. Może on przyjmować wartości on i off czy odpowiednio włączony i wyłączony.
Wybieramy klawisz +, kategorię Task i akcję If. W konfiguracji akcji w lewej części obszaru Condition wpisujemy %SCREEN, w prawej on, a jako operator wybieramy Matches. Czyli dalsze akcje zostaną wykonane jeśli zmienna %SCREEN będzie miała wartość on (ekran włączony).

Po powrocie do ekranu edycji tasku zajmiemy się przygotowaniem danych do naszego tostu. Dane te są przechowywane w zmiennej %WIFII. Można sprawdzić jakie dane są dostępne w zmiennej wybierając klawisz menu / More / Run An Action / Alert / Flash i w polu text wpisać %WIFII. Po dotknięciu klawisza wstecz wyświetli się tost z zawartością zmiennej %WIFII. Nam zależy na nazwie SSID sieci, przyznanym urządzeniu adresie IP oraz prędkości połączenia. Aby wyciągnąć potrzebne nam dane skorzystamy z akcji Variable Split jednak najpierw wartość zmiennej %WIFII musimy przekazać do innej tymczasowej zmiennej %wifiinfo, którą będziemy mogli edytować. Wybieramy klawisz + następnie Variables / Variable Set i w konfiguracji akcji w pole Name wpisujemy %wifiinfo, a do pola To %WIFII. Następnie naciskamy klawisz wstecz, klawisz + i wybieramy Variables / Variable Split. W konfiguracji akcji w pole Name wpisujemy %wifiinfo oraz zaznaczamy opcję Delete Base (czyli usuwamy zmienną %wifiinfo po jej podziale). Akcja Variable Split dzieli ciąg znaków na części oddzielone wybranym znakiem (Splitter). W naszym przypadku nie wybraliśmy splittera więc Tasker przyjmie spację jako znak podziału. Każde słowo z oryginalnego tekstu jest teraz dostępne w zmiennej %wifiinfoX gdzie X to numer słowa w tekście.
Wybieramy klawisz wstecz, następnie + i dodajemy akcję Alert / Flash. W konfiguracji tej akcji w polu Text wpisujemy następujący tekst:

Połączono z siecią: %wifiinfo4
Adres IP: %wifiinfo9
Prędkość: %wifiinfo13
oraz zaznaczamy opcję Long (by tost wyświetlał się dłużej).
Naciskamy teraz dwukrotnie wstecz i mamy gotowy profil. Powinien on wyglądać następująco:

Rozpisany profil

Profile: Połączone WiFi (91)
State: Wifi Connected [ SSID:* MAC:* IP:* ]
Enter: Anon (152)
A1: If [ %SCREEN ~ on ]
A2: Variable Set [ Name:%wifiinfo To:%WIFII Do Maths:Off Append:Off ]
A3: Variable Split [ Name:%wifiinfo Splitter: Delete Base:On ]
A4: Flash [ Text:Połączono z siecią %wifiinfo4
Adres IP: %wifiinfo9
Prędkość: %wifiinfo13 Long:On ]

Wideo

Pobieranie profilu

Profil Tost z danymi sieci WiFi po połączeniu [Tasker 4.4u2]

Aktualizacja

Jak kolega mrtur zauważył w komentarzach w przypadku gdy nazwa sieci będzie zawierała spację profil wyświetli niepoprawne dane. Dlatego poniżej przedstawiam poprawioną wersję.
Tym razem posłużyłem się akcją Variable Search Replace z wyszukiwaniem ciągu (?<=(\n)).*, który podzieli tekst na poszczególne linie, które trzeba poprzycinać do odpowiednich długości za pomocą kolejnych akcji Variable Search Replace z odpowiednimi wartościami pola Search.

6 sierpnia 2014

Tworzymy pierwszy profil

Przyszedł w końcu czas na własnoręczne stworzenie pierwszego profilu. Przedstawię krok po kroku jak stworzyć bardzo prosty profil wyświetlający tzw. tost "Witaj" po odblokowaniu ekranu. Do opisu załączę wyeksportowany plik xml do pobrania, opis wszystkich akcji i kontekstów oraz klip wideo, na którym pokażę, co i jak trzeba po kolei wykonać.

Ekran edycji tasku

Zaczniemy jednak od omówienia ekranu edycji tasku. Standardowo na dole mamy klawisz +, który umożliwia dodanie nowej akcji, w dolnym pasku jest jeszcze klawisz ze znakiem Play umożliwiający uruchomienie tasku. Dłuższe przytrzymanie palca na którejś z dodanych już akcji wyświetla na górze ekranu pasek umożliwiający kopiowanie, wklejanie i wyłączanie tej akcji. Wyłączona akcja oznaczona będzie fioletowym paskiem i nie będzie uruchamiana.

Profil "Witaj"

Zaczynamy tworzyć profil. Na zakładce profile Taskera naciskamy klawisz +. Pojawi się lista rodzajów kontekstów. Chcemy by nasz profil uaktywniał się przy odblokowaniu ekranu z listy wybieramy Event, a następnie z listy Display / Display Unlocked. W tym momencie Tasker wyświetli ekran konfiguracji tego kontekstu gdzie można wybrać priorytet kontekstu. Od priorytetu zależy pozycja tasku wejściowego profilu na liście oczekiwania (jeśli akurat wykonują się inne taski). W tym przypadku nie zależy nam na wysokim priorytecie więc pozostawiamy standardowy Normal.
Naciskamy klawisz Back i z listy, która się pokaże wybieramy New Task. W tym momencie Tasker zapyta o nazwę tasku. Nie ma konieczności podawania nazwy tasku ale na dłuższą metę dzięki nazwom tasków łatwiej się zorientować co i kiedy się uruchamia. W naszym przypadku nie wpisujemy nazwy zadania. Tasker przenosi nas do ekranu edycji tasku wejściowego.
Przy okazji tworzenia tego tasku użyjemy po raz pierwszy zmiennych. Nie są one w tym przypadku konieczne ale im szybciej zaczniesz ich używać tym szybciej je opanujesz. Naciskamy więc klawisz plus, z listy akcji wybieramy Variables / Variable Set. Na ekranie edycji tej akcji w polu Name wpisujemy %tekst (czyli tworzymy zmienną lokalną o nazwie %tekst), a w polu To wpisujemy Witaj (czyli nadajemy zmiennej wartość). Naciskamy klawisz wstecz i wracamy do ekranu edycji tasku. Znów naciskamy klawisz plus i wybieramy Alert / Flash. Na ekranie edycji tej akcji w polu Text wpisujemy %tekst oraz zaznaczamy opcję Long (by nasz tost dłużej trwał). Zadaniem akcji Flash będzie wyświetlenie na ekranie tekstu znajdującego się w zmiennej %tekst czyli słowa Witaj. Naciskamy klawisz wstecz i mamy przed sobą cały task tworzonego profilu. Po ponownym naciśnięciu klawisza wstecz widzimy gotowy profil. Ekrany te powinny wyglądać jak na poniższych zrzutach ekranu.

Jeśli wszystko wygląda prawidłowo możemy wyjść z Taskera, wyłączyć i włączyć ekran urządzenia i po odblokowaniu powinien pojawić się tost o treści "Witaj".

Rozpisany profil

Profile: Powitanie po odblokowaniu (152)
Event: Display Unlocked
Enter: Anon (160)
A1: Variable Set [ Name:%tekst To:Witaj Do Maths:Off Append:Off ]
A2: Flash [ Text:%tekst Long:On ]

Wideo

Pobieranie profilu

Profil Witaj [Tasker 4.4u2]