czwartek, 20 grudnia 2012

Perl encoding problem

SW asked me to augment a Perl script that originally processes ISO-8859-2 encoded text (TeX) files only by adding UTF-8 and CP1250 (one byte MS Windows encoding for Central Europe) encodings as well.

I made up it as follows (not sure if correct):


use Getopt::Long;
my $coding = 'utf8'; my $showhelp= '' ;
GetOptions( "coding=s" => \$coding, "help|\?" => \$showhelp,) ;
if ( $showhelp ) { print "*** $0 [-coding=[cp1250|iso88592|utf-8]] file1 file2...\n" ;
exit 1; }

if ( $coding =~ /cp1250/ ) { $coding='cp1250'; use open ':encoding(cp1250)'; }
elsif ( $coding =~ /iso8859\-?2/ ) { $coding='iso-8859-2'; use open ':encoding(iso-8859-2)'; }
elsif ( $coding =~ /utf\-?8/ ) { $coding='UTF-8'; use open ':encoding(UTF-8)'; }
else { die "*** Unknown coding: $coding\n"; exit 1; }

print STDERR "*** Coding: $coding\n";
## rest of the script omitted ....

I reencoded the script from original ISO-8859-2 to UTF-8 as well with iconv, so all strings are UTF-8 encoded now.

poniedziałek, 17 grudnia 2012

GDP per capita in purchasing power standards of EU member states

While GDP per capita is mainly an indicator reflecting the level of economic activity, Actual Individual Consumption (AIC) per capita is an alternative indicator better adapted to describe the material welfare situation of households.

GDP and AIC per capita in PPS, EU27 = 100


+-------------------------------------------------+
GDP per capita AIC per capita
2009 2010 2011 2009 2010 2011
+-------------------------------------------------+
EU27 100 100 100 100 100 100
Euro area (EA17) 109 108 108 107 107 107
+-------------------------------------------------+
Luxembourg 255 267 271 144 141 140
Netherlands 132 131 131 118 114 113
Ireland 130 129 129 103 103 101
Austria 125 127 129 116 118 119
Sweden 120 124 127 116 114 116
Denmark 123 128 125 116 116 113
Germany 115 119 121 115 117 120
Belgium 118 119 119 109 111 111
Finland 114 113 114 110 111 112
United Kingdom 111 111 109 121 120 118
France 109 108 108 113 113 113
Italy 104 101 100 103 102 101
Spain 103 99 98 96 95 94
Cyprus 100 97 94 102 99 98
Malta 83 85 85 85 83 84
Slovenia 87 84 84 81 80 81
Czech Republic 83 80 80 73 71 71
Greece 94 87 79 104 97 91
Portugal 80 80 77 83 84 81
Slovakia 73 73 73 72 71 70
Estonia 63 63 67 58 56 58
Lithuania* 55 57 66 63 61 70
Hungary 65 65 66 62 60 61
Poland 61 63 64 64 67 69
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Latvia 54 54 58 52 53 57
Romania 47 47 49 46 46 47
Bulgaria 44 44 46 43 43 45
+-------------------------------------------------+
Norway 177 181 186 134 136 135
Switzerland 150 154 157 128 129 130
Iceland 120 112 111 111 106 107
Croatia 62 59 61 58 57 59
Turkey 46 50 52 51 54 57
Montenegro 41 42 42 50 52 53
FYR Macedonia 36 36 35 41 40 40
Serbia 36 35 35 44 44 43
Albania** 28 27 30 32 30 34
BosniaHerzegovina 31 30 30 37 36 36
+-------------------------------------------------+

Source: Eurostat newsrelease 180/2012, December 2012 (http://epp.eurostat.ec.europa.eu)

* 2011 population figures adjusted on the basis of the 2011 Census. Therefore the per capita indices for 2011 are not entirely comparable with previous years due to this break in time series.

** Figures for all years based on Eurostat estimate of GDP

The euro area (EA17) consists of Belgium, Germany, Estonia, Ireland, Greece, Spain, France, Italy, Cyprus, Luxembourg, Malta, the Netherlands, Austria, Portugal, Slovenia, Slovakia and Finland.

piątek, 14 grudnia 2012

Grim prospects of EU economy

Total production in EU 2012 Unemployment in EU 2012
Source: Eurostat
Click on image to enlarge

The collapse of production during April-2008--April-2009 period (left figure) corresponds to a significant rise in unemployment (right figure), however in April 2009, when production was at the lowest level, unemployment rate was approx 9% while currently is is approx 12%.

sobota, 8 grudnia 2012

Raspberry Pi/DHT-22 sensor: registering temperature and humidity

Czujnik DHT-22
Fig. #1: DHT-22 sensor

Fig. #2: Testing DHT-22
Instalacja 2x czujnik DHT-22
Fig. #3: Wiring

To build the installation one has to buy:

DHT-22 temperature/humidity sensor (8 USD per sensor). Not cheap...

0,25W 10K OHM carbon resistor (very cheap).

female connectors (pol. kable połączeniowe żeńskie), telephone cables or similar four core cable (pol. kabel czterożyłowy), terminal block (pol. kostka połączeniowa) and heat shrink tubing (pol. rurka termokurczliwa) to insulate and strengthen connections. The recommended way is to use a breadboard (pol. płytka stykowa/prototypowa) as described in learn.adafruit.com. My interest in electronics is limited, I've never used breadboards etc... I had some spare cables and terminal blocks so I designed it that way (cf. pictures).

NOTE: The cheaper version of the DHT-22 is a DHT-11 (aka SHT-11). Tempted by the lower price I bought two DHT-11 sensors but I do not recommend it. First of all, the temperature is measured in the range of 0 °C to 50 °C (with poor accuracy of +/- 2 °C) so is not suitable for outdoor (at least in Europe). Second, the humidity seems to be understated. Third, it does not work when DQ line is connected to other GPIO pins than pin #24 (maybe it's a software problem). For comparison, DHT-22 measures the temperature in the range of-40C to +80 C with an accuracy of +/- 0.5 °C.

I follow the tutorial available at learn.adafruit.com but some details were modified.

Hardware

There are four pins in DHT-22 (see Figure # 1). I connected data line (DQ) of each sensor to pins P22, P24 and P25 respectively (each sensor must have a separate data line). Vdd pin of each sensor to P1 (3.3 V supply). GND (ground) pin of each sensor to P6. In addition, each DQ was connected via the resistor with the power line Vdd.

Pin Null is not used.

The sensors were connected to GPIO pins via terminal blocks, cables and some soldering.

Software

One has to download, compile and install the necessary library:


pi@raspberrystar $ wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.8.tar.gz
pi@raspberrystar $ tar -zxvf bcm2835-1.8.tar.gz
pi@raspberrystar $ cd bcm2835-1.8
pi@raspberrystar $ ./configure && make && sudo make install

then the application retrieving the data from the sensors has to be installed:


pi@raspberrystar $ git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
pi@raspberrystar $ cd Adafruit-Raspberry-Pi-Python-Code
pi@raspberrystar $ cd Adafruit_DHT_Driver

One has to modify Makefile file, namely add -l rt at the end of the line that starts with CFLAGS:


CFLAGS = -std=c99 -I. -lbcm2835 -l rt

now:


## in Adafruit_DHT_Driver directory
pi@raspberrystar $ make

If everyting works, then:


# Run ./Adafruit_DHT sensor-type DQ-pin-number
pi@raspberrystar $ sudo ./Adafruit_DHT 22 25
Using pin #25
Data (40): 0x3 0xe7 0x0 0x17 0x1
Temp = 2.3 *C, Hum = 99.9 %

The directory Adafruit_DHT_Driver contains also Adafruit_DHT_googledocs.ex.py Python script which can upload sensor readings directly to google.docs spreadsheet. To run Adafruit_DHT_googledocs.ex.py one has to install gspread module first:


pi@raspberrystar $ wget http://pypi.python.org/packages/source/g/gspread/gspread-0.0.13.tar.gz
pi@raspberrystar $ tar -zxvf gspread-0.0.13.tar.gz
pi@raspberrystar $ cd gspread
pi@raspberrystar $ sudo python setup.py install

Adafruit_DHT_googledocs.ex.py script: 1) in an infinite loop runs every 30 seconds the program Adafruit_DHT, 2) retrieves temperature/humidity, 3) sends temperature/humidity readings to google.docs. A fragment of the script looks like:


while(True):
output = subprocess.check_output(["./Adafruit_DHT", "2302", "4"]);
print output
# search for humidity printout
matches = re.search("Hum =\s+([0-9.]+)", output)
if (not matches):
time.sleep(3)
continue
humidity = float(matches.group(1))
## omitted code ...

time.sleep(30)

Because I want to process somehow the data (not only to retrieve and upload to google.docs) I modify Adafruit_DHT_googledocs.ex.py script. My version Adafruit_DHT_googledocs.ex.py is limited to sending to google.docs values passed as arguments to the call:


temp = float(sys.argv[1])
humidity = float(sys.argv[2])
## omitted code ...

The following bash script takes care of the rest:


#!/bin/bash
#
LOG_DIR=/home/pi/Logs/DHT
BIN_DIR=/home/pi/bin
SENSTYPE=22
SLEEP_TIME=5

function ReadSensor() {
local sensorType="$1"
local sensorId="$2"
local WYNIK=""
local SUCCESS=""

## 5 tries with 5s sleep between them
for i in 1 2 3 4 5; do
WYNIK=`sudo $BIN_DIR/Adafruit_DHT $sensorType $sensorId | tr '\n' ' '`
SUCCESS=`echo $WYNIK | awk ' { if (NF > 10) {print "YES"} else { print "NO"}}'`

if [ "$SUCCESS" = "YES" ] ; then
echo "$sensorId=$i $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP=`echo $WYNIK | awk '{print $13}'`
DHT_CURR_HUM=`echo $WYNIK | awk '{print $17}'`
break
fi
sleep $SLEEP_TIME;
done

## All attempts to read sensors were unsuccessful
if [ $SUCCESS = "NO" ] ; then
echo "$sensorId=? $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP="999.9"
DHT_CURR_HUM="999.9"
fi
}
echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/DHT22.log

## A sensor in the room:
ReadSensor $SENSTYPE "24"
READINGS="$DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## Outdoor sensor:
ReadSensor $SENSTYPE "25"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## A sensor in the porch:
ReadSensor $SENSTYPE "22"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"

## HTML + chart
/usr/bin/perl /home/pi/bin/dht2ht.pl > /var/www/stats/DHT22.html

# Upload to google
/home/pi/bin/DHT_googledocs.ex.py $READINGS

As in the case of 1-Wire bus there are problems with the reading of the sensor. That's why the function ReadSensor is trying to read the sensor several times. Maximum number of failed attempts, we have observed during several days of operation is 3.

