Sunday, October 13, 2013

mobilECG - accessible clinical-grade electrocardiography

There is a crowdfunding campaign for a medical grade mobile ecg at a fraction of the usual cost.

Go have a look at it and support it.

http://www.indiegogo.com/projects/mobilecg-accessible-clinical-grade-electrocardiography

I am in contact with the creators to see if we can connect it to GNUmed somehow.



Friday, September 13, 2013

Matrox Monarch HD - the real thing in a medical environment

When the Matrox Monarch HD was first announced I immediately thought of a nice use case for it.

It combines some nice features. I does streaming and recording simultaneously. It supposedly can be set up in a way that one MHD can control a number of slaves. It can record to USB, network drive and SD-Card.







It is not yet available but Matrox was kind enough to provide a demo unit.

Our use case is medical procedures streaming and recording. Sure we could call in professionals to do the job and we probably should but streaming medical live cases often does not get paid by anyone. So sender and receiver usually end up with 2000-4000 Euro bill for a professionally done job.

However most of the time it does not have to be all that professional with regards to live switching and so on. Streaming one source rough and dirty will do if you do it weekly to a known audience. Image quality is important.

What's nice about the box are the hardware button. Start/Stop recording ? Just press the button. No extra computer to connect. The box came with pre-release software which could explain problems with RTMP streaming. RTSP streaming however works just fine. There is a hardware button to start/stop streaming as well.

We tested the box by connecting a cable TV receiver to the MHD and streaming 720p to an iPAD for 8 hours continously. The RTSP stream was ingested by Evostream server (free trial or grab crtmpserver) and delivered to the iPAD as HLS stream. Not a single glitch and excellent quality.

So overall a nice box for everyday medical live streaming in predefined environments. And just in case you want to record some footage from the operating room for presentation during the next medical conference you can simply connect a HDMI camera or DVI/HDMI output of a medical device to the input and record straigth to SD-Card.

A 720p high quality source recorded for 1hour and ten minutes came in at 1.6 GB.

Interesting features which were not tested include master/slave configurations with multiple MHDs.

The box is configured over a webinterface. It would be nice if some sort of remote control API would be implemented. That way webapps for tablets or smartphones could be developed to start/stop streaming, recording and confidence monitoring.

The MHD will retail for about 799 Euro plus VAT.

Saturday, May 01, 2010

Configure CUPS as print server for USB printer on WD MyBook

Hi all,

A while back I got myself a Western Digital (White Light) MyBook. It comes with an USB port and I want it to serve as a printer server. I found out that it runs Linux and a great group of people has done all the groundwork to get this going. The main source of information is

http://mybookworld.wikidot.com/

There is a tutorial on how to set up cups on the WD MyBook but this did not work out for me. Searching for hours I collected information from various sources and pieced it togehter. When I had the pieces together I came across a German tutorial which would have save me many hours.

http://members.aon.at/berwinter/mbwe/mbwe_en.html

which is referenced from this thread.

http://mybookworld.wikidot.com/forum/t-180724/

I am going to reproduce this here as often it gets lost. Thanks to these people who deserve all the credit.

Tested with firmware 01.00.16, 01.00.18 and 01.01.16!


Updates


  • Firmware 01.01.16 tested
  • Firmware 01.00.18 tested
  • Addgroup added
  • Print Test Page
  • Add a printer using web interface

Thanks to mad_ady and Fidatelo
of mybookworld.wikidot.com for their Feedback!


Preparations:


First of all must be, if not already geschähen, SSH is enabled in
the web interface. Then you can log in using Putty, for example on the
console. (User: root / Password: welc0me)

First, the MBWE for Optware will be prepared. This is best done with
the script by Frater, that also makes some other improvements



wget -O prep_whitelight http://wd.mirmana.com/prep_whitelight
sh prep_whitelight



This takes some time and there are many packages downloaded and
installed. Then Crond should be disabled so that the disks do not start
every 15 minutes.


