Har mannen falt ned?

Har mannen falt ned?

Etter et par uker med "nå faller mannen", "mannen faller når som helst" overskrifter har selv media lagt krigstypene på hylla når de skriver om mannen og hvorvidt han faller eller ikke. Flere mediekanaler har satt opp døgndekkende webkameraer, men hvem har vel tid til å følge med på når det fremtidige fallet evt. vil skje? 

Overdrevent mediestyr har tidligere gitt oss morsomme ting som for eksempel nettleserplugins som blokker artikler om Justin Bieber. Denne gangen har oppstyret inspirert noen til å lage harmannenfaltned.no (i samme stil som den klassiske sau.no) og medfølgende api.harmannenfaltned.no.

Delcom USB gadget

Jeg har en stund hatt en Delcom USB gadget med det fengende navnet "904402 USB HID Red Visual Indicator" liggende. Dette er rett og slett en programmerbar varsellampe og tanken var at det hadde vært morsomt å koble den til byggserveren på jobb. En av grunnene til at jeg valgte akkurat denne enheten var at Delcom hadde publisert eksempelkode på nett.

I ettertid viste det seg selvfølgelig at denne eksempelkoden baserer seg på en gammel versjon av libhid som ikke kompilerer på nyere Debian distribusjoner. Dette kombinert med det faktum at det snart er ti år siden forrige gang jeg skrev så mye som en en linje C kode, la jeg prosjektet på hylla inntil videre. Når http://api.harmannenfaltned.no dukket opp, og jeg hadde en ledig kveld, fant jeg imidlertid ut at jeg iallefall skulle se hvor mye jobb det ville være å implementere en C klient, basert på libusb.

C klient basert på libusb

Det viste seg veldig snart at USB standarden er overraskende godt dokumentert, og basert på en del dokumentasjon, med en Ruby implementasjon for en annen Delcom gadget gikk det overraskende fort å implementere en fungerende klient.

lamp.c

#include <stdio.h>
#include "libusb.h"
static const int INTERFACE_NUMBER = 0;
 
static const unsigned char RED = 0x02;
static const unsigned char OFF = 0x00;
 
int main(int argc, char *argv[]) {
if (argc != 2 || (strcmp(argv[1], "on") != 0 && strcmp(argv[1], "off"))) {
fprintf(stderr, "Usage: lamp [on | off]\n");
return 1;
}
 
int r;
libusb_context *ctx;
 
r = libusb_init(&ctx);
if (r < 0) {
return r;
}
 
libusb_set_debug(ctx, 1); // error messages are printed to stderr
libusb_device_handle *devh = libusb_open_device_with_vid_pid(ctx, 0x0fc5, 0xb080);
 
if (devh != NULL) {
libusb_detach_kernel_driver(devh, INTERFACE_NUMBER);
r = libusb_claim_interface(devh, INTERFACE_NUMBER);
 
if (r >= 0) {
unsigned char command = strcmp("on", argv[1]) == 0 ? RED : OFF;
 
unsigned char buffer[] = {
0x65, // 8 byte packet size
0x0C, // Command type
command, // DataLSB - Command parameter
0xFF, // DataMSB - Command parameter
0x00, // HID, first byte
0x00, // HID, second byte
0x00, // HID, third byte
0x00 // HID, fourth byte
};
 
/* http://www.usb.org/developers/hidpage/HID1_11.pdf page 50 */
libusb_control_transfer (
devh,
0x21, // bmRequestType (host to device, type: class, recipient: interface)
0x09, // bRequest (SET_REPORT - allows the host to send a report to the device)
0x0635, // wValue (Report Type / ID - Specific to the device)
0x000, // wIndex (interface)
buffer, // Data / message
sizeof(buffer), // wLength (report length)
0 // Timeout
);
 
libusb_release_interface(devh, INTERFACE_NUMBER);
} else {
fprintf(stderr, "libusb_claim_interface error %d\n", r);
}
 
libusb_close(devh);
} else {
fprintf(stderr, "No device\n");
}
 
libusb_exit(ctx);
return 0;
}

Koden av avhengig av libusb og kan kompileres med gcc.

gcc flash.c `pkg-config --libs --cflags libusb-1.0` -o ./lamp

Bash script for integrasjon med harmannenfaltned.no

Den enkleste delen av dette kveldsprosjektet var å skrive et bash script som kaller api’et og blinker med lampen når / om det viser seg at mannen faller. Scriptet består rett og slett av en evig løkke som ved hjelp av curl henter ned json fra api’et, bruker det kjekke jq verktøyet til å hente ut informasjon fra json strukturen, og basert på om mannen har falt eller ikke, blinker med lyset eller sjekker på nytt om en liten stund.

mannalarm.sh

#!/bin/bash
while :
do
echo "$(date): Henter data..."
JSON=$(curl --fail --silent --show-error http://www.vondess.com/mannen/api)
#JSON='{ "falt_ned": true }'
 
if [ $? -eq 0 ]; then
HAR_RAMLET_NED=$(echo $JSON | jq -r '.falt_ned')
 
if [ "$HAR_RAMLET_NED" == "true" ]; then
while :
do
echo "$(date): MANNEN HAR RAMLET NED!!"
for i in `seq 1 3`;
do
./lamp on
sleep 0.2
./lamp off
sleep 0.3
done
sleep 15
done
else
 echo "$(date): Mannen har enda ikke ramlet ned"
sleep 60
fi
else
echo "Nettverksfeil.."
sleep 60
fi
done

Nå gjenstår det bare å se om mannen faller før eller etter Dovre!

Forslag og innspill mottas som allid med stor takk!

comments powered by Disqus