The script runs every 30 minutes from cron:


1,31 * * * * /home/pi/bin/dht2ht.sh

LOG file looks something like this:


@20121113230101
24=1 Using pin #24 Data (40): 0x2 0x22 0x0 0xc9 0xed Temp = 20.1 *C, Hum = 54.6 %
25=1 Using pin #25 Data (40): 0x3 0xe7 0x0 0x1c 0x6 Temp = 2.8 *C, Hum = 99.9 %
22=4 Using pin #22 Data (40): 0x2 0x73 0x0 0xb0 0x25 Temp = 17.6 *C, Hum = 62.7 %

Row starting with the @ contains the date and time (@ is added for subsequnt easy parsing). Lines that begin with nn = m contain the data retrived from the sensor (nn is the sensor number, m denotes the number of successful attempt or ? in case when all attempts were unsuccessful)

Note: I noticed that higher system load (including intensive I/O operations) cause problems to retrieve data from the sensors. I tried to run motion detection application (motion) configured to use as little system resources as possible with no success. Rapberry overclocked to 900 Mhz performs significantly better but still only about 20% tries returns some data. Exact nature of the problem is a mystery to me as for example top indicates that still more there 80% of CPU is free.

Other question to consider is: whether the readings are correct during high humidity? My outdoor sensors tend to indicate 99% humidity pretty frequently which seems suspicious. I have compared data obtained from 3 different sensors (namely WH 2080 clone, Oregon Scientific's RMS300 and DHT-22) and some differ significantly.

Conversion to HTML and generating charts with dht2ht.pl

Perl script dht2ht.pl creates a HTML table and charts showing temperature/humidity readings as well as dew point, calculated with the following approximation formula: $$ D_p = (237.7 \cdot \gamma(T, H) ) / (17.271 - \gamma(T, H) ) $$

where: $$ \gamma(T, H) = 17.271 \cdot T / (237.7 + T) + \log (H / 100.0) $$

Script outcome is available here. All scripts and other stuff discussed in this blog post are available here.

Google.docs sheet containing readings from all my 3 sensors is available here. (Note: for some important reasons Adafruit_DHT_googledocs.ex.py script started adding data from the 162th line of the spreadsheet.)

czwartek, 22 listopada 2012

Raspberry Pi: system backup with dd

First I find the device with SDHC card mounted:


pi@raspberrypi ~ $ sudo fdisk -l

Disk /dev/mmcblk0: 7969 MB, 7969177600 bytes
4 heads, 16 sectors/track, 243200 cylinders, total 15564800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000108cb

Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 15564799 7720960 83 Linux

Now I mount a USB stick for storing a copy of the system:


pi@raspberrypi ~ $ mkdir /media/sda1
## Assume USB stick is /dev/sda1
pi@raspberrypi ~ $ mount /dev/sda1 /media/sda1

Raw copy with dd


pi@raspberrypi ~ $ sudo dd if=/dev/mmcblk0 | gzip -1 > /media/sda1/sd_backup.img.gz
## w/o compression:
pi@raspberrypi ~ $ sudo dd if=/dev/mmcblk0 of=/media/sda1/sd_backup.img
## over ssh in case there is no USB stick at hand:
user@othercomputer ~ $ sudo ssh root@raspberrystar dd if=/dev/mmcblk0 | gzip -1 | dd of=sd_backup.img.gz

Note: raspberrystar is the name of my system---change it to appropriate IP address or name.

Restoring system image:


pi@raspberrypi ~ $ zcat sd_backup.img.gz > /dev/sdX

Where /dev/sdX denotes the device with blank SDHC card mounted.

More details can be found here.

Copying over sshfs:


pi@raspberrypi ~ $ sudo apt-get install sshfs fuse-utils

pi@raspberrypi ~ $ mkdir -p ~/Dist/jupiter

## mounting (as user tomek) remote directory /public/raspberry at jupiter;
## mounting point is: ~/Dist/jupiter
pi@raspberrypi ~ $ sshfs tomek@jupiter:/public/raspberry/ ~/Dist/jupiter
failed to open /dev/fuse: Permission denied

On first try failure (as usual). Only fuse group members can read/write from/to /dev/fuse. User pi should be added to group "fuse":


pi@raspberrypi ~ $ sudo usermod -a -G fuse pi

To activate the modifications made in /etc/group one should log out/log in now.


pi@raspberrypi ~ $ sshfs tomek@jupiter:/public/raspberry/ ~/Dist/jupiter
pi@raspberrypi ~ $ ls -l /home/pi/Dist/jupiter
total 0

## Raw copy with dd (with compression):
sudo dd if=/dev/mmcblk0 | gzip -1 > /home/pi/Dist/jupiter/raspberrystar.iso

Added 3 Oct 2012:


15564800+0 przeczytanych recordów
15564800+0 zapisanych recordów
skopiowane 7969177600 bajtów (8,0 GB), 3504,04 s, 2,3 MB/s

Raw copying of 8Gb SDHC card with compression over sshfs took about 1 hr. The resulting image size is about 1,6 Gb.

Overclocking raspberry pi

It is said to overclock Raspberry Pi one has to upgrade the system:


sudo apt-get update && sudo apt-get install raspberrypi* raspi-config

Then configure it with raspi-config utility:


sudo raspi-config

It is good anyhow to check the system version first:


uname -a
Linux raspberrystar.pinkaccordions.org 3.2.27+ #174 PREEMPT Wed Sep 26 14:09:47 BST 2012 armv6l GNU/Linux

The kernel is up to date. Inspecting raspi-config I have discovered it is not updated, but I prefer to configure the system via CLI (command line or console) interface rather than GUI one (no need to connect the RPi to a TV set which is in another room:-). So I decided not to upgrade the system but rather manually configure it. To achieve overclocking one has to add the following lines to /boot/config.txt file:


pi@raspberrystar ~ $ sudo vim /boot/config.txt
## add the following:
temp_limit=80
arm_freq=900
sdram_freq=500

Now reboot:


pi@raspberrystar ~ $ sudo reboot

Check the dmesg:


pi@raspberrystar ~ $ dmesg | grep 7000
[ 1.956412] bcm2835-cpufreq: min=700000 max=900000 cur=700000

CPU frequency is still 700Mhz. To increase it one has to edit scaling_governor file:


pi@raspberrystar ~ $ sudo bash
root@raspberrystar:/home/pi#
echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
## check if the above works:-)
pi@raspberrystar ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
performance
# display available options:
pi@raspberrystar ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
conservative ondemand userspace powersave performance

The ondemand option allows for adjusting CPU frequency depending on CPU utilization.

Without any further reboot the new settings work:


# check current CPU frequency
pi@raspberrystar ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
900000

There is even a temperature sensor available so one can check if the CPU is not overheated:


# check processor temperature:
pi@raspberrystar ~ $ /opt/vc/bin/vcgencmd measure_temp
temp=46.5'C

To boot the system with scaling_governor set to appropriate value one has to edit /etc/rc.local:


pi@raspberrystar ~ $ sudo vim /etc/rc.local
# Add the following line
# echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

I have performed a simple test:


#!/bin/bash
#
N=5
START=$(date +%s)

for ((i=1;i<=$N;i++ )) ; do

echo "**** Iteration $i ****"

STARTI=$(date +%s)
perl -e 'for ($i=0;$i<=10000000;$i++) { $s .= "xx"; }'
ENDI=$(date +%s) ; TOTALI=$(( $ENDI - $STARTI ))
echo "*** $TOTALI s."

done

END=$(date +%s)
TOTAL=$(( $END - $START ))
MEAN=`awk -v m=$TOTAL -v n=$N 'BEGIN { print m/n }'`

echo "total: " $TOTAL "mean: " $MEAN
##

The test uses the following perl program:


perl -e 'for ($i=0;$i<=10000000;$i++) { $s .= "xx"; }'

Because computing time can vary, the program has to be run N times and the mean time is reported.

My Rpi runs 28--29s at 700 Mhz, 25,8s at 800 Mhz and 21s at 900 Mhz.

So running at 900 Mhz results in almost 30% reduction of computing time.

środa, 14 listopada 2012

Raspberry Pi/czujnik DHT-22: rejestrowanie temperatury i wilgotności

Czujnik DHT-22
Rys. #1: DHT-22

Rys. #2: Testowanie DHT-22
Instalacja 2x czujnik DHT-22
Rys. #3: Okablowanie

Do wykonania instalacji potrzebne są:

Czujnik DHT-22 temperatury/wilgotności (ok. 30 zł za sztukę). Droga sprawa...

REZYSTOR 0,25W 10K OHM węglowy (1,00 zł za 100 sztuk na Allegro).

Do tego: przewody połączeniowe żeńskie, przewód telefoniczny czterożyłowy lub inny podobny, kostka elektryczna oraz rurka termokurczliwa do izolacji i wzmocnienia połączeń. (Por. Raspberry Pi: magistrala 1-Wire i rejestracja temperatury.)

UWAGA: tańszą wersja DHT-22 jest DHT-11 (aka SHT-11). Połasiłem się nawet na takowy, bo taniej ale nie polecam. Przede wszystkim mierzy temperaturę w przedziale od 0C do 50C (z kiepską dokładnością +/- 2C) więc nie nadaje się do pomiaru temperatury zewnętrznej. Do tego odczyt wilgotności jest zaniżony i nie działa podłączony do niektórych pinów GPIO (być może jest to problem oprogramowania, którego używam). Dla porównania DHT-22 mierzy temperaturę w przedziale od -40C do +80C z dokładnością +/- 0,5C.

Na stronie learn.adafruit.com znajduje się tutorial, z którego korzystałem...

Hardware

Sensor DHT-22 ma cztery piny (por. rys #1). Podłączyłem linie danych (DQ) do pinów P22, P24 i P25 (każdy sensor musi mieć oddzielną linię danych). Vdd każdego sensora do pina P1 (zasilanie 3,3V). GND (masa) każdego czujnika do pina P6. Ponadto każde DQ należało połączyć za pomocą rezystora z linią zasilania Vdd.

Pin Null nie jest wykorzystywany.

Lutowanie i łączenie wszystkiego do kupy wykonałem w sposób identyczny (kostka elektryczna, rurka termokurczliwa itp.) z opisanym bardziej szczegółowo we wpisie Raspberry Pi: magistrala 1-Wire i rejestracja temperatury.

Software

Pobieram, kompiluję i instaluję niezbędną bibliotekę:


pi@raspberrystar $ wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.8.tar.gz
pi@raspberrystar $ tar -zxvf bcm2835-1.8.tar.gz
pi@raspberrystar $ cd bcm2835-1.8
pi@raspberrystar $ ./configure && make && sudo make install

Pobieram program do obsługi czujników:


pi@raspberrystar $ git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
pi@raspberrystar $ cd Adafruit-Raspberry-Pi-Python-Code
pi@raspberrystar $ cd Adafruit_DHT_Driver

W pliku Makefile należy dopisać -l rt na końcu wiersza zaczynającego się od CFLAGS:


CFLAGS = -std=c99 -I. -lbcm2835 -l rt

teraz:


## w katalogu Adafruit_DHT_Driver
pi@raspberrystar $ make

Jeżeli wszystko działa, to:


# Uruchomienie ./Adafruit_DHT typ-czujnika nr-pina-DQ
pi@raspberrystar $ sudo ./Adafruit_DHT 22 25
Using pin #25
Data (40): 0x3 0xe7 0x0 0x17 0x1
Temp = 2.3 *C, Hum = 99.9 %

W katalogu Adafruit_DHT_Driver znajduje się też skrypt Pythona pn. Adafruit_DHT_googledocs.ex.py służący do wysyłania odczytanych danych do arkusza google.docs. Skrypt Adafruit_DHT_googledocs.ex.py do działania potrzebuje modułu gspread:


pi@raspberrystar $ wget http://pypi.python.org/packages/source/g/gspread/gspread-0.0.13.tar.gz
pi@raspberrystar $ tar -zxvf gspread-0.0.13.tar.gz
pi@raspberrystar $ cd gspread
pi@raspberrystar $ sudo python setup.py install

Skrypt Pythona Adafruit_DHT_googledocs.ex.py: 1) w nieskończonej pętli uruchamia co 30 sekund program Adafruit_DHT, 2) wyłuskuje z wydruku wartości temperatury/wilgotności, 3) wysyła co trzeba na google.docs. Fragment skryptu wygląda następująco:


while(True):
output = subprocess.check_output(["./Adafruit_DHT", "2302", "4"]);
print output
# search for humidity printout
matches = re.search("Hum =\s+([0-9.]+)", output)
if (not matches):
time.sleep(3)
continue
humidity = float(matches.group(1))
## pominięty kod ...

time.sleep(30)

Ponieważ ja chcę oprócz wysłania na google.docs coś tam jeszcze zrobić z danymi, to miałem do wyboru albo rozbudować Adafruit_DHT_googledocs.ex.py o dodatkową funkcjonalność albo go uprościć. Wybrałem to drugie: moja wersja Adafruit_DHT_googledocs.ex.py ogranicza się wyłącznie do wysłania na google.docs wartości przekazanych jako argumenty wywołania:


temp = float(sys.argv[1])
humidity = float(sys.argv[2])
## pominięty kod ...

Resztą zajmie się poniższy skrypt basha:


#!/bin/bash
#
LOG_DIR=/home/pi/Logs/DHT
BIN_DIR=/home/pi/bin
SENSTYPE=22
SLEEP_TIME=5

function ReadSensor() {
local sensorType="$1"
local sensorId="$2"
local WYNIK=""
local SUCCESS=""

## zwiększyłem powtórzenia do 5 (sleep zmniejszony do 5s/było 10)
for i in 1 2 3 4 5; do
WYNIK=`sudo $BIN_DIR/Adafruit_DHT $sensorType $sensorId | tr '\n' ' '`
SUCCESS=`echo $WYNIK | awk ' { if (NF > 10) {print "YES"} else { print "NO"}}'`

if [ "$SUCCESS" = "YES" ] ; then
echo "$sensorId=$i $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP=`echo $WYNIK | awk '{print $13}'`
DHT_CURR_HUM=`echo $WYNIK | awk '{print $17}'`
break
fi
sleep $SLEEP_TIME;
done

## Wszystkie próby okazały się nieudane
if [ $SUCCESS = "NO" ] ; then
echo "$sensorId=? $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP="999.9"
DHT_CURR_HUM="999.9"
fi
}
echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/DHT22.log

## Czujnik w pokoju:
ReadSensor $SENSTYPE "24"
READINGS="$DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## Czujnik na zewnątrz:
ReadSensor $SENSTYPE "25"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## Czujnik weranda:
ReadSensor $SENSTYPE "22"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"

## zamiana na HTML + wykres
/usr/bin/perl /home/pi/bin/dht2ht.pl > /var/www/stats/DHT22.html

# Wyslanie na google
/home/pi/bin/DHT_googledocs.ex.py $READINGS

Podobnie jak w przypadku magistrali 1-Wire zdarzają się problemy z odczytaniem wartości czujnika. Na tą okoliczność funkcja ReadSensor próbuje odczytu kilkukrotnie. Maksymalna nieudana liczba prób, którą zaobserwowałem w ciągu kilkudniowej eksploatacji to 3.

Skrypt jest uruchamiany co 30 min przez crona:


1,31 * * * * /home/pi/bin/dht2ht.sh

Plik LOG wygląda jakoś tak:


@20121113230101
24=1 Using pin #24 Data (40): 0x2 0x22 0x0 0xc9 0xed Temp = 20.1 *C, Hum = 54.6 %
25=1 Using pin #25 Data (40): 0x3 0xe7 0x0 0x1c 0x6 Temp = 2.8 *C, Hum = 99.9 %
22=4 Using pin #22 Data (40): 0x2 0x73 0x0 0xb0 0x25 Temp = 17.6 *C, Hum = 62.7 %

Wiersz zaczynający się od @ zawiera datę i czas odczytu. Wiersze zaczynające się od nn=m zawierają odczytane dane (nn to numer czujnika, m numer próby w której odczytano wartości lub ? jeżeli wszystkie próby były nieudane)

Uwaga: zauważyłem, że przy intensywnych operacjach I/O są duże problemy z odczytaniem wskazań czujników.

Skrypt dht2ht.pl

Perlowy skrypt dht2ht.pl tworzy tabelę oraz wykresy prezentujące odczytane wartości plus obliczoną na ich podstawie temperaturę punktu rosy. Rezultat działania można oglądać tutaj. Omawiane w tym wpisie skrypty są zaś tutaj.

Arkusz google.docs zawierający odczyty z moich trzech czujników jest dostępny tutaj. (Uwaga: z jakiś ważnych powodów skrypt Adafruit_DHT_googledocs.ex.py zaczął dopisywanie danych od 162 wiersza arkusza.)

wtorek, 13 listopada 2012

Raspberry Pi: tworzenie kopii systemu z wykorzystaniem rsync

W temacie kopii zapasowej na stronach poświęconych Raspberry Pi znaleźć można wyłącznie(?) opisy jak to zrobić za pomocą dd. Ten sposób nie podoba mi się na dłużą metę z uwagi na czas -- kopiowanie karty 8Gb z kompresją przez sshfs zajęło około 1 godziny. Tworzenie kopii przyrostowych (za pomocą rsync) wydaje się lepszym pomysłem...

Wariant #1: dysk USB podłączony do RPi

Załóżmy, że do /etc/fstab wpisano:


/dev/disk/by-id/usb-WD_5000AAV_External_57442D574341535535303634313031-0:0-part1 \
/mnt/external-disk ext4 noauto,user,rw 0 0

Utworzenie kopii systemu sprowadza się wykonania:


rsync -av --exclude=/proc/ --exclude=/sys/ --exclude=/tmp/ \
--exclude=/mnt/ --exclude=/home/pi/Dist/ --delete / /mnt/external-disk/backup/rpi

Opcja --exclude pomija wymienione pliki/katalogi. W szczególności należy koniecznie umieścić tam katalogi, w których są/mogą być montowane inne systemy plików, np. /mnt/ (uniknięcie pętli, bo przecież /mnt/ zawiera zamontowany dysk USB) oraz /home/pi/Dist/ (moje zwyczajowe miejsce montowania systemów plików przez sshfs)

Wariant #2: kopia systemu tworzona na innym komputerze

Kopia systemu z raspberry będzie tworzona na innym komputerze dostępnym poprzez sieć.

Konfigurowanie rsynca należy rozpocząć od jego zainstalowania na obu komputerach (źródłowym i odbiorcy):


apt-get install rsync

Zawartość pliku /etc/rsyncd.conf po stronie źródła (czyli raspberry):


uid = 0
gid = 0
hosts allow = 192.168.1.***
transfer logging = no
read only = yes

[wholefs]
path = /
comment whole root fs

W pliku /etc/default/rsync (także po stronie źródła, tj. raspberry) należy wpisać lub ,,odhaszować'':


RSYNC_ENABLE=true

Teraz trzeba wystartować rsync (po ustawnieniu RSYNC_ENABLE, rsync będzie już uruchamiany w momencie startu systemu -- nie potrzeba do tego żadnych dodatkowych zabiegów w konfiguracji)


# /etc/init.d/rsync restart

Można sprawdzić czy działa podając polecenie (moje raspberry nazywa się raspberrystar) na komputerze odbiorcy (jako root):


rsync raspberrystar::wholefs/

Jeżeli wszystko jest OK to wyświetlona zostanie zawartość katalogu / na raspberrystar (czyli źródle).

Utworzenie kopii systemu sprowadza się wykonania:


rsync -av --exclude=/proc/ --exclude=/sys/ --exclude=/tmp/ \
--exclude=/mnt/ --exclude=/home/pi/Dist/ --delete \
raspberrystar::wholefs/ /public/sheeva/backup/raspberrystar/rootfs

Przywracanie systemu z kopii zapasowej

W razie potrzeby kopia może być szybko przeniesiona na inną kartę SDHC.


# uwaga: nazwy katalogów odpowiadają wariantowi #2 tworzenia kopii:
rsync -av --log-file=rsync_`date +%Y%m%d%H`.log --delete \
/public/sheeva/backup/raspberrystar/rootfs/ /public/sdX

Gdzie /public/sdX oznacza miejsce zamontowania karty SDHC. Karta musi być wcześniej sklonowana z ,,pierwszej'' kopii systemu wykonanej za pomocą dd, tj.:


zcat sd_backup.img.gz > /dev/sdX

Teraz można gdybać czy użycie samego dd nie będzie prostsze. Być może -- ja wolę korzystać na co dzień z rsynca.

Zauważyłem, że przy intensywnych operacjach I/O są problemy z odczytem danych przez GPIO (temperatura/wilgotność). Problem nie jest duży, ponieważ tworzenie pierwszej kopii systemu zajęło mi jakieś 20 min (można się spodziewać, że kolejne będą tworzone w ciągu kilku minut), ale dla większej pewności dodałem ionice--bwlimit (specjalnie tego nie testując, oprócz sprawdzenia, że działa)


ionice -c3 rsync -av --bwlimit=500 --exclude=/proc/ --exclude=/sys/ --exclude=/tmp/ \
--exclude=/mnt/ --exclude=/home/pi/Dist/ --delete \
raspberrystar::wholefs/ /public/sheeva/backup/raspberrystar/rootfs