Install Cups:


Meanwhile cups can be installed directly from the sources and you
have to compile anything yourself. Simply execute the following as root
on the console MBWE:



/opt/bin/ipkg install cups<br />/opt/bin/ipkg install cups-pdf<br />/opt/bin/ipkg install cups-doc<br />/opt/bin/ipkg install cups-driver-gutenprint<br />



With cups-doc is needed for the web interface of cups. During this
moment is cups already bootable, but it can not find the connected USB
printer. This is a kernel module needed.


Kernel module to install:


The module was compiled by me from the Western Digital sources.
In order to save you the work you can download the module here, please
only use kernel 2.6.24.4.




mkdir /lib/modules/2.6.24.4/kernel/drivers/usb/class/

wget http://members.aon.at/berwinter/mbwe/usblp.ko.whitelight -O
/lib/modules/2.6.24.4/kernel/drivers/usb/class/usblp.ko



The modules can now be loaded with insmod. However, the file
incorrectly awarded rights. We use a startup script that makes all the
settings at startup, and cups start.



For this we create the file / opt/etc/init.d/_SK88cupsd with the
following contents:



#!/bin/sh<br />#<br />#<br />#<br />case "$1" in<br />        start)<br />                if ( [ ! -c /dev/lp0 ] ) then<br />                        mknod /dev/lp0 c 180 0<br />                fi<br />                /bin/chown sys:lp /dev/lp0<br /><br />                if ( !(lsmod | grep "^usblp" -q) ); then<br />                         insmod /lib/modules/2.6.24.4/kernel/drivers/usb/class/usblp.ko<br />                fi<br /><br />                if [ -n "`pidof cupsd`" ]; then<br />                        /usr/bin/killall cupsd 2>/dev/null<br />                fi<br />                /opt/sbin/cupsd<br />        ;;<br />        stop)<br />                if [ -n "`pidof cupsd`" ]; then<br />                        /usr/bin/killall cupsd 2>/dev/null<br />                fi<br />        ;;<br />        *)<br />                echo "Usage: (start|stop)"<br />                exit 1<br />esac<br />


Finally, do not execute and set the startup and shutdown links:



chmod +x _SK88cupsd<br />ln -s _SK88cupsd S88cupsd<br />ln -s _SK88cupsd K88cupsd<br />


Eventually, the group has yet to be created lp (if not yet
available):



addgroup lp<br />


Cups configure:



To open the file / opt / etc / cups / cupsd.conf and change
accordingly:




# Show general information in error_log.<br />LogLevel info<br />MaxLogSize 100000<br />MaxJobs 50<br />User sys<br />Group lp<br /># Allow remote access<br />Port 631<br />MaxClients 10<br /><Location /><br />  Encryption Never<br />  AuthType None<br />  Deny From All<br />  Allow From 127.0.0.1<br />  Allow From 10.0.0.0/16<br />  # Allow shared printing and remote administration...<br />  # Order allow,deny<br />  # Allow @LOCAL<br /></Location><br /><Location /printers><br />  AuthType None<br />  Order Deny,Allow<br />  Deny From None<br />  Allow From All<br /></Location><br /><Location /admin><br />  Deny From All<br />  Allow From 127.0.0.1<br />  Allow From 10.0.0.0/16<br />  # Allow remote administration...<br />  # Order allow,deny<br />  # Allow @LOCAL<br /></Location><br /># Share local printers on the local network.<br />Browsing On<br />BrowseOrder allow,deny<br />BrowseAddress @LOCAL<br /><Location /admin/conf><br />  AuthType Default<br />  Require user @SYSTEM<br />  # Allow remote access to the configuration files...<br />  # Order allow,deny<br />  # Allow @LOCAL<br /></Location>	<br />



where all the lines need to be adapted to the 10.0.0.0/16 Allow From
his own network.



Now should Cups with:



/opt/etc/init.d/S88cupsd start<br />



start without errors can and watch the master at:
http://<ip_mbwe>:631/.



Printer configuration:


NNow go to the printer's configuration in the file / opt / etc /
cups / printers my looks for the Brother HL-2030 the following measures:



<DefaultPrinter Brother_HL2030><br />	Info Brother 2030 series<br />	Location Local Printer<br />	DeviceURI parallel:/dev/lp0<br />	State Idle<br />	StateTime 1252837845<br />	Accepting Yes<br />	Shared Yes<br />	JobSheets none none<br />	QuotaPeriod 0<br />	PageLimit 0<br />	KLimit 0<br />	OpPolicy default<br />	ErrorPolicy stop-printer<br /></Printer><br />



important is the line DeviceURI parallel: / dev/lp0 that specifies where
the printer is connected.


Using the Web Interface


It is also possible to add the printer via the web interface.
To
open the web interface in the browser: http://<ip_mbwe>:631/

Administartion>
Add Printer> Enter name> Select LPD / LPR Host or Printer>
Device URI: parallel: / dev/lp0> Raw> Raw Query





Now the clients can be established:


MacOSX client:


Add In System Preferences> printer a new printer:



IP protocol and select Internet Printing Protocol - IPP



Specify the IP address MBWE and waitlist
/printers/<Druckername>



Finally, select, the driver and click the Add!



Ubuntu client:


System> System Administration> Printing> New> Network
Printer



Internet Printing Protocol specify IP address of the MBWE and
waitlist /printers/<Druckername>



Select Driver



finish



Windows XP client:


Start> Printers and Faxes> Add Printer> Next



Network printer ... > Next> Connect to a printer on the
Internet ...

http://<ip_mbwe>:631/printers/<Druckername>



next > select driver




next > finish



Windows Vista client:


Start> Devices and Printers> Add Printern



Network Printer > The printer is not listed you're looking for
> a select Share this printer as the name
enter
http://<ip_mbwe>:631/printers/<Druckername>



next > selct driver




next > finish


Tips and Tricks


If the print queue is stopped after a reboot, / should be
opt/etc/init.d/_SK88cupsd amended as follows: (Thanks to Fidatelo)



#!/bin/sh <br /># <br /># <br /># <br />case "$1" in <br />        start) <br />                if ( [ ! -c /dev/lp0 ] ) then <br />                        mknod /dev/lp0 c 180 0 <br />                fi <br />                /bin/chown sys:lp /dev/lp0 <br /><br />                if ( !(lsmod | grep "^usblp" -q) ); then <br />                         insmod /lib/modules/2.6.24.4/kernel/drivers/usb/class/usblp.ko <br />                fi <br /><br />                if [ -n "`pidof cupsd`" ]; then <br />                        /usr/bin/killall cupsd 2>/dev/null <br />                fi <br />                /opt/sbin/cupsd<br />                sleep 10<br />                /opt/sbin/cupsenable HP-Deskjet-812c<br />        ;; <br />        stop) <br />                if [ -n "`pidof cupsd`" ]; then <br />                        /usr/bin/killall cupsd 2>/dev/null <br />                fi <br />        ;; <br />        *) <br />                echo "Usage: (start|stop)" <br />                exit 1 <br />esac<br />


With the printer name is replaced with our own. After starting
cupsd to wait 10 seconds and started to join the queue.



Monday, March 08, 2010

GNUmed web interface

Hi all,

I am bringing this up every once in a while. There is no need to discuss the need for it again. I am simply interested in a proof of concept and collecting thoughts.

GNUmed has a wxpython based client. It is a wrapper around GTK on GNU/Linux. In the past I have wondered what it would take to hack a web interface for GNUmed.

There a far too many web toolkits to choose from. One of the ideas is to use a toolkit that will allow reuse of existing code as rewriting (e.g. the middleware) not feasible.

