上海問屋で買ったものですが、PCsenserのTEMPerと同じ物のようです。
CentOS 6でpcsensor-1.0.0-multi.tgzを少し弄って使用しています。
MRTG用の出力オプションを使用して利用するつもりでしたが、私の環境では1回起動すると2回目以降正常動作しませんでした。
機器を抜き差しすると1回は正常動作するため、初期化か終了処理がうまくいっていないようなのですが、いろいろ試しても直せませんでした。
取りあえずループモード(-lオプション)では動作するので、次のようにHTTPで情報取得できるようにして使用しています。
$ curl http://localhost:9999/ 30.12 30.12 10:37 pcsensor $
pcsenser-1.0.0-multi との差分は下記になります。
Index: Makefile =================================================================== --- Makefile (.../vendor/pcsensor/1.0.0-multi) +++ Makefile (.../pcsensor/trunk) @@ -3,7 +3,7 @@ CFLAGS = -O2 -Wall pcsensor: pcsensor.c - ${CC} -DUNIT_TEST -o $@ $^ -lusb + ${CC} -DUNIT_TEST -o $@ $^ -lusb -levent clean: rm -f pcsensor *.o Index: pcsensor.c =================================================================== --- pcsensor.c (.../vendor/pcsensor/1.0.0-multi) +++ pcsensor.c (.../pcsensor/trunk) @@ -34,6 +34,8 @@ #includeUSB温度計を複数持っていないので試していませんが、恐らく複数機器ではうまく動かないかと…。#include #include +#include +#include #define VERSION "1.0.0" @@ -45,6 +47,8 @@ #define INTERFACE2 0x01 #define MAX_DEV 4 +#define PID_FILE "/var/run/pcsensor.pid" +#define PORT_NUM 9999 const static int reqIntLen=8; const static int reqBulkLen=8; @@ -64,6 +68,7 @@ static int formato=0; static int mrtg=0; static int calibration=0; +static int use_daemon=0; static usb_dev_handle *handles[MAX_DEV]; @@ -78,24 +83,24 @@ void usb_detach(usb_dev_handle *lvr_winusb, int iInterface) { int ret; - ret = usb_detach_kernel_driver_np(lvr_winusb, iInterface); - if(ret) { - if(errno == ENODATA) { - if(debug) { - printf("Device already detached\n"); - } - } else { - if(debug) { - printf("Detach failed: %s[%d]\n", - strerror(errno), errno); - printf("Continuing anyway\n"); - } - } - } else { - if(debug) { - printf("detach successful\n"); - } - } + ret = usb_detach_kernel_driver_np(lvr_winusb, iInterface); + if(ret) { + if(errno == ENODATA) { + if(debug) { + printf("Device already detached\n"); + } + } else { + if(debug) { + printf("Detach failed: %s[%d]\n", + strerror(errno), errno); + printf("Continuing anyway\n"); + } + } + } else { + if(debug) { + printf("detach successful\n"); + } + } } int setup_libusb_access() { @@ -152,10 +157,10 @@ struct usb_bus *bus; struct usb_device *dev; - int i; + int i; - memset(handles, 0, sizeof(handles)); - i = 0; + memset(handles, 0, sizeof(handles)); + i = 0; for (bus = usb_busses; bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == VENDOR_ID && @@ -170,8 +175,8 @@ continue; } handles[i++] = handle; - if (i == MAX_DEV) - break; + if (i == MAX_DEV) + break; } } } @@ -314,6 +319,81 @@ (void) signal(SIGINT, SIG_DFL); } + +void daemonize() +{ + pid_t pid; + + pid = fork(); + if (pid < 0) { + perror("failed fork()"); + exit(1); + } + + if (pid > 0) { + FILE *fp; + fp = fopen(PID_FILE, "w"); + if (fp != NULL) { + fprintf(fp, "%d\n", pid); + fclose(fp); + } + exit(0); + } + seteuid(99); + setsid(); +} + +void http_handler(struct evhttp_request *req, void *arg) +{ + int i; + char msg[1024]; + + if (req->type != EVHTTP_REQ_GET) { + evhttp_send_error(req, HTTP_SERVUNAVAIL, "server unavail"); + return; + } + + struct evbuffer *ebuf; + ebuf = evbuffer_new(); + if (ebuf == NULL) { + evhttp_send_error(req, HTTP_SERVUNAVAIL, "Cannot allocate buffer"); + return; + } + + for (i = 0; handles[i] != NULL && i < MAX_DEV; i++) { + float tempc; + struct tm *local; + time_t t; + + memset(msg, 0, sizeof(msg)); + control_transfer(handles[i], uTemperatura ); + interrupt_read_temperatura(handles[i], &tempc); + + t = time(NULL); + local = localtime(&t); + + if (formato==2) { + tempc = (9.0 / 5.0 * tempc + 32.0); + } + snprintf(msg, sizeof(msg), "%.2f\n%.2f\n%02d:%02d\npcsensor\n", tempc, tempc, local->tm_hour, local->tm_min); + } + char content_length[8]; + + snprintf(content_length, sizeof(content_length)-1, "%d", strlen(msg)); + + evhttp_add_header(req->output_headers, "Content-Type", "text/plain"); + evhttp_add_header(req->output_headers, "Content-Length", content_length); + evbuffer_add(ebuf, msg, strlen(msg)); + evhttp_send_reply(req, HTTP_OK, "", ebuf); + evbuffer_free(ebuf); +} + +void signal_cb(int fd, short event, void *arg) +{ + struct event *signal = arg; + // printf("%s: got signal %d, ev=%0x\n", __func__, EVENT_SIGNAL(signal), event); + event_base_loopexit(signal->ev_base, 0); +} int main( int argc, char **argv) { @@ -323,7 +403,7 @@ time_t t; memset(handles, 0, sizeof(handles)); - while ((c = getopt (argc, argv, "mfcvhl::a:")) != -1) + while ((c = getopt (argc, argv, "mfcvhl::a:d")) != -1) switch (c) { case 'v': @@ -359,19 +439,23 @@ } else { break; } + case 'd': + use_daemon=1; + break; case '?': case 'h': printf("pcsensor version %s\n",VERSION); - printf(" Aviable options:\n"); - printf(" -h help\n"); - printf(" -v verbose\n"); - printf(" -l[n] loop every 'n' seconds, default value is 5s\n"); - printf(" -c output only in Celsius\n"); - printf(" -f output only in Fahrenheit\n"); - printf(" -a[n] increase or decrease temperature in 'n' degrees for device calibration\n"); - printf(" -m output for mrtg integration\n"); + printf(" Aviable options:\n"); + printf(" -h help\n"); + printf(" -v verbose\n"); + printf(" -l[n] loop every 'n' seconds, default value is 5s\n"); + printf(" -c output only in Celsius\n"); + printf(" -f output only in Fahrenheit\n"); + printf(" -a[n] increase or decrease temperature in 'n' degrees for device calibration\n"); + printf(" -m output for mrtg integration\n"); + printf(" -d daemon for mrtg integration\n"); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); default: if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); @@ -394,67 +478,112 @@ (void) signal(SIGINT, ex_program); for (i = 0; handles[i] != NULL && i < MAX_DEV; i++) { - ini_control_transfer(handles[i]); + ini_control_transfer(handles[i]); - control_transfer(handles[i], uTemperatura ); - interrupt_read(handles[i]); + control_transfer(handles[i], uTemperatura ); + interrupt_read(handles[i]); - control_transfer(handles[i], uIni1 ); - interrupt_read(handles[i]); + control_transfer(handles[i], uIni1 ); + interrupt_read(handles[i]); - control_transfer(handles[i], uIni2 ); - interrupt_read(handles[i]); - interrupt_read(handles[i]); - } + control_transfer(handles[i], uIni2 ); + interrupt_read(handles[i]); + interrupt_read(handles[i]); + } - do { - for (i = 0; handles[i] != NULL && i < MAX_DEV; i++) { - control_transfer(handles[i], uTemperatura ); - interrupt_read_temperatura(handles[i], &tempc); + if (use_daemon) { + struct event_base *ebase; + struct evhttp *http; + struct event signal[2]; - t = time(NULL); - local = localtime(&t); + daemonize(); - if (mrtg) { - if (formato==2) { - printf("%.2f\n", (9.0 / 5.0 * tempc + 32.0)); - printf("%.2f\n", (9.0 / 5.0 * tempc + 32.0)); - } else { - printf("%.2f\n", tempc); - printf("%.2f\n", tempc); - } - - printf("%02d:%02d\n", - local->tm_hour, - local->tm_min); + ebase = event_base_new(); + if (ebase == NULL) { + perror("failed event_base_new()"); + goto EXIT; + } + signal_set(&signal[0], SIGHUP, signal_cb, &signal[0]); + event_base_set(ebase, &signal[0]); + signal_add(&signal[0], 0); - printf("pcsensor\n"); - } else { - printf("%04d/%02d/%02d %02d:%02d:%02d ", - local->tm_year +1900, - local->tm_mon + 1, - local->tm_mday, - local->tm_hour, - local->tm_min, - local->tm_sec); + signal_set(&signal[1], SIGTERM, signal_cb, &signal[1]); + event_base_set(ebase, &signal[1]); + signal_add(&signal[1], 0); - if (formato==2) { - printf("Temperature %.2fF\n", (9.0 / 5.0 * tempc + 32.0)); - } else if (formato==1) { - printf("Temperature %.2fC\n", tempc); - } else { - printf("Temperature %.2fF %.2fC\n", (9.0 / 5.0 * tempc + 32.0), tempc); - } - } - - if (!bsalir) - sleep(seconds); - } - } while (!bsalir); + http = evhttp_new(ebase); + if (http == NULL) { + perror("failed evhttp_new()"); + event_base_free(ebase); + goto EXIT; + } + + if (evhttp_bind_socket(http, "127.0.0.1", PORT_NUM) < 0) { + perror("failed evhttp_bind_socket()"); + evhttp_free(http); + event_base_free(ebase); + goto EXIT; + } + + evhttp_set_gencb(http, http_handler, NULL); + event_base_dispatch(ebase); + + evhttp_free(http); + event_base_free(ebase); + unlink(PID_FILE); + } + else { + do { + for (i = 0; handles[i] != NULL && i < MAX_DEV; i++) { + control_transfer(handles[i], uTemperatura ); + interrupt_read_temperatura(handles[i], &tempc); + + t = time(NULL); + local = localtime(&t); + + if (mrtg) { + if (formato==2) { + printf("%.2f\n", (9.0 / 5.0 * tempc + 32.0)); + printf("%.2f\n", (9.0 / 5.0 * tempc + 32.0)); + } else { + printf("%.2f\n", tempc); + printf("%.2f\n", tempc); + } + + printf("%02d:%02d\n", + local->tm_hour, + local->tm_min); + + printf("pcsensor\n"); + } else { + printf("%04d/%02d/%02d %02d:%02d:%02d ", + local->tm_year +1900, + local->tm_mon + 1, + local->tm_mday, + local->tm_hour, + local->tm_min, + local->tm_sec); + + if (formato==2) { + printf("Temperature %.2fF\n", (9.0 / 5.0 * tempc + 32.0)); + } else if (formato==1) { + printf("Temperature %.2fC\n", tempc); + } else { + printf("Temperature %.2fF %.2fC\n", (9.0 / 5.0 * tempc + 32.0), tempc); + } + } + + if (!bsalir) + sleep(seconds); + } + } while (!bsalir); + } +EXIT: for (i = 0; handles[i] != NULL && i < MAX_DEV; i++) { usb_release_interface(handles[i], INTERFACE1); usb_release_interface(handles[i], INTERFACE2); + usb_reset(handles[i]); usb_close(handles[i]); }
初めてlibeventを使ってみましたが、面白いですね。
0 件のコメント:
コメントを投稿