воскресенье, 25 апреля 2010 г.

Настройка резкости web-камеры

Жила-была у меня веб-камера вот такая
Bus 002 Device 007: ID 046d:08d7 Logitech, Inc. QuickCam Communicate STX

Обзавелся я ею, когда писал систему документооборота с модулем поддержки веб-камер. Вот возникло желание поиграться с девайсом - поглядеть, что можно получить, если разобрать и подстроить фокусировку. Что касается воспроизведения видео, то mplayer у нас уже работает с V4l2 (пару лет назад не работал и я держал в своем репозитории mplayer, собранный с V4l). Команда просмотра, соответственно, будет такой:
mplayer tv:// -tv driver=v4l2:width=640:height=480:device=/dev/video1

Разобрать было несложно, достаточно снять кнопку сбоку на корпусе и выкрутить единственный винтик, скрывающейся в колодце под этой кнопкой. Подкрутил на пару оборотов положение линзового блока (приблизил к матрице). Результат мне вполне понравился - на расстоянии от от полуметра до метра самое то.

Upd.
Вот так можно вести запись с камеры наблюдения (длительность записи 1 минута):
$ mencoder tv:// -tv driver=v4l2:width=320:height=240:device=/dev/video1:noaudio -ovc lavc -lavcopts vcodec=mpeg4:mbd=1:vbitrate=120 -o webcam.avi -ofps 15 -endPos 00:01:00

Вот что получается:
$ ffmpeg -i webcam.avi 2>&1 | grep -i duration
  Duration: 00:01:00.06, start: 0.000000, bitrate: 140 kb/s

$ file webcam.avi 
webcam.avi: RIFF (little-endian) data, AVI, 320 x 240, ~15 fps, video: FFMpeg MPEG-4

$ ls -lh
1,1M

Ставим в cron на запуск каждый час с именем файла вида "2010-09-01 12:00:00" и получаем готовый архив видеонаблюдения.

Ссылки:

Ubuntu Documentation > Community Documentation > Webcam

Конвертация видео вручную

http://forum.sharereactor.ru/showthread.php?t=163415

http://mydebianblog.blogspot.com/2007/08/blog-post_8710.html

Как ускорить или замедлить видеоролик

Скрипты для mapserver: mapinfo.py и mapdraw.py

Скрипты давно уже выложены, но приведу еще и здесь, для гарантии, что не потеряются. Реализация на питоне, поскольку именно в питоне лучшая поддержка модуля mapscript.

mapinfo.py
#!/usr/bin/python
# This program comes with ABSOLUTELY NO WARRANTY.  This is free software, and
# you are welcome to redistribute it under certain conditions.  
# See the GNU General Public Licence for details.
# Copyright (C) 2007, Alexey Pechnikov

import sys
import mapscript 

def Usage():
    print 'Usage: map.py [-extent    ] -conf  [-point  ] [-width ] [-height ]'
    sys.exit(1)

in_file  = None
extent   = None
point    = None
width    = None
height   = None

args = sys.argv
arg = args.pop(0)
while len(args) > 0:
    arg = args.pop(0)

    if arg == '-extent':
        if len(args) < 3:
            Usage()
        else:
            minx = float(args.pop(0))
            miny = float(args.pop(0))
            maxx = float(args.pop(0))
            maxy = float(args.pop(0))
            extent = 1

    elif arg == '-point':
        if len(args) < 2:
            Usage()
        else:
            point_x = float(args.pop(0))
            point_y = float(args.pop(0))
            point = 1

    elif arg == '-width':
        if len(args) < 1:
            Usage()
        else:
            width_px = int(args.pop(0))
            width = 1

    elif arg == '-height':
        if len(args) < 1:
            Usage()
        else:
            height_px = int(args.pop(0))
            height = 1

    elif arg == '-conf':
        if len(args) < 1:
            Usage()
        else:
            in_file = args.pop(0)

    else:
        Usage()

if in_file is None:
    Usage()

mf = mapscript.mapObj(in_file) 

if not extent is None:
    mf.extent.minx = minx
    mf.extent.miny = miny
    mf.extent.maxx = maxx
    mf.extent.maxy = maxy

if not width is None:
    mf.width = width_px