Toolkits that come to mind and have some userbase are Django, Turbogears and Pylons. All of them provide access to the PostgreSQL database and make use of python. However all of them are designed to talk to the database bypassing our middleware. Replicating the middleware makes no sense.

It is possible to reuse the midlleware we have. It can be done through XML-RPC. Mere chance has it I came across TinyERP Web on freshmeat. Digging a little deeper it looks like the solved the same problem. They have a default GTK-Client and now came up with a web-client based on Turbogears. They use XML-RPC. I am not sure if they use it to access what I would call the middleware. However if anyone wants to have a go at this here is their code to look at http://www.openerp.com/download/old/eTiny-1.0.1.1.tar.gz If you are going to attempt that I recommend to:

- create a webbased log-in dialog which resembles the fat client dialog.
- reuse GNUmed's python middleware for the connection
- glue it together by using XML-RPC to talk to the middleware
- implement a page that shows that you are actually connected to the GNUmed database

There is a project called 'medical'. It tries to implement an EMR on top of OpenERP which is the current version of TinyERP - the software the above webinterface is for.

http://medical.sourceforge.net/

Have fun,
Sebastian

Thursday, March 04, 2010

Voltcraft DL-140TH - data download fails

When building a house you sometimes want to continously monitor temperature and humidity. There are a few devices that can do that. Many of them can be programed via USB. The cheaper ones rely on the host PCs clock to make sense of the recordings while the more expensive ones carry an internal clock.

I got a Voltcraft DL-140TH. I can collect data for about 11 days if you program it to measure temp and humidity every two minutes. Unfortunately there is not software to read the data from GNU/Linux. A basic Windows software is available.

The other day I programed it and let it sit for 11 days. When I tried to get the data off the device it would download but not display it. It took two days and a bit of luck to find out that you cannot get a useful data transfer on USB 2.0 ports. When I plugged it into a USB 1.1 port it would work without a hitch.

So remember to plug it into an USB 1.1 port if you have trouble reading the data. If anyone has information on how to read that data on GNU/Linux I would like to hear about it.

Saturday, January 02, 2010

How to fight TWiki / FOSSWiki spam

I operate a TWiki instance. It is a great tools and eases collaboration. However the more popular it gets the more attractive is it for spammers. There is little one can do about this. Even Google's captcha has been broken recently.

There seems to be little one can do to automatically prevent spam. There are however a few things a sysadmin can do manually to keep a Wiki clear or better yet to clean it up.

At first it seemed random how spammers show up. However there are a few tricks to identify them.

1.) First thing to do is to configure TWiki in a way it will email the sysadmin whenever someone registers. That way you get informed when someone , spammer or not, shows up.
2.) When someone registers take a look at the E-Mail address and potential links that are placed in their profile. Most spammers register for placing links in their profile.

If you identify a spammer do not just delete their profile. Instead go tho the .htaccess file and delete a character or two from their password. That way the account still exists but the spammer cannot log in anymore. If you do not delete the profile the spammer cannot register the same name again.

Next step is to log into TWiki and delete the offending links in the corresponding profile. The sooner you do this the fewer the chances a spammer will put content into the Wiki. If they have done so delete the topic and the corresponding rcs file.

One of the more obvious measures is to install the BlackList plugin. Once configured you can extract the IP address of the spammer from their registration mail and block it.

It's not perfect but if done continously it will keep your Wiki clean. Just in case an attack is launched against you site it might be a good idea to do nightly backups of TWiki so you can always roll back.

Friday, June 26, 2009

PostgreSQL on USB flash drive performance

The idea of running PostgreSQL off a removable drive such as USB thumbdrive or flash drive is appealing. However performance can sluggish. Who is to blame ?
Is it PostgreSQL that is too slow or poorly configured ? Is it GNUmed that stresses the database too much ? Or is it the storage media that slows things down ?

