Category Archives: Tech

Mese az Excelről és a context menüről

TL;DR: 2010-es Excelnél újabb verzióban soha ne használd a Workbook_SheetBeforeRightClick() event handlert arra, hogy saját CommandBart hozz létre – helyette ott a Custom UI editor for Microsoft Office, amivel ugyan csak bedrótozott hierarchiát tudsz csinálni, viszont cserébe nem fagy majd random szénné alatta a host környezet. A dolog úgy indult, hogy egy Office update után elkezdett furán viselkedni a VBA kód pár táblában. Jó szokás szerint a hibajelenségnek semmi köze nem volt a hiba okához, a Microsoftos alkalmazásnak pedig esze ágában sem volt bármiféle notificationt küldeni, hogy neki XY kóddarabbal lenne baja, sokkal inkább a számukra már sokszor bevált utat választba, nemes egyszerűséggel vagy rommá fagyasztotta a futtató környezetet, vagy a teljes Excel UI elfelejtett a végfelhasználóval kommunikálni. Mutatom:

Excel 2010+ event handler madness from Gabor Penoff on Vimeo.

A videóban jól látszik, hogy a testData tábla kiválasztása után az megnyílik, majd az Excel előbb mintha elfelejtené a screent update-elni, később viszont teljesen meggárgyul és a saját UI elemei is megszűnnek működni. Nézzük végig, mi történik belül. A 2. kattintásra a standard context menünek kellene előbújnia, azonban én ezt elkapom és a saját cuccaimat pakolom a gyári menü helyére. Mindez úgy történik, hogy a Workbook_SheetBeforeRightClick() event handlert használom:
Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Excel.Range, Cancel As Boolean)
    rightClickMenuShow (rightClickMenuTitle)
    Cancel = RightClickCancel
End Sub
A rightClikMenuShow() törli az előző custom menüt, majd újra létrehozza és megjeleníti:
Sub rightClickMenuShow(rightClickMenuName As String)
    RightClickCancel = True
    Call rightClickMenuDelete(rightClickMenuName)
    Call rightClickMenuCreate(ActiveSheet)
    CommandBars(rightClickMenuTitle).ShowPopup
End Sub
A törlés így néz ki:
Sub rightClickMenuDelete(rightClickMenuName As String)
    Dim bar As CommandBar
    For Each bar In CommandBars
        If UCase(Trim(bar.Name)) = UCase(Trim(rightClickMenuTitle)) Then bar.Delete
    Next bar
End Sub
Az új menü létrehozása pedig így:
Sub rightClickMenuCreate(S_Caller As Worksheet)
    Dim rightClickMenuName As String
    Dim rightClickMenuIndex As Long
    rightClickMenuName = rightClickMenuTitle
    Call rightClickMenuDelete(rightClickMenuName)
    Application.CommandBars.Add Name:=rightClickMenuName, Position:=msoBarPopup
    rightClickMenuIndex = 0
    rightClickMenuIndex = rightClickMenuIndex + 1
    CommandBars(rightClickMenuName).Controls.Add Type:=msoControlButton, Before:=rightClickMenuIndex
    With CommandBars(rightClickMenuName).Controls(rightClickMenuIndex)
        .FaceId = 263
        .Style = msoButtonIconAndCaption
        .Caption = "Excel's &Default Shortcut Menu"
        .OnAction = "ShowDefaultRightClickMenu"
    End With
    rightClickMenuIndex = rightClickMenuIndex + 1
    CommandBars(rightClickMenuName).Controls.Add Type:=msoControlButton, Before:=rightClickMenuIndex
    With CommandBars(rightClickMenuName).Controls(rightClickMenuIndex)
        .Style = msoButtonCaption
        .Caption = "Freeze me please"
        .OnAction = "myTestSub"
        .BeginGroup = True
    End With
End Sub
Röviden ennyi a jobb klikkes menüből a myTestSub() makrót elindító event handler mechanizmus. Miután ebben hozzá nem nyúlok a képernyő frissítését szabályozó Application.ScreenUpdating metódushoz, nézzük meg, mit csinál a myTestSub():
Sub myTestSub()
    Dim f As Variant
    f = Application.GetOpenFilename
    If f = False Then
        MsgBox "No file selected."
    Else
        Workbooks.Open Filename:=f, ReadOnly:=True
    End If