if not height is None:
    mf.height = height_px
    
if not point is None:
    point_geo = mapscript.pointObj();
    point_geo.setXY (point_x, point_y);
    mf.queryByPoint (point_geo, mapscript.MS_SINGLE, 5);

for i in range(mf.numlayers):
 layer = mf.getLayer(i)
 numResults = layer.getNumResults()
 if numResults > 0:
  layer.open()
  results = layer.getResults()
  for j in range(numResults):
   result = results.getResult(j)
   shape = layer.getFeature(result.shapeindex, result.tileindex)
   numItems = layer.numitems
   print 'array set ident_layer { map_name {',mf.name, '} layer_name {',layer.name,'} ', \
    'layer_title {', layer.getMetaData('LYRNAME'), '} }'
   print 'array set ident_fields { '
   for k in range(numItems):
    print '{',layer.getItem (k),'}'
    print '{',shape.getValue(k),'}'
   print '}'

  layer.close()

mapdraw.py
#!/usr/bin/python
# This program comes with ABSOLUTELY NO WARRANTY.  This is free software, and
# you are welcome to redistribute it under certain conditions.  
# See the GNU General Public Licence for details.
# Copyright (C) 2007, Alexey Pechnikov

import sys
import mapscript 

def Usage():
    print 'Usage: map.py [-extent    ] -conf  -image  [-point  ] [-width ] [-height ]'
    sys.exit(1)

in_file  = None
out_file = None
extent   = None
point    = None
width    = None
height   = None

args = sys.argv
arg = args.pop(0)
while len(args) > 0:
    arg = args.pop(0)

    if arg == '-extent':
        if len(args) < 3:
            Usage()
        else:
            minx = float(args.pop(0))
            miny = float(args.pop(0))
            maxx = float(args.pop(0))
            maxy = float(args.pop(0))
            extent = 1

    elif arg == '-point':
        if len(args) < 2:
            Usage()
        else:
            point_x = float(args.pop(0))
            point_y = float(args.pop(0))
            point = 1

    elif arg == '-width':
        if len(args) < 1:
            Usage()
        else:
            width_px = int(args.pop(0))
            width = 1

    elif arg == '-height':
        if len(args) < 1:
            Usage()
        else:
            height_px = int(args.pop(0))
            height = 1

    elif arg == '-image':
        if len(args) < 1:
            Usage()
        else:
            out_file = args.pop(0)

    elif arg == '-conf':
        if len(args) < 1:
            Usage()
        else:
            in_file = args.pop(0)

    else:
        Usage()

if in_file is None:
    Usage()

if out_file is None:
    Usage()

mf = mapscript.mapObj(in_file) 

if not extent is None:
    mf.extent.minx = minx
    mf.extent.miny = miny
    mf.extent.maxx = maxx
    mf.extent.maxy = maxy

if not width is None:
    mf.width = width_px

if not height is None:
    mf.height = height_px
    
if not point is None:
    point_geo = mapscript.pointObj();
    point_geo.setXY (point_x, point_y);
    mf.queryByPoint (point_geo, mapscript.MS_SINGLE, -1);

img = mf.drawQuery() 
img.save(out_file) 

Работа с bluetooth

Приведена подборка советов из моих заметок примерно 5-ти летней давности. Может, кто всплакнет над ними на досуге, вспомниная времена былые. Впрочем, для встраиваемых устройст кое-что из описанного ниже по-прежнему может быть актуально.

OBEX
Устанавливаем пакет для работы с OPEN OBEX
apt-get install obexftp
После этого перезапускаем bluez-utils
/etc/init.d/bluez-utils restart
Теперь мы можем, например, получить список всех директорий первого bluetooth-устройства
obexftp -b -l
Или получить список директорий устройства 00:12:62:C0:6E:9E
obexftp -b 00:12:62:C0:6E:9E -l
Следующая команда отправляет mp3-файл /tmp/1/Mihail_Boyarskii_-_Vstrecha_v_puti.mp3 на сотовый телефон
obexftp -b -p /tmp/1/Mihail_Boyarskii_-_Vstrecha_v_puti.mp3
Здесь также можно указать устройство 00:12:62:C0:6E:9E и папку назначения "Memory card" (карта памяти)
obexftp -b 00:12:62:C0:6E:9E --chdir "Memory card" -p /tmp/1/Mihail_Boyarskii_-_Vstrecha_v_puti.mp3
Отметим, что указанный в справке ключ -c не работает. Также предоставляется полезная возможность одной командой загрузить список файлов, например, так:
obexftp -b 00:12:62:C0:6E:9E --chdir "Memory card" -p *.mp3
При отправке на телефон списка файлов разрешение на сохранение файла запрашивается только один раз.
Другие возможные команды и ключи можно посмотреть в справке
man obexftp

