Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

22 November 2022

675. Surviving a migration to Outlook 365 in a Linux-hostile environment

 At work we were just migrated to o365 ('M365' as they call it), and :

* they've disabled forwarding (so can't automatically forward my mail to e.g. a gmail account)

* they've disabled access for all email clients other than Outlook


This happened half a year ago to the students at my university, and here's the solution one of them sent me:

1. Get evolution-ews

 -- on thunderbird you have the non-free (as in beer) options of OWL for exchange and ExQuilla

-- DAVmail may also be a solution, but I haven't managed to get it to work. It will act as a layer between your mail client (e.g. thunderbird) and the EWS server, allowing you to continue using e.g. thunderbird without having to install anything.

2. Create a 'New Mail Account':

Identity: do whatever is appropriate for you organisation. Disable 'Look up mail server ...'



Receiving Email: Add the appropriate username for connecting to the mail server.

Host URL: use https://outlook.office365.com/EWS/Exchange.asmx -- it's the same for all organisations these days.

Authentication type: OAUTH2 (Office 365)

Check 'Override Office365 OAuth2 settings'

Tenant: leave empty

Application ID: d3590ed6-52b3-4102-aeff-aad2292ab01c

Redirect URI: urn:ietf:wg:oauth:2.0:oob


Then click on Fetch URL. This should populate the OAB URL field.


You should now be done.

30 October 2020

668. Controlling the fan speed of an Nvidia card when you're using the nouveau driver and no xorg.conf

 My old GT210 has served me well, but I've had a few odd freezes recently, coupled with weird graphics behaviour. It's a pity, since it's a nice, silent fan-less graphics card from way back when: https://www.gigabyte.com/Graphics-Card/GV-N210SL-1GI#ov