Jeżeli powyższe zapisane zostanie do skryptu, np. o nazwie backup_raspberry.sh, to teraz aby ten skrypt był uruchamiany raz na tydzień, np. w niedzielę o 4:00 należy wpisac do pliku crontab (na komputerze odbiorcy) coś takiego:


0 4 * * 7 /root/bin/backup_raspberry.sh >> /root/logs/RSync/RSync.log 2>&1

wtorek, 9 października 2012

Zgranie filmu z płyty DVD do formatu AVI

Ponieważ zainstalowany frontend pn. k9copy kończy pracę błędem, zripowałem płytę DVD za pomocą czegoś takiego:


#!/bin/bash
if [ "$1" = "" ] ; then echo "*** Podaj numer ścieżki, np $0 3 ***" ; exit 1 ; fi
mencoder dvd://$1 -ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=2400:aspect=16/9 \
-vf scale=720:576 -oac mp3lame -lameopts br=128 -o Movie-$1.avi

czwartek, 4 października 2012

Raspberry Pi: magistrala 1-Wire i rejestracja temperatury

DS18B20
Rys. #1: Układ DS18B20
zdjęcie
Rys. #2
zdjęcie
Rys. #3
zdjęcie
Rys. #4
zdjęcie
Rys. #5: Kostka
DS18B20
Schemat #6: 2 czujniki

Poniższy opis w dużym stopniu jest oparty na tekście Raspberry Pi odczyt temperatury przez nodejs.

Podłączenie czujników DS18B20 do Raspberry Pi

Czujniki temperatury DS18B20 firmy Dallas należy dołączyć do portu GPIO (styki P1, P6 oraz P7)

Port GPIO

Do wykonania instalacji potrzeba:

Tzw. przewody połączeniowe żeńskie (4 zł za 10 sztuk); w oryginale to się nazywa jumper wire.

REZYSTOR 0,25W 4,7K OHM węglowy (1,50 zł za 100 sztuk).

DS18B20 termometr 1-wire (4,00--5,00 zł za sztukę).

Kostka elektryczna (około 3 zł za 10 sztuk).

Rurka termokurczliwa do izolacji i wzmocnienia połączeń.

Przewód telefoniczny czterożyłowy lub inny podobny.