Для пересылки приложения J2ME на телефон можно воспользоваться утилитами gammu и wammu
Добавьте следующую строку в sources.list
deb http://debian.cihar.com/ unstable gammu
Установите утилиты
apt-get install gammu wammu
Конфигурационный файл из пакета gammu необходимо поправить следующим образом:
#/home/имя_пользователя/.gammurc
Device=00:12:62:C0:6E:9E
Connection=bluephonet
SyncTime=no
LockDevice=yes
StartInfo=no
Информацию по работе с телефонами Nokia можно получить также
#gammu --help nokia
В ответ получаем следующее
--nokiaaddfile Application|Game file [-readonly]
А теперь можно отправить приложение на телефон командой
gammu --nokiaaddfile Application /mnt/c/work/WTK2.1/apps/FPDemo1/bin/FPDemo1
Аналогично пересылаются игры. Отметим, что название приложения указывается без расширения jar или jad.
Кроме того, указанные утилиты позволяют работать с записной книгой, а также получать доступ к другим функциям телефона.
Если вы хотите удаленно управлять через bluetooth программой xmms, вам понадобится приложение
http://bemused.sourceforge.net/
На телефон для этой цели нужно установить мидлет
http://fred.hexbox.de/bemused/


GPRS
1.Установить поддержку bluetooth и пакет утилит bluez-utils
2.Поправить конфиги в /etc/bluetooth/

В hcid.conf указать скрипт, который перешлет телефону при подключении его pin-код
После строки
# PIN helper
нужно написать
pin_helper /etc/bluetooth/pin;

Файл hcid.conf
#
# HCI daemon configuration file.
#
# $Id: hcid.conf,v 1.3 2002/07/18 18:12:46 maxk Exp $
#

# HCId options
options {
# Automatically initialize new devices
autoinit yes;

# Security Manager mode
# none - Security manager disabled
# auto - Use local PIN for incoming connections
# user - Always ask user for a PIN
#
security auto;

# Pairing mode
# none - Pairing disabled
# multi - Allow pairing with already paired devices
# once - Pair once and deny successive attempts
pairing multi;

# PIN helper
pin_helper /etc/bluetooth/pin;
}

# Default settings for HCI devices
device {
# Local device name
# %d - device id
# %h - host name
name "%h-%d";

# Local device class
class 0x100;

# Default packet type
#pkt_type DH1,DM1,HV1;

# Inquiry and Page scan
iscan enable; pscan enable;

# Default link mode
# none - no specific policy
# accept - always accept incoming connections
# master - become master on incoming connections,
# deny role switch on outgoing connections
#
#lm accept,master;
#
lm accept;

# Default link policy
# none - no specific policy
# rswitch - allow role switch
# hold - allow hold mode
# sniff - allow sniff mode
# park - allow park mode
#
#lp hold,sniff;
#
lp hold,sniff,park;

# Authentication and Encryption
#auth enable;
#encrypt enable;
}

Теперь создаем исполняемый скрипт /etc/bluetooth/pin, где xxxx – PIN-код телефона

Файл pin
#!/bin/sh
echo "PIN:xxxx"

3.Ищем все доступные bluetooth-устройства
hcitool scan
Выбираем MAC-адрес нужного. Дополнительную информацию об устройстве можно (но не необходимо) получить командой
hcitool info [MAC]
4.Определяем список доступных сервисов для выбранного bluetooth-устройства
sdptool browse [MAC]
ищем “Dial-up networking channel”, далее [channel]
5.Присоединяем нужный сервис к любому свободному виртуальному устройству
rfcomm bind [device] [MAC ] [channel]
Список уже подключенных виртуальных устройств и соответствующих каналов можно просмотреть командой
rfcomm show
6.Запускаем pppd для подключения к сети
pppd call bluetooth-gprs