This clearly calls for some sort of benchmark. Google has little to offer on how to benchmark perfomance. Representative or not we are going to benchmark a few use cases.

1.) The storage media performance
2.) Real world installation performance
3.) Real world GNUmed client startup performance

- Storage media performance:
I am not aware of any GNU/Linux tool that can test read/write speed of both harddisk and usb-thumbdrives. Sure there is hdparm but it only works for harddisks. I reverted to HdTach and hdbench form CT magazine. One more word on theoretical performance. I use USB 2.0 so performance should be in the area of 60MB/s. I have seen reports that USB-connected removable drives that have S-ATA II storage media can reach throughput of up to 55MB/s
. Effizienzgurus.de have tested USB-thumbdrive perfomance with HD-Tach and the list top read performance from 7,9 to 51,2 MB/s.

Let's see how the USB thumbdrives I bought for GNUmed compare:

Harddrive Seagate IDE 60GB native: avg. sequential read 22,9MB/s | random access 15ms |
Thumbdrive Intenso 2GB native: avg. sequential read 23,7 MB/s | random access 0,4 ms | sequential write 6,4 MB/s
Thumbdrive Buffalo 2GB native: avg. sequential read
8,7 MB/s | random access 8,7ms | sequential write 2,4 MB/s
Thumbdrive Samsung 8GB native: avg sequential read 18MB/s | random access 1,7ms | sequential write 5,5 MB/s
Generic Business Card 1GB native: avg sequential read 16MB/s | sequential write 2,9 MB/s
Thumbdrive OCZ 16GB native: : avg sequential read 27MB/s | sequential write 8,7 MB/s

The bigger the file size the faster the drive.

Same on VMware:
Harddrive (S-ATA native) in VMware : avg. sequential read 317MB/s | random access 23ms
Thumbdrive Intenso 2GB on Vmware: avg. sequential read 8MB/s
Thumbdrive Buffalo 2GB on Vmware: avg. sequential read 4,5MB/s
Thumbdrive Samsung 8GB on Vmware: avg sequential read 5,7MB/s | random access 7,8ms

Conclusion: a) Performance in VMWare is let's say not what we need here. Good to know since I guess a few people might try running it in a virtual machine. Don't. If you must copy the stuff from the thumbdrive to the virtual harddrive of the virtual machine. b) Native performance to the 2GB USB drive is nowhere close to the theoretical maximum for USB 2.0 but comes close to the IDE harddrive in this fairly old PC (1,6GHz AMD 2600+, 1,5GB RAM) c) The Buffalo 2GB thumbdrives is cheap but unusable performance wise.

- PortableApps Suite installation (355MB as many files)

Harddrive Seagate IDE 60GB native : avg write 1,6 MB/s = 1667KB/s (3 minutes 38 seconds)
Thumbdrive Intenso 2GB native : avg write 0,307 MB/s = 314KB/s (19 minutes 15 seconds)
Thumbdrive Bufallo 2GB native :avg write 0,091 MB/s = 93KB/s (125 minutes)
Thumbdrive Samsung 8GB native:
Thumbdrive OCZ 16GB native: avg write 0,8MB/s = 865KB/s (06 minutes 59 seconds)

Conclusion: a) The slower Buffalo stick has half the read speed compared to the faster Intenso stick. The write speed for the 355MB written to the faster drive is devastating at 0,3 MB/s compared to the harddisk installation at 1,6MB/s. The installation to the faster USB thumbdrive (Intenso) is 7x faster then to the slower one.

- PortablePostgresql installation (171 MB as many files)
This involves unzipping 40,7MB to the USB drive. This is potentially limited by the unzip operation and host-PC speed but relative speeds still apply.