Although some of it may be due to switching back and forth between VGA and HDMI output (between an old HP 19'' and my new fancy xp pen display) I ripped it out and replaced it with an almost as ancient GT 520 (https://www.gigabyte.com/Graphics-Card/GV-N520OC-1GI#ov)

The fan isn't loud, but it's there, and it's distracting since I'm working in a home environment (Corona!).

Looking online I found these posts:
http://floppym.blogspot.com/2013/07/fan-control-with-nouveau.html
https://forums.opensuse.org/showthread.php/501517-OS-13-1-Driver-quot-nouveau-quot-Unable-to-command-fan-speed-Nvidia-6800-GS
https://www.kernel.org/doc/Documentation/thermal/nouveau_thermal

So, first to check if fan control is possible:

me@indium:~$ find /sys -name pwm1_enable
find: ‘/sys/kernel/debug’: Permission denied
/sys/devices/platform/it87.2624/hwmon/hwmon2/pwm1_enable
/sys/devices/platform/it87.2656/hwmon/hwmon3/pwm1_enable
/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/hwmon/hwmon0/pwm1_enable
me@indium:~$ readlink /sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0/driver
../../../../bus/pci/drivers/nouveau

Good, and we got the hwmon number -- 0. 

I then created a script called gpufan.sh:

sudo sh -c "echo 1 > /sys/class/hwmon/hwmon0/pwm1_enable"
sudo sh -c "echo 35 > /sys/class/hwmon/hwmon0/pwm1_min"
sudo sh -c "echo 45 > /sys/class/hwmon/hwmon0/pwm1"

I set the min% to 35 -- it used to be 65. And I tested my way to 45% as a good compromise between noise and temperature. By default the fan speed was >4,000 rpm. Output from sensors now:

nouveau-pci-0500
Adapter: PCI adapter
GPU core:     +0.90 V  (min =  +0.90 V, max =  +1.11 V)
fan1:        2790 RPM
temp1:        +34.0°C  (high = +95.0°C, hyst =  +3.0°C)
                       (crit = +105.0°C, hyst =  +5.0°C)
                       (emerg = +135.0°C, hyst =  +5.0°C)

27 October 2020

667. XP PEN/virtual whiteboard during a lecture -- mirroring an application window on linux

The situation:

We're allowed to teach on campus at the moment, but we're also strongly encouraged to adopt a hybrid model where we stream everything via zoom so that students don't show up if they have flu/cold-like symptoms.

We've spent the past few years killing off ppt and transitioning to whiteboard/chalk-and-talk. The students love it -- the pace is better, and the lectures become more interactive since we can adjust our teaching to the students' learning. Good stuff. But horrible for streaming -- you can't just point a webcam at a whiteboard and expect a good outcome (although if need be, it can be done -- just use a good camera and write large with a dark pen).

I have an XP Pen Artist 13.3 Pro (https://www.parkablogs.com/content/review-xp-pen-artist-133-pro-pen-display ) which is fantastic for drawing. A lot of fun, and a potential solution to the whiteboard quandary.

The Problem:

Both the students in the class room and those following the lecture on zoom need to be able to see what you're doing. And since the pen display is a DISPLAY, you need to have your drawing program open on the pen display, and not on the projector (which is also a display).

The Solution:

1. Open your drawing window (xournal, or xournal++ or openboard or krita) on your pen display ... display. 

2. Then run xwininfo (part of x11-utils) and click on your window. You get a window id, e.g. 36000a

Then run x11vnc:
x11vnc -id 36000a

Note the port number -- likely 5900.

The window is now being shared via vnc. 

3. To see it, use e.g. vinagre, click Connect, set the protocol to vnc and the port to 5900 (and you're presumably connecting to localhost). 

Make sure to enable 'scaling', since many old video projectors have a 4:3 resolution ratio, whereas e.g. the xp pen 13.3 has a 16:9 ratio.

Drag this window to the projector.

4. Share the original window via zoom

Note that I've had issues getting the pen display to map correctly when all three display (laptop, xp pen, and projector) are connected. Turning off the laptop screen solved it.


A script:

I've made a script called mirror.sh which starts the x11vnc with the correct id:

winid=`xwininfo |grep "Window id"|gawk '{print $4}'`
x11vnc -id  $winid




21 August 2020

662. Mini-post: Getting a bluetooth headset to work on linux -- B350-XT

 I have a BlueParrot  B350-XT which is causing issues on linux. It pairs fine, and shows up as a sound device, but it won't actually play sound or record sound.


Looking at dmesg -T, I see

[Tue Aug 18 01:25:33 2020] Bluetooth: hci0: BCM: chip id 63
[Tue Aug 18 01:25:33 2020] Bluetooth: hci0: BCM: features 0x07
[Tue Aug 18 01:25:33 2020] Bluetooth: hci0: BCM20702A
[Tue Aug 18 01:25:33 2020] Bluetooth: hci0: BCM20702A1 (001.002.014) build 0000
[Tue Aug 18 01:25:33 2020] bluetooth hci0: firmware: failed to load brcm/BCM20702A1-050d-065a.hcd (-2)
[Tue Aug 18 01:25:33 2020] bluetooth hci0: Direct firmware load for brcm/BCM20702A1-050d-065a.hcd failed with error -2
[Tue Aug 18 01:25:33 2020] Bluetooth: hci0: BCM: Patch brcm/BCM20702A1-050d-065a.hcd not found


To solve this, unplug/turn off your headset. REMOVE/FORGET the device  so that you can re-pair it.


Download the hcd file to ~/Downloads, then
me@niobium:/lib$ sudo mkdir /lib/firmware/brcm
me@niobium:/lib$ sudo cp ~/Downloads/BCM20702A1-050d-065a.hcd /lib/firmware/brcm/

Now try again. 
Output from dmesg -T:
[Tue Aug 18 01:33:59 2020] Bluetooth: hci0: BCM: chip id 63
[Tue Aug 18 01:33:59 2020] Bluetooth: hci0: BCM: features 0x07
[Tue Aug 18 01:33:59 2020] Bluetooth: hci0: BCM20702A
[Tue Aug 18 01:33:59 2020] Bluetooth: hci0: BCM20702A1 (001.002.014) build 0000
[Tue Aug 18 01:33:59 2020] bluetooth hci0: firmware: direct-loading firmware brcm/BCM20702A1-050d-065a.hcd
[Tue Aug 18 01:33:59 2020] Bluetooth: hci0: BCM20702A1 (001.002.014) build 1482
[Tue Aug 18 01:33:59 2020] Bluetooth: hci0: Broadcom Bluetooth Device


09 July 2020

658. Teaching during the pandemic, part 1: How to use a mobile phone as a wireless lavalier microphone

This pandemic isn't going anywhere soon. We'll be using online/remote teaching or hybrid teaching models for at least the next two semesters up here, and it's time to figure out how to do it in a way that works for the students, as well as us lecturers, in spite of not actually getting any more time to prepare our classes than we would during a normal year.

This post is linux-centric, but the solution should be applicable to OSX and Win as well.

Using a mobile phone as a wireless lavalier microphone
While I've made proper videos in the past, I haven't tried recording 'live' lectures before. We've been asked to resume on-campus lectures this fall, but have also been told to make sure that we record everyhting so that students don't show up to class in spite of being sick.

I've moved away from using powerpoints to using the whiteboard for my lectures (I've surveyd my students -- 95% in class after class prefer chalk-and-talk).

Simply using a camera with a static microphone to record won't cut it -- it won't capture the sound properly, in particular not when you're up at the whiteboard. Also, audio-quality matters -- if you have to choose between good audio and good video, pick audio.

What do you need?
You need
* an android phone (similar solutions should be available for iOS)
* for the phone and your recording device (e.g. laptop or computer) to be online and able to connect to each-other (e.g. a LAN). You can use the laptop as a hotspot.
* the program LANMic installed on your phone
* OBS Studio to receive the stream from LANMic. There are other programs -- as long as they can receive rtsp streams, they are OK.


How-to

1. Install LANmic on your phone. Connect a lavalier/lapel mic to your phone. Install OBS Studio on your computer.

2. Both devices (phone and computer) need to be able to communicate with each other over the LAN.

If you have EduRoam, this might not be the case. In that case, use your computer to set up a wifi hotspot. See the end of this post for how to do that.

3. Start LANmic on your phone, select rtsp and start streaming. Note the address of your phone (here: rtsp://192.168.2.13:8080)
It'll look like this because nothing's connect to it:


4. Start OBS Studio and add your sources.

I've just made a quick example here. To add the phone, add Media Source, uncheck local file, and enter the address from the previous step.




If all goes well you'll see the meter for the moble mic moving.


Your phone will now look like this:


This isn't a perfect solution, but it works. Importantly, it will allow you to record everything on the fly/and or stream it and/or stream via zoom (have a look at https://obsproject.com/forum/resources/obs-virtualcam.539/).

In the next few posts I'll be exploring other solutions


Here's how to set up a wifi hotspot on debian:

Open Network:









Set up hotspot:




Then connect your phone to the new network. Note that this means that you won't have any network connectivity, unless you're also using a LAN cable.



26 October 2018

654. Screen-casting on linux (debian 9)

Minipost:
I'm interested in making course videos where I show my desktop (I might have a full-screen presentation going), but where I also want to show my face.

I'm using debian.

Solution:
To screen-cast the desktop I'm using EasyScreenCast, which is a Gnome Extension: https://extensions.gnome.org/extension/690/easyscreencast/

Not much to say about it really, other than that it works very well.

To get my face on the desktop I use guvcview, which is in the repos.

To make guvcview stay on top even during a full-screen presentation I followed this: https://www.linuxquestions.org/questions/linux-general-1/how-to-make-guvcview-stay-always-on-top-4175541777/

My son's orca lecturing on the importance of experiments in formulating new theories
kdenlive seems like an interesting editor for post-production, but I haven't got that far yet.

23 August 2017

645. Moodle on Debian

I want to play around with moodle on my own desktop so I can experiment before making any major commits to a course website.

I first had a look at https://docs.moodle.org/33/en/Installing_Moodle_on_Debian_based_distributions, but, realising that moodle is in sid, decided to build my own .deb package.

This was done on debian jessie (8.9), which has at this point been overtaken by stretch as stable. I'm thus three releases behind sid.

1. Add the sid /src/ repo to sources.list
deb-src http://ftp.au.debian.org/debian/ sid main non-free contrib

2. Get source and build
I don't know exactly what dependencies you'll need. Error messages will tell you.
sudo apt-get update sudo apt-get install build-essential dpkg-dev mysql-server mysql-client php5-xmlrpc php5-intl sudo service mysql start mkdir ~/tmp/moodle -p cd ~/tmp/moodle sudo apt-get source moodle
Edit debian/control (necessary if you're on Jessie/8.9 -- newer debian versions may not need this):
14 Depends: ${misc:Depends}, 15 php5, php5-mysql | php5-pgsql, php5-gd, php5-curl, php5-cli, 16 apache2 | httpd, ucf, postgresql-client | default-mysql-client | virtual-mysql-client, 17 dbconfig-common, libphp-phpmailer, libphp-adodb, php-htmlpurifier, php-tcpdf, 18 php-cas (>= 1.3.3-1), libjs-jquery-migrate-1 19 Pre-Depends: debconf (>= 0.5) | debconf-2.0
Then continue in the terminal:
cd ~/tmp/moodle-2.7.19+dfsg sudo dpkg-buildpackage -us -uc cd .. sudo dpkg -i moodle_2.7.19+dfsg-2_all.deb sudo apt-get -f install sudo cp /etc/moodle/apache.conf /etc/apache2/sites-available/moodle.conf sudo ln -s /etc/apache2/sites-available/moodle.conf /etc/apache2/sites-enabled/moodle.conf sudo chmod o+r /etc/apache2/sites-available/moodle.conf sudo chmod go+w /var/lib/moodle sudo service apache2 reload
Navigate to http://localhost/moodle and follow the prompts

20 November 2014

603. Mobile bankid; works fine in a VM too

Turns out I got it wrong in my earlier post -- mobile bankid has nothing to do with the telecom network.

How it works:
1. Phone: Start BankID on your phone. The program will say that it's waiting for a connection.
2. Computer: You go to your bank/government service web page, select Mobile BankID, then type in your 'person nummer' (like SSN).
3. Phone: BankID on your phone will then prompt you for your PIN.
4. Computer: You're logged in.

It's all happening over the internet. Sure, it might not work if you change SIM, for example, but at least it's not telephony based.

Best of all, I could get an activation code for mobile bankid using the win 7 bankid instance I set up in http://verahill.blogspot.com.au/2014/11/602-surviving-bankid-rant-moving-nge.html and now I never have to use it again.

[if you're on linux and in Scandinavia, just install mobile bankid on your phone or on android in a vm]

So, if you're on linux and you've been using the official bankid application and you happen to be a couple of continents removed from Scandinavia follow this post which basically does the following:
1. Install ubuntu 10.04 LTS in a VM
2. Install bankid 4.19.XXXX or earlier in the ubuntu VM
3. Copy your ~/.personal from your regular linux computer to the ubuntu VM
4. export your key using persadm export to a USB stick
5. Install windows 7 in a VM using the free, legal isos and the free, legal installation key. The copy will expire after 30 days (but will still continue working).
6. Install bankid in the Win 7 VM
7. Under File/Preferences in bankid add the directory on your USB stick with the exported bankid key
8. Log in to your BankID issuer (probably your bank) using bankid 'on file', and request a mobile bankid. You'll get an activation code
9. Install the bankid app on your phone (e.g. bankid from the play store on android)
10. Start the bankid app on your phone, and type in your personnummer and the activation code. Create a pin, which is your password
11. You're done.

I mean, sure, it's a very awkward way of going about it, but it works and is conceptually simple.

Android in a VM
And there's absolutely no reason you can't use mobile bankid it in a virtualbox VM if you want to -- I used an android 4.4 x86 iso and created a virtual machine, and then set up bankid which works fine.


28 July 2014

587. Very Briefly: Getting pictures off of a corrupted Compact Flash card using testdisk

Nothing terribly complicated here. My CFII card (above, at /dev/sdb1)  is about a decade old and occasionally becomes corrupted. To recover the photos I use photorec which is part of testdisk:

sudo apt-get install testdisk
sudo photorec

Select the correct device, in this case /dev/sdb

Search

Pick the correct file system, typically FAT16 or 32
Also select a place to store the recovered photos. Then recover:



And you're done.

586.Very Briefly: Gnuradio, RTL-SDR, GQRX and an R280T device on debian jessie

NOTE:
* I did this on debian jessie which at the time has gnuradio v 3.7.3-9+b1 and rtl-sdr v 0.5.3-3

* I'm having a lot of trouble getting gqrx working on debian wheezy even with backports. Whereas the backports versions of gnuradio, rtl-sdr and gqrx-sdr install just fine, when running gqrx I get the following error:
gqrx: symbol lookup error: /usr/lib/x86_64-linux-gnu/libQtNetwork.so.4: undefined symbol: _ZN16QIODevicePrivate13putCharHelperEc
* gqrx won't work on debian wheezy systems with 2 Gb of memory for some reason. I get the same error as is shown in this post: https://groups.google.com/forum/#!topic/gqrx/20F8RMWkNbU

The post:
I recently bought a DVB USB dongle based on RTL2832 and R280T: http://www.ebay.com.au/itm/221450623699?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649. AU$11for a TV card which actually works flawlessly under linux really isn't bad!

As I already have a mythtv setup using leadtek DTV 1000S I was more interested in exploring the R820T dongle as a software defined radio (SDR).

 So, after glancing at  http://www.thepowerbase.com/2012/06/getting-started-with-rtl-sdr/2/ I did the following


sudo apt-get install rtl-sdr gnuradio gnuradio-dev libgnuradio-osmosdr0.1.1.4 git libboost-dev liblog4cpp5-dev libboost-system-dev libboost-program-options-dev checkinstall
mkdir ~/tmp
cd ~/tmp
git clone https://github.com/csete/gqrx.git gqrx.git
cd gqrx.git/
mkdir build
cd build
qmake ../
make
sudo checkinstall --install=no
0 - Maintainer: [ root@niobium ] 1 - Summary: [ gqrx ] 2 - Name: [ gqrx ] 3 - Version: [ 20140726 ] 4 - Release: [ 1 ] 5 - License: [ GPL ] 6 - Group: [ checkinstall ] 7 - Architecture: [ amd64 ] 8 - Source location: [ build ] 9 - Alternate source location: [ ] 10 - Requires: [ ] 11 - Provides: [ build ] 12 - Conflicts: [ ] 13 - Replaces: [ ]
sudo dpkg -i gqrx_20140726-1_amd64.deb

Starting gqrx and using it is easy:
gqrx
So far I haven't managed to get anything other than regular commercial radio signals (I've only explored the FM band).

29 May 2014

579. TEMPerHum (0c45:7402 ) on debian linux wheezy

Yet another little usb device from PC sensors (I seem to have been giving them a fair amount of money recently ).

This is the device in question: http://pcsensor.com/index.php?_a=product&product_id=178 (note that I buy my devices via ebay where the prices are apparently always the campaign ones -- I paid AUD25 , not USD80)

It didn't come in a box so I have no scans or shots to show.

[See here for the regular TEMPer USB device (0c45:7401), and here for the TEMPer 1K4  (0c45:7403) USB thermocouple reader. Note that since the temper-usb code is in  a lot of flux you can't use the line numbers in those posts directly -- you'll have to read and understand the code before pasting it in. Luckily, it's quite simple -- even I managed to sort it out!]

I couldn't get temper-usb to work even when making (what I consider) the necessary edits, but instead got lots of errors (including " usb.USBError: could not detach kernel driver from interface 1: No data available"). So I finally gave up.

Instead, web searching led me to http://edorfaus.wordpress.com/2012/07/02/new-library-examples-and-features/ -- one of the replies by eg1l spelled out the solution -- I'll grant myself the liberty to repost it here, but please remember where it originally came from and link to the original article (exclusively or in addition).

mkdir ~/tmp
cd ~/tmp/
sudo apt-get install libudev-dev libusb-1.0.0-dev libfox-1.6-dev autoconf cmake

git clone git://github.com/signal11/hidapi.git
cd hidapi/
./bootstrap
./configure
cd libusb/
make
sudo make install

cd ../../

git clone git://github.com/edorfaus/TEMPered.git
cd TEMPered/
mkdir build
cd build/
cmake ..
make
cd utils/
sudo ./tempered 
cd ../
sudo make install

sudo ln -s /usr/local/lib/x86_64-linux-gnu/libtempered.so.0 /usr/local/lib/libtempered.so.0
sudo ln -s /usr/local/lib/x86_64-linux-gnu/libtempered-util.so.0 /usr/local/lib/libtempered-util.so.0
sudo ldconfig

sudo tempered
0006:000e:01 0: temperature 21.75 °C, relative humidity 49.1%, dew point 10.6 °C

Create an 80-temper.rules file in /etc/udev/rules.d:
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7401", GROUP="users", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7402", GROUP="users", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0c45", ATTRS{idProduct}=="7403", GROUP="users", MODE="0666"

Then do
sudo usermod -a -G users $USER

And
sudo service udev restart

Unplug and re-plug your device, then open a new terminal and you're set (type group to make sure that users show up).

me@boron:~$ tempered
0006:000f:01 0: temperature 23.34 °C, relative humidity 46.8%, dew point 11.3 °C

13 May 2014

576. Shortening the bash prompt in debian

This is yet another post in which I'm (almost) simply reposting a solution that someone else has already posted online.

Let's say that my contribution is to put it in context of debian.

Either way, here's the problem that needed solving: the debian prompt by default lists all directories, which sometimes means that the prompt itself breaks across two lines.

Luckily, it's not difficult to chop the prompt down to a more manageable, yet still informative, length. The solution is here (we do like a descriptive URL): http://superuser.com/questions/387673/how-can-i-limit-the-number-of-directories-in-my-prompt

That particular solution also allows you to change the permissible length of the path that will be shown -- change the 50 in the argument to droppath to set the number of chars.

Edit your ~/.bashrc and add the bits in red:
# drops first portion of a path $1 if length is greater than $2 function __droppath { if [[ ${#1} -gt $2 ]]; then p=$1 while [ ${#p} -gt $2 ]; do p="/"$(echo "$p"|cut -d"/" -f3-) done echo "..."$p else echo $1 fi } if [ "$color_prompt" = yes ]; then PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]$(_droppath "\w" 50)\[\033[00m\]\$ ' else PS1='${debian_chroot:+($debian_chroot)}\u@\h: $(__droppath "\w" 50)\$ ' fi

and here's an example using a length of 25 chars (which is a bit short).

Unmodified:
me@niobium: /usr/local/lib/python2.7/site-packages$\

Modified:
me@niobium: .../python2.7/site-packages$

You can always use pwd to figure out what the full path is if necessary:
me@niobium: .../python2.7/site-packages$ pwd
/usr/local/lib/python2.7/site-packages

20 April 2014

573. PCSensors K-type USB thermocouple adapter TEMPer1K4 (0c45:7403) on debian

UPDATE 1 May 2014:
I've rewritten the code now to properly deal with the presence of both a 0c45:7401 and a 0c45:7403 simultaneously. Note that I'm not convince about the accuracy of the temperature readings (accuracy as in whether there's any systematic bias to the output. The reproducibility seems to be excellent though).

Original post:
I just received this usb thermocouple reader (TEMPer1k4): http://www.pcsensor.com/index.php?_a=product&product_id=104

About the product:
lsusb shows 0c45:7403 (Microdia Foot Switch)

dmesg shows
[13448.536120] usb 6-1: new low-speed USB device number 3 using uhci_hcd [13448.709126] usb 6-1: New USB device found, idVendor=0c45, idProduct=7403 [13448.709139] usb 6-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [13448.709146] usb 6-1: Product: TH1000isoV1.5 [13448.709152] usb 6-1: Manufacturer: RDing


Getting it to work:
You can use the same program as in this post: http://verahill.blogspot.com.au/2013/12/532-temper-temperature-monitoring-usb.html with some minor modifications. Before running
sudo python setup.py install

make some changes in temperusb/temper.py.

Firstly, you need to allow for the detection of devices with the 0c45:7403 ID
 
15 VIDPIDs = [(0x0c45L,0x7401L),(0x0c45L,0x7403L)]
Secondly, you need to make sure that the program knows which device is which and treats them differently. Finally, you need to collect the right data-- the TEMPer1k4 returns a data_s with a length of 8 (caveat -- I haven't checked what the output from 0c45:7401 looks like. Maybe it too yields 8 fields), and the [2:4] data block contains the internal temperature of the USB device, while the [4:6] data block holds the thermocouple junction temperature. Of a sort -- you get a number which you need to translate into a temperature. See the bottom of this post for how I worked it all out. Please note that you should calibrate the thermocouple -- the uncorrected output seems to be at least 2-3 degrees too high.
temper.py
 
 15 VIDPIDs = [(0x0c45L,0x7401L),(0x0c45L,0x7403L)]

 63     def getid(self):
 64         return self._device.idProduct

125             if self._device.idProduct==29697:
126                 temp_c = 125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0])+0.0025
127                 if format == 'celsius':
128                     temp_c = temp_c * self._scale + self._offset
129                     return temp_c
130                 elif format == 'fahrenheit':
131                     return temp_c*1.8+32.0
132                 elif format == 'millicelsius':
133                     return int(temp_c*1000)
134                 else:
135                     raise ValueError("Unknown format")
136             elif self._device.idProduct==29699:
137                 temp_c = (struct.unpack('>h', data_s[4:6])[0])*0.25-2.00
138                 temp_internal=(125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0]))+0.0025
139                 if format == 'celsius':
140                     temp_c = temp_c * self._scale + self._offset
141                     return temp_c
142                 elif format == 'fahrenheit':
143                     if self._device.idProduct==29697: #0x7401
144                         return temp_c*1.8+32.0
145                     elif self._device.idProduct==29699: #0x7403
146                         return temp_internal
147 

cli.py
 
 31     for i, dev in enumerate(devs):
 32         readings.append({'device': i,
 33                          'id':dev.getid(),
 34                          'temperature_c': dev.get_temperature(),
 35                          'temperature_f':
 36                          dev.get_temperature(format="fahrenheit"),
 37                          'ports': dev.get_ports(),
 38                          'bus': dev.get_bus()
 39                          })
 40 
 41     for reading in readings:
 42         if disp_ports:
 43             portinfo = " (bus %s - port %s)" % (reading['bus'],
 44                                                 reading['ports'])
 45         else:
 46             portinfo = ""
 47         if reading['id']==29697:
 48             print('Device #%i%s: %0.1f°C %0.1f°F'
 49                   % (reading['device'],
 50                      portinfo,
 51                      reading['temperature_c'],
 52                      reading['temperature_f']))
 53         elif reading['id']==29699:
 54             print('Device #%i%s: %0.1f°C %0.1f°C'
 55                   % (reading['device'],
 56                      portinfo,
 57                      reading['temperature_c'],
 58                      reading['temperature_f']))

Beyond this, follow the instructions in http://verahill.blogspot.com.au/2013/12/532-temper-temperature-monitoring-usb.html and make sure to set up a rules file with the correct USB ID for this device.

Done!

If you're curious about the details, have a look below.

Analysing USB traffic:
Since I wasn't quite sure where to start I figured the easiest approach would be to sniff the traffic between the usb device and the offically supported programme from PC Sensors. So I installed it Win XP in virtualbox, read a couple of temperatures and compared them with the captured data.

To capture data I did:
sudo apt-get install tshark
sudo modprobe usbmon
lsusb
Bus 008 Device 003: ID 17ef:4815 Lenovo Integrated Webcam [R5U877] Bus 008 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 043: ID 0c45:7403 Microdia Foot Switch Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
sudo tshark -D
1. eth0 2. wlan0 3. nflog 4. nfqueue 5. usbmon1 6. usbmon2 7. usbmon3 8. usbmon4 9. usbmon5 10. usbmon6 11. usbmon7 12. usbmon8 13. any 14. lo (Loopback)
touch 1.pcap chmod ugo+w 1.pcap sudo tshark -i usbmon4 -w $HOME/1.pcap

I opened the 1.pcap file in wireshark and looked for fields called leftover data.

Here are two examples of such 'leftover data' fields:
Host to USB: 01 80 00 00 00 00 00 00
USB to Host: 80 06 17 f0 00 5c 0f ff

Subjecting the system to different temperatures helped me figure out what fields where changing -- I've marked them in bold above (blue for the thermocouple, red for the internal temperature). Interestingly, I got overflow when freezing the thermocouple between two ice cubes, which indicated that there was a fairly high lower limit (1.5 degrees)
The following are some of the data I harvested. The temperature is in the first column, the hex code is in the second one and the decimal value is in the third one:
Internal:
23.63 17a 378
23.69 17b 379
23.94 17f 383
23.75 17c 380
21.88 15e 350
22.31 165 357
22.88 16e 366

Thermocouple: 23.75 05f 95 23.50 05e 9 38.25 099 153 24.00 066 102 87.50 15e 350 79.50 13e 318
In other words, T(thermo)=output(thermo)*0.25+1.50 and T(int.)=(output(int.)-0.0025)/0.0625. Because the internal data is in fields 2:4 it's seen as e.g. 17b0 instead of 17b, so the decimal version needs to be divided by 16 (line 126 above).

I also set up an /etc/temper.conf file and did chown $USER /etc/temper.conf in order to be able to read it (must be a better way). I tried to calibrate the thermocouple in my kitchen with iced water and boiling water. The boiling water gave a reading of 102 degrees, while the iced water gave me 7.5 degrees Celsius even after what should've been long enough to achieve equilibrium. I'll calibrate it in the lab later. So for now a simple offset might be enough to give a working temperature.
temper-poll -p
Device #0 (bus 2 - port 2)
so temper.conf became
2-2: scale = 1.00, offset = -4.0


The temper-usb code is changing too quickly!. You'll thus need to read and understand the code rather than just pasting it in. Here are the full, edited cli.py an temper.py files.

cli.py
# encoding: utf-8
from __future__ import print_function
from temper import TemperHandler


def main():
    th = TemperHandler()
    devs = th.get_devices()
    readings = []
    print("Found %i devices" % len(devs))

    for i, dev in enumerate(devs):
        readings.append({'device': i,
                         'id':dev.getid(),
                         'temperature_c': dev.get_temperature(),
                         'temperature_f':
                         dev.get_temperature(format="fahrenheit")
                         })

    for reading in readings:
  if reading['id']==29697:
   print('Device #%i: %0.1f°C %0.1f°F' % (reading['device'],
                                               reading['temperature_c'],
                                               reading['temperature_f']))
  elif reading['id']==29699:
   print('Device #%i: %0.1f°C %0.1f°C' % (reading['device'],
                                               reading['temperature_c'],
                                               reading['temperature_f']))

temper.py
# encoding: utf-8
#
# Handles devices reporting themselves as USB VID/PID 0C45:7401 (mine also says RDing TEMPerV1.2).
#
# Copyright 2012, 2013 Philipp Adelt 
#
# This code is licensed under the GNU public license (GPL). See LICENSE.md for details.

import usb
import sys
import struct

VIDPIDs = [(0x0c45L,0x7401L),(0x0c45L,0x7402L),(0x0c45L,0x7403L)]
REQ_INT_LEN = 8
REQ_BULK_LEN = 8
TIMEOUT = 2000

class TemperDevice():
    def __init__(self, device):
        self._device = device
        self._handle = None

    def get_temperature(self, format='celsius'):
        try:
            if not self._handle:
                self._handle = self._device.open()
                try:
                    self._handle.detachKernelDriver(0)
                except usb.USBError:
                    pass
                try:
                    self._handle.detachKernelDriver(1)
                except usb.USBError:
                    pass
                self._handle.setConfiguration(1)
                self._handle.claimInterface(0)
                self._handle.claimInterface(1)
                self._handle.controlMsg(requestType=0x21, request=0x09, value=0x0201, index=0x00, buffer="\x01\x01", timeout=TIMEOUT) # ini_control_transfer

            self._control_transfer(self._handle, "\x01\x80\x33\x01\x00\x00\x00\x00") # uTemperatura
            self._interrupt_read(self._handle)
            self._control_transfer(self._handle, "\x01\x82\x77\x01\x00\x00\x00\x00") # uIni1
            self._interrupt_read(self._handle)
            self._control_transfer(self._handle, "\x01\x86\xff\x01\x00\x00\x00\x00") # uIni2
            self._interrupt_read(self._handle)
            self._interrupt_read(self._handle)
            self._control_transfer(self._handle, "\x01\x80\x33\x01\x00\x00\x00\x00") # uTemperatura
            data = self._interrupt_read(self._handle)
            data_s = "".join([chr(byte) for byte in data])

            if self._device.idProduct==29697: 
    temp_c = 125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0])+0.0025
    if format == 'celsius':
     return temp_c
    elif format == 'fahrenheit':
     return temp_c*1.8+32.0
    elif format == 'millicelsius':
     return int(temp_c*1000)
    else:
     raise ValueError("Unknown format")
            elif self._device.idProduct==29699: 
    temp_c = (struct.unpack('>h', data_s[4:6])[0])*0.25-4.00
    temp_internal=(125.0/32000.0*(struct.unpack('>h', data_s[2:4])[0]))+0.0025
    if format == 'celsius':
     return temp_c
    elif format == 'fahrenheit':
     if self._device.idProduct==29697: #0x7401
      return temp_c*1.8+32.0
     elif self._device.idProduct==29699: #0x7403
      return temp_internal
    elif format == 'millicelsius':
     return int(temp_c*1000)
    else:
     raise ValueError("Unknown format")
        except usb.USBError, e:
            self.close()
            if "not permitted" in str(e):
                raise Exception("Permission problem accessing USB. Maybe I need to run as root?")
            else:
                raise
    
    def getid(self):
        #print self._device.idProduct
        return self._device.idProduct

    def close(self):
        if self._handle:
            try:
                self._handle.releaseInterface()
            except ValueError:
                pass
            self._handle = None

    def _control_transfer(self, handle, data):
        handle.controlMsg(requestType=0x21, request=0x09, value=0x0200, index=0x01, buffer=data, timeout=TIMEOUT)

    def _interrupt_read(self, handle):
        return handle.interruptRead(0x82, REQ_INT_LEN)

        
class TemperHandler():
    def __init__(self):
        busses = usb.busses()
        self._devices = []
        for bus in busses:
            self._devices.extend([TemperDevice(x) for x in bus.devices if (x.idVendor,x.idProduct) in VIDPIDs])

    def get_devices(self):
        return self._devices

28 February 2014

558. More options for PDF annotation: Master PDF Editor and I, Librarian

This is an update to my previous posts (here and here) about annotating PDFs on Linux.

Master PDF Editor
 http://code-industry.net/pdfeditor.php
The linux version of this software is free and closed source. It will not run on Debian Wheezy, as it requires glibc >= 2.14, whereas Wheezy has version 2.13. You can either pull in a newer libc from testing, or simply use testing (Jessie). See here for how to use glibc > 2.13 on wheezy: http://verahill.blogspot.com.au/2014/03/562-pulling-in-glibc-214-from-testing.html

So I tried it on Jessie.

While it almost works, I can't prevent the program from screwing up the fonts in the process. Also, the annotations don't show up in acroread for some reason. Saving as PDF/A didn't make any positive difference.

The annotation shows up in evince -- but the font's weird now

Same goes for Xournal

In acrobat reader before editing with Master PDF Editor
in acrobat reader after adding an annotation. The annotation doesn't show up, but the fonts are screwed up.

So we're almost there -- Master PDF Editor does everything I want in terms of PDF annotation, but at least on linux there are issues with the fonts in the resulting PDFs.

I, Librarian
http://www.bioinformatics.org/librarian/
I, Librarian is both free and open source. It claims to be web-based -- which is true but can be misunderstood. What it means is that it is browser-based and runs a server on your computer. My first thought when I see 'web-based' is that I'm handing over my data to someone else, but luckily that's not the case here.

I installed the .deb file meant for ubuntu.

Using I, Librarian is quite straight forward, but I could not see the annotations in any other program that I tried, which makes it of little use for me -- I make annotations in galley drafts for journal editors, and for students to give them feedback on latex documents.

Either way, to start, just go to http://127.0.0.1/librarian





Make sure to edit the settings to make I, Librarian use the internal pdf viewer in order for editing to work.





No matter what I did, I could not export my pinned annotations though. They did not show up in either evince or acroread.

19 February 2014

557. Briefly: Drawing Molecules on Linux: ACD/ChemSketch in Wine

This is another post where I'm cheating a bit -- this is a windows program running in wine.

Let me explain. Sometimes you absolutely need to get a task done -- I use linux at work and I can't not do something just because I can't write/find a piece of software that does it for me. Science is the goal, and the route there is immaterial. So sometimes you need to be pragmatic about your software choices.

I much prefer to use free and open source software since it allows me to keep a copy of the source code which I can recompile in case the prebuilt binary suddenly won't work with a future version of debian. Having the source makes me feel more secure in the assertion that it's worth my time learning how to use that piece of software.

Second to that, I prefer native linux software -- although unfortunately 'native' here often means 'written in java', and -- while not knowing too much about java -- from a user point of view java software tends to be comparatively slow to load and run. Certainly it appears slower than a comparable C/C++ program.

As a last resort, I can accept having to run a windows binary in wine. It doesn't make me happy, and often there are small, niggling issues associated with it -- but if it can get the job done, so be it.

Note that I'm unwilling to actually run a native windows program on a native windows installation -- one has to have some standards...

Either way, this is why I look at windows programs as well for drawing structures and processing NMR spectra.

So I recently tested marvinsketch (linux), bkchem (linux), easychem (linux), chemtool (linux), gchempaint (linux), ISISDraw (wine) and ChemSketch (wine). Out of those I prefer MarvinSketch. However, I'm still exploring the alternatives.

ACD/ChemSketch for Linux is really just an older (2006) version of ACD/LABS free ChemSketch (the windows version is from 2013). To get it, go to http://www.acdlabs.com/resources/freeware/index.php and click on Download. I tried the version 'for linux', and not the windows one. I'm making the presumption that the newer binary won't play well with wine.

You don't need to be an academic to qualify for the free version.

wine ~/Downloads/chemsk50.exe

Once it's installed you can explore ChemSketch. Overall it's fairly similar to e.g. ISISDraw.







18 February 2014

556. Briefly: Drawing molecules on linux: ghempaint, chemtool and easychem

chemtool, easychem and gchempaint are in the Wheezy repos.
See also the following posts for ISISDraw, MarvinSketch and BKChem.

Chemtool
I didn't get along with this at all. I managed to import a few structures from the templates, but e.g. the clean molecule function didn't actually work, although it's there. Selecting, deleting etc. were all a bit non-intuitive (to me -- this is obviously very subjective)




Easychem
I can't find any templates. Drawing becomes a bit tedious since I didn't find an easy way of converting an existing bond from e.g. single to double.



gChemPaint
It's pretty straightforward to use and I like it the best of the three. However, it's still very sparse even compared to e.g. bkchem. It certainly works if you quickly need to make a simple structure. There's no clean function.