====== shack open/close monitor ======= {{process:shack-heritage-badge.png}} {{tag> project infrastructure shackoperations process hardware software needs-rewrite}} das open/close-monitoring basiert auf der annahme, dass die shack-tuere nur unverschlossen ist, wenn der shack geoeffnet ist. ===== abstract ===== der server erhaelt einen cron-job der alle 2 minuten ein cgi-script auf einem webserver aufruft, das wiederum eine von zwei flag-dateien schreibt. welche flag-datei geschrieben wird, ist abhaengig davon, ob der status "open" oder "closed" uebermittelt wird. die jeweils nicht geschriebene flag-datei wird dabei geloescht. auf dem webserver wird jede minute geprueft, ob diese datei aelter als 3 minuten ist, in diesem falle wird sie geloescht. das cgi-script gibt bei aufruf ohne parameter ein pixel als gif zurueck, das abhaengig von der existenz der flagdateien gruen (vorhanden, offen), rot (vorhanden, closed) oder grau (fehlen) ist. dieses pixel wird vergroessert aus der passenden wiki-seite heraus aufgerufen weiter kann der status als text auf deutsch und english abgefragt werden die anzeige ist somit auf 2 minuten genau ===== trafficabschaetzung ===== ein simpler http-request der form GET /sopen/******************************** HTTP/1.0\r\nHost: shackspace.de\r\n\r\n ergibt: - 899 Byte/Rq. \\ - 647.280 KiB/d \\ - 20.065680 MiB/m \\ fuer wurschtkaes 20mb im monat hat man den status auf 2 minuten genau. messung: exemplarischer traffic mit tcpdump beobachtet, 32 '*' in der uri ===== details & implementierung ===== ---- **Dieser Teil ist obsolet und benötigt einen Neuschrieb** ---- in der tuerzarge ist in die oeffnung fuer den schliessriegel ein reedkontakt mit expoxidharz eingeklebt. in den schliessriegel ist ein magnet eingearbeitet. vom reedkontakt fuehrt eine zweidrahtleitung zur naechsten cat5-dose im lager. das andere ende der leitung ist mit einem cisco-consolekabel ueber einen usb-rs232-adaper mit einem rechner verbunden. benutzt werden dabei nur zwei adern, sie verbinden RTS und DSR (an sich: beliebige statusleitungen, ausgenommen RI, weil nicht durch das ciscokabel gefuehrt), wenn die tuer abgeschlossen ist. wenn die tuere offen ist, bleiben die leitungen unverbunden. das programm ''/usr/local/app/shackdoor/shackdoor'' setzt RTS und prueft daraufhin DSR. je nach stand des schalters ergibt sich das eine oder andere ergebnis. da aufgrund der etwa 40-50 m leitungslaenge und des bei geoeffneter tuere hohen abschlusswiderstands die signalqualitaet schlecht ist, laesst sich die offene tuer nicht immer eindeutig erkennen (und seltsamer weise seit januar 2015 auch der geschlossene kontakt nicht mehr). also findet die abfrage einfach 20 mal statt. das ging schneller, als an der verkabelung weitere schaltmittel anzubringen. #include #include #include #include #include #include #include #include #define STIME 3000000 void SetRTS(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); currstat |= TIOCM_RTS; ioctl(fd, TIOCMSET, &currstat); } void ResetRTS(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); currstat &= ~TIOCM_RTS; ioctl(fd, TIOCMSET, &currstat); } void SetDTR(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); currstat |= TIOCM_DTR; ioctl(fd, TIOCMSET, &currstat); } void ResetDTR(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); currstat &= ~TIOCM_DTR; ioctl(fd, TIOCMSET, &currstat); } void ClearSerPins(int fd) { int currstat = 0; ioctl(fd, TIOCMSET, &currstat); } int GetRI(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); return((currstat & TIOCM_RNG)?1:0); } int GetCD(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); return((currstat & TIOCM_CAR)?1:0); } int GetDSR(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); return((currstat & TIOCM_DSR)?1:0); } int GetCTS(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); return((currstat & TIOCM_CTS)?1:0); } int GetSerStat(int fd) { int currstat; ioctl(fd, TIOCMGET, &currstat); return(currstat); } int main (int argc, char** argv) { int i, stat; int fd = 0; if ( argc != 2 ) { printf("usage: %s device\n",argv[0]); exit(1); } if (( fd = open(argv[1], O_RDWR | O_NDELAY )) < 0 ) { printf("can't open device '%s'\n",argv[1]); exit(2); } SetRTS(fd); stat = GetSerStat(fd); if ( stat & TIOCM_DSR) puts("DSR "); printf("\n"); /* debug for (;;) { usleep(100000); stat = GetSerStat(fd); if ( stat & TIOCM_RNG) puts("RI "); if ( stat & TIOCM_CAR) puts("CAR "); if ( stat & TIOCM_DSR) puts("DSR "); if ( stat & TIOCM_CTS) puts("CTS "); printf("\n"); } */ close(fd); return(0); } die tuerstatus-kvm prueft jede minute per cronjob den zustand des tuerkontakts: 0-59/1 * * * * nobody /usr/local/app/shackdoor/sopen-client 2>&1 | logger sopen-client fragt den zustand der tuere ab und setzt einen http-request an shackspace.de ab, der den zustand uebermittelt: #!/bin/bash set -u #old# closed loop (=closed door) is more reliable to detect. #old# so, if there are $CHECKS checks in favour to the door #old# being closed, we might assume that this is the case. # as of 2015-01 things got fishy # so we just look who got the most votes # DEV=/dev/ttyUSB0 if [ ! -e "$DEV" ]; then logger -t "sopen-client" "'$DEV' missing: $( ls -ld /dev )" exit fi CHECKS=20 QUOTA=$(( $CHECKS / 2 )) FLAG=0 for i in $( seq 1 $CHECKS ); do if [ x`/usr/local/app/shackdoor/shackdoor /dev/ttyUSB0` = xDSR ] ; then FLAG=$(( $FLAG + 1 )) fi done echo FLAG=$FLAG if [ "$FLAG" -lt "$QUOTA" ] ; then echo -e -n "GET /sopen/open/************ HTTP/1.0\r\nHost: shackspace.de\r\n\r\n" | nc shackspace.de 80 else echo -e -n "GET /sopen/closed/************ HTTP/1.0\r\nHost: shackspace.de\r\n\r\n" | nc shackspace.de 80 fi === trouble === die erkennung der dsr-leitung funktioniert nicht in jedem falle zuverlaessig, insbesondere der zustand "tuere offen", bei dem die Leiterschleife geoeffnet ist, ist verrauscht, weil hochohmig. das sieht dann so aus: {{http://shackspace.de/projects/chris/shack-status/shackstatus-signal.gif}} die leitungslaenge macht das sicher nicht besser. daher wird der zustand mehrfach abgefragt und eine mehrheitsentscheidung getroffen. das usb-rs232-dingsy faellt manchmal logisch vom host und braucht dann einen powercycle (aus- und wieder einstecken). deshalb prueft sopen-client extra, ob /dev/ttyUSB0 da ist. ==== auf shackspace.de ==== ''sopen'' ist ein CGI und wurde als ''/var/www/shackspace.de/htdocs/sopen'' abgelegt: #!/usr/bin/perl -Tw # Thu Nov 29 17:52:13 CET 2012, chris # Wed Jan 7 11:35:36 CET 2015, chris # - added three-state display # # - Doku hier: # - http://shackspace.de/wiki/doku.php?id=shack_open_close_monitor use strict; my $uri_c = "/sopen/closed/**********"; my $uri_o = "/sopen/open/**********"; my $uri_text_de = "/sopen/text/de"; my $uri_text_en = "/sopen/text/en"; my $uri_img_png = "/sopen/img/png"; my $uri_img_gif = "/sopen/img/gif"; my $uri_imgtxt_png = "/sopen/imgtxt/en/png"; my $uri_imgtxt_gif = "/sopen/imgtxt/en/gif"; my $statfilename = "/var/run/sopen/stat"; my $trackfilenameon = "/var/run/sopen/track-on"; my $trackfilenameoff = "/var/run/sopen/track-off"; # strip trailing ?... my $request_uri = (split(/\?/,$ENV{REQUEST_URI}))[0]; # korrekte uri setzt flag file $request_uri eq $uri_o and do { open F,">".$statfilename or die "can't open '$statfilename': $!"; print F time ," OPEN\n"; close F; -e $trackfilenameon or do { open F,">".$trackfilenameon or die "can't open '$trackfilenameon': $!"; print F time ,"\n"; close F; }; -e $trackfilenameoff and do { unlink $trackfilenameoff; }; print "Content-Type: text/plain\n\n1\n"; exit; }; # else if $request_uri eq $uri_c and do { open F,">".$statfilename or die "can't open '$statfilename': $!"; print F time ," CLOSED\n"; close F; -e $trackfilenameon and do { unlink $trackfilenameon; }; -e $trackfilenameoff or do { open F,">".$trackfilenameoff or die "can't open '$trackfilenameoff': $!"; print F time ,"\n"; close F; }; print "Content-Type: text/plain\n\n1\n"; exit; }; # else if $request_uri eq $uri_text_de and do { print "Content-Type: text/plain\n\n"; -f $trackfilenameon and do { print "offen\n"; } or -f $trackfilenameoff and do { print "geschlossen\n"; } or do { print "keine Daten\n"; }; exit; }; # else if $request_uri eq $uri_text_en and do { print "Content-Type: text/plain\n\n"; -f $trackfilenameon and do { print "open\n"; } or -f $trackfilenameoff and do { print "closed\n"; } or do { print "no data\n"; }; exit; }; # else if $request_uri eq $uri_img_png and do { print "Content-Type: image/png\n\n"; -f $trackfilenameon and do { # pixel gruen print "\211\120\116\107\15\12\32\12\0\0\0\15\111\110\104\122\0\0\0\1\0", "\0\0\1\1\3\0\0\0\45\333\126\312\0\0\0\4\147\101\115\101\0\0\261", "\217\13\374\141\5\0\0\0\3\120\114\124\105\0\377\0\64\136\300", "\250\0\0\0\70\164\105\130\164\123\157\146\164\167\141\162\145", "\0\130\126\40\126\145\162\163\151\157\156\40\63\56\61\60\141\40", "\40\122\145\166\72\40\61\62\57\62\71\57\71\64\40\50\120\116\107", "\40\160\141\164\143\150\40\61\56\62\51\335\25\56\111\0\0\0\12", "\111\104\101\124\170\234\143\140\0\0\0\2\0\1\110\257\244\161", "\0\0\0\7\164\111\115\105\7\333\13\27\7\64\73\1\135\24\55\0\0\0", "\0\111\105\116\104\256\102\140\202"; } or -f $trackfilenameoff and do { # pixel rot print "\211\120\116\107\15\12\32\12\0\0\0\15\111\110\104\122\0\0\0\1\0", "\0\0\1\1\3\0\0\0\45\333\126\312\0\0\0\4\147\101\115\101\0\0\261", "\217\13\374\141\5\0\0\0\3\120\114\124\105\377\0\0\31\342\11\67\0", "\0\0\70\164\105\130\164\123\157\146\164\167\141\162\145\0\130\126", "\40\126\145\162\163\151\157\156\40\63\56\61\60\141\40\40\122\145", "\166\72\40\61\62\57\62\71\57\71\64\40\50\120\116\107\40\160\141", "\164\143\150\40\61\56\62\51\335\25\56\111\0\0\0\12\111\104\101", "\124\170\234\143\140\0\0\0\2\0\1\110\257\244\161\0\0\0\7\164\111", "\115\105\7\333\13\27\7\65\17\71\362\321\331\0\0\0\0\111\105\116", "\104\256\102\140\202"; } or do { # pixel grey print "\211\120\116\107\15\12\32\12\0\0\0\15\111\110\104\122\0\0\0\1\0", "\0\0\1\1\3\0\0\0\45\333\126\312\0\0\0\4\147\101\115\101\0\0\261", "\217\13\374\141\5\0\0\0\3\120\114\124\105\177\177\177\220\312\33", "\43\0\0\0\70\164\105\130\164\123\157\146\164\167\141\162\145\0\130", "\126\40\126\145\162\163\151\157\156\40\63\56\61\60\141\40\40\122", "\145\166\72\40\61\62\57\62\71\57\71\64\40\50\120\116\107\40\160\141", "\164\143\150\40\61\56\62\51\335\25\56\111\0\0\0\12\111\104\101\124", "\10\231\143\140\0\0\0\2\0\1\364\161\144\246\0\0\0\7\164\111\115\105", "\7\337\1\7\13\12\35\32\267\176\341\0\0\0\0\111\105\116\104\256\102", "\140\202"; }; exit; }; # else if $request_uri eq $uri_imgtxt_png and do { print "Content-Type: image/png\n\n"; -f $trackfilenameon and do { # image text gruen print "\211\120\116\107\15\12\32\12\0\0\0\15\111\110", "\104\122\0\0\0\57\0\0\0\25\10\3\0\0", "\0\341\30\107\125\0\0\0\140\120\114\124\105\77", "\277\140\7\367\13\0\376\0\5\371\11\14\362\22", "\23\353\35\27\347\44\25\351\40\31\345\46\33\343", "\52\47\327\74\41\335\63\45\331\70\50\326\76\54", "\322\103\61\315\113\71\305\127\73\303\132\102\274\145", "\110\266\157\116\260\167\122\254\176\127\247\206\130\246", "\206\133\243\214\136\240\220\141\235\225\144\232\231\150", "\226\237\157\217\252\154\222\245\160\217\253\370\234\167", "\162\0\0\0\355\111\104\101\124\170\332\325\222\315", "\162\303\40\14\204\15\210\26\203\377\222\206\70\266", "\43\351\375\337\62\22\156\153\174\354\55\325\1\326", "\322\67\73\153\15\215\375\133\65\357\312\207\344\313", "\355\14\230\135\200\201\242\335\376\155\134\305\307\47", "\63\56\101\324\225\21\171\351\144\42\2\361\41\2", "\107\105\356\363\301\367\230\3\164\13\5\235\246\64", "\314\350\105\304\276\357\223\166\264\157\347\203\167\124", "\264\331\344\152\110\224\347\161\27\5\241\165\3\153", "\363\301\47\214\145\62\261\331\61\340\111\154\103\10", "\255\121\376\223\362\311\277\347\217\302\17\45\206\163", "\160\343\126\362\113\251\221\70\14\174\261\371\376\313", "\7\36\12\177\45\47\274\374\57\136\24\3\51\247", "\371\165\13\135\305\333\165\325\235\171\272\51\26\243", "\246\250\363\313\361\240\265\332\117\240\155\214\23\255", "\120\143\70\152\175\167\340\311\25\157\175\106\246\57", "\70\331\112\56\106\372\351\264\47\136\267\371\136\357", "\355\237\362\57\123\170\25\154\160\141\302\111\0\0", "\0\0\111\105\116\104\256\102\140\202", ; #perl -e '$/="";$c=0;for (split //,<>) { printf "\\%o",ord($_); ++$c%14 or print "\n"}' ~chris/open.png } or -f $trackfilenameoff and do { # image text rot print "\211\120\116\107\15\12\32\12\0\0\0\15\111\110", "\104\122\0\0\0\100\0\0\0\25\10\3\0\0", "\0\301\364\30\250\0\0\0\132\120\114\124\105\377", "\0\0\377\13\13\377\24\24\377\31\31\377\41\41", "\377\53\53\377\63\63\377\73\73\377\104\104\377\112", "\112\377\124\124\377\133\133\377\145\145\377\153\153\377", "\161\161\377\203\203\377\213\213\377\220\220\377\232\232", "\377\243\243\377\263\263\377\274\274\377\307\307\377\313", "\313\377\324\324\377\334\334\377\344\344\377\353\353\377", "\363\363\377\374\374\46\155\212\6\0\0\1\44\111", "\104\101\124\170\332\355\122\111\266\204\40\14\4\34", "\160\150\301\131\132\250\373\137\363\47\212\266\372\372", "\0\177\321\265\200\172\41\103\205\104\210\37\116\344", "\145\116\247\114\116\203\56\263\73\223\11\103\155\104", "\311\107\170\355\1\274\265\150\161\65\70\115\54\173", "\107\326\201\261\104\342\232\133\74\226\132\327\156\242", "\267\303\60\25\111\351\2\251\32\103\231\126\23\51", "\153\121\23\112\116\120\125\315\210\341\23\57\375\302", "\222\244\24\135\330\15\141\346\53\361\124\317\271\350", "\165\44\217\304\242\70\23\24\250\357\116\45\52\261", "\73\51\321\143\66\331\376\246\11\112\304\76\45\354", "\245\3\35\131\33\156\206\27\50\324\322\167\354\55", "\60\50\163\224\31\372\213\202\346\256\100\343\265\335", "\75\266\337\316\73\156\270\103\232\46\251\74\234\324", "\105\201\130\75\217\57\127\347\24\326\267\342\1\204", "\221\222\61\163\263\370\114\150\47\75\162\161\221\340", "\155\323\123\231\16\206\40\111\302\152\52\33\326\204", "\76\330\333\272\105\313\205\115\143\114\263\21\143\27", "\66\135\326\150\2\174\257\342\254\111\116\76\2\141", "\140\135\31\61\14\362\330\3\354\304\117\325\143\225", "\244\172\356\246\372\302\176\370\237\370\3\237\327\25", "\353\351\254\364\365\0\0\0\0\111\105\116\104\256", "\102\140\202", ; } or do { # image text grey print "\211\120\116\107\15\12\32\12\0\0\0\15\111\110", "\104\122\0\0\0\72\0\0\0\25\10\3\0\0", "\0\40\237\15\371\0\0\0\4\147\101\115\101\0", "\0\261\217\13\374\141\5\0\0\0\146\120\114\124", "\105\172\172\172\176\176\176\203\203\203\204\204\204\210", "\210\210\215\215\215\223\223\223\227\227\227\230\230\230", "\235\235\235\240\240\240\245\245\245\251\251\251\255\255", "\255\260\260\260\266\266\266\271\271\271\274\274\274\303", "\303\303\305\305\305\314\314\314\316\316\316\324\324\324", "\327\327\327\331\331\331\337\337\337\340\340\340\344\344", "\344\351\351\351\355\355\355\362\362\362\364\364\364\373", "\373\373\377\377\377\250\34\47\121\0\0\0\70\164", "\105\130\164\123\157\146\164\167\141\162\145\0\130\126", "\40\126\145\162\163\151\157\156\40\63\56\61\60\141", "\40\40\122\145\166\72\40\61\62\57\62\71\57\71", "\64\40\50\120\116\107\40\160\141\164\143\150\40\61", "\56\62\51\335\25\56\111\0\0\0\360\111\104\101", "\124\70\215\355\121\313\162\302\60\14\124\36\206\72", "\61\204\330\111\234\30\374\320\377\377\144\245\200\11", "\320\366\322\351\364\304\36\74\132\215\326\273\262\1", "\336\310\160\366\117\244\107\54\177\57\55\276\16\134", "\106\23\103\107\105\241\3\272\346\332\54\207\20\65", "\113\305\30\222\255\100\42\242\7\250\47\237\346\152", "\223\46\55\7\224\0\66\235\224\345\202\260\244\256", "\165\110\122\65\311\66\116\120\366\270\27\0\207\111", "\66\161\313\162\161\144\210\75\354\120\21\73\73\356", "\355\271\256\322\155\310\370\307\135\7\377\20\230\216", "\250\241\105\301\143\221\173\12\353\333\256\107\117\121", "\103\336\65\263\27\351\352\132\144\127\312\135\122\64", "\201\247\142\275\356\300\256\167\366\44\65\353\256\255", "\305\353\73\55\101\311\231\166\255\320\210\46\4\276", "\254\357\152\142\273\46\276\112\65\71\232\200\347\374", "\302\143\214\206\3\53\237\226\201\207\373\350\77\230", "\315\303\26\370\107\174\363\221\157\374\33\76\1\352", "\14\23\160\224\41\237\53\0\0\0\7\164\111\115", "\105\7\337\1\7\13\67\50\46\354\362\174\0\0", "\0\0\111\105\116\104\256\102\140\202", ; # perl -e '$/="";$c=0;for (split //,<>) { printf "\\%o",ord($_); ++$c%14 or print "\",\n\t\t\t\""}' nodata.png }; exit; }; # else if $request_uri eq $uri_imgtxt_gif and do { print "Content-Type: image/gif\n\n"; -f $trackfilenameon and do { # image text gruen print "\107\111\106\70\71\141\57\0\25\0\365\46\0\77", "\277\140\7\367\13\0\376\0\5\371\11\11\365\16", "\14\362\22\23\353\35\27\347\44\25\351\40\31\345", "\46\33\343\52\47\327\74\41\335\63\45\331\70\50", "\326\76\57\317\110\54\322\103\61\315\113\66\310\123", "\71\305\127\73\303\132\117\257\172\102\274\145\106\270", "\153\110\266\157\116\260\167\122\254\176\127\247\206\125", "\251\202\130\246\206\133\243\214\136\240\220\141\235\225", "\144\232\231\150\226\237\157\217\252\154\222\245\156\220", "\250\160\217\253\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\41\371\4\0\0", "\0\0\0\54\0\0\0\0\57\0\25\0\0\6", "\376\100\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\10", "\200\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\0", "\5\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\20\10", "\4\2\201\100\40\20\10\4\2\201\100\40\0\12", "\4\2\201\100\40\20\10\4\11\206\101\40\20\10", "\4\203\100\41\40\20\10\4\202\101\41\120\10\24", "\2\2\301\40\40\20\10\4\202\300\100\40\20\10", "\4\2\201\100\40\130\210\114\246\321\47\1\24\10", "\4\26\323\150\144\372\64\4\2\200\151\64\32\215", "\74\2\1\140\24\21\10\4\202\115\107\40\20\10", "\4\2\201\376\100\340\30\151\22\205\306\207\224\20", "\10\0\43\6\3\322\31\31\4\200\321\2\350\160", "\70\30\2\1\140\104\112\10\4\202\116\107\40\20", "\10\4\2\201\140\100\352\10\4\2\101\40\324\21", "\10\0\44\201\100\140\60\105\4\0\222\100\40\20", "\10\4\2\0\11\24\52\10\4\232\16\120\40\20", "\10\4\2\201\200\61\132\10\4\2\201\140\142\12", "\10\0\44\201\100\120\60\115\4\200\121\42\221\120", "\4\4\2\0\11\101\322\10\4\235\216\100\40\20", "\10\4\2\201\303\164\20\10\4\2\240\0\62\62", "\10\0\243\301\240\220\61\51\4\0\223\311\144\32", "\55\4\2\0\111\0\61\121\4\232\215\100\40\20", "\10\4\2\101\302\4\21\10\4\2\201\205\64\20", "\0\106\243\221\151\104\21\10\0\100\122\241\120\50", "\14\4\2\300\110\40\260\230\32\232\215\100\40\20", "\10\4\2\201\0\4\12\10\4\2\3\51\43\20", "\0\110\213\205\42\40\20\10\0\44\201\100\40\20", "\10\4\0\222\100\40\360\220\200\240\216\100\40\20", "\10\4\2\201\40\101\376\12\105\26\23\22\250\40", "\20\0\110\2\201\100\40\20\10\0\243\110\44\22", "\211\10\4\0\222\100\40\50\210\114\35\201\100\40", "\20\10\4\2\201\300\240\31\1\115\44\114\101\40", "\20\0\110\2\201\100\40\20\10\0\243\221\311\64", "\42\11\4\0\222\100\40\20\50\114\35\201\100\40", "\20\10\4\2\201\100\40\20\4\4\2\201\100\40", "\20\10\4\2\201\100\40\0\12\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\100\0\24\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\0\50\20\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\4\2\201\100\40", "\20\10\4\2\201\100\40\20\10\165\4\2\201\100", "\40\20\10\4\2\1\120\40\20\10\4\2\201\100", "\40\20\10\4\2\201\100\40\20\10\4\2\201\100", "\40\20\10\4\2\201\100\40\20\10\4\2\201\100", "\40\20\10\4\2\201\100\40\20\10\4\2\201\100", "\40\20\10\4\2\240\100\40\20\10\4\2\201\100", "\40\20\10\4\2\201\100\40\20\10\4\2\201\100", "\40\20\10\4\2\201\100\40\20\10\4\2\201\100", "\40\20\10\4\2\201\100\40\20\10\4\2\201\40", "\10\0\73", ; # perl -e '$/="";$c=0;for (split //,<>) { printf "\\%o",ord($_); ++$c%14 or print "\",\n\t\t\t\""}' ~chris/open.gif } or -f $trackfilenameoff and do { # image text rot print "\107\111\106\70\71\141\100\0\25\0\364\35\0\377", "\0\0\377\13\13\377\24\24\377\31\31\377\41\41", "\377\53\53\377\63\63\377\73\73\377\104\104\377\112", "\112\377\124\124\377\133\133\377\145\145\377\153\153\377", "\161\161\377\203\203\377\213\213\377\220\220\377\232\232", "\377\243\243\377\263\263\377\274\274\377\307\307\377\313", "\313\377\324\324\377\334\334\377\344\344\377\353\353\377", "\363\363\377\374\374\0\0\0\0\0\0\41\371\4", "\0\0\0\0\0\54\0\0\0\0\100\0\25\0", "\0\5\376\40\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\200\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\2\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\10\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\40\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\200\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\2\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\10\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\40\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\200\221\30", "\0\0\200\301\0\0\0\0\0\0\0\34\111\1", "\0\0\0\0\300\221\24\0\0\0\301\0\16\303", "\60\10\0\20\14\203\20\0\0\0\0\0\0\0", "\0\0\0\300\262\376\165\35\330\145\7\0\165\0", "\0\0\0\0\54\133\327\165\330\1\0\100\221\165", "\135\207\35\40\0\104\135\327\165\335\5\0\121\327", "\165\35\326\0\0\0\0\0\0\0\0\260\200\335", "\265\34\13\126\1\121\7\0\0\0\0\113\127\41", "\103\202\161\6\0\120\134\2\22\112\65\0\0\324", "\55\313\262\44\0\20\165\212\322\120\335\4\0\0", "\0\0\0\10\0\301\166\5\0\0\4\1\20\161", "\0\0\0\100\300\131\0\0\0\303\166\1\40\200", "\141\0\0\0\0\0\104\35\0\0\0\0\0\121", "\7\0\0\360\164\10\0\200\0\0\0\0\200\164", "\13\0\0\0\0\0\121\7\0\0\0\44\235\2", "\0\0\0\2\117\47\0\122\147\71\5\0\0\100", "\324\35\307\161\10\0\0\165\0\0\0\1\330\75", "\0\0\0\0\0\0\113\167\0\0\0\0\0\0", "\161\0\0\0\300\322\35\40\0\0\0\300\164\5", "\0\74\133\327\125\3\0\100\135\327\165\235\2\0", "\21\7\200\0\0\0\234\4\0\0\0\0\0\200", "\164\15\0\0\0\0\0\121\376\7\0\0\0\2", "\107\307\0\0\0\0\122\27\0\0\0\30\121\67", "\1\100\324\21\304\100\4\0\10\104\35\0\0\200", "\320\75\0\0\0\0\0\0\200\266\15\0\0\30", "\2\0\165\40\0\0\0\0\150\231\0\0\100\301", "\121\0\160\10\0\0\140\26\0\100\35\0\200\0", "\0\0\0\324\1\0\0\110\235\1\0\0\0\0", "\0\0\40\335\366\64\122\7\116\100\324\71\216\343", "\4\300\321\151\216\362\160\332\0\4\333\366\54\120", "\7\1\0\30\165\116\343\70\15\0\104\235\343\74", "\127\7\1\0\0\0\0\0\0\0\140\124\140\327", "\155\222\0\104\135\327\165\335\0\0\6\325\165\334", "\64\0\0\120\120\135\327\201\123\0\0\121\327\165", "\135\327\1\100\324\165\335\126\51\0\0\0\0\0", "\0\0\0\2\0\0\4\2\0\0\0\0\0\0", "\0\0\0\0\0\200\0\0\0\0\0\0\10\0", "\2\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\40\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\376\0\0", "\0\0\0\200\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\2", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\10\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\40\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\200\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\2\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\10\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\40\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\200\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\2\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\10\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\33\0\0\0\0\0\0\0\40\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\100\10", "\0\73", ; # perl -e '$/="";$c=0;for (split //,<>) { printf "\\%o",ord($_); ++$c%14 or print "\",\n\t\t\t\""}' ~chris/closed.gif } or do { # image text grey print "\107\111\106\70\71\141\72\0\25\0\366\120\0\172", "\172\172\173\173\173\176\176\176\177\177\177\200\200\200", "\201\201\201\203\203\203\204\204\204\207\207\207\210\210", "\210\213\213\213\215\215\215\216\216\216\223\223\223\226", "\226\226\227\227\227\230\230\230\233\233\233\235\235\235", "\237\237\237\240\240\240\243\243\243\245\245\245\247\247", "\247\250\250\250\251\251\251\253\253\253\255\255\255\256", "\256\256\260\260\260\263\263\263\265\265\265\266\266\266", "\270\270\270\271\271\271\272\272\272\274\274\274\275\275", "\275\276\276\276\303\303\303\304\304\304\305\305\305\306", "\306\306\307\307\307\310\310\310\313\313\313\314\314\314", "\315\315\315\316\316\316\320\320\320\321\321\321\324\324", "\324\326\326\326\327\327\327\331\331\331\334\334\334\337", "\337\337\340\340\340\341\341\341\342\342\342\343\343\343", "\344\344\344\351\351\351\354\354\354\355\355\355\356\356", "\356\357\357\357\361\361\361\362\362\362\363\363\363\364", "\364\364\365\365\365\366\366\366\367\367\367\370\370\370", "\371\371\371\373\373\373\374\374\374\375\375\375\376\376", "\376\377\377\377\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", "\0\0\0\0\0\41\371\4\0\0\0\0\0\54", "\0\0\0\0\72\0\25\0\0\7\376\200\0\202", "\203\204\205\206\207\210\211\212\213\214\215\216\217\220", "\221\222\223\224\225\226\212\71\65\227\233\211\231\212", "\35\120\6\234\222\236\211\240\2\221\76\60\51\106", "\104\40\203\2\47\104\120\71\24\206\6\56\104\106", "\47\245\13\60\104\114\65\7\0\22\120\306\100\202", "\11\63\100\114\66\303\207\76\114\47\22\56\120\22", "\202\65\114\42\31\65\326\205\70\114\40\26\71\120", "\232\0\31\63\22\26\106\63\0\6\44\120\17\13", "\202\33\351\24\106\346\206\76\71\202\2\120\44\0", "\32\100\311\60\250\7\277\101\17\6\12\72\20\314", "\120\12\144\0\100\211\62\344\2\242\76\30\203\166", "\1\260\0\145\236\40\126\204\62\100\111\60\250\124", "\7\40\306\240\20\21\164\152\320\311\224\53\241\141", "\24\244\121\40\101\0\2\14\22\112\170\315\35\76", "\0\13\240\210\100\5\22\300\206\120\202\202\16\5", "\120\364\142\306\24\330\264\131\350\146\213\20\16\42", "\31\44\330\50\7\340\0\224\24\13\50\20\211\231", "\220\4\210\4\136\123\64\270\147\4\221\252\214\61", "\47\372\245\230\325\243\52\41\3\60\214\30\111\121", "\52\3\63\34\56\332\12\42\141\4\10\204\163\314", "\154\344\32\165\10\25\343\307\220\43\113\236\114\271", "\262\345\313\230\55\5\2\0\73", ; }; exit; }; # else print "Content-Type: image/gif\n\n"; -f $trackfilenameon and do { # pixel gruen print "GIF87a\001\0\001\0\200\0\0\0\377\0\0\0\0,\0\0\0\0\001\0\001\0\0\002\002D\001\0;"; exit; } or -f $trackfilenameoff and do { # pixel rot print "GIF87a\001\0\001\0\200\0\0\377\0\0\0\0\0,\0\0\0\0\001\0\001\0\0\002\002D\001\0;"; exit; }; # else # pixel grau print "GIF87a\001\0\001\0\200\0\0\177\177\177\0\0\0,\0\0\0\0\001\0\001\0\0\002\002D\001\0;"; dieser cronjob wirft ''/var/run/sopen/stat'', ''/var/run/sopen/track-on'' und ''/var/run/sopen/track-off'' weg, wenn ''/var/run/sopen/stat'' aelter als 3 minuten ist: ''/etc/cron.d/sopen'': * * * * * www-data /usr/bin/perl -e '$s = "/var/run/sopen/stat"; [stat $s]->[9] + 180 < time and do { unlink $s, "/var/run/sopen/track-on", "/var/run/sopen/track-off" };' run-verzeichnis angelegt: mkdir /var/run/sopen chown www-data:www-data /var/run/sopen der webserver muss ''/sopen'' als cgi starten. ausserdem muss ''sopen'' als ''sopen.gif'' aufrufbar sein, da dokuwiki sonst anstelle des bildes einen link darstellt. ''/etc/apache2/sites-available/20-shackspace.de.conf'' ScriptAlias /sopen /var/www/shackspace.de/htdocs/sopen ScriptAlias /sopen.gif /var/www/shackspace.de/htdocs/sopen ''apache'' ueber neue config informieren: /etc/init.d/apache2 reload im wiki wird es so eingebunden: {{http://shackspace.de/sopen.gif?20x10}} oder so: {{http://shackspace.de/sopen?.gif?20x10}} und so sieht's dann aus: {{http://shackspace.de/sopen.gif?20x10}} ===== anwendung und ausgabeformate ===== ^ format ^ desc. ^ url ^ sample ^ | gif | pixel | http://shackspace.de/sopen/img/gif | {{http://shackspace.de/sopen?.gif?20x10}} | | png | pixel | http://shackspace.de/sopen/img/png | {{http://shackspace.de/sopen?.png?20x10}} | | gif | grafische anzeige mit eingerendertem text | http://shackspace.de/sopen/imgtxt/en/gif | {{http://shackspace.de/sopen/imgtxt/en/gif?.gif?}} | | png | grafische anzeige mit eingerendertem text | http://shackspace.de/sopen/imgtxt/en/png | {{http://shackspace.de/sopen/imgtxt/en/png?.png?}} | | ascii[0] | deutscher text | http://shackspace.de/sopen/text/de | ''offen'' | | ascii[0] | english text | http://shackspace.de/sopen/text/en | ''closed'' | [0] als content-type wird "text/plain" uebermittelt ===== Kabelweg ===== Die Leitung verlaeuft von der Zuhaltung der Eingangstuere am Tuerrahmen nach oben, ueber den Tuerrahmen, an die Decke, durch die Wand zum Lager, im Lager links, oben unter der Decke ans Fenster, dort nach unten bis auf Hoehe des Fensterbankkanals. Hier ist ein db9-Stecker[0] angeloetet, in den ein hellblaues Cisco-Console-Kabel eingesteckt ist, dessen RJ45-Stecker in eine Netzwerkdose im Fensterbankkanal eingesteckt ist. Im RZ kommt die Leitung auf einem Patchfeld wieder raus, es folgen ein LAN-Kabel, ein weiteres hellblaues Cisco-Console-Kabel sowie ein USB/RS232-Adapter, der schliesslich im linken Rack in den KVM-Host (Name?): eingesteckt ist. Pix: * http://shackspace.de/?s=shack_open_close_monitor * http://shackspace.de/projects/chris/shack-status ===== Debugging ===== [0] Der db9-Stecker waere der erste Pruefpunkt fuer die Messung des Tuerkontakts: Abziehen, Widerstand an den Leitungen messen * Tuer auf: Widerstand unendlich * Tuer zu: Widerstand nahe null Fuer die Funktion Richtung Server: * db9-Stecker wieder einstecken und (nur!) die beiden Leitungen kurzschliessen. Der Tuerstatus sollte innerhalb 3 Minuten reagieren. Auf dem KVM-Host (Name?): * ist der USB/RS232-Adapter ueberhaupt am USB sichtbar? * ist das USB-Device dort vorhanden? * ist das USB-Device der KVM zugaenglich gemacht? Auf der KVM-Instanz "tuerstatus": * ist ''/dev/ttyUSB0'' vorhanden * hat ''/dev/ttyUSB0'' die Device-IDs "188, 0" * ist ''/dev/ttyUSB0'' world-readable * ''while sleep 1 ; do /usr/local/app/shackdoor/shackdoor /dev/ttyUSB0; done'' liefert bei geschlossener Tuere "DSR", bei offener Tuere Leerzeilen * ausgelesene Werte der letzten 2 Wochen: ''( zcat syslog.{14,13,12,11,10,9,8,7,6,5,4,3,2}.gz ; cat syslog{.1,} ) | awk '-F[ =]+' '$6 == "FLAG" { print $1,$2,$3,$7 }' | less'' (idee und drehbuch: chris) ===== abgeleitete anwendungen ===== ==== shackspace Opening Statistics ==== apache --------------------------------------+ | | | writes log | V | /var/www/shackspace.de/logs/access.log* | | | | | /etc/cron.d/sopen | is read by | | | | | calls 1/10m | | V V | calls /usr/local/bin/sopen-rrd ----+ | | | | | writes data | calls | | | | +--> rrdtool <------+ | | | | writes rrd | V | /var/cache/sopen/sopen.rrd | | | +-------------+ | | | | /var/www/shackspace.de/htdocs/sopen-show-42h.png <--+ | | | | +--------+ | | | | | | /var/www/shackspace.de/htdocs/sopen-show-23d.png <--+ | | | | | +--------+ | | | | | | /var/www/shackspace.de/htdocs/sopen-show-42w.png <--+ | | | | +--------+ | | calls | V | /var/www/shackspace.de/htdocs/sopen-show | | | is read by | calls | V +--------> rrdtool | | writes image data V png / stdout / cgi ==== Weekly, hourly and half-hourly breakdowns ==== apache | | writes log V /var/www/shackspace.de/logs/access.log* | | /etc/cron.d/sopen | is read by | | | calls 1/4h | V V /usr/local/bin/sopen-list ---+ | | | writes data | calls V | /var/cache/sopen/sopen.dat | | | | is read by | | | +--> gnuplot <------+ | | writes images V /var/www/shackspace.de/htdocs/sopen.d/bywday.png /var/www/shackspace.de/htdocs/sopen.d/byhour.png /var/www/shackspace.de/htdocs/sopen.d/byhalfhour.png ==== shackspace offen? (1x1 pixel abfragen)==== Autor: Felix Ein Kommandozeilen-Skript welches den Status des Shacks ( open/close ) anzeigt. Gut auch um persönliche Statistiken zu bauen. Dependencies sind bash, wget, awk, md5sum ( alles core-utils ). Ziel war es die Dependencies und den Footprint so gering wie möglich zu halten. #!/bin/bash # author: makefu # fetch the status from the website CURR=` wget "http://shackspace.de/sopen.gif" -O - 2>/dev/null | md5sum | awk '{print $1}'` # reference md5sum of a green 1x1 pixel REF="d8ced8c4a470ea0098a2b0d7b19c06b2" [ "$CURR" == "$REF" ] && echo -e "shack is \e[1;32mOPEN\e[0m" && exit 0 [ "$CURR" != "$REF" ] && echo -e "shack is \e[1;31mCLOSED\e[0m" && exit 1 ==== Shackspace offen? (String abfragen)==== Autor: chf is_shack_open.sh: #!/bin/bash status=$( echo -e -n "GET /sopen/text/en HTTP/1.0\r\nHost: shackspace.de\r\n\r\n" | nc shackspace.de 80 2>&1 | egrep -c "^open$" ) if [ $status -eq 1 ]; then echo -e "Yuhuu, doors are \e[1;32mopen\e[0m! ;-)" else echo -e "Damn, it's \e[1;31mclosed\e[0m." exit 1 fi und um dann gleich informiert zu werden: while [ 1 ]; do is_shack_open.sh && zenity --info --text="Shack is open" ; sleep 1m; done ==== !offen im IRC ==== Autor: cmile Im IRC einfach !open schreiben und auf die Antwort von Krebsbeam warten. # jsb/plugs/common/c-lang.py # -*- coding: utf-8 -*- ## jsb imports from jsb.utils.exception import handle_exception from jsb.lib.commands import cmnds from jsb.lib.examples import examples ## basic imports import re, urllib import random ## defines ## isopen command def handle_isopen(bot, ievent): mysock = urllib.urlopen("http://shackspace.de/sopen/text/de") ievent.reply(mysock.read()) cmnds.add('isopen', handle_isopen, ['OPER', 'USER', 'GUEST']) cmnds.add('offen', handle_isopen, ['OPER', 'USER', 'GUEST'])