Harddrive
Seagate IDE 60GB native: avg write 2,85 MB/s = 2918KB/s (1min)
Thumbdrive Intenso 2GB native: avg write 0,63 MB/s = 650 KB/s (4 min 25 sec)
Thumbdrive Bufallo 2GB native:
avg write 0,05 MB/s = 59KB/s (49 min 15 sec)
Thumbdrive Samsung 8GB native: avg write 0,21 MB/s = 214KB/s (13 min 35 sec)
Thumbdrive OCZ 16GB native: avg write 1,2 MB/s = 1306KB/s (2 min 14 sec)

Unzipping the Postgresql Server to this the slower USB (Buffalo) drive took 12x longer than to the faster one (Intenso). The slower USB drive is 49x slower then the harddrive. The 8GB Samsung drive doesn't come close to the harddrive. This implies that bigger drives don't neccessarly have better performance.

- PortableGNUmed client time to login window (first start uncached, second start cached)
Harddrive Seagate IDE 60GB native: (4 sec , 3 sec
Thumbdrive Intenso 2GB native: (5 sec, 5 sec )
Thumbdrive Bufallo 2GB native:
(8 sec, 6 sec )
Thumbdrive Samsung 8GB native: (2min 29 sec, 1min 30 sec)
Thumbdrive OCZ 16GB native: (4 sec, 3 sec )

- PortableGNUmed client time from login window to first window (first login, second login)
Note that both client and server are running off the same drive. For the second login times are shorter since much data is cached.

Harddrive Seagate IDE 60GB native: (17 sec , 10 sec )
Thumbdrive Intenso 2GB native: (54 sec , 21 sec )
Thumbdrive Bufallo 2GB native: ( 2 min 41 , 59 sec )

Thumbdrive Samsung 8GB native: (2min 22 sec, 1min 38 sec )
Thumbdrive OCZ 16GB native: (20 sec, 17 sec )

conclusion: The OCZ drive is the clear winner. The cheaper Intenso is second. The Buffalo and Samsung drives have disappointing performance. The startup performance is interesting but the real performance of the database can only be measured during heavy sql operations.

- Pushing a 12 MB document into the database
Harddrive Seagate IDE 60GB native: 30 sec
Thumbdrive Intenso 2GB native: 5 min 1 sec
Thumbdrive Bufallo 2GB native:
15 min 30 sec
Thumbdrive Samsung 8GB native: 32 min
Thumbdrive OCZ 16GB native: 3 min 4 sec

The results are somewhat helpful to get a feeling for the database speed. Note that even for the harddrive it takes 7x its drive speed to complete the task. Be aware that I cannot say if these results are reproducable.

- Retrieving a 12 MB document from the database
Harddrive Seagate IDE 60GB native: 5 sec
Thumbdrive Intenso 2GB native: 12 sec
Thumbdrive Bufallo 2GB native:
12 sec
Thumbdrive Samsung 8GB native: 1 min 11 sec
Thumbdrive OCZ 16GB native: 9 sec

Conclusions: In theory the user oriented performance should be identical between the USB thumbdrive and the harddisk. Unfortunately it is not always the case. If you can make sure you get a decent USB thumbdrive. The 16GB OCZ is fairly usable at 30MB/s sequential read and 8 MB/s sequential write performance. There is a catch. A huge difference exists between the sequential read/write values and the random read/write vaues. According to codinghorror.com the random read performance is 6MB/s and the write performance is 3MB/s. Those are the values you are looking for.

Only the best USB thumbdrives come close to the el-cheapo IDE harddisk I used for testing. This is really disappointing since the first batch of USB drives I ordered for GNUmed is really only useful as storage media. I had to order a second batch. If you intend to use one of these in production for GNUmed you should really be ready to spend the $79 for an adequate 32GB USB thumbdrive. If you wanna go cheap make you can go with something like the 2GB Intenso since it gives you acceptable performance.

The road ahead:
None of the storage media I had available really come close to a real harrddrive. Options to pursue in the future are flash media, solid state drives and external harddrives. External legacy harddrives are error prone due to many moving parts. Flash or SSD might be a way out.