End Sub
Láthatóan ennek sincs köze a ScreenUpdating-hez, mégis elpusztul tőle az Excel. Miután a probléma nyilván nem egy ilyen ~20 soros toolban jött elő, pár órát elvett az életemből mire rájöttem, hogy az 2010-es verziónál frissebb Exceleknek azzal van baja, ahogyan én a right click menüt újradefiniálom a Workbook_SheetBeforeRightClick() event handlerben egy CommandBars(rightClickMenuTitle).ShowPopup() hívással. A helyes megoldás ilyenkor az, hogy ezt a popup generátort úgy ahogy van kidobod és létrehozol egy XML-t, ami a fenti két eljárás meghívásához legyártja majd az UI eleme(ke)t a jobb klikkre megjelenő context menüben:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
    <contextMenus>
        <contextMenu idMso="ContextMenuCell">
            <menu id="appMenu" label="engine" insertBeforeMso="Cut">
                <button id="item_id1" label="(Do not) freeze me please" onAction="myTestSub"/>
            </menu>
        </contextMenu>
    </contextMenus>
</customUI>
Ebben az esetben azonban ne felejtsd el, hogy fel kell készíteni a hívott rutinodat az IRibbonControl paraméter fogadására:
Sub myTestSub(control As IRibbonControl)
Tanulság nincs, csak ledokumentáltam 4 óra őrjöngés után a megoldást. ]]>

Excel VBA: Application.Evaluate – Error (2015|2029)

Application.Evaluate() metódusával és a rohadék a nem túl beszédes "Error 2015" vagy "Error 2029" stringeket adná vissza cserébe, akkor ne a formulákban keresd a hibát, hanem azt nézd meg, hogy a kiértékelés forrásaként használt képlet és az aktív workbook referenciastílusa megegyezik-e. Ha nem, akkor állítsd át az

Application.ReferenceStyle = (xlA1|xlR1C1)
értékadással és problem solved, a redmondi felelősök meg süllyedjenek el szégyenükben a gusztustalan workaroundjukkal együtt.]]>

REST csajoknak

Ryan Tomayko bejegyzésének többé-kevésbé sikerült tükörfordítása: akárhányszor olvasom, bénának érzem, de kész van, eddig babusgattam, gondoltam megosztom, hátha lesz akinek hasznára válik.

Hogy magyaráztam el a REST-et a nejemnek