Файл /etc/chatscripts/bluetooth-gprs(стандартный, можно использовать с irda-соединением)
# This chatfile was generated by pppconfig 2.3.2.
# Please do not delete any of the comments. Pppconfig needs them.
#
# ispauth PAP
# abortstring
ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT DELAYED
# modeminit
'' ATZ
# ispnumber
OK "ate1"
OK 'at+cgdcont=1,"IP","internet.mc","",0,0'
OK "atdt*99#"
# ispconnect
CONNECT \d\c
# prelogin

# ispname
# isppassword
# postlogin

# end of pppconfig stuff

Файл /etc/ppp/peers/bluetooth-gprs
lcp-echo-failure 0
lcp-echo-interval 0
debug 10
connect "/usr/sbin/chat -v -f /etc/chatscripts/bluetooth-gprs"
/dev/rfcomm0
115200
crtscts
local
noipdefault
ipcp-accept-local
defaultroute
usepeerdns
novj
nobsdcomp
novjccomp
nopcomp
noaccomp
noauth

Комментарий:
*99# - для сотовых телефонов, отличных от Nokia, может быть другим
internet.mc – точка доступа для оператора Мегафон в центральном регионе

Возможные неисправности и методы их устранения:
1.Нестабильная работа Bluetooth – заменить модуль ядра uhci на usb-uhci
2.hcitool scan после запуска сразу же отвечает, что все хорошо, но ни одно устройство не найдено. В этом случае следует запустить демон /etc/init.d/bluez-utils start


Access point

Recommended:
Install packets with usefull utils
apt-get install ip-route
Use as so:
ip a a 192.168.21.1/24 dev bnep0 brd +
ip a d 192.168.21.2/24 dev bnep0 brd +

1.If bluetooth package not installed jet, install this
apt-get install bluez-utils
2. Adding this section into network interfaces
#/etc/network/interfaces
iface bnep0 inet manual
up ifconfig $IFACE 0.0.0.0 up
up ip a a 192.168.21.1/24 dev $IFACE brd +
down ifconfig $IFACE down
brctl addif br0 $1

3. Replace this string
#/etc/bluetooth/hcid.conf
# lm accept;
lm accept,master;

4. Create directory /etc/bluetooth/pan/ and add this excutable script
#/etc/bluetooth/pan/dev-up
#!/bin/sh
/sbin/ifup $1

Интернет через irda

Просматривая свои архивы, нахожу немало интересного. Например, сабж. Выкладываю здесь, чтобы не хранить еще десятилетие в бэкапах документации :-)

1.Установить поддержку irda и пакет утилит irda-tools
2.Подсоединяем irda-устройство Tekram (в нашем случае подключено к порту ttyS1)
irattach /dev/ttyS1 -d tekram -s
3.Проверяем успешность подключения
cat /proc/net/irda/discovery
4.Запускаем pppd для подключения к сети
pppd call irda-gprs

cat /etc/chatscripts/irda-gprs

# стандартный, можно использовать с bluetooth-соединением
# This chatfile was generated by pppconfig 2.3.2.
# Please do not delete any of the comments.  Pppconfig needs them.
# 
# ispauth PAP
# abortstring
ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT DELAYED
# modeminit
'' ATZ
# ispnumber
OK "ate1"
OK 'at+cgdcont=1,"IP","internet.mc","",0,0'
OK "atdt*99#"
# ispconnect
CONNECT \d\c
# prelogin

# ispname
# isppassword
# postlogin

# end of pppconfig stuff

cat /etc/ppp/peers/irda-gprs

lcp-echo-failure 0
lcp-echo-interval 0
debug 10
connect "/usr/sbin/chat -v -f /etc/chatscripts/irda-gprs"
/dev/ircomm0
115200
crtscts
local
noipdefault
ipcp-accept-local
defaultroute
usepeerdns
novj
nobsdcomp
novjccomp
nopcomp
noaccomp
noauth

VirtualBox на 32-бит системе с 64-бит ядром

