Animace

HomeO mněBlogKontaktVěže...Přihlásit

Glukometr OneTouch UltraSmart a Linux

Datum:

2009-08-25

Čas:

15:04:25

Zobrazení:

3989

Reakcí:

0

Uživatel:

andrej

Kategorie:

Software, informatika

Několik slov úvodem

Jediným, zato však vydatným zdrojem informací pro tento článek jsou dva příspěvky na http://www.diabetesforums.com/. [1, 2]

Glukometr LifeScan OneTouch UltraSmart si pamatuje poměrně značný počet naměřených hodnot, řádově několik tisíc. Je vybaven sériovým rozhraním, které umožňuje přenos těchto dat do počítače k dalšímu zpracování. Přesněji řečeno, jedná se (v závislosti na dodávaném kabelu) většinou o virtuální sériový port připojený přes rozhraní USB. Je to dědictví z dávných dob, kdy byly peripheral-side USB řadiče příliš drahá vymoženost a sériový port dostal přednost.

Jak lze u zařízení tohoto typu očekávat, dodávaný software předpokládá pouze použití Mrkvosoft Doors, navíc ještě ve velmi staré verzi. Pro pořádné operační systémy žádná oficiální podpora neexistuje. Komunikační protokol byl až donedávna držen v tajnosti, aby nikdo nemohl vyvinout alternativní software pro získání dat z glukometru. Přitom jde jen o obyčejnou komunikaci přes sériový port. Nejde o převratný vynález, jehož vyzrazení by zhoršilo konkurenceschopnost výrobce. Naštěstí se situace v poslední době zlepšila. Právě díky tomu se několika geniálním lidem podařilo připravit software, který umožňuje komunikaci s glukometrem v mnoha UNIXových operačních systémech.

V tomto článku bude řeč o dvou programech, které umí přečíst a zobrazit paměť glukometru. Celý popis rozdělím do několika částí. V první části pohovořím o základních předpokladech pro komunikaci glukometru s operačním systémem založeným na kernelu Linux. Druhá část bude věnována prvnímu z odkazovaných programů, který je napsaný v C++. Třetí část popíše druhý program, tentokrát v C#. Ve čtvrté části se budu zabývat nejlepším možným technickým řešením, které se mi ovšem zatím nepodařilo realizovat.

1. část: Základní software

Je pravděpodobné, že většina uživatelů už má všechen potřebný software nainstalovaný ve své distribuci. Tato kapitola obsahuje návod, jak to zjistit a jak případné chybějící součásti doplnit.

Příprava kernelu

Ke komunikaci se sériovým rozhraním glukometru slouží virtuální sériový port na USB, zabudovaný přímo v dodávaném kabelu. Kernelový modul pro ovládání tohoto portu se jmenuje pl2303. Pokud tento modul máte k dispozici, není třeba v této věci nic dalšího podnikat. Příkaz modinfo pl2303 by měl vypsat něco takového:

[andrej@argos ~]$ modinfo pl2303
filename:       /lib/modules/2.6.30.5-AP/kernel/drivers/usb/serial/pl2303.ko
license:        GPL
description:    Prolific PL2303 USB to serial adaptor driver
alias:          usb:v03F0p3524d*dc*dsc*dp*ic*isc*ip*

[ ... ]

alias:          usb:v067Bp2303d*dc*dsc*dp*ic*isc*ip*
depends:        usbserial,usbcore
vermagic:       2.6.30.5-AP preempt mod_unload PENTIUMM 4KSTACKS
parm:           debug:Debug enabled or not (bool)

Po zasunutí kabelu do USB portu přibude ve zprávách kernelu (dmesg) několik nových řádek. Jejich konkrétní podoba se může samozřejmě lišit podle verze a konfigurace kernelu.

usb 2-1: new full speed USB device using uhci_hcd and address 5
usb 2-1: configuration #1 chosen from 1 choice
usbcore: registered new interface driver usbserial
USB Serial support registered for generic
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial Driver core
USB Serial support registered for pl2303
pl2303 2-1:1.0: pl2303 converter detected
usb 2-1: pl2303 converter now attached to ttyUSB0
usbcore: registered new interface driver pl2303
pl2303: Prolific PL2303 USB to serial adaptor driver