Feleség: Ki az a Roy Fielding? Ryan:Egy fickó. Okos. Feleség: Oh? Mit csinált? Ryan: Segített megírni az első webservereket, majd rengeteget kutatott, hogy elmagyarázza, miért úgy működik a web, ahogy. Ott van a neve azon a protokoll specifikáción, amelyet a böngésződ a webservereken tárolt oldalak lekéréséhez használ. Feleség: Hogyan működik ez? Ryan: A web? Feleség: Ja. Ryan: Hmm. Igaziból bámulatos az dolog. A vicces az, hogy ugyanakkor az egész nagyon alulértékelt. A protokoll, amelyről beszélek, a HTTP (=HyperText Transfer Protocol), egy csomó klassz dologra képes, amit az emberek valamilyen okból figyelmen kívül hagynak. Feleség: Úgy érted, ez az a http, amit a böngésző címsorába a cím elejére írok? Ryan: Igen. A címnek ez az eleje mondja meg a böngészőnek, hogy milyen protokollt használjon. Amit odagépelsz az az egyik legfontosabb áttörés az információtechnológia történetében. Feleség: Miért? Ryan: Mert képes definiálni az információ helyzetét bárhol a világon. Ez a web alapja. Úgy tekints rá, mint az ismeretanyagok GPS koordinátája. Feleség: “GPS” a weboldalakhoz? Ryan: Valójában bármihez. Az a fickó, Roy Fieling, sokat beszél arról, hogy mik ezek a dolgok abban a specifikációban, amiről beszéltem. A web egy REST nevű acrhitekturális stílus alapján épül fel. A REST az erőforrás definícióját szolgáltatja, azokra mutat. Feleség: A weboldalak erőforrások? Ryan: Egyfajta erőforrás. Egy weboldal egy erőforrás megjelenítési formája. Az erőforrás csak koncepció. Az URL-ek (=Universal Resource Locator) – azok a címek, amiket a böngésződ címsorába gépelsz… Feleség: Tudom mi az az URL… Ryan: Oh, rendben. Szóval azok megmondják a böngészőnek, hogy hol van az adott információ-csomag (=erőforrás). A böngésző elkéri a csomagot (=erőforrást) a meghatározott formátumban. A böngészők tipikusan weboldal formában kérik el az információ-csomagokat. Feleség: Milyen más formátumok léteznek még? Ryan: Nos, pont a különböző formátumok azok, melyeket nem használnak túlzottan. Legtöbb esetben egy információ csomagnak csak egyféle formátuma létezik. De reméljük, hogy a jövőben a különböző formátumokat többet fogják használni, mivel időről időre újabb és újabb formátumok születnek. Feleség: Mint például? Ryan: Hmm. Nos, van egy koncepció, amit Web Service-nek hívnak. Sok embernek sok különböző dolgot jelent, de az alapkoncepció az, hogy a gépek éppúgy használják a webet, ahogyan az emberek. Feleség: Ez valami robotszerű dolog? Ryan: Nem, nem igazán. Nem úgy értem, hogy gépek leülnek majd az íróasztal elé és böngészik a webet. Úgy értem a számítógépek ugyanazokat a protokollokat tudják használni egymás közti üzenetváltásra. Már régóta csináljuk ezt, de a ma használt technikák közül egyik sem működik túl jól, mikor a világ összes gépével kellene tudnod kommunikálni. Feleség: Miért nem? Ryan: Mert nem ilyen használatra tervezték őket. Amikor Fielding és a cimborái elkezdték építeni a webet, a gépek egymás közti kommunikációjának megoldása volt az elsődleges feladat. Ma a legtöbb kommunikációs technika, amit a számítógépek egymás közti kommunikációjában használunk már nem felel meg ennek a követelménynek. A számítógépeknek csak más gépek egy kis csoportjával kellett kommunikálniuk. Feleség: És tudnod kell kommunikálni az összes géppel? Ryan: Igen – és még többel. Minden géppel, a rajtuk tárolt minden adattal kapcsolatban kell tudnunk kommunikálni. Szóval kell valami módszer arra, hogy egy gép elkérhessen egy másik géptől egy erőforrást (=adatot), ami akár épp egy harmadik gépen lehet. Feleség: Micsoda? Ryan: Mondjuk, hogy beszélsz a tesóddal és ő kölcsön akarja kérni a seprűd, vagy valami mást. De neked nincs seprűd – anyukádnak viszont van. Ezért elmondod a tesódnak, hogy kérje el anyukád seprűjét anyukádtól. Ilyen helyzetek folyamatosan adódnak a valós életben és akkor is, amikor gépek kezdenek el beszélgetni egymással. Feleség: És a gépek hogy mondják el egymásnak, hogy hol vannak a dolgok? Ryan: az URL (=Universal Resource Locator, Univerzális Erőforrás Lokátor) mondja meg nekik. Ha mindennek, amit a gépeknek egymással meg kell dumálniuk van egy meghatározott URL-je, akkor megalkottad a gépek nyelvén a főnevet. Te és én és a világ többi része is mind egyetért abban, hogy a főnevek nagyon fontosak ahhoz, hogy kommunikálni tudjunk, ugye? Feleség: Ja. Ryan: a gépeknek nincsenek univerzális főneveik – ez a “szívás” oka. Minden programnyelv, adatbázis vagy bármilyen egyéb rendszer más módon használja a saját főneveit. Ezért olyan fontos az URL. Lehetővé teszi, hogy a különböző rendszerek egymás főneveit használva beszélgetni tudjanak. Feleség: De amikor egy weboldalt nézek, nem gondolkodok ilyesmiken. Ryan: Senki sem agyal ezen. Kivéve Fieldinget és még egy maroknyi embert. Épp ezért “szívnak” a gépek. Feleség: És mi van az igékkel, a névmásokkal és a melléknevekkel? Ryan: Vicces, hogy ezt kérdezed, mert pont ez magyarázza a REST másik oldalát. Az igéket, egyébként. Feleség: Csak vicceltem. Ryan: Vicces volt, de valójában ez egyáltalán nem vicc. Az igék fontosak. Van egy polimorfizmus nevű nagyon fontos koncepció a számítógép tudományban és a programozási nyelvekben. Geek nyelven így mondjuk, ha a különböző főnevekkel ugyanazokat az igéket használhatjuk. Feleség: Nem értem. Ryan: Nos.. nézd meg a kávéasztalt. Mik a főnevek, amiket látsz? Csésze, tálca, újság, távirányító. Most mondd meg, mik azok a dolgok, amiket mindegyikükkel tudsz csinálni? Feleség: Nem értem… Ryan: Megkaphatod őket, ugye? Fel tudod őket emelni. Kopogni tudsz rajtuk. Elégetheted mindet. De használhatnánk akár ugyanazt az igét minden tárgyra, amiket itt látsz. Feleség: Oké… és? Ryan: Nos, ez az, ami fontos. Mi van akkor, ha ahelyett, hogy azt mondanám neked, hogy “fogd a csészét”, “fogd az újságot”, “fogd a távirányítót”; mi lenne, ha ehelyett minden főnévhez más igét kellene használnunk? Nem használhatnám a “fogd” igét univerzálisan, helyette minden főnév/ige kombinációban más-más igét kellene használnom. Feleség: Azta! Ez különös. Ryan: Igen, az. Valahogy az agyunk elég okos ahhoz, hogy tudja, néhány “univerzális” ige többféle főnévvel együtt használható. Néhány másik ige pedig jóval speciálisabb ettől és csak a főnevek egy meghatározott kis csoportjával alkalmazható. Például nem igazán vezethetek egy csészét és nem is ihatok egy autóból. Néhány ige azonban egészen univerzális, mint például a KAP, az AD és a TÖRÖL. Feleség: Nem TÖRÖLHETSZ egy csészét. Ryan: Nos, valóban, de kidobhatod. Ez egy másik vicc volt, ugye? Feleség: Igen. Ryan: Szóval HTTP – a protokoll, amit Fielding és a barátai létrehoztak – pont arról szól, hogy hogyan alkalmazzuk az igéket a főnevekkel. Például, ha felkeresel egy weboldalt, a böngésződ az oldal tartalmát egy HTTP GET kéréssel kéri el attól a géptől, amit az általad begépelt URL határoz meg és az eredményt egy weboldal formájában jeleníti meg neked. A weboldalkon általában képek is vannak, igaz? Ezek másfajta adatok (=erőforrások). A weboldal csak a képek URL-jét határozza meg, a böngésző feladata az, hogy ezek alapján az URL-ek alapján újabb HTTP GET kérésekkel elkérje a weboldal képeit egész addig, míg minden egyes adatot (=erőforrást) meg nem kap, majd végül megjeleníti a weboldalt neked. És ez a fontos: a böngésző nagyon különbőző főnevek beszerzéséhez használja ugyanazt az igét. Mindegy, hogy a főnév egy kép, szöveg, video, mp3, slideshow, bármi más. Mindet a GET ige segítségével kéri el onnan, ahova az adat URL-je mutat. Feleség: Úgy tűnik a GET egy nagyon fontos ige. Ryan: Az. Különösen amikor böngészőt használsz, mivel a böngészők javarészt csak GET-tel kérnek. Nem képesek túl sok másfajta interakciókra a különböző erőforrásokkal. Ez a valódi probléma, mert ez vezetett ahhoz, hogy sok ember azt gondolja, a HTTP csak a GET kéréseken alapul. Ezzel ellentétben a HTTP egy általános célú protokoll különböző igék és főnevek alkalmazására. Feleség: Klassz. De még mindig nem látom, hogy változtatna ez meg bármit is. Milyen másfajta főneveket és igéket akarsz még? Ryan: Nos, a főnevek már megvannak, csak épp még nem a megfelelő formátumban. Gondolj arra, mikor az amazon.com-ot böngészed, karácsonyi ajándék után kutatva nekem. Képzeld azt, hogy minden egyes termék főnév. Ha mindezek a gépek számára is érthetőek lennének, egy csomó klassz dolgot tudnánk csinálni. Feleség: Miért nem értenek meg a gépek egy átlagos weboldalt? Ryan: Mert a weboldalakat úgy tervezték, hogy azt emberek értsék. Egy gép nem törődik az adatok külalakjával. A gépeknek alapvetően csak az adatra van szükségük. Ideális esetben, minden URL-nek léteznie kellene egy emberek számára olvasható és egy gépek számára értelmezhető formában. Amikor a gépek GET-tel elkérik az adatot egy ember részére, az ember számára érthető változatot kérik el. Feleség: Szóval az emberek meg kellene csinálniuk az oldalaikat a gépek számára érthető formában is? Ryan: Ha az értékes. Nézd, elég sok absztakcióval beszélgetünk erről. Mi lenne, ha valós emberekkel néznénk meg mindezt. Tanár vagy – fogadok, hogy a sulitokban van egy nagy számítógép rendszer, vagy legalábbis 3-4 számítógép, amelyeken adminisztráljátok a diákokat: ki melyik osztályba jár, milyen jegyeik vannak, információk a könyvekről, amikből tanítotok, stb. Ha a rendszeretek web alapú, akkor valószínűleg minden főnévnek, amit az előbb használtam van saját URL-je: diák, tanár, osztály, könyv, terem, stb. Az URL-t a böngészőbe írva visszakapsz egy weboldalt. Ha az URL-nek van gépek által olvasható megfelelője, akkor egy új információ integrálása a rendszerbe elég triviális, mert minden adat standard módon fogyasztható. Ráadásul így valószínűleg könnyebb a különböző rendszerek egymás közti kommunikációja is. Emiatt könnyen építhettek akár egy országos méretű rendszert, amely elemei egymással kommunikálva összegyűjtheti az egyes iskolákban megíratott tesztek pontszámait. A lehetőségek határtalanok. Minden egyes rendszerelem egy egyszerű HTTP GET kéréssel szerzi meg a másiktól az információt. Ha az egyik rendszernek információt kell adnia a másik számára, HTTP POST-ot fog használni. Ha az egyik rendszer információt akar frissíteni egy másik rendszerben, HTTP PUT segítségével oldja meg. Az egyetlen dolog, ami hátra van az az, hogy kitaláljátok, hogy kell az adatnak kinéznie. Feleség: Szóval ez az, amin te és a többi számítógépes ember dolgozik most? Meghatározni, hogy hogy nézzen ki az adat? Ryan: Sajnos, nem. A többség ehelyett azzal van elfoglalva, hogy komplex specifikációkat írjon arról, hogy oldjuk meg mindezt más módon. A főneveik nem univerzálisak, az igéik nem polimorfok. Kidobunk évtizedes megbízhatóan használt és bizonyított technikákat és újrakezdjük olyanokkal, melyek úgy néznek ki, mint korábbi technikák, melyek a múltban már megbuktak. HTTP-t használunk de csak azért mert az segít nekünk, hogy a hálózati és biztonságtechnikai emberek kevesebbet beszéljenek róla. Az egyszerűséget áldozzuk fel a csini eszközök és varázslók oltárán. Feleség: Miért? Ryan: Fogalmam nincs. Feleség: Miért nem mondasz valamit? Ryan: Talán fogok.
Ha a fenti olvasmány nem tetszett és a REST-ről inkább komolyabban olvasnál, akkor itt a Wikipedia link.]]>