Долго ли, коротко ли, а 64-бит архитектуры развиваются и становятся интересными для практического применения. Ядро ветки 2.6.32 вполне прилично работает на нетбуке, так что возникла мысль попробовать 64-бит ядро. Почему именно такая конфигурация? Да очень просто - всегда можно загрузиться в 32-бит ядро и оказаться в хорошо известной 32-бит конфигурации. Почему на нетбуке? Все просто - мне хватает его производительности, а по размерам он меньше ноутбука и практически бесшумен. Пару дней назад, когда я уже сидел с 64-бит ядром, понадобилось запустить VirtualBox. А он запускаться не хочет. Ну, что поделать, значит, пришло время попробовать 64-бит чрут в 32-бит системе с 64-бит ядром. Поставил sid, хотя можно было и squeeze, это не принципиально, поскольку виртуалбокс все равно для ленни собран в репозитории на оффсайте. Плюс сделал скрипт для запуска VirtualBox в чруте:
$ cat /usr/local/bin/virtualbox 
#!/bin/sh

CHROOT=/srv/chroot_amd64

    if test ! -e $CHROOT/dev/.udev; then
        sudo mount -t none /dev $CHROOT/dev/ -o bind
    fi
    if test `ls $CHROOT/proc | wc -l` = "0"; then
        sudo mount -t proc none $CHROOT/proc
    fi
    if test `ls $CHROOT/sys | wc -l` = "0"; then
        sudo mount -t sysfs none $CHROOT/sys
    fi
    if test `ls $CHROOT/home | wc -l` = "0"; then
        sudo mount --bind /home $CHROOT/home
    fi
#    if test `ls $CHROOT/srv | wc -l` = "0"; then
#        sudo mount --bind /srv $CHROOT/srv
#    fi
    if test `ls $CHROOT/tmp | wc -l` = "0"; then
        sudo mount --bind /tmp $CHROOT/tmp
    fi
    if test `ls $CHROOT/var/run/dbus | wc -l` = "0"; then
        sudo mount --bind /var/run/dbus $CHROOT/var/run/dbus
    fi

    echo "Hello to chroot $CHROOT!"
    sudo chroot $CHROOT sh -c "su - veter VirtualBox"
    sleep 10

    if test `ls $CHROOT/var/run/dbus | wc -l` != "0"; then
        sudo umount $CHROOT/var/run/dbus
    fi
    if test `ls $CHROOT/proc | wc -l` != "0"; then
        sudo umount $CHROOT/proc
    fi
    if test `ls $CHROOT/sys | wc -l` != "0"; then
        sudo umount $CHROOT/sys
    fi
    if test `ls $CHROOT/tmp | wc -l` != "0"; then
        sudo umount $CHROOT/tmp
    fi
    if test -e $CHROOT/dev/.udev; then
        sudo umount $CHROOT/dev/
    fi
    if test `ls $CHROOT/home | wc -l` != "0"; then
        sudo umount $CHROOT/home
    fi
#    if test `ls $CHROOT/srv | wc -l` != "0"; then
#        sudo umount $CHROOT/srv
#    fi

    echo "Chroot $CHROOT is unmounted!"
Замечу, что USB-устройства подключаются (благодаря примонтированному /var/run/dbus). Таймаут нужен для того, чтобы успели остановиться некоторые сервисы, запускаемые VirtualBox - иначе не удастся отмонтировать ФС. Профит :-)

суббота, 17 апреля 2010 г.

ASUS EEEPC 1005PE

Решил написать пару слов о сем девайсе, поскольку о нем "ходят слухи тут и там", притом мало соответствующие действительности. Итак, по порядку.