Trzy wyprowadzenia układu DS18B20 to: masa (GND), linia danych (DQ) i zasilanie (Vdd). Jeżeli położymy układ ,,napisem do góry''/,,stykami do dołu'' (por. rys. #1), to pierwszy styk od lewj (#1) to GND, środkowy (#2) to DQ a prawy (#3) to Vdd.

Styki DQ oraz Vdd należy złączyć za pomocą rezystora 4K7 (4k7 ohm resistor).

Ja to zrobiłem w ten sposób, że obciąłem złącza żeńskie po jednej stronie przewodów połączeniowych i wsadziłem je do kostki elektrycznej. Następnie dolutowałem dwa kilkucentymetrowe przewody po obu stronach rezystora i końce tych przewodów wsadziłem do odpowiednich styków w kostce elektrycznej. W ten sposób połączyłem DQ oraz Vdd za pomocą rezystora (rys. #5).

Styki czujnika DS18B20 dolutowuję do poszczególnych żył przewodu telefonicznego (jedna żyła jest zbędna). Ponieważ DS18B20 jest bardzo mały, to żeby piny się nie stykały izoluję każdą żyłę cienką rurką termokurczliwą (por. zdjęcie #2, umieszczone obok). Żeby ładniej wyglądało, ale przede wszystkim żeby połączenie czujnik-kabel było mocniejsze (żyły są bardzo cienkie) to na cały przewód naciągam szerszą rurkę (por. zdjęcie #3) i też zgrzewam (por. zdjęcie #4). Zgrzewam zapalniczką....

Odpowiednie żyły przewodu telefonicznego z dolutowanym na końcu układem DS18B20 łączę z kostką. Wydaje mi się, że tak jest lepiej--można łatwiej dodać kolejny termometr lub wydłużyć przewód. Układ jest gotowy i można go podłączyć: Vdd do pina P1, GND do pina P6 a DQ do pina P7. Który pin jest P1 jest jasno oznaczone na płytce.

Moja instalacja ma dwa układy DS18B20: jeden do mierzenia temperatury w pokoju a drugi do mierzenia temperatury na zewnątrz (por. rysunek #5/schemat #6).

Aktualizacja systemu (czyli po co robiłem kopię zapasową)

Aby Raspberry obsługiwał 1-Wire należy dokonać aktualizacji systemu, co można wykonać na kilka sposobów. Zgodnie z sugestią ze strony Raspberry Pi odczyt temperatury przez nodejs zdecydowałem się na Hexxeh's easy updater tool:


wget http://goo.gl/1BOfJ -O rpi-update
sudo mv rpi-update /usr/bin/rpi-update
sudo chmod +x /usr/bin/rpi-update

# Na wszelki wypadek:
sudo apt-get install ca-certificates

# rpi-update wymaga zainstalowania gita
sudo apt-get install git-core

Teraz można wykonać aktualizację (zabieg zawsze potencjalnie ryzykowny dlatego lepiej się zabezpieczyć wykonaniem kopii systemu, co opisano tutaj.)


pi@raspberrystar ~ $ sudo rpi-update
Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS
Performing self-update
Autodetecting memory split
Using ARM/GPU memory split of 192MB/64MB
We're running for the first time
Setting up firmware (this will take a few minutes)
Using HardFP libraries
If no errors appeared, your firmware was successfully setup
A reboot is needed to activate the new firmware

Teraz należy dodać do jądra moduły niezbędne do obsługi instalacji pomiaru temperatury:


sudo modprobe w1-gpio
sudo modprobe w1-therm

Uwaga: aby moduły były dodawana automatycznie, przy starcie systemu należy dodać w1-gpio oraz w1-therm do pliku /etc/modules. Mój plik /etc/modules wygląda następująco:


pi@raspberrystar ~ $ less /etc/modules
snd-bcm2835
w1-gpio
w1-therm

Odczyt temperatury

Po podłączeniu ,,magistrali 1-Wire'' (czytaj kabelków z czujnikami DS18B20 w opisany wyżej sposób) wykonanie polecenia ls w katalogu /sys/bus/w1/devices/ powinno ujawnić urządzenia dołączone do magistrali:


pi@raspberrystar ~ $ ls -l /sys/bus/w1/devices/
lrwxrwxrwx 1 root root 0 paź 3 13:45 w1_bus_master1 -> ../../../devices/w1_bus_master1
lrwxrwxrwx 1 root root 0 paź 3 13:58 28-0000032562aa -> ../../../devices/w1_bus_master1/28-0000032562aa
lrwxrwxrwx 1 root root 0 paź 3 19:27 10-000802012743 -> ../../../devices/w1_bus_master1/10-000802012743

W przypadku mojej ,,magistrali'' są to dwa termometry: 28-0000032562aa oraz 10-000802012743.

Do odczytania temperatury korzystamy z pliku w1_slave:


pi@raspberrystar ~ $ cat /sys/bus/w1/devices/28-0000032562aa/w1_slave
60 01 4b 46 7f ff 10 10 b5 : crc=b5 YES
60 01 4b 46 7f ff 10 10 b5 t=22000

Wielkość temperatury to 22,000 stopnie Celsjusza (t=22000).

Aby odczytać dwa termometry na raz, dodać datę i czas odczytu, a następnie zapisać wszystko do pliku LOG można zastosować następujący skrypt (,,prywatne'' skrypty umieszczam w katalogu ~/bin/):


#!/bin/bash
LOG_DIR=/home/pi/Logs/Digitemp
## Data/czas odczytu
echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/digitemp.log
## Czujnik nr1
echo "28-0000032562aa `cat /sys/bus/w1/devices/28-0000032562aa/w1_slave | tr '\n' ' '`" >> $LOG_DIR/digitemp.log
## Czujnik nr2
echo "10-000802012743 `cat /sys/bus/w1/devices/10-000802012743/w1_slave | tr '\n' ' '`" >> $LOG_DIR/digitemp.log

Zapis wygląda jakoś tak (przy założeniu, że powyższy skrypt znajduje się w pliku ~/bin/dt2ht.sh):


pi@raspberrystar ~ $ ~/bin/dt2ht.sh
@20121004100001
28-0000032562aa 5f 01 4b 46 7f ff 01 10 9b : crc=9b YES 5f 01 4b 46 7f ff 01 10 9b t=21937
10-000802012743 1e 00 4b 46 ff ff 0d 10 38 : crc=38 YES 1e 00 4b 46 ff ff 0d 10 38 t=14937

Gdzie: @20121004100001 oznacza datę i czas, 28-0000032562aa/10-000802012743 to identyfikatory czujników a zapis w stylu t=21937, to temperatura (21,937 stopni Celsjusza).

Teraz wystarczy dodać odpowiedni wpis do pliku crontab użytkownika pi, aby, przykładowo temperatura była rejestrowana co godzinę (dt2ht.sh to nazwa opisanego wyżej skryptu służącego odczytu temperatury i zapisania wyników do pliku LOG):


pi@raspberrystar ~ $ mkdir ~/Crontab
pi@raspberrystar ~ $ vi ~/Crontab/crontab
# do pliku ~/Crontab/crontab wpisuję jeden wiersz:
# 0 * * * * /home/pi/bin/dt2ht.sh
# zapisuję/kończę pracę vi

# dodanie zawartości ~/Crontab/crontab do zadań crona
pi@raspberrystar ~ $ crontab ~/Crontab/crontab

# sprawdzenie czy wszystko jest OK:
pi@raspberrystar ~ $ crontab -l
0 * * * * /home/pi/bin/dt2ht.sh

Pozostaje tylko wykonanie (np. za pomocą prostego skryptu PeHaPe) jakiś bardziej efektownego sposobu wyświetlania zawartości pliku LOG.

Dopisane 14 października 2012: W zasadzie działa, ale nie do końca. Czasami nie odczytuje temperatury wypisując CRC error, co wygląda następująco:


62 01 4b 46 7f ff 0e 10 03 : crc=03 NO 62 01 4b 46 7f ff 0e 10 03 t=-1250

Nie mam pojęcia czemu tak się dzieje. Jako workaround wymyśliłem kilkukrotny odczyt:


#!/bin/bash

LOG_DIR=/home/pi/Logs/Digitemp

function ReadSensor() {
local sensorId=$1
local WYNIK=""
local SUCCESS=""

## próbuj odczytać max 3 razy
for i in 1 2 3; do
WYNIK=`cat /sys/bus/w1/devices/$sensorId/w1_slave | tr '\n' ' '`
## pole 12 ($12) to wynik odczytu (YES albo NO):
SUCCESS=`echo $WYNIK | awk '{ print $12}'`

if [ "$SUCCESS" = "YES" ] ; then
## zapisuje numer próby oraz odczytaną informację :
echo "$sensorId=$i $WYNIK" >> $LOG_DIR/digitemp.log
## przerwij pętlę odczytano temperaturę:
break
fi
sleep 3;
done

## Trzy próby okazały się nieudane:
if [ $SUCCESS = "NO" ] ; then
echo "$sensorId=? $WYNIK" >> $LOG_DIR/digitemp.log
fi
}

echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/digitemp.log

## Czujnik w pokoju:
ReadSensor "28-0000032562aa"

## Czujnik na zewnątrz:
ReadSensor "10-000802012743"

Plik LOG wygląda jakoś tak:


@20121014220001
28-0000032562aa=1 62 01 4b 46 7f ff 0e 10 03 : crc=03 YES 62 01 4b 46 7f ff 0e 10 03 t=22125
10-000802012743=1 0e 00 4b 46 ff ff 0f 10 fd : crc=fd YES 0e 00 4b 46 ff ff 0f 10 fd t=6812

gdzie pierwszy wyraz to numer sensora, znak równości, numer próby w której odczytano temperaturę lub ?, jeżeli temperatury nie odczytano.

wtorek, 2 października 2012

Raspberry Pi: tworzenie kopii karty SDHC

Ustalamy jak nazywa się urządzenie, w którym jest zamontowana karta SDHC:


pi@raspberrypi ~ $ sudo fdisk -l

Disk /dev/mmcblk0: 7969 MB, 7969177600 bytes
4 heads, 16 sectors/track, 243200 cylinders, total 15564800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000108cb

Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 15564799 7720960 83 Linux

Teraz można zamontować pendrive'a, na którym zostanie zapisana kopia:


pi@raspberrypi ~ $ mkdir /media/sda1
## zakładamy że pendrive jest oznaczony jako /dev/sda1
pi@raspberrypi ~ $ mount /dev/sda1 /media/sda1

Kopiowanie za pomocą dd


pi@raspberrypi ~ $ sudo dd if=/dev/mmcblk0 | gzip -1 > /media/sda1/sd_backup.img.gz
## bez kompresji będzie szybciej:
pi@raspberrypi ~ $ sudo dd if=/dev/mmcblk0 of=/media/sda1/sd_backup.img
## po sieci, w przypadku gdy nie mamy wolnego pendrive'a
ktos@inny-komputer ~ $ sudo ssh root@raspberrystar dd if=/dev/mmcblk0 | gzip -1 | dd of=sd_backup.img.gz

Uwaga: raspberrystar powinno być zamienione na odpowieni adres IP (lub nazwę).

Przywracanie systemu z kopii zapasowej:


pi@raspberrypi ~ $ zcat sd_backup.img.gz > /dev/sdX

Gdzie /dev/sdX to nazwa urządzenia z zamontowaną czystą kartą SDHC.

Więcej szczegółów i bardziej detalicznie jest tutaj.

Kopiowanie do pliku zamontowanego za pomocą sshfs:


pi@raspberrypi ~ $ sudo apt-get install sshfs fuse-utils

pi@raspberrypi ~ $ mkdir -p ~/Dist/jupiter

## montuję (jako użytkownik tomek) zdalny katalog /public/raspberry na
## komputerze jupiter; punkt montowania to ~/Dist/jupiter
pi@raspberrypi ~ $ sshfs tomek@jupiter:/public/raspberry/ ~/Dist/jupiter
failed to open /dev/fuse: Permission denied

# Za pierwszym strzałem (jak zwykle) nie wyszło, a to dlatego, że
# wyłącznie członkowie grupy "fuse" mogą czytać/pisać do/na /dev/fuse.
# Należy zatem dodać użytkownika pi do grupy "fuse":

pi@raspberrypi ~ $ sudo usermod -a -G fuse pi
## Teraz trzeba się wy/zalogować żeby zadziałały modyfikacje w /etc/group

pi@raspberrypi ~ $ sshfs tomek@jupiter:/public/raspberry/ ~/Dist/jupiter
pi@raspberrypi ~ $ ls -l /home/pi/Dist/jupiter
razem 0

## kopiowanie za pomocą dd (z kompresją `w locie'):
sudo dd if=/dev/mmcblk0 | gzip -1 > /home/pi/Dist/jupiter/raspberrystar.iso

poniedziałek, 24 września 2012

Jak obrócić plik AVI?

Umieszczony obok film przedstawiający dzięcioła dużego (Dendrocopos major) zaciekle borującego dziurę w płycie styropianowej na moim bloku został oryginalnie zarejestrowany przekręconym do pionu aparatem (być może nie był to dobry pomysł.)

Żeby ,,odkręcić'' dzięcioła z powrotem do pionu (proporcje obrazu wyszły takie sobie przyznaję) zastosowałem program mencoder:


mencoder -vf rotate=3 -o OUTPUT.AVI -oac copy -ovc lavc INPUT.AVI

Jeżeli obraz wyszedł odwrócony do góry nogami, to zamiast rotate=3 trzeba wstawić rotate=1.

Przy okazji: w jakim celu dzięcioł kuje dziury w styropianie? Nauka wskazuje trzy powody: szuka robaków (raczej nie w moim przypadku), znaczy terytorium hałasem (też nie, bo wtedy dziur jest dużo i są płytkie. Poza tym styropian słabo hałasuje przy kuciu), buduje dziuple lęgowe lub ,,wypoczynkowe'' (roosting cavity). Por. wyjaśnienia na ten temat tu oraz tu.

Jeżeli już, to ,,mój'' dzięcioł buduje sobie roosting cavity, tyle, że jakoś nie zaobserwowałem, żeby tam specjalnie przesiadywał.

poniedziałek, 17 września 2012

Uruchomienie Raspberry Pi

Urządzenie kupiłem w firmie Farnell. Z dostawą z UK wyszło 180 PLN. Do tego obudowa za ca 30 PLN (do kupienia np. na ebay.pl na aukcjach firmy A1 Items Ltd. Akrylowe obudowy oferowane na allegro.pl nie podobają mi się) i ładowarka z wyjściem mikroUSB, też za 30 PLN. No i karta 8GB Toshiba (do kupienia np. na Allegro.pl), przetestowana w Sheevaplugza -- 43 PLN.

Razem jak widać około 300 PLN. Dla porównania, Sheevaplug (plus karta) = 600 PLN.

Zainstalowanie systemu jest tak proste jak:

1. Ściągnięcie obrazu karty:


[tomek@darkstar ~]$ wget http://downloads.raspberrypi.org/images/raspbian/2012-08-16-wheezy-raspbian/2012-08-16-wheezy-raspbian.zip
[tomek@darkstar ~]$ sha1sum 2012-08-16-wheezy-raspbian.zip
[tomek@darkstar ~]$ unzip 2012-08-16-wheezy-raspbian.zip

2. Nagranie obrazu:


[root@darkstar]# df -h
## wsadzamy kartę do czytnika kart
## w moim przypadku się okazało że system `widzi' kartę jako /dev/sdc1
[root@darkstar]# umount /dev/sdc1
## w poniższym, koniecznie of=/dev/sdc a nie of=/dev/sdc1
[root@darkstar]# dd bs=1M if=2012-08-16-wheezy-raspbian.img of=/dev/sdc
1850+0 przeczytanych recordów
1850+0 zapisanych recordów
skopiowane 1939865600 bajtów (1,9 GB), 499,495 s, 3,9 MB/s

[root@darkstar]# sync

3. Powiększenie wielkości partycji w programie gparted (dla kart o pojemności większej od 2Gb):


[root@darkstar]# gparted
Rpi console
Rysunek #1
Rpi console
Rysunek #2
Rpi configuration tool
Rysunek #3

Example WWW page
Rysunek #4

Za pierwszym razem nie poszło -- nie wiem czemu. Gparted odmawiał stanowczo powiększenia partycji. Zamontowałem kartę niepowiększoną, uruchomiłem RPi, żeby sprawdzić czy w ogóle działa (Rysunek 1). Potem wyłączyłem urządzenie. Dla świętego spokoju spróbowałem drugi raz z gparted i tym razem poszło (Rysunek 2).

Połączyć się z RPi można przez ssh, ponieważ raspbian jest tak skonfigurowany, że demon ssh jest uruchamiany przy starcie systemu.


[tomek@darkstar ~]$ ssh -l pi 192.168.1.115

Aby dokończyć konfigurację zalecane jest uruchomienie raspi-config:


pi@raspberrypi ~ $ sudo raspi-config

Narzędzie to pozwala na (por. rys. 3): 1) powiększenie partycji, 2) ustawienie klawiatury, 3) zmianę hasła użytkownika o nazwie pi, 4) zmianę locale, 5) zmianę strefy czasu, 6) zmianę podziału pamięci (domyślnie 64Mb z dostępnych 256 Mb jest wykorzystywane przez GPU), 7) włączanie/wyłączanie serwera ssh, 8) start systemu w trybie graficznym lub tekstowym (domyślne).

Z powyższych interesowało mnie jedynie 2--5, reszta jest albo wykonana (punkt jeden wykonałem za pomocą gparted) albo domyślne nastawy mnie satysfakcjonują (serwer ssh chcę mieć włączony, start systemu ma być w trybie tekstowym). Narzędzie raspi-config można uruchomić zresztą w każdej chwili.

Ponieważ wiem jak ustawić klawiaturę, locale, zmienić strefę czasu oraz hasło w Debianie ,,tak w ogóle'', bez uciekania się do konfiguratorów, ostatecznie nie uruchamiałem raspi-config, tylko wykonałem następujące polecenia:


pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get install debconf

## zmiana stefy czasowej
pi@raspberrypi ~ $ sudo dpkg-reconfigure tzdata

## zmiana locale na pl_PL.UTF-8
pi@raspberrypi ~ $ sudo dpkg-reconfigure locales

## zmiana hasła:
pi@raspberrypi ~ $ sudo passwd pi

## klawiatura (nie przewiduję na razie podłączenia klawiatury)
pi@raspberrypi ~ $ sudo vi /etc/default/keyboard

Instalowanie serwera apache


pi@raspberrypi ~ $ sudo groupadd www-data
groupadd: group 'www-data' already exists
pi@raspberrypi ~ $ sudo apt-get install apache2

Instalowanie serwera MySQL


pi@raspberrypi ~ $ sudo apt-get install mysql-server mysql-client php5-mysql

Instalowanie PHP


pi@raspberrypi ~ $ sudo sudo apt-get install php5-cgi php5-mysql \
php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap \
php5-mcrypt php5-memcache php5-mhash php5-ming php5-pspell \
php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc \
php5-xsl php5-fpm php5-cgi php5-cli php5-common