Sipos Jánosnak, szeretettel

Backblaze nyílt forráskódúvá tette az általuk használt saját RAID tömbjeiket védő Reed-Solomon implementáció Java forráskódját. A Reed-Solomon algoritmus egy hibajavító eljárás, amelyet Irvin S. Reed és Gustave Solomon bácsik dolgoztak ki 1960-ban. A módszert a Backblaze a RAID adattömbjei védelmére használja, de ugyanez az algoritmus “óvja” az optikai lemezeinken tárolt adatokat csakúgy, mint az (A|S)DSL átviteli technológiákban mozgatott adatcsomagokat, vagy épp a QR kódokat, sőt, a Voyager 2 űrszonda is egyfajta Reed-Solomon származékot használt! A világban rengeteg adaton alkalmaznak hibafelismerő módszereket és valamivel kevesebbszer hibajavító algoritmusokat. Hibafelismerés szinte mindenben van: a személyi számodtól kezdve a számlaszámodon át a TAJ azonosítódig minden hivatalos adat tartalmaz ilyet. Míg a hibát csak felismerni képes algoritmusok arra jók, hogy az adathibát detektáljuk, addig a hibajavító algoritmusok az adathibát akár korrigálni is képesek. Hibafelismerő algoritmus a mezei ismétlő módszer, a paritásteszte, a leggyakrabban használt CRC és a különböző hash algoritmusok is, de ezeket hagyjuk most, mert minket a Reed-Solomon cucc hozott lázba! A Reed-Solomon algoritmus úgynevezett “előremutató hibajavító” (=FEC, Forward Error Correction) algoritmus. Az “előremutató” jelzőt azzal érdemelte ki, hogy a hibajavításhoz nem kell a hibásan érkezett adatcsomagot újraküldeni. Az egész posztot az indukálta, hogy végigolvastam a fent már linkelt Backblaze bejegyzést, amiben Brian Beach baromi közérthetően el is magyarázza, hogy néz ki a hibajavító implementációjuk belül. Arra buzdítalak, hogy ezt te is tedd meg – ám ahhoz, hogy értsd is amit Brian magyaráz, nem baj ha fejben van, amit középsuliban a mátrixokkal kapcsolatban próbáltak meg beletömni. Mivel mint említettem, engem anno nem hozott kifejezetten lázba a lineáris algebra, Sipi minden igyekezetének ellenére sem (ellentétben pl. a jód-aziddal), így nekem is kutakodnom kellett, hogy megértsem a magyarázatot. Így találtam rá Horváth Dániel remek mátrixos előadásaira. Ebből nekünk mindenekelőtt a mátrixok szorzására lesz szükségünk: Majd kelleni fog a mátrix inverzének kiszámítása is, ahhoz viszont előbb fel kell fogni a determinánst (ahhoz meg a kifejtési tételt, de ezek egy videóban lesznek): Végül a mátrix inverzének számítása: Végignéztem a videókat és a determináns számításnál azért csak beugrott, hogy az a jó az endusernek, ha a legtöbb nullát tartalmazó sorral|oszloppal kezdi a kifejtést, szóval Sipi, csak megmaradt valami!-) Ha neked is megvolt a fenti 3 videó (vagy kened-vágod a mátrixműveleteket amúgy is), akkor most nyomás a Backblaze posztot olvasni! ]]>