Открываем коробку и достаем девайс. На нем по дефолту установлена виндоус 7, которую я вижу первый раз (а вот с вистой и вовсе познакомиться не довелось, чему я искренне рад). Долго и упорно настраивается при первом запуске, с полчаса примерно. Наконец запустилась, логинюсь. Тормози-и-ит. Проверяю конфигурацию - 2 Гб ОЗУ, винт 250 гиг и довольно шустрый, но все это пропадает втуне, поскольку система весьма задумчива. Из приятного - наконец-то увидело точку доступа с WPA2 без лишних телодвижений. Делаю то, ради чего, собственно, я винду загружал - регистрируюсь в ASUS WebStorage. Вроде как приложение для регистрации для нетбука и сделано, но шрифты страшные, лет 10 назад такие в линуксе иногда попадались, а некоторые "окошки" не влазят на экран (открыл еще несколько предустановленных программ - та же хрень). При первой попытке выдает ошибку, повторяю через час и теперь регистрация проходит успешно и у меня есть логин и пароль для доступа в асусовское "облако". Тут же с дебиан-хоста проверяю доступ, поставив клиент для убунты с сайта асуса - работает. Все, винда готова на закланье, выключаем нетбук.

Ради интереса попробуем и встроенную быструю ОС, которая загружается отдельной кнопкой. Грузится и правда быстро - секунд за 5. Правда, при желании выбрать задачу, скажем, доступ в веб, ждем еще столько же. Точка доступа с WPA2 работает, это приятно. Выходим в инет. Браузер неудобный и медленный - после google chrome плююсь и закрываю побыстрее. Идем в фотоальбом - запускается те же секунд 5. Вставляю SD-карточку из фотоаппарата, тройку секунд жду пока опознается, потом так же медленно и мучительно открываю папки, добираясь до фоток. Превьюшка каждой фотографии размером около 3 Мб строится примерно секунду, это меня начинает всерьез напрягать. Пройдя по паре десятку папок, зарекаюсь пользоваться этим жутким фотоальбомом, но для полноты эксперимента запускаю слайдшоу. И тихо зверею - фотографии очень заметно растянуты по горизонтали. Пытаюсь найти средства это исправить - не нахожу, но замечаю, что и превьюшки так же растянуты. По ходу дела постоянно вылазит сообщение, что фотоальбом сделан на флэш. Мда... Обнаруживаю функцию обновления ПО и обновляюсь - фотографии по-прежнему искажены, зато теперь добавилась куча тормозных эффектов слайдшоу. Выключаю жуткое асусовское творение, которое они выдают за фичу.

А теперь займемся более приятными вещами - установкой дебиана. Качаю свежий инсталлер и образ netinst, пишу на SD-карточку. Отключаю у нетбука в биосе опцию ускорения загрузки и указываю новый порядок загрузки - начинать с внешнего носителя. Инсталлер WPA2 не понимает, подтыкаю эзернет. Винт переразбиваю целиком, удаляя виндоус, скрытый раздел для восстановления и асусовскую недоОС. Делаю разделы по 10 Гб для /, /tmp, /usr, /var, /home и все остальное свободное пространство подключаю в /srv. Своп-раздел не делаю, не нужен он, если потребуется, всегда можно своп-файл в корне создать. При установке компонентов выбираю ноутбук и базовую систему, ядро беру 2.6.32-3. Готово. Ставим пакет eeepc-acpi-scripts, добавляем к нему xorg, lxde, gdm. Грузимся в новорожденный дебиан. Как обычно, ручками настраиваю сеть редактированием /etc/network/interfaces. Ставим google-chrom, mplayer, ksnapshot. Система "летает", видео показывает, музыку играет. Задумавшись о том, что я несовременен и вручную сеть настраивать на нетбуке не бонтон, начинаю гуглить. Оказывается, среда LXDE включает менеджер сети lxnm, но в дебиане его нет. Вики lxde подсказывает альтернативу в виде wicd, который я и ставлю - он тут же сам появляется в автозагрузке, так что после выбора сети и указания ключа сети перезагружаюсь и вайфай работает (свои правки из interfaces уже удалил). Настраиваем трей, добавляя индикатор языка и заряда батареи.



Возникает желание настроить переключение раскладки клавишей CapsLock, т.к. клавиша WIN, которая обычно у меня переключает раскладку, на нетбуке не очень удобна для это цели. Обнаруживаю, что способ настройки клавиатуры изменился - погрепав по /etc, нахожу нужный конфиг:
cat /etc/default/keyboard
...
XKBMODEL="pc105"
XKBLAYOUT="us,ru"
XKBVARIANT=","
#XKBOPTIONS="grp:lwin_toggle,grp_led:scroll"
XKBOPTIONS="grp:caps_toggle,grp_led:scroll"
...
Наконец-то сделали отдельный конфиг, так намного логичнее.