Pokud je vše v pořádku, můžete zbytek této podkapitoly směle přeskočit. Pokud příslušný modul nemáte nainstalovaný, což příkaz modinfo pl2303 ihned odhalí, bude třeba jej napřed získat. První možností je instalace balíčku s moduly pro vaší distribuci. Ne každá distribuce takový balíček má, v každé distribuci se bude pravděpodobně jmenovat jinak a ne každý uživatel používá distribuční kernel. Nicméně pokud najdete balíček, jehož název aspoň trochu připomíná usbserial, máte vyhráno.

Pokud balíček neexistuje nebo nepoužíváte distribuční kernel (nebo platí obě tvrzení), přijde na řadu ta nejzajímavější možnost — kompilace kernelu. Tu zde nebudu dopodrobna rozebírat, protože existuje spousta návodů. Budu vycházet z tohoto návodu.

Podstatný je zejména bod 3 — výběr součástí pro kompilaci. Vřele doporučuji nekonfigurovat kernel „na zelené louce“, ale vyjít z již existující konfigurace. Konfigurace je několik stovek proměnných, které jsou uložené v souboru .config přímo v hlavním adresáři se zdrojovým kódem kernelu. Před make menuconfig tedy doporučuji ještě následující dva kroky:

  1. Získat konfiguraci momentálně běžícího kernelu. (zcat /proc/config.gz > .config)
  2. Upravit tuto konfiguraci pro aktuální verzi. (make oldconfig)

Teď může přijít na řadu například make menuconfig, případně můžete použít jiné konfigurační dialogy podle gusta. V menu, které se zobrazí, je třeba zapnout podporu pro modul pl2303. K příslušné položce se dostanete přes Device Drivers ---> USB support ---> USB Serial Converter Support ---> USB Prolific 2303 Single Port Serial Driver. Volby „po cestě“ je třeba taktéž povolit, pokuž už povolené nejsou. (V 99,9% systémů povolené budou.) Zmíněnou položku je třeba nastavit na hodnotu M, aby se příslušný ovladač zkompiloval jako dynamický modul. Pak už stačí jen opustit konfigurační menu a nezapomenout novou konfiguraci uložit. Pokud je všechno v pořádku, příslušná proměnná se v konfiguraci objeví takto:

[root@argos linux]# grep PL2303 .config
CONFIG_USB_SERIAL_PL2303=m

Poté už lze přikročit k vlastní kompilaci a instalaci kernelu. Kompilace může trvat i desítky minut, což ale člověku vadit nemusí. Například slavný Tomáš Baťa kdysi řekl: „Strojům dřinu, lidem myšlení!“ Když dřina skončí, musí myslící člověk kernel nainstalovat. Při použití zavaděče GRUB to zajistí přímo instalační skripty. Zavaděč LILO vyžaduje trochu víc pozornosti ze strany uživatele, která se ovšem bohatě vyplatí. Všechny potřebné návody snadno najde Google. Výše odkazovaný návod se také o této problematice zmiňuje.

Pokud se nově zkompilovaný a aktuálně běžící kernel shodují ve verzi, bude nový modul pravděpodobně ihned k dispozici. Stačí například vysunout a opět zasunout kabel glukometru. V opačném případě bude nutné počítač restartovat a nabootovat s novým kernelem. Detaily opět přesahují rámec tohoto článku, ale je velmi snadné je vyhledat.

Software a knihovny

Budete potřebovat dynamického správce souborového systému devfs, který automaticky vytváří virtuální soubory zařízení v adresáři /dev. Ten je ovšem v drtivé většině dnešních distribucí samozřejmostí. Jinými slovy, pokud ho nemáte, pravděpodobně nemá smysl tuto situaci řešit jinak než upgradem celé vaší instalace.

Pro první z popisovaných programů budete potřebovat kompilátor g++ a knihovnu boost. Obojí by mělo být buď součástí standardní instalace vaší distribuce, nebo snadno dostupné v podobě balíčků. Kompilátor g++ je součástí sady kompilátorů GCC a stejnojmenného balíčku.

Druhý popisovaný program je závislý na frameworku Mono. Ten bývá taktéž ve všech distribucích dostupný. Pokud ve vaší distribuci není, lze ho snadno získat, neboť se jedná o volně šiřitelný open-source software.