Logitech MX Master: NE VEDD MEG

Állítólag nagy kezem van. Ezt támasztja alá az is, hogy idáig a kedvenc egerem a Logitech Performance MX volt. Most megjelent az utóda, amit a gyártó MX Master névre keresztelt. Ez az első emberes egér, aki Bluetooth LE támogatást kapott és Mac kompatibilis. Meg is rendeltem azonnal, az előbb ért ide. Már a csomagolására adtam egy piros pontot – rettenet utálom, mikor a ritkaföldfém mágneseket dobáljuk a szemétbe. Tapasztalatok:

  • A Performance MX háta domborúbb kicsit, ez laposabb az ujjak felé. Majd meglátjuk, hogy olyan kényelmes-e, mint az elődje.
  • Bluetooth connect megy azonnal, interferencia semmi (nem úgy, mint az unified kis bigyóval, amit muszáj volt a gép hátából egy USB hosszabbító dróttal előre hoznom, hogy ne lagoljon).
  • A teflon talpak elképesztő síkosak. Már az előző is oké volt, de ez hihetetlenül csúszik az asztalon.
  • A hasán levő szenzor első ránézésre könnyebben takarítható lesz, de majd meglátjuk, ha összeszed ez is valami hajszálat.
  • Az oldalára hátra pakolt két button (forward és back) teljesen értelmetlen RSI gyár, ellenben az oldalsó görgővel nagy élmény Final Cutban a timeline-t mozgatni.
  • A scrollwheel megérzi, ha izomból megtolod és átvált racsnis módból szabadonfutóba magától, aztán ha megállítod, akkor meg vissza. Ezt a váltást lehet force-olni a wheel mögé rakott buttonnal, de szerencsére ez utóbbi átállítható egy rakat másik funkcióra (meg is kapta az idáig csak trackpaddel elérhető smart zoomot azonnal).
  • A hüvelykujj alá pozícionált gombon maradt a default “Gesture” mód, amivel workspace-ek között lehet lapozni (hold + LEFT|RIGHT move), illetve Mission Controlt (hold + UP move, vagy egérmozgás nélkül csak klikk) meg App Exposét (hold + DOWN move) lehet indítani.
  • Az akksi a korábbi cserélhető AA helyett beépítetté változott, ugyanúgy micro USB tölti az egér elején. Ha addig kibírja az akksi, amíg a Logitech előáll egy még lapátkezűbb példánnyal, akkor semmi gondom ezzel.