Так-с, теперь о времени автономной работы подумаем. В хроме удаляем флэш-плугин (переименовываю файл /opt/google/chrome/libgcflashplayer.so), меняем политику производительности процессора
sudo cpufreq-set -c 0 -g powersave
sudo cpufreq-set -c 1 -g powersave
# проверяем
cpufreq-info
# вписываем установку нужной политики при загрузке системы
sudo mcedit /etc/init.d/cpufrequtils

Получаем около 8 часов работы от батареи при включенном вайфай. Имхо маловато, но надо будет еще батарею потренировать. Грузится система за 30 секунд от нажатия на кнопку включения и до появления окна с предложением залогиниться, еще пять секунд на ввод логина и пароля и уже открылся рабочий стол.


Upd. В скайпе не работает микрофон, разбираюсь. Нашел по ходу гугления несколько занимательных статеек, вот ссылки:
Ставим Debian Squeeze на ASUS EEE PC 901

А вот и решение проблемы с микрофоном - как выяснилось, я его все-таки не включил, и всего лишь нужно было его активировать:
Подключение микрофона

Здесь про настройку boot booster можно почитать (про установку дополнительного ПО не смотреть - оно не нужно, сейчас уже все "из коробки" работает):
Perfect Ubuntu Jaunty on the Asus eeePC 1005HA (and 1008HA)

Upd.
По непонятной причине "слетает" запоминание и указатель раскладок, разбираться не стал, сделав простейший хак для выставления нужной раскладки и, заодно, запуска gpg-agent:
sudo mcedit /etc/xdg/lxsession/LXDE/autostart

setxkbmap -option grp:switch,grp:caps_toggle,grp_led:scroll us,ru
# starting gpg-agent
eval $(gpg-agent --daemon)

@xscreensaver -no-splash
@lxpanel --profile LXDE
@pcmanfm -d
Теперь порядок.

Upd 2010-08-04. В России летом наступила жара, температура уверенно подбирается к отметке +40 градусов и кулер в нетбуке шумит чертовски громко. Для активизации контроля кулера в debian squeeze понадобилось поправить конфиг grub согласно Fan Control for Asus 1005PE.
Конфиг fancontrol у меня получился такой:
/etc/fancontrol
# Configuration file generated by pwmconfig, changes will be lost
INTERVAL=10
DEVPATH=hwmon0= hwmon1=devices/platform/eeepc
DEVNAME=hwmon0=acpitz hwmon1=eeepc
FCTEMPS= hwmon1/pwm1=hwmon0/temp1_input
FCFANS= hwmon1/pwm1=hwmon1/fan1_input
MINTEMP= hwmon1/pwm1=54
MAXTEMP= hwmon1/pwm1=70
MINSTART= hwmon1/pwm1=0
MINSTOP= hwmon1/pwm1=0
MINPWM= hwmon1/pwm1=0
MAXPWM= hwmon1/pwm1=200
В итоге разницы наблюдаемой в sensors температуры не наблюдаем, а кулер почти все время молчит.

Презентация по HTML5

Эта интерактивная презентация понравилась ясностью и наглядностью, примеры работают и притом вполне "жизненные":
This presentation is an HTML5 website

суббота, 3 апреля 2010 г.

Селективность индексов в SQLite

При разработке больших БД возникает необходимость в использовании множества индексов, но скорость вставки данных при этом падает катастрофически. Проанализировав, пришел к следующему результату - высокоселективный индекс на больших таблицах ведет себя ужасно. То есть, если в таблице 10М записей проиндексировать поле с десятком вариантов значений, это еще ничего, но если значений миллион, то скорость вставки записей снизится на несколько порядков.

Для небольших таблиц рекомендации известны:
Re: Behavior of SELECT queries during transaction

С большими наборами данных все интереснее - в случае единственного индекса потенциально хорошую производительность можно получить при вставке заранее упорядоченного набора записей. Если же индексов много, то даже предварительная подготовка добавляемых записей ничего не даст.