Instalowanie różnych przydatnych rzeczy:


pi@raspberrypi ~ $ sudo apt-get install fuse-utils
pi@raspberrypi ~ $ sudo apt-get install make zip unzip
## digitemp -- program do obsługi sensorów temperatury DS18B20
pi@raspberrypi ~ $ sudo apt-get install digitemp
pi@raspberrypi ~ $ sudo apt-get install vim

pi@raspberrypi ~ $ sudo apt-cache search emacs | grep 23
pi@raspberrypi ~ $ sudo apt-get install emacs23-nox

Apache działa o czym świadczy rysunek 4.

Sprawdzam też czy demon ntpd (synchronizacja czasu) jest uruchomiony:


ps aux | grep ntpd
ntp 1840 0.0 0.8 5424 1544 ? \
Ss 20:04 0:03 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 102:104

Okazuje się, że jest...

poniedziałek, 10 września 2012

Ambernia Obywatelska

Ambernia Obywatelska -- główna kwatera polowa
Hauptquartier

Dziś pojechałem do pracy Elki instalować jej mój ,,super program'' (org-mode + TeX).

Po drodze, przechodząc koło opuszczonej siedziby spółki mającej od niedawna jedną z bardziej rozpoznawalnych nazw w Polsce:-), czyli Amber Gold (zwanej także złośliwie Ambernią Obywatelską), zrobiłem kilka zdjęć.

czwartek, 6 września 2012

Zamiana kolorowego PDFa na czarno-biały za pomocą ghostscripta

Taką zamianę można wykonać za pomocą komercyjnej i do tego windzianej aplikacji Acrobat Pro. Zamiast Acrobata Pro można też użyć ghostscripta:


#!/bin/bash
INPUT=$1
OUTPUT=`basename $1 .pdf`_grayscale.pdf
gs -sOutputFile=$OUTPUT -sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 $INPUT < /dev/null

Sprawdziłem -- na dużym pliku -- i wygląda, że działa.

Tutaj piszą, że nie zawsze.

poniedziałek, 3 września 2012

Państwo polskie zdało egzamin

,,Państwo polskie zdało egzamin'' oświadczył ówczesny marszałek i PO prezydenta B. Komorowski w kwietniu 2010 r. Teraz też zdało, ale już nie tak celująco, jak wtedy więc zamiast awansu (którego wtedy doświadczył przykładowo gen. Be-O-eR Janicki) paru funkcjonariuszy ma dostać dymisję.

Co jest najważniejsze w ,,aferze Amber-Gold''? Nie jest nim bynajmniej oszukanie kilku tysięcy ludzi na kilkaset milionów złotych. Takie rzeczy były, są i będą. IMHO najważniejsze i najbardziej bolesne jest ujawnienie fasadowości instytucji państwa zwanego 3Rp (tego które zdało egzamin):

Prokuratura i sądy nie były w stanie egzekwować obowiązującego prawa w przypadku 28 letniego cffaniaczka, który przywłaszczył sobie utarg z kasy dla emerytów (Multikasa) i wyłudzał od banków kredyty na podstawionych figurantów. Skoro od takiego nie jest w stanie, to co dopiero w bardziej skomplikowanych sprawach i/lub przypadkach bardziej ,,finezyjnych'' przestępców?

Służby skarbowe wykazały się zdumiewającą bezradnością. NO COMMENTS po prostu, bo co tu komentować? Można się tylko zapytać, czy kontrola w/s ministra P. Grasia dot. jego ew. przestępstw karno-skarbowych (słynne cieciowanie) trwa dalej?

