Итак, в поисках возможных решений, как таки заставить ноутбук быть человечнее, я даже создал тему на ЛОРе и в ЖЖ ru_linux.
Помощь зала и гугла дала возможность еще кое-что добавить.
Во-первых, для того, чтобы парковать головки HDD при падении, надо поставить демон hpfall. Настраивается он в файле /etc/conf.d/hpfall, в котором указано, на каких HDD (/dev/sdX) парковать головки при падении. Вроде работает.
Во-вторых, на просторах БХ найден скрипт, позволяющий менять ориентацию экрана при наклоне ноутбука:
while true; do
sleep 2
POS=`cat /sys/devices/platform/lis3lv02d/position | sed -e 's/(\([-0-9]\+\).*/\1/'`
if [ $POS -ge 500 ]; then
xrandr --output LVDS --rotate left
elif [ $POS -le -500 ]; then
xrandr --output LVDS --rotate right
else
xrandr --output LVDS --rotate normal
fi
done
Помониторив /sys/devices/platform/lis3lv02d/position, я обнаружил, что система координат датчика - правовинтовая. Ось X смотрит влево, Y - на тебя, Z - вверх. Сначала я подумал, что координаты ориентации есть проекции некоторого вектора на эти оси. Длина этого вектора непостоянна (видимо, квантователь велик), но примерно она составляет 1150. Вектор этот ориентирован строго перпендикулярно клавиатуре. Таким образом, теоретически даже можно определить угол наклона бука.
ОК, пробуем. А поможет в этом как всегда Octave.
Вот так можно вытащить системные данные в переменные X, Y, Z:
function [X Y Z] = AccelCoords()
% [X Y Z] = AccelCoords()
% возвращает координаты с акселерометра
%
[st out] = system("cat /sys/devices/platform/lis3lv02d/position | sed -e 's/(//' -e 's/)//' -e 's/,/ /g'");
if(st == 0)
coords = sscanf(out, "%d %d %d");
X = coords(1);
Y = coords(2);
Z = coords(3);
else
X = nan; Y = nan; Z = nan;
endif
endfunction
А вот эта функция измеряет углы наклона ноутбука в плоскостях ZY и ZX относительно вертикали (положительное направление - как обычно, против часовой стрелки в сторону положительного направления оси Y или X):
function [ZY ZX] = AccelAngle()
% [ZY ZX] = AccelAngle()
% возвращает углы наклона бука в плоскостях ZY и ZX
%
[X Y Z] = AccelCoords();
if(isnan(X))
ZY = nan; ZX = nan;
else
ZY = atan2(Y, Z) * 180. / pi;
ZX = atan2(X, Z) * 180. / pi;
endif
endfunction
Помониторив вот такой строчкой:
i=0;while(i++<60);[a b]=AccelAngle();printf("ZY=%g,ZX=%g\n",a,b);fflush(1);endwhile
я обнаружил, что определяется положение довольно сносно, с точностью около 1°. Вот, что получается, когда бук просто стоит:
ZY = 0, ZX = 0.924045
ZY = 0, ZX = -0.924045
ZY = 0, ZX = 1.84761
ZY = 0, ZX = 1.84761
ZY = 0, ZX = 0.939191
ZY = -0.924045, ZX = 0
ZY = 0.924045, ZX = 0
ZY = 1.84761, ZX = 0
ZY = 0.924045, ZX = 0.924045
ZY = 0.90938, ZX = 0.90938
ZY = 0, ZX = 0
…
Т.е., судя по всему, АЦП у акселерометра восьмибитный, а шумит он (акселерометр) довольно прилично.
Итак, в первом приближении мне надо использовать угол в плоскости ZY. После некоторого количества проб и ошибок, я родил такой скрипт:
#!/bin/bash
while true; do
sleep 1
cat /sys/devices/platform/lis3lv02d/position | sed -e 's/(//' -e 's/)//' -e 's/,/ /g' | while read x y z; do
echo "x=$x, y=$y, z=$z"
if [ "$z" -ge 0 ]; then
if [ "$y" -ge 800 ]; then
xrandr --output LVDS1 --rotate right
elif [ "$y" -le -800 ]; then
xrandr --output LVDS1 --rotate left
else
xrandr --output LVDS1 --rotate normal
fi
elif [ "$z" -ge -600 ]; then
if [ "$y" -le 800 ]; then
xrandr --output LVDS1 --rotate left
elif [ "$y" -ge -800 ]; then
xrandr --output LVDS1 --rotate right
fi
else
xrandr --output LVDS1 --rotate inverted
fi
done
done
Кручу-верчу ноутбук, а ориентация экранчика остается удобочитаемой. Класс!!!
Запихал этот скрипт в автостарт IceWM. Все отлично!
В-третьих, заставить веб-камеру работать в нормальном режиме можно (как я об этом сразу не подумал):
mplayer tv:// -tv driver=v4l2:width=1280:height=720
Вот с управлением питания wifi у меня вышла незадача. Напрямую - ругается:
iwconfig wlan0 power off
Error for wireless request "Set Power Management" (8B2C) :
SET failed on device wlan0 ; Operation not supported.
Установил rfkill. Похоже, при помощи него можно делать "софтовую блокировку". Правда, я не понял: отключает ли она питание. Судя по выхлопу iwconfig, питание не отключается: происходит то же самое, что и при вызове iwconfig wlan0 txpower off, т.е. только лишь отключается питание на передачу.
В общем, с wifi я пока так и не разобрался.