Végül egy korrekt videós review, hogy ne csak egy száraz lista legyen a post: Update #20150720: sajna bármit csinálok, az MX Master csúszik. És a csúszás nem a fasza teflon talp pozitív tulajdonsága, hanem a szar rádiós kommunikációé: az egérkurzor pozícionálása akadozik egy 100 EUR értékű eszköznél, az agyam eldobom! A Logitech saját fóruma egyre jobban telik a dühödt userekkel, akik az idióta, semmit nem csináló, kifárasztós taktikát játszó supportra panaszkodnak. ]]>

iOS: a kriptikus Mail swipe és a Reminders sync lag

nem szinkronizál normálisan a Reminders iOS app a desktop változattal. A történet megértéséhez szükség van arra, hogy két másik problémát is elmeséljek, ezért készült el ez az iOS HOWTO poszt. A dolog ott indult, hogy egyik iPhone-ról másik iPhone-ra költözöm. Ez ugye normál esetben úgy néz ki, hogy

  • ellenőrizzük, hogy a két telefon szoftvere ugyanaza a major release (különben a backup nem biztos, hogy kompatibilis lesz az új céleszközzel)
  • készítünk egy backupot a régi eszközről akár a cloudba, akár iTunes segítségével lokálisan
  • az új eszközön nyomunk egy restore from backupot, forrásul a régi eszközről frissen készített mentést választva
Ezt meg is csináltam, ahogy illik, rengeteg idő múlva (sok app, sok adat=rengeteg restore idő) a friss telefonon úgy állt minden, ahogy a régin hagyam. A problémák ott kezdődtek, amikor ki kellett mozdulnom otthonról. A telefon elhagyva a WiFi range-et egyszercsak nem vette észre a 3G hálózatot, ám ezt egy AirPlane mód be/kikapcsolás helyretette. Aztán hazaérve ugyanígy reagált a WiFi hálózatra – magától nem detektált semmit, de az AirPlane mód toggle itt is meggyógyította. Végül az AirDrop funkció volt az, ami csak ugyanígy talált magára. Felhívtam az Apple szervizt, ahol egy technikus közölt egy rossz és egy jó hírt: a jó hír az volt, hogy a telefon valószínűleg nem hardverhibás, a rossz viszont az, hogy a problémát nagy eséllyel az előző telefon backupja okozza, ami csak úgy gyógyítható, ha nulláról újrakonfigurálom az új eszközt és nem használom a backupot. Érted, clean install, MINT AZ ÁLLATOK! Szívtam a fogam, mert ez nem kevés idő, de megcsináltam és valóban: probléma megoldva, minden wireless kommunikációs probléma megszűnt. Ahogy időm engedte, nekiálltam lépésről lépésre konfigurálni a friss telefont, de úgy látszik még egy RTFM junkienak is el tudja kerülni néhány apró részlet a figyelmét, mert a Mail appban az újrakonfigurálás után a swipe gesztusok a két telefonon másként viselkedtek. A forráseszközön a jobbról balra swipe jelentette a törlést, míg a céltelefonon ez az archiválás funkcióhoz volt hozzárendelve: iOS-mail-right-swipe-trash Jobbról balra swipe a régi eszközön iOS-mail-right-swipe-archive Jobbról balra swipe a friss eszközön iOS-mail-left-swipe-archive Balról jobbra swipe a régi eszközön iOS-mail-left-swipe-trash Balról jobbra swipe a friss eszközön Megnéztem a Settings/Mail, Contacts, Calendars/Swipe Options beállításokat, de ott esély nem volt arra, hogy törlést kérjünk bármelyik swipe irányra – kizárólag a jobbról balra swipe-ot lehet archiválásra konfigurálni. Ráadásul ezek a beállítások mindkét telefonon megegyeznek. Akkor meg hol a rákban van a right-to-left-swipe=trash? Nos, “kicsit” eldugták: az Apple logikája szerint ez úgy aktiválható, ha az adott mailboxunk beállításai között a kidobott üzenetek mappáját az archivált üzenetek mappa helyett a törölt üzenetek mappájára állítjuk: iOS-mail-delete-swipe-preference Mindez a Settings/Mail, Contacts, Calendars/{mail account}/Account/Advanced fülön lakik. BTW nem tudom ki az, aki az egyik mailboxában a jobbról balra swipe-pal törölne, míg a másikban inkább a balról jobbra swipe lenne neki komfortos… Miközben a fenti beállítást kerestem, észrevettem még egy különbséget a két eszköz konfigurációjában. A Settings/Mail, Contacts, Calendars/Fetch New Data fül a friss telefonon “Push”-t mutatott, míg a régi készüléken ez “Off” állapotú volt. Már mozdultam is rá, hogy kikapcsolom az új eszközön is a Push-t (=emailt akkor akarok olvasni, amikor én gondolom, nem pedig akkor, amikor az megjön), mikor eszembe jutott, hogy a korábbi Reminders szinkronizálási “probléma” esetleg pont ezen múlik, hiszen ha ezt kikapcsolom, akkor én magam tiltom meg az iCloudnak a push típusú publikálást! iOS-iCloud-push-settings És így is van: az iCloud push visszakapcsolása egy huszárvágással megoldotta a Reminders sync problémát, már csak vissza kell szoknom rá. ]]>

Android a házban, avagy egy geek ebédje

IP Webcam alkalmazás kell, meg persze némi mount a telefonnak a konyhában, valahogy így: IP_webcam-in-da-kitchen Kamera a helyére, app elindít, aztán már jön is a secondary monitorra a stream egy Chrome ablakban, mi meg nem aggódjuk halálra magunkat, hogy véletlenül odaég a drága pecsenye: IP_camera-UI Persze ugyanez megy iOS alatt is, ott IP Cam az áhított alkalmazás neve, csak én szívesebben állítottam a Moto G-t a sercegő hús mellé. ]]>

Kismalac, kismalac, let me in!

Na de a telefon nem szólt, hogy csengettek… 🙂 írta ma Ákos nekem. Summa summarum, ma telefonos kapucsengőt szerelünk. Sokszor előjött már a probléma, hogy a lakásban levő csengőt nem halljuk, amikor kint vagyunk a kertben, sőt ez még inkább gond, ha épp valahol a városban bócorgunk és egy futár épp megáll az ajtó előtt. Mivel a kapucsengő is csak egy mezei kontaktus, ami a homeaut serverben egy digitális input formájában jelenik meg, így nem nagy dolog az egészet bárhová elirányítani. A bejáratot látja egy IP kamera is, úgyhogy akár meg is nézhetjük, ki tenyerelt rá a csengőre. Mindezekből a következő recept állt össze:

  • a csengő megnyomása generáljon egy push notificationt a fiúk és eFi telefonjára
  • a push üzenetből azonnal el tudjak navigálni abba az iOS alkalmazásba, amin látom a bejárati IP kamera képét
  • egyúttal tegyük el a kameraképet egy network storage-ra, plusz küldjük el eFinek emailben
  • mindezt tegyük védetté a csengőt N alkalommal kényszeresen egymás után megnyomókkal szemben
