2016-01-28 грозния hack, който контролира лампите на фасата
Thursday, January 28th, 2016Кодът, който пиша е грозна работа и пълен с hack-ове. Явно така ми харесва :)
Това е кодът, който контролира лампите по фасадата на лаба. Потрил съм малко от от вътрешната информация в него, като просто исках да се спра на няколко забавни неща в него.
Редове 11-18 се занимават с това да сменят статуса на лампите. Това, което правят е просто да сменят статуса на релетата на netcontrol-а, id-тата са от 13 до 15 включително (което отговаря на релета от 5 до 7, втория set в устройството).
Редове 20-39 се занимават с взимането на текущия state на системата:
– ред 23 взима дали е ден или нощ, от една малко patch-ната версия на sunwait. Сметката е сравнително проста, има я описана на доста места и се оказа един от най-лесните начини. (очаквах да има директно инструмент в debian, дето да ми го каже, но не открих такъв)
– ред 24 взима дали лампите са светнати, като взима статуса на едно от релетата. Това е малко некадърно, понеже поглежда дали е светната само една от лампите, но ме мързи да измисля по-приличен начин, който да лови неконсистентно светнати лампи. Също така това може да се направи доста по-човешко, без cut и awk.
– редове 26-29 питат контрола на входната врата дали е заключена или не (системата е описана във wiki-то на лаба).
– и редове 31-37 проверяват дали trigger-ът за форсиране на светването на лампите е вдигнат (който е един файл в /tmp)
Редове 41-44 са функция за печат на текущия статус, в общи линии за debug-ване.
Редове 47-53 инициализират един пакетен unix domain socket, който е в общи линии нещо като UDP socket – лесен начин за получаване на отделни съобщения. Инициализираме го за получаване, връзваме го във файловата система и го правим nonblocking.
На ред 56 ни започва главния цикъл.
В началото на цикъла се възползваме от socket-а (редове 57-61), като изчакваме или да се появи нещо на socket-а, или 60 секунди, което се случи по-рано. В първоначалната версия socket-ът го нямаше и имаше просто sleep(60), но така се налагаше да се изчака всеки път sleep-а, преди да се промени нещо. Така е възможно когато fauna-та получи информация, че вратата е отключена, да форсира демона да препровери състоянията и да светне лампите.
Тук може четенето от socket-а да се прави, докато не остане нищо в него, за да можем да се предпазим от DoS-ване, заедно с някакъв минимален timeout.
Нататък (редове 63-66) взимаме текущото състояние и dump-ваме малко информация.
На редове 68-70 правим проверка дали спрямо предишното състояние се е променил статусът на ключалката, и ако се е случило, отбелязваме кога. Това ни помага малко по-нататък.
Редове 73-84 хващат моментите, в които лампите са включени:
– Ако е ден и не сме форсирани от trigger-а, гасим лампите;
– Ако е нощ, вратата е заключена, не е вдигнат trigger-а и са минали 15 минути от заключването, гасим лампите. Така човек може да си тръгне спокойно от лаба и да не се пребие в тъмницата, като му угаснат лампите веднага като заключи.
Редове 86-97 обработват ситуацията, когато лампите са изключени:
– Ако trigger-ът е вдигнат, палим лампите;
– Ако е нощ и вратата е отключена (т.е. има хора в лаба), палим лампите.
Системата е кратка, цялата е един hack и работи прекрасно. Интегрира се лесно със съществуващите друг системи в лаба и ни дава още една доста полезна функционалност, и ни спестява да се сещаме да включваме лампите, когато навън е тъмно и railsgirls имат да идват към лаба :)