Komisja Nadzoru Finansowego (KNF), ta która rzekomo nie zawiodła, zajmuje się bzdurami. Słynna lista ostrzeżeń publicznych jest tworzona w oparciu o nie wiadomo jakie kryteria. Pomijając wszystkie inne, w ten sposób zarządzana `czarna lista' może być np. instrumentem do udupienia firmy. Dobrze jest zatem (a nie źle, jak się usiłuje teraz wmówić), że nikt się tą listą nie przejmuje.

KNF nie powinna się zajmować wszystkim, tylko wyłącznie swoją ,,białą listą'', tj. bankami, czyli podmiotami działającymi na podstawie udzielonej licencji (jest tam sporo do poprawienia BTW). Reszta nie ma licencji, a co za tym idzie, gwarancji na wypadek niewypłacalności, a jak ktoś chce próbować szczęścia i tam lokować oszczędności -- to wolny wybór.

Agencja Bezpieczeństwa Wewnętrznego (ABW) -- wg. słów D. Tuska -- nie zajmuje się takimi sprawami jak rozkręcenie w 2 lata biznesu wartego kilkaset milionów (jeżeli nie więcej) przez człowieka znikąd, który nie stroni od kontaktów z władzą, w tym z najbliższą rodziną premiera. Jeżeli w podobnie profesjonalny sposób działały służby specjalne w kwietniu 2010, to także NO COMMENTS.

Czwarta władza, czyli media dostały w pierwszym półroczu od A-G 20 mln PLN (tytułem reklam). Jeżeli czwarta władza bierze pieniądze od każdego, kto je ma, to potem pisze to, co jej każą. To chyba oczywiste...

Reszta to mgła propagandowa mająca odwrócić uwagą od istoty.

PS: Czym zajmuje się ABW można się było dowiedzieć oglądając zdjęcia (przykładowo tutaj) z konwojowania Marcina P. z aresztu do sądu, otoczonego chmarą ubranych na czarno osiłków oznaczonych stosownymi naszywkami. ABW to po prostu służba konwojowa, tyle, że wysoko opłacana, a nie żadna Agencja Bezpieczeństwa Wewnętrznego.

sobota, 18 sierpnia 2012

Najniebezpieczniejsza forma propagandy

W doskonałej książce Timothy P. Mulligana pn. Samotny Wilk. Życie i śmierć asa U-bootów Wernera Henke (Finna, Gdańsk 1999), dużo miejsca poświęcone jest walce propagandystów alianckich z tzw. gebelsowską propagandą (która nota bene jest uważana za wyjątkowo kłamliwą). Traf chciał, że tym razem prawda była po stronie tych drugich. Mulligan beznamiętnie pisze: ,,Zwalczana był każda forma niemieckiej propagandy, lecz program na temat Ceramica stanowił jej najniebezpieczniejszą formę -- prawdę [zatem ...] wymagała ostrej riposty''. Dalej Mulligan opisuje tą ripostę, która siłą rzeczy musiała brnąć w coraz większe kłamstwa.

Niedawna wizyta zwierzchnika Rosyjskiego Kościoła Prawosławnego patriarchy moskiewskiego i Całej Rusi Cyryla I, podczas której podpisane zostało Wspólne przesłanie do narodów Polski i Rosji zawierające m.in. zdanie ,,Po II wojnie światowej i bolesnych doświadczeniach ateizmu, który narzucono naszym narodom, wchodzimy dzisiaj na drogę duchowej i materialnej odnowy.'' ewidentnie strona przeciwna odczytała jako ww. najniebezpieczniejszą formę propagandy. Bezzwłoczna i ostra riposty is a must w takiej sytuacji.

Ponieważ żartów nie ma, to zamiast etatowej ale niezbyt lotnej specjalistki od Kościoła (Wiśniewska) głos zabrał sam Wielki Myśliciel -- A. Michnik: ,,Istotą reżimów, takich jak nazizm czy bolszewizm, nie był ateizm (a tym bardziej nie liberalizm), lecz totalitarny terror''.

Coś powiedzieć trzeba, bezzwłocznie i ostro. O sens i zgodność z faktami mniejsza. Te zawsze podlegają przecież interpretacji.

piątek, 10 sierpnia 2012

Wycieczka do Locarno

Pod koniec lipca pojechaliśmy na 5 dni w okolice Locarno (Szwajcaria). Tu są ślady wycieczek rowerowych: 23, 24, 25, 2627. Jak widać nie był to super wyczyn. No ale dzięki temu można było podziwiać piękne widoki w tym a zwłaszcza śliczne miasteczka z oryginalną zabudową.

Po drodze, z soboty na niedzielę, zatrzymaliśmy się w Norymberdze. W sobotę po południu zwiedzaliśmy piękną starówkę. Niedzielę rozpoczęliśmy od Germanische Nationalmuseum (wystawa poświęcona Durerowi + zbiór instrumentów muzycznych). Potem obejrzeliśmy Justizpalast. Wstęp jest płatny, w naszym przypadku było to 10,50 EUR za bilet rodzinny. Jak ktoś wie, co to były procesy norymberskie, to zwiedzanie tego miejsca można sobie darować. Nie jest to muzeum, ale coś w rodzaju izby pamięci -- eksponatów żadnych tam nie ma (co zrozumiałe). Są mniej lub bardziej znane zdjęcia. Obszerny audio przewodnik (w cenie biletu i dostępny także w języku polskim) szczegółowo opisuje przebieg wydarzeń. Słynna sala 600--miejsce procesu jest udostępniana w święta (w pozostałe dni odbywają się tam rozprawy). Ogłupione lewacką propagandą półgłówki (Głos Cadyka itp...) mogą przeżyć dysonans poznawczy widząc w tzw. środku Europy ogromnych rozmiarów krzyż wiszący nad stołem sędziowskim (mam na myśli, ich zitiere, tzw. zawłaszczenie przestrzeni publicznej przez Kościół).

Na koniec obejrzeliśmy pozostałości po tzw. 1000 letniej Rzeszy w postaci niedokończonej Kongresshalle oraz Reichsparteitagsgelände na ZeppelinFeld.

Wracając z Locarno zwiedziliśmy Pragę--pięknie miasto

Wszystkie zdjęcia z wycieczki są tutaj

wtorek, 7 sierpnia 2012

Running old Debian on a new Plug computer

Although Sheevaplug has appeared to be not particularly reliable piece of hardware (this claim is based on personal experience and numerous reports of other users), it is a great fun as well, so I gave it next (the last one) chance and have bought another new plug to replace the broken one.

I planned to use SDHC card with Debian which worked seamessly with my previous plug computer, so I follow the procedure described below.

Connect PC to Sheevaplug with USB-miniUSB cable

Turn on the plug computer.

Run cu:


cu -s 115200 -l /dev/ttyUSB0

press any key. In response to boot loader prompt type:


Marvel>> version
U-Boot 1.1.4 (Dec 27 2009 - 22:03:21) Marvell version: 3.4.27

The u-boot boot loader have to be upgraded before installing Debian (cf. http://www.cyrius.com/debian/kirkwood/sheevaplug/uboot-upgrade.html).

Copy the U-Boot binary u-boot.kwb to a USB stick formated with the FAT filesystem.

Plug the USB stick into a plug computer, connect the serial console and type the following commands:


usb start
fatload usb 0:1 0x0800000 u-boot.kwb
nand erase 0x0 0x60000
nand write 0x0800000 0x0 0x60000

Regardless of how U-Boot was installed, one have to restart the machine to load the new version of U-Boot:


reset

Boot the system (cf. http://www.cyrius.com/debian/kirkwood/sheevaplug/unpack.html).

Configure the boot loader now. First of all, one has to change a setting so the device will boot the kernel which is used by Debian:


setenv mainlineLinux yes
setenv arcNumber 2097
saveenv
reset

Restart the device so the changes will take effect. Now configure the machine to boot:


setenv bootargs_console console=ttyS0,115200
setenv bootargs_root 'root=/dev/mmcblk0p2'
setenv bootcmd_mmc 'mmc init; ext2load mmc 0:1 0x00800000 /uImage; ext2load mmc 0:1 0x01100000 /uInitrd'
setenv bootcmd 'setenv bootargs $(bootargs_console) $(bootargs_root); run bootcmd_mmc; bootm 0x00800000 0x01100000'
saveenv

At this point SheevaPlug is ready to boot Debian automatically from SD card. So, I inserted my SDHC card with Debian 5.0 installed some 2 years ago and tried to connect via ssh.


ssh -l <user> 192.168.1.88

Linux neptune.pinkaccordions.org 2.6.30-5-kirkwood #1 Wed Jan 12 15:27:07 UTC 2011 armv5tel

System is up and running so it seems reusing SDHC card with old Debian installation was sucessfull, but shortly I discovered there were problems...

System clock is terribly fast and there are problems communicating with USB port. Upon consulting google I have discovered kernel upgrade is recommended (cf. http://www.cyrius.com/debian/kirkwood/sheevaplug/boot.html and http://www.cyrius.com/journal/debian/kirkwood/sheevaplug/):


apt-get update
apt-get dist-upgrade
flash-kernel

First command generated lots of 404 errors because Lenny is not supported anymore (I was not aware of that). I decided not to upgrade to Lenny and fixed /etc/apt/sources.list instead (cf. http://superuser.com/questions/404806/did-debian-lenny-repositories-vanish):


deb http://archive.debian.org/debian/ lenny main non-free contrib
deb-src http://archive.debian.org/debian/ lenny main non-free contrib
# Volatile:
deb http://archive.debian.org/debian-volatile lenny/volatile main contrib non-free
deb-src http://archive.debian.org/debian-volatile lenny/volatile main contrib non-free
# Backports:
deb http://archive.debian.org/debian-backports lenny-backports main contrib non-free
# Previously announced security updates:
deb http://archive.debian.org/debian-security lenny/updates main

Then, apt-get dist-upgrade and flash-kernel was completed without errors.

After reboot, system works fine. I plan to upgrade it to Squeeze in the nearest future.

The moral from the story is: with God's and Google help one has not to be an expert to cope with running Linux.

wtorek, 17 lipca 2012

My sheevaplug seems to be broken

Żarło, żarło i zdechło -- odpowiedział chłop na pytanie czemu krowa nie żyje...

Sheevaplug mi padła znienacka doszedłszy do 240 dni uptime'u. Diody w większości się świecą, ale po podłączeniu kablem USB nic się nie dzieje (nie ma /dev/ttyUSB0 ani żadnego innego /dev/tty*) , wzw. z tym nie można się skomunikować z urządzeniem.

Kilka trików dotyczących LaTeXa

Parę trików LaTeXa, na które wpadłem w/z ze składanymi ostatnio dokumentami.

Szerokie tabele (lub rysunki) wystające na zewnętrzny margines:


\usepackage{ifoddpage}
%% Istotne są polecenia \unskip i \ignorespaces, inaczej zawartość nie jest
%% wyrównana do wewnętrznego marginesu:
\newenvironment{ShiftToOuterMargin}{\leavevmode
\noindent \hbox to\textwidth \bgroup\checkoddpage\unskip \ignorespaces
\ifoddpage \else\hss\fi}{\ifoddpage\hss\else\fi\unskip\egroup}
%% ... ... ...
\begin{ShiftToOuterMargin}
\begin{tabular}{|l|rrrr|rrrr|} ...
\end{tabular}
\end{ShiftToOuterMargin}

Do ustalenia, czy bieżąca strona jest parzysta czy nieparzysta używam pakietu ifoddpage (polecenia \checkoddpage oraz \ifoddpage). Zwykły zapis \ifodd\c@page nie zadziała z oczywistych względów. Więcej na ten temat znajduje się w TeX Frequently Asked Questions.

Zapamiętanie zawartości tekstu składanego literalnie (pakiet fancyvrb; otoczenie SaveVerbatim i polecenie \BUseVerbatim):


\usepackage{fancyvrb}
%% ... ... ...
\begin{SaveVerbatim}{VerbEnv}
... tekst literalny ...
\end{SaveVerbatim}
\begin{ShiftToOuterMargin}
\BUseVerbatim{VerbEnv}
\end{ShiftToOuterMargin}

Formatowanie przypisów w poprzek reguł LaTeXa: przypis ma być umieszczony w kolumnie tekstu wciętej o wielkość wcięcia akapitowego z lewej strony. Na marginesie (o wielkości wcięcia akapitowego) ma być umieszczony numer odsyłacza. Numer przypisu nie we być złożony we frakcji górnej ale stopniem podstawowym pisma.

Pomysł rozwiązania zgłoszony na GUST-l (autor anonimowy):


\makeatletter
\newdimen \@parindent \@parindent=\parindent
\renewcommand{\@makefntext}[1]{%
\everypar = {\hangindent = \@parindent \hangafter = 1}{\par}
\parindent 1.5\@parindent % wcięcie drugiego (i kolejnych) akapitu tego samego długiego przypisu
\noindent\hb@xt@ \@parindent % 0\@parindent
{\hss\@makefnmark \enspace}#1}
%{\hss{\@thefnmark} \enspace}#1} % do nautycznych
\makeatother

Polecenie \@makefnmark formatuje numer odsyłacza, domyślnie jest to:


\def\@makefnmark{\hbox{\@textsuperscript{\normalfont\@thefnmark}}}

Odsyłacz jest formatowany identycznie w tekście i w kolumnie przypisów. Zamiast tego trzeba zdefiniować formatowanie na dwa sposoby, przykładowo:


%% numer odsyłacza do kolumny tekstu:
\def\@makeTextfnmark{\hbox{\@textsuperscript{\normalfont\@thefnmark}}}
%% numer odsyłacza do kolumny przypisów
\def\@makefnmark{\hbox{\normalfont\@thefnmark}}

oraz w definicji \@makefntext zamiast \@makefnmark wstawić \@makeTextfnmark.

niedziela, 8 lipca 2012

Sposoby redagowania odsyłaczy bibliograficznych w schemacie autor-rok

Sposoby redagowania odsyłaczy bibliograficznych w schemacie autor-rok przy pomocy LaTeX-owego pakietu natbib:

F1. Na końcu zdania (najczęściej) w nawiasie, \citep

Ekwiwalencja pomiaru jest ważnym kryterium oceny jakości projektowanych skal pomiarowych (Cheung i Rensvold, 1999; Steenkamp i Baumgartner, 1998).

Co wygląda ,,w źródle'' LaTeXowym następująco:


Ekwiwalencja pomiaru jest ważnym
kryterium oceny jakości projektowanych
skal pomiarowych~\citep{CheungRensvold1999,SteenkampBaumgartner1998}.

Uwaga: jeżeli podstawową formą odsyłacza jest autor (rok), to wydawać by się mogło, że powinno być:

Ekwiwalencja pomiaru jest ważnym kryterium oceny jakości projektowanych skal pomiarowych (Cheung i Rensvold (1999), Steenkamp i Baumgartner (1998)).

Ale to mi się wizualnie nie podoba, bo mnoży ponad potrzebę nawiasy, no i ten fatalnie wyglądający podwójny nawias na końcu.

F2. Inny wariant, wtrącenie z komentarzem \citealp

koncentruje się raczej na fenomenie jego tworzenia, motywacji twórców, koordynacji itd. (por. Al Marzouq, 2005; Niederman i inni, 2006a, Feller i Fitzgerald, 2002; Niederman i inni 2006a).


koncentruje się raczej na fenomenie jego
tworzenia, motywacji twórców,
koordynacji itd. (por.~\citealp{AlMarzouq05,Niederman2006a,FellerFitzgerald2002,Niederman2006b}).

Wreszcie podnoszone są zarzuty dotyczące zbytniej arbitralności proponowanej procedury (por. Straub i inni, 2004, s. 391 oraz Bollen, 1989, s. 192).


Wreszcie podnoszone są zarzuty
dotyczące zbytniej arbitralności proponowanej
procedury (por.~\citealp[s.~391]{StraubBoudreauGefen2004} oraz \citealp[s.~192]{Bollen89}).

Uwaga: jedna z dwóch form, tj. F1 i F2 wydaje się zbędna(?). Kowal (Metody Statystyczne w badaniach sondażowych rynku, PWN, Warszawa 1998) używa F2, co m.in. powoduje że słowo por. jest przypuszczalnie najczęściej używanym trzyliterowym wyrazem w książce:-)

F3. Wariant powyższego, \citet

Do zastosowania w sytuacji, kiedy nie można umieścić odsyłaczy en-block w nawiasach (czyli zastosować polecenie \citep).

W licznych przeglądach podjęto wiele prób krytyki i oceny stosowanych podejść badawczych, por. Orlikowski i Baroudi (1991), Galliers (1992), Benbasat i Zmud (1999), Vessey i inni (2002), Mingers (2003), Palvia i inni (2004).


W~licznych przeglądach podjęto wiele prób
krytyki i~oceny stosowanych podejść
badawczych,
por. \citet{OrlikowskiBaroudi91,Galliers1992,BenbasatZmud99,VesseyGlass2002,Mingers2003,PalviaEtAl2004}.

Uwaga: ta forma wydaje się zbędna(?). Zawsze można cytat umieścić w nawiasie czyli w formie F2).

F4. W tekście z odmianą nazwisk autorów, \citeyearpar

przez Ajzena i Fishbeina (1975) na gruncie psychologii społecznej teorii uzasadnionego...


przez Ajzena i~Fishbeina~\citeyearpar{FishbeinAjzen1975} na gruncie psychologii
społecznej teorii uzasadnionego

W przeglądach Schepersa i Wetzelsa (2007), Kinga i He (2006) oraz Yousafzai i~innych~(2007b) testowano


W~przeglądach Schepersa i~Wetzelsa~\citeyearpar{SchepersWetzels2007},
Kinga i~He~\citeyearpar{KingHe2006} oraz
Yousafzai i~innych~\citeyearpar{ShumailaetAl2007b}
testowano

Uwaga: Książka Chowa (Ekonometria, PWN, Warszawa 1995) tak została zredagowana, że stosowane są wyłącznie odsyłacze typu F4.

Formy nieregularne:-)

działania będą akceptowane na tak lub nie przez ważne dla tej jednostki osoby'' (por. Ajzen, 1991, s. 302 za Venkateshem i Davisem, 2000, s. 187).


działania będą akceptowane na tak lub nie przez ważne dla tej
jednostki osoby'' por.~\citealp[s.~302]{Ajzen1991}
za Venkateshem i~Davisem,~\citeyear[s.~187]{VenkateshDavis00}).

Aksjomat Przechlewskiego

Odsyłacze typu F1--F4 można zawsze zredukować do postaci F1 i F4. Tak zredagowane są przykładowo książki: Konarski, Modele równań strukturalnych, PWN, Warszawa 2009; Brzeziński, Metodologia badań psychologicznych, PWN, Warszawa 2004; Gatnar i Walesiak, Analiza danych jakościowych i symbolicznych z wykorzystaniem pakietu R, CH Beck, Warszawa 2011.

Przykłady odnośników autor-rok podane przez Osuchowską (Poradnik redaktora i autora, Wydawnictwo Polskiego Towarzystwa Wydawców Książek, Warszawa 1988, s. 174) także ograniczają się do postaci F1 i F4.

czwartek, 24 maja 2012

Wycieczka do Berlina

Wyjechaliśmy 1. maja a wróciliśmy 5. maja. Czerwoną kreską zaznaczona (była) granica między Berlinem Wschodnim a zachodnim. Jak widać zwiedzaliśmy głównie dawne DDR:


Pokaż Berlin2012 na większej mapie

Ślad w Berlinie jest poprzerywany bo korzystaliśmy często z S-bahna/U-bahna albo wchodziliśmy do budynków z naprawdę solidnym dachem (muzea, Deutscher Dom, itp.).

(Nb. Całodzienny grupowy bilet umożliwiający korzystanie z komunikacji publicznej w Berlinie to 15 EUR dla bodajże maksimum 5 osób.)

poniedziałek, 21 maja 2012

Wycieczka z Damnicy do Lęborka

W sobotę pojechałem SKMką do Damnicy (15 PLN) a stąd już rowerem przez Dębnicę Kaszubską i Czarną Dąbrówkę do Lęborka. Głównym celem (oprócz rowerowania) było odwiedzenie poniemieckich cmentarzy w Damnicy, Lubuniu, Dobieszewie, Dobrej, Gogolewie i Gogolewku.

Usiłując dostać się do Lubunia od strony Dębnicy ugrzęzłem beznadziejnie na piaszczystych drogach i zmarnowałem tutaj sporo czasu. Wracając z Lubunia -- w akcie desperacji -- usiłowałem poszukać innej drogi -- co nie było dobrym pomysłem i nie tylko skończyło się nadłożeniem kilku kilometrów ale nawet forsowaniem strumienia. Z Lubunia do Dębnicy chyba nie ma możliwości dojechania droga utwardzoną -- a jeżeli, to strasznie naokoło!

Cmentarzy w Dobrej i Gogolewku nie odszukałem, bo i tak wycieczka się przeciągnęła i obawiałem się czy zdążę na powrotny pociąg w Lęborku.

Na koniec został powrót SKMką w wagonie dla rowerów w nieprzyjemnym towarzystwie palących, pijących piwo, słuchających głośnej muzyki typu disco polo i przeklinających prostaków. Przypomiał mi się Al Sieber, Chief of Scouts (grany przez Roberta Duvalla) z filmu Geronimo: Amerykanska legenda: ,,Must be Texans... the lowest form of white man there is''1. Tylko zamiast Texans (Teksańczycy) podstawiłem Kaszub.

Ślad jest poniżej:


Pokaż Damnica-Lębort(trk) na większej mapie

1To muszą być Teksańczycy...najniższa forma białego człowieka

piątek, 18 maja 2012

Grube greckie litery nie są składane po dołączeniu qtxmath/pxtmath

Już wiem, że pakiety txfonts/pxfonts nie są najwyższej jakości. Teraz się okazało, że zalecane (zapomniałem tylko przez kogo:-) jako uzupełnienie pakiety qtxmath/pxtmath też zawierają błędy:


%& --translate-file=il2-pl
\documentclass{article}
\usepackage{amsmath,bm}
\usepackage[T1]{polski}
\usepackage{txfonts}
\usepackage{tgtermes,qtxmath}
\begin{document}
$\Omega \mathbf{\Omega} $
\end{document}

Gube greckie litery są zamieniane na litery łacińskie. Nawet nie chce mi się sprawdzać czemu bo pakiet qtxmath/pxtmath nie zawiera plików źródłówych, z których są generowane fonty tfm/vf. Nie idzie też tych źródłowych plików nigdzie znaleźć.

Po usunięciu qtxmath skład jest poprawny. Z tego co mi się obiło o uszy qtxmath/qpxmath miało poprawiać pakiety txfontspxfonts, ale jak widać nie do końca.

środa, 16 maja 2012

Sheevaplug half anniversary

My tiny server running on Debian/SDHC card/Sheevaplug has reached 183 days of uptime today.

Rzecz o propagandzie nie o ekonomii

W cenionym organie propagandowym pn. Głos Cadyka felieton uznanego propagandzisty J. Żakowskiego nt. długu, pn. Co się liczy. Tekst przeczytałem nie dlatego, że jest ciekawy merytorycznie (wręcz przeciwnie -- od strony merytorycznej jest to 100% bełkot -- jak to w Głosie Cadyka zwykle bywa), ale ponieważ jest to modelowy przykład prostych technik propagandowych.

Zastosowana manipulacja sprowadza się do 4 punktów:

  1. Ustawienie przeciwnika pod właściwym kątem. We wstępie Żakowski konsekwentnie używa nieokreślonego terminu dług zamiast dług publiczny pisząc nt. licznika długu publicznego L. Balcerowicza. Bynajmniej nie jest to przypadek albo niechlujstwo, ponieważ:

  2. Polemika z ustawionym pod właściwym kątem przeciwnikiem. Zamiana konkretnego pojęcia dług publiczny na bliżej nieokreślony dług jest wstępem do zasadniczej manipulacji, mianowicie: wprowadzenia zyliona różnych pojęć typu dług demograficzny, dług infrastrukturalny, itp. Oczywiście te ,,inne długi'' są dużo ważniejsze od ,,długu Balcerowicza''. [Nawiasem mówiąc: ,,Długi Żakowskiego'' nie są żadnym długiem ale (przyszłymi) korzyściami albo kosztami, czyli zupełnie innymi kategoriami ekonomicznymi.]

  3. Oczywista konkluzja. Ponieważ ,,dług Balcerowicza'' to mały pikuś wobec ,,długów Żakowskiego'' należy zapewne ,,stłuc termometr bo nie mierzy tego co trzeba.''

  4. Przypomnienie jednego z kanonów wiary (dla utrwalenia). Na koniec dowala komu trzeba czyli PiSowi pisząc że wtedy rządy były populistyczne a teraz nie są co jest jeszcze jednym powodem żeby stłuc termometr. [Za tych nie-populistycznych rządów dług znakomicie wzrósł nota bene, ale z aksjomatami się nie dyskutuje więc kto jest populistą a kto nie jest nie trzeba nawet podpierać żadnym wywodem -- nawet takim jak przeprowadzony wyżej w punktach 1--3].

sobota, 10 marca 2012

Czarny koń z Redmond

System Windows do 2015 r. zdobędzie 20% rynku smartfonów i ponad 10% tabletów -- prognozują analitycy z firm Gartner i IDC. Czarnym koniem w branży ma być nowa platforma Microsoftu. Windows 8 zmieni oblicze branży IT powiedział ,,Rz'' pan z MSC.

System MS w ciągu roku znajdzie się w pierwszej trójce[...] dodaje w rozmowie z ,,Rz'' pan z firmy sprzedającej oprogramowanie antywirusowe (czyli produkt komplementarny).

Dziś zaś w Rzeczpospolitej (,,Rz'') felieton też na ten temat. Równie merytoryczny i kończący się bezsensownym (z punktu widzenia teorii ekonomicznych i stanu faktycznego) apelem: Wypada kibicować Microsoftowi, bo choć ciąży na nim odium monopolisty na rynku oprogramowania dla komputerów osobistych, to jednak daje on szansę na przełamanie dominacji Google'a i Apple'a na rynku oprogramowania dla smartfonów i tabletów.

Zapewne dalszego tego typu dzieła w druku...

Wygląda to wszystko na teksty ordynarnie sponsorowane przez MSC (aka MałoMiękkiego). Będzie świetnie zapewniają ludzie z MSC albo firmy zależne (sprzedawca antywirusów). A będzie tak jak z Bingiem -- gównianą wyszukiwarką, którą MSC usiłował dogonić Google'a, tyle że jedyną strategią był marketing jaka to ona jest wyjątkowa.

BTW: Decydujący (bo jedyny) argument Windows 8 będzie wyglądał tak samo na PC i smartfonie więc użytkownicy zapewne chętniej....itd. No na pewno: rower, samochód i samolot powinien być obsługiwany identycznie. Taki dajmy na to kpt. Wrona z pewnością wolałby baranią kierownicę a'la Eddy Merckx albo odwrotnie Cancellara o niczym nie marzy tylko o autopilocie i wolancie.

No dobra pośmialiśmy się a teraz czemu kibicowanie MSC jest bezsensowne?

Tak jak wyżej wspomniano można to wiarygodnie objaśnić na gruncie elementarnych teorii ekonomicznych. Przyjrzyjmy się poniższemu diagramowi:

Commodity stack
Komodyzacja IT a strategia rynkowa wybranych producentów oprogramowania

Upraszczając w branży IT można zarabiać na sprzedaży sprzętu, oprogramowania infrastrukturalnego, oprogramowania middleware, aplikacji oraz usług. Google sprzedaje tylko usługi, resztę traktuje jako półprodukt, którego koszt winien być możliwie najniższy (warstwa utowarowiona na wykresie). MSC praktycznie nie sprzedaje usług: 100% przychodów firmy to sprzedaż systemu operacyjnego i oprogramowania biurowego. Samo kibicowanie nic nie da jeżeli życie delikwenta zależy od tego ile sprzeda kopii czegoś co tak w ogóle jest warte zero (linux/android).

Tu są szersze wyjaśnienia, ale w języku. O tym samym pisze Nicholas G. Carr w artykule IT Doesn't Matter. Jest to dużo bardziej znany tekst, bo opublikowany w Harvard Business Review, ale jednocześnie dzięki temu niedostępny bezpłatnie (można oczywiście zaleźć via Google, ale to będzie illegal kopia).