Расширение FTS3 предоставляет другую реализацию индекса - и этот индекс отлично работает с высокоселективными значениями. Зато имеет большие проблемы при выборок низкоселективных значений :-)
sqlite - FTS3 performance oddity

Замечу, что при упорядоченной вставке 1 миллиарда первичных ключей в таблицу скорость вставки снижается всего лишь примерно на 3% - великолепный результат. Но это верно только до тех пор, пока вставляемые записи строго упорядочены.

Улучшение zlib-сжатия для FTS3

Все бы хорошо с zlib-сжатием, но при вставке коротких строк или чисел оверхед получается многократный - сжатая строка в разы больше исходной. В качестве решения я решил не сжимать короткие строки (маньше 80 символов в данный момент), указывая 4-х байтный заголовок такой строки (содержит длину исходной строки, если строка сжата) как FFFFFF. Таким образом, эти строки легко распознаются при распаковке и оверхед минимален.

Замечу, что сначала попытался использовать типы данных - если строку не сжимаю, то возвращаю text, а не blob. На выходе функции compress() получается набор сжатых и несжатых строк. Оверхед меньше, но решение потенциально способно породить сложноуловимые грабли. Как минимум, определить, использовано ли сжатие для записей, станет сложно.

В моем деб-пакете с эскулайт это усовершенствование уже есть, а в fossil-репозиторий пока не добавил.

пятница, 2 апреля 2010 г.

SQLite index performance degradation tests

.schema
CREATE TABLE role
(
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  uid BLOB
);
CREATE INDEX role_uid_idx on role(uid);

Method
10 iterations of the 500 000 inserts:
insert into role (uid) values (uid)

uid=randomblob(1)
$ ./test.tcl
1 7 seconds per iteration
2 7 seconds per iteration
3 7 seconds per iteration
4 7 seconds per iteration
5 7 seconds per iteration
6 7 seconds per iteration
7 7 seconds per iteration
8 7 seconds per iteration
9 7 seconds per iteration
10 7 seconds per iteration

uid=randomblob(8)
$ ./test.tcl
1 7 seconds per iteration
2 8 seconds per iteration
3 9 seconds per iteration
4 10 seconds per iteration
5 11 seconds per iteration
6 12 seconds per iteration
7 13 seconds per iteration
8 13 seconds per iteration
9 14 seconds per iteration
10 15 seconds per iteration


uid=randomblob(16)
$ ./test.tcl
1 7 seconds per iteration
2 10 seconds per iteration
3 12 seconds per iteration
4 14 seconds per iteration
5 18 seconds per iteration
6 44 seconds per iteration
7 118 seconds per iteration
8 206 seconds per iteration
9 215 seconds per iteration
10 404 seconds per iteration

uid=hex(randomblob(16))
$ ./test.tcl
1 9 seconds per iteration
2 12 seconds per iteration
3 23 seconds per iteration
4 139 seconds per iteration
5 280 seconds per iteration
6 501 seconds per iteration
7 632 seconds per iteration
8 779 seconds per iteration
9 898 seconds per iteration
10 957 seconds per iteration

uid=[clock clicks]
$ ./test.tcl
1 7 seconds per iteration
2 7 seconds per iteration
3 7 seconds per iteration
4 7 seconds per iteration
5 7 seconds per iteration
6 7 seconds per iteration
7 7 seconds per iteration
8 7 seconds per iteration
9 7 seconds per iteration
10 7 seconds per iteration

uid="1234567890abcdef"
$ ./test.tcl
1 6.2 seconds per iteration
2 6.5 seconds per iteration
3 6.5 seconds per iteration
4 6.6 seconds per iteration
5 6.6 seconds per iteration
6 6.6 seconds per iteration
7 6.6 seconds per iteration
8 6.6 seconds per iteration
9 6.6 seconds per iteration
10 6.7 seconds per iteration

uid=random()
$ ./test.tcl
1 6 seconds per iteration
2 7 seconds per iteration
3 8 seconds per iteration
4 9 seconds per iteration
5 10 seconds per iteration
6 11 seconds per iteration
7 11 seconds per iteration
8 12 seconds per iteration
9 13 seconds per iteration
10 14 seconds per iteration

(C) Alexey Pechnikov aka MBG, mobigroup.ru