Az iOS oldalhoz az alapot két alkalmazás szolgáltatta: az IP kamera képét mutató IP Cam Viewer Pro, valamint a user által gyártott push notifikációk küldözgetésére kitalált Pushover. Az ismétlődő csengetés elleni védelmi logika simán maradhatott volna a dataflow homeaut serverben (mindössze egy Delay és egy Blocker komponens kell a megvalósításához), ám valami miatt ez később jutott eszembe és így beledolgoztam az egész folyamatot levezénylő shell scriptbe – íme:
#!/bin/bash
lastrun () {
	TESTFILE="./kapucsengo.timestamp"
	if [ -e $TESTFILE ]
	then
		LASTRUNDATE=`date +%s -r $TESTFILE`
	else
		LASTRUNDATE="0"
	fi
	NOW=`date +%s`
	DIFF=$((NOW-LASTRUNDATE))
	touch $TESTFILE
	return $DIFF
}
MIN_REPEAT=30 # 30 másodpercen belül nem reagálunk újra
lastrun
LR=$?
if [ $LR -gt $MIN_REPEAT ]
then
	# ask pushover.net to send notification
	curl -s \
	  -F "token=MY_PUSHOVER_TOKEN" \
	  -F "user=MY_PUSHOVER_USERID" \
	  -F "message=CSENGETTEK" \
	  -F "title=ihome - r9" \
	  -F "url=ipcamviewer://launch?groupName=kapucsengo" \
	  -F "url_title=View cameras" \
	  https://api.pushover.net/1/messages.json 2>&1 /dev/null
	# save streetcam image on ring
	NOW=`date +%Y%m%d_%H%M%S`
	curl -u CAM_USER:CAM_PASS http://cam_url/cgi-bin/viewer/video.jpg >/media/cam_offline/$NOW.jpg
	cp /media/cam_offline/$NOW.jpg /media/camstorage/kapucsengo/
	/usr/bin/mpack -s "Csengettek - r9" /media/cam_offline/$NOW.jpg EFI_EMAIL_ADDRESS
	find /media/cam_offline/* -mtime +365 -exec rm{} \;
	exit 0
else
	# Repeated call within $MIN_REPEAT seconds - script cancelled
	exit 1
fi
A fenti scriptet egy Shell komponens indítja el, amint megjön a kapucsengő digitális bemenetén a kontaktus. A script megnézi, hogy utoljára 30 másodpercnél később indult-e és ha igen, teszi a dolgát:
  • szól a curl-nak, hogy küldjön a pushover.net felé egy notifikációs üzenetet JSON formátumban
  • szintén a curl-t kéri meg, hogy cibálja le az IP kamerából az épp látott képet
  • felmásolja az előbb letöltött képet a NAS-ra
  • megkéri az mpack binárist, hogy küldje el nekem a fotót attachmentben
  • végül a lokális storage-ből törli az esetlegesen meglevő, 365 napnál régebbi kameraképeket
Nálam a homeaut server csillió más dolgot is csinál, így kézenfekvő volt simán beleintegrálni az ő workflowjába a feladatot. Ha te csak egy “telefonálós” kapucsengőt szeretnél, az sem rocket science: elég egy Raspberry Pi, annak egy GPIO portja és egy Python script, hogy az egészet levezényeld, pont úgy, ahogy maandag megírta a blogján tegnapelőtt.]]>

Mac workflow: Alfred

Alfred viszont annál inkább a szívemhez nőtt. Az Alfred a készítők definíciója szerint egy “productivity” alkalmazás, mely a korábbi Quicksilver, illetve a most is aktívan fejlesztett Launchbar launcherek konkurrense. Most eltekintek attól, hogy a sok default Alfred jóságot részletesen ismertessem, azokról született már kismillió jó írás. Rettenet erő lakik a szoftverben, főleg, ha pénzt áldozol a 17 GBP-be kerülő PowerPack kiegészítésre. Amint van PowerPackod, már gyárthatod is a friss workflow-kat Alfredben. Én is csináltam sok ilyet és használok mások által fejlesztetteket – ebből szedtem most össze egy csokorra valót kedvcsinálónak. Lássuk a macit!

Uni-Call

FaceTime vagy Skype hívást tudok desktopról indítani anélkül, hogy az egeret használnám, így: callf calls

Currency converter

Árfolyamot vált, baromi gyorsan, bármiről bármire. Beállíthatod a kedvenc célárfolyamod default targetnek, de harmadik paraméterként bármikor konvertálhatsz tetszőleges másikra is: curr1 curr2 curr3

Image dimensions

Kép méretét adja vissza azonnal: dim1 dim2

Encode

URL/UTF8/Base64 formába konvertálja az inputot: encode

Animgif search

giffy

Google translate

UI-ben tökölés nélkül fordítja az inputot azonnal. Csináltam belőle 3 targetet: magyarra, angolra és lengyelre: gt-2hu gt-2en gt-2pl

Safari history search

h

IP és Mac addressek CLI nélkül, gyorsan

ip mac

Disk space check azonnal

space

Compose mail

m

Keresés a menubarban egér nélkül

menu

Új file gyártása és azonnali megnyitása

nf nfo

Cheatsheet azonnal

qr

Rate current iTunes track és add current iTunes track to singalong playlist

rate singalong

Recent items

rec rec-doc rec-downloads rec-folders

Save current URL with tags

save1 save2

Send current URL

send1 send2

Show all iCloud tabs

tabs

Timezones

tz Ha kedvet csináltam, már megérte! ]]>