Čášt 2: Komunikační software v C++

Zdrojové kódy lze stáhnout například zde. Po rozbalení archivu nás bude zajímat pouze soubor ultrasmartcmd/ultrasmartcmd.cpp. Ten obsahuje jednoduchý program pro přečtení paměti glukometru. Celý archiv obsahuje ještě další zajímavý software pro obousměrnou komunikaci, nicméně zatím jsem neměl čas ho prozkoumat podrobněji.

Program implicitně hledá virtuální sériový port pod špatným názvem a navíc ukazuje pouze miligramy na decilitr. Proto jsem připravil patch, který oba tyto problémy odstraní. Cesta k portu bude odpovídat současným konvencím platným pro Linux a hodnoty glykemie se převedou na milimoly na litr. Zdrojový kód bohužel obsahuje konce řádků typu Mrkvosoft Doors, proto je třeba patch přímo uložit do souboru a nijak s ním nemanipulovat přes prohlížeč nebo terminál. Aplikuje se v adresáři ultrasmartcmd například příkazem patch < /cesta/k/souboru/onetouchpatch:

[andrej@argos ultrasmartcmd]$ patch < /tmp/onetouchpatch
patching file ultrasmartcmd.cpp

Pak stačí program zkompilovat. Jak už bylo řečeno, je nutné mít nainstalovanou knihovnu boost. Kompilátor spustíme (z adresáře ultrasmartcmd) takto:

[andrej@argos ultrasmartcmd]$ g++ -lboost_system -lboost_regex -lpthread ultrasmartcmd.cpp -o ultrasmartcmd

Nepřebernou spoustu varování lze (téměř) bez obav ignorovat. Pokud kompilace nedopadne úspěšně, nejspíš vám chybí některá důležitá součást knihovny boost nebo hlavičkových souborů.

Pokud kompilace uspěje, objeví se v aktuálním adresáři nový binární soubor ultrasmartcmd. Pak už stačí připojit kabel a zapnout glukometr levým horním tlačítkem. Na displayi by se mělo ukázat PC. Spuštění programu ultrasmartcmd je snadné; jeho přespříliš hubatý výstup je ovšem rozumné filtrovat:

[andrej@argos ultrasmartcmd]$ ./ultrasmartcmd | grep record

Výsledky mohou vypadat například takto:

[ ... ]

record 0048 2009-Aug-23 17:35:00 153 mg/dl, 8.49 mmol/l before dinner
record 0049 2009-Aug-23 20:13:00 109 mg/dl, 6.05 mmol/l after dinner
record 0050 2009-Aug-23 22:37:00 86 mg/dl, 4.77 mmol/l after dinner
record 0051 2009-Aug-24 02:48:00 67 mg/dl, 3.71 mmol/l night
record 0052 2009-Aug-24 05:51:00 55 mg/dl, 3.05 mmol/l night
record 0053 2009-Aug-24 07:50:00 99 mg/dl, 5.49 mmol/l before breakfast
record 0054 2009-Aug-24 12:22:00 90 mg/dl, 4.99 mmol/l before lunch
record 0055 2009-Aug-24 18:48:00 115 mg/dl, 6.38 mmol/l before dinner
record 0056 2009-Aug-25 07:11:00 157 mg/dl, 8.71 mmol/l before breakfast
record 0057 2009-Aug-25 11:29:00 171 mg/dl, 9.49 mmol/l before lunch

Rád bych poznamenal, že těch 3.05 mmol/l byl pořádný odvaz! Když už jsme u těch technických poznámek, je důležité vědět, že tolerance vůči hypoglykemii se mění v závislosti na denní době a mnoha dalších faktorech. Lze zažít například 2.6 mmol/l bez subjektivních příznaků a o den později 3.7 mmol/l se zcela nepřehlédnutelnými příznaky.

V souvislosti s následující kapitolou bych rád předem upozornil na způsob, jakým se z dat získaných z glukometru počítá glykemie v mg/dl. Používá se jeden celý byte a dva nejnižší bity z následujícího bytu. Při nesprávné interpretaci dat a zanedbání těchto dvou bitů lze přehlédnout velmi nebezpečné hyperglykemie! Správný vzorec najdeme snadno ve zdrojovém kódu:

bloodglucoselevel = (unsigned int) ((unsigned char) buf[6] & 0x03) << 8;
bloodglucoselevel |= (unsigned char) buf[5];

Část 3: Komunikační software v C#

C# je jazyk původně určený pro platformu Mrkvosoft .NET. Naštěstí pro UNIXové systémy existuje rozšířená a poměrně kompatibilní implementace Mono, která obsahuje kompilátor (do bytecode) i potřebný virtuální stroj. Lze ji využít například v systémech založených na kernelu Linux. Výhodou je především přenositelnost vzniklého bytecode mezi různými systémy a hardwarovými architekturami.

Zdrojové kódy programu jsou ke stažení zde. Po rozbalení archivu je třeba (v adresáři OneTouchLib) spustit kompilátor C# takto:

[andrej@argos OneTouchLib]$ gmcs -pkg:dotnet -recurse:'*.cs' -out:onetouch.exe

[ ... ]

Compilation succeeded - 2 warning(s)

Podstatná je poslední řádka. ;-) Pokud kompilace neuspěje, nejspíš nemáte nainstalovaný některý důležitý balíček. Po úspěšné kompilaci už stačí program spustit a sledovat, co se bude dít. Samozřejmě je třeba mít zapojený a zapnutý glukometr.

[ ... ]

LRD= 16 2 0 48 95 103 77 153 80 0 47 0 0 59 16 3 111
LRD= 16 2 0 49 253 103 77 109 96 0 48 0 0 72 16 3 49
LRD= 16 2 0 50 141 104 77 86 96 0 49 0 0 73 16 3 55
LRD= 16 2 0 51 136 105 77 67 112 0 50 0 0 105 16 3 114
LRD= 16 2 0 52 63 106 77 55 112 0 51 0 0 82 16 3 82
LRD= 16 2 0 53 182 106 77 99 16 16 0 52 0 0 126 16 3 46
LRD= 16 2 0 54 198 107 77 90 48 0 53 0 0 12 16 3 125
LRD= 16 2 0 55 72 109 77 115 80 0 54 0 0 107 16 3 104
LRD= 16 2 0 56 47 112 77 157 16 16 0 55 0 0 85 16 3 103
LRD= 16 2 0 57 49 113 77 171 48 0 56 0 0 72 16 3 105

Jak je vidět, tento program zatím není dokončený a nepřevádí získaná data přímo do lidsky čitelné podoby. Nicméně jeho úprava je pouze otázkou času. Kdybych ho měl dostatek, neváhal bych a pustil bych se do toho.

Nelze si nevšimnout, že osmé číslo je hodnota glykemie v mg/dl. Nicméně v souladu se vzorcem (a varováním) z minulé kapitoly je třeba nezapomenout na fakt, že součástí tohoto čísla jsou i nejnižší dva bity z následujícího (v tomto případě devátého) bytu. Pokud je některý z těchto bitů nenulový, může jít o nebezpečnou hyperglykemii vyžadující lékařskou pomoc! U měření zde uvedených jsou naštěstí dolní dva bity devátého bytu vždy nulové. ;-) To se pozná velmi snadno tak, že příslušné číslo je dělitelné čtyřmi.

Část 4: O něco lepší řešení, které zatím nefunguje

Jak už jsem psal v úvodu, toto řešení se mi zatím nepodařilo uvést do praxe. I přesto se tu o něm zmíním pro případ, že by někdo měl zájem v tomto směru dál experimentovat. Informace budu samozřejmě průběžně aktualizovat, pokud se objeví nějaký pokrok.

Ke glukometru se dodává OneTouch Diabetes Management Software, který kromě komunikace s glukometrem poskytuje ještě spoustu dalších užitečných vlastností. Tento program je (opět) určený pouze pro Mrkvosoft Doors, což ale dnes už nemusí být nepřekonatelná překážka. Pokud by celý program byl provozuschopný pod Wine, bylo by možné ho využívat hned na několika UNIXových systémech.

S největší pravděpodobností tedy stačí, aby byl port /dev/ttyUSB0 z pohledu Wine dostupný jako com4. To není problém zařídit. Stačí k tomu něco jako ln -s /dev/ttyUSB0 ~/.wine/dosdevices/com4. Pak by měla komunikace s glukometrem fungovat stejně dobře jako přímo v Doors. Nicméně právě zde je kámen úrazu. V současné verzi Wine je chyba, která způsobuje pád většiny instalátorů. Z toho důvodu tam program momentálně nefunguje. Jakmile bude chyba opravena, zkusím to znova.

Na tento problém už narazilo víc lidí, nicméně navrhované řešení v případě tohoto software nefunguje. Pokud by měl někdo nápad, jak zprovoznit nativní podporu MDAC a OLE, dokud Wine nebude příslušné API skutečně implementovat, velmi rád případné řešení vyzkouším. Chybové hlášky zatím nasvědčují tomu, že nativní podpora nefunguje, přestože jsem ji nainstaloval:

err:ole:ClientIdentity_QueryMultipleInterfaces IRemUnknown_RemQueryInterface failed with error 0x80004002
err:ole:marshal_object object doesn't expose interface {be6115a1-7de5-48dc-ad2a-25060e00fce2}, failing with error 0x80004002

[...]

err:ole:ClientIdentity_QueryMultipleInterfaces IRemUnknown_RemQueryInterface failed with error 0x80004002
err:ole:marshal_object object doesn't expose interface {be6115a1-7de5-48dc-ad2a-25060e00fce2}, failing with error 0x80004002
err:ole:ClientIdentity_QueryMultipleInterfaces IRemUnknown_RemQueryInterface failed with error 0x80004002
err:ole:TLB_ReadTypeLib Loading of typelib L"C:\\Program Files\\Common Files\\Microsoft Shared\\DAO\\dao2535.tlb" failed with error 2
fixme:ole:DllRegisterServer stub
fixme:ole:DllRegisterServer stub
err:ole:CoGetClassObject class {6c736db1-bd94-11d0-8a23-00aa00b58e10} not registered
err:ole:CoGetClassObject no class object {6c736db1-bd94-11d0-8a23-00aa00b58e10} could be created for context 0x1
err:ole:CoGetClassObject class {2206cdb0-19c1-11d1-89e0-00c04fd7a829} not registered
err:ole:CoGetClassObject no class object {2206cdb0-19c1-11d1-89e0-00c04fd7a829} could be created for context 0x1
err:ole:CoGetClassObject class {c8b522cf-5cf3-11ce-ade5-00aa0044773d} not registered
err:ole:CoGetClassObject no class object {c8b522cf-5cf3-11ce-ade5-00aa0044773d} could be created for context 0x1

Současný stav je tedy takový, že téměř celá instalace proběhne úspěšně, ale selže inicializace databáze. (To vzhledem k výše uvedeným chybovým hláškám není nic překvapivého.) Program je po instalaci normálně spustitelný a zobrazí úvodní konfigurační dialog. Pokus o vytvoření nové databáze však pochopitelně selže.

Je zajímavé, že přesně tentýž problém (s inicializací databáze) může nastat dokonce i přímo v Doors. Píše se o tom v seznamu FAQ na kanadských stránkách firmy LifeScan. Řešení, které tam popisují, ovšem pod Wine opět nefunguje.

Ideální řešení

Skvělé by bylo, kdyby se výrobci glukometrů dohodli na jednom univerzálním protokolu, kterým by bylo možné komunikovat prakticky se všemi chytřejšími glukometry. To by bylo velké plus nejen pro pacienty, ale i pro diabetology. Bohužel se něčeho takového asi nedočkáme.

Protokoly většiny glukometrů už byly reverzním inženýrstvím rozluštěny. Jejich uzavřenost už není (až na možné právní důsledky jejich zveřejnění) tak nepřekonatelným problémem. Pozornost by se nyní měla zaměřit spíš na vývoj open-source řešení pro ukládání a statistické zpracování dat. Pokud je mi známo, zatím ještě žádný software tohoto druhu a produkční kvality neexistuje.

Odpovědět

| Platné XHTML a CSS| | Prohlížeč: Gecko (Firefox), KHTML (Konqueror) | | Počítadla: 283305 zobrazení, 16506 IP adres |