USB温度計
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
*USB温度計 [#m586d8d5]
**はじめに [#md38cef7]
>
>[[安価なUSB温度計が発売されています。>http://www.limemo....
購入後しばらく放置していましたが、いつも電源が入りっぱな...
<
**Linux(CentOS)で温度測定 [#gf917631]
>
>付属のCD-ROMにはWindowsのドライバ、APLが収録されています...
早速、先人の成果を調査すると、[[Ubuntuでの情報>http://www...
ドライバはLinuxでは特にインストールすることなく、認識され...
# dmesg | grep TEMP
input: RDing TEMPerV1.2 as /class/input/input14
input,hidraw0: USB HID v1.10 Keyboard [RDing TEMPerV1.2]...
hiddev96,hidraw96: USB HID v1.10 Device [RDing TEMPerV1....
<
>
# lsusb
Bus 003 Device 001: ID 0000:0000
Bus 006 Device 001: ID 0000:0000
Bus 002 Device 005: ID 0624:0248 Avocent Corp.
Bus 002 Device 001: ID 0000:0000
Bus 004 Device 016: ID 0c45:7401 Microdia
Bus 004 Device 003: ID 0518:0001 EzKEY Corp. USB to PS2 ...
Bus 004 Device 002: ID 067b:2303 Prolific Technology, In...
Bus 004 Device 001: ID 0000:0000
Bus 005 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
<
***gitでtemperを取得 [#p2a3e08f]
-APLはgitのレポジトリにあるため、まず、gitをインストール...
>
# yum install git
Loaded plugins: fastestmirror, priorities, security
Loading mirror speeds from cached hostfile
* base: ftp.jaist.ac.jp
* extras: ftp.jaist.ac.jp
* rpmforge: ftp.kddilabs.jp
* updates: ftp.iij.ad.jp
126 packages excluded due to repository priority protect...
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package git.i386 0:1.7.11.3-1.el5.rf set to be upda...
--> Processing Dependency: perl-Git = 1.7.11.3-1.el5.rf ...
--> Processing Dependency: perl(Git) for package: git
--> Running transaction check
---> Package perl-Git.i386 0:1.7.11.3-1.el5.rf set to be...
--> Processing Dependency: perl(SVN::Ra) for package: pe...
--> Processing Dependency: perl(SVN::Delta) for package:...
--> Processing Dependency: perl(SVN::Client) for package...
--> Processing Dependency: perl(YAML::Any) for package: ...
--> Processing Dependency: perl(SVN::Core) for package: ...
--> Running transaction check
---> Package perl-YAML.noarch 0:0.72-1.el5.rf set to be ...
---> Package subversion-perl.i386 0:1.6.11-11.el5_9 set ...
--> Finished Dependency Resolution
Dependencies Resolved
========================================================...
Package Arch Version ...
========================================================...
Installing:
git i386 1.7.11.3-1.el5.rf...
Installing for dependencies:
perl-Git i386 1.7.11.3-1.el5.rf...
perl-YAML noarch 0.72-1.el5.rf ...
subversion-perl i386 1.6.11-11.el5_9 ...
Transaction Summary
========================================================...
Install 4 Package(s)
Upgrade 0 Package(s)
Total download size: 9.2 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): perl-Git-1.7.11.3-1.el5.rf.i386.rpm ...
(2/4): perl-YAML-0.72-1.el5.rf.noarch.rpm ...
(3/4): subversion-perl-1.6.11-11.el5_9.i386.rpm ...
(4/4): git-1.7.11.3-1.el5.rf.i386.rpm ...
--------------------------------------------------------...
Total ...
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : perl-YAML ...
Installing : subversion-perl ...
Installing : git ...
Installing : perl-Git ...
Installed:
git.i386 0:1.7.11.3-1.el5.rf
Dependency Installed:
perl-Git.i386 0:1.7.11.3-1.el5.rf perl-YAML...
subversion-perl.i386 0:1.6.11-11.el5_9
Complete!
<
-いよいよ、temperを落としてきます。
>
# cd /opt
# git clone git://github.com/bitplane/temper.git
Cloning into 'temper'...
remote: Counting objects: 69, done.
remote: Compressing objects: 100% (42/42), done.
remote: Total 69 (delta 28), reused 61 (delta 24)
Receiving objects: 100% (69/69), 13.39 KiB, done.
Resolving deltas: 100% (28/28), done.
# ll
合計 4
drwxr-xr-x 3 root root 4096 10月 19 10:38 temper
# cd temper/
<
***ビルド [#h275bd88]
-makeします。
>
# make
gcc -Wall temper.c pcsensor.c -o temper -lusb
<
>
>元の記事では、Ubuntuのため、
-build-essential
>をインストールしていますが、CentOSでは不要です。
<
***動作確認 [#zd546662]
-まず、素のままで動作確認します。
>
# ./temper
19-Oct-2013 01:48,28.403656
<
***修正 [#m60a956e]
-元記事にあるように、表示形式とローカライズ(GMT->JST)...
>
# diff -c temper.c.org temper.c
*** temper.c.org 2013-10-19 10:49:15.000000000 +0...
--- temper.c 2013-10-19 11:38:10.000000000 +0900
***************
*** 41,50 ****
struct tm *utc;
time_t t;
t = time(NULL);
! utc = gmtime(&t);
char dt[80];
! strftime(dt, 80, "%d-%b-%Y %H:%M", utc);
printf("%s,%f\n", dt, tempc);
fflush(stdout);
--- 41,52 ----
struct tm *utc;
time_t t;
t = time(NULL);
! //utc = gmtime(&t);
! utc = localtime(&t);
char dt[80];
! //strftime(dt, 80, "%d-%b-%Y %H:%M", utc);
! strftime(dt, 80, "%Y-%m-%d,%H:%M:%S", ut...
printf("%s,%f\n", dt, tempc);
fflush(stdout);
<
-修正が終了したら、リビルドを実施
>
# make
gcc -Wall temper.c pcsensor.c -o temper -lusb
<
***再度動作を確認 [#w0ab4567]
>
# ./temper
2013-10-19,11:41:29,26.732019
<
>
>次はWebからグラフを表示できるようにしましょう。
<
***定期測定 [#n45d28c1]
>
>定期的に温度測定をするため、シェルスクリプトをcronに登録...
<
-スクリプト
>
====================== /opt/temper/record.sh ===========...
#! /bin/sh
/usr/bin/tail -n 300 /opt/temper/data/temper.dat > /opt/...
/opt/temper/temper >> /opt/temper/data/temper.tmp
/bin/mv -f /opt/temper/data/temper.tmp /opt/temper/data/...
<
>
>301エントリーを最大保持します。
<
-cronへの登録
>
# temparature logging
*/15 * * * * /opt/temper/record.sh
<
**問題発生 [#j9d93c41]
>
>temperでは、以下の問題があります。
<
>
>単一のセンサしか制御できません。(2個入りのTEMPerは2個ま...
<
>
>>
+時々エラーが発生し、正常な読み取りができないばかりか、デ...
+温度補正ができません。
+特定のデバイスを指定して測定ができません。
<<
>1.2.については、temper同様、リトライ、補正処理を実施する...
>今回、pcsensorのソースを元に、temperのリトライ機能とバス...
<
***pcsensorの入手 [#w68fae0d]
-[[OSAKANA TAROさんのブログ>http://blog.osakana.net/]]か...
>
# wget http://blog.osakana.net/sw/pcsensor/pcsensor-1.0....
--2013-10-20 22:53:59-- http://blog.osakana.net/sw/pcse...
blog.osakana.net をDNSに問いあわせています... 222.229.47...
blog.osakana.net|222.229.47.46|:80 に接続しています... ...
HTTP による接続要求を送信しました、応答を待っています......
長さ: 12668 (12K) [application/x-gzip]
`pcsensor-1.0.2.tar.gz' に保存中
100%[===================================================...
2013-10-20 22:54:00 (401 KB/s) - `pcsensor-1.0.2.tar.gz'...
#
<
***ソースの修正 [#e16cce5a]
-ソースを修正します修正ポイントは以下のとおりです。
>
+オプション名の変更(省略可能な引数を許可しない)
+リトライの実施
+補正情報をオフセットとスケールに修正
+出力形式をtemperに整合
+バス番号指定による特定デバイス情報のみの表示
<
-まず、一部の定義をヘッダファイルを作成し、移動します。
>
>pcsensor.h
<
>
#define VENDOR_ID 0x0c45
#define PRODUCT_ID 0x7401
#define INTERFACE1 0x00
#define INTERFACE2 0x01
#define MAX_DEV 4
#define RETRY_CNT 3
void message_dump( char *mess, char *data, int len );
int exec_usb_detach( int dev, int iInterface );
int setup_libusb_access( void );
int find_lvr_winusb( void );
int ini_control_transfer( int dev_num );
int control_transfer( int dev_num, const char *pquestion...
int interrupt_transfer( int dev_num );
int interrupt_read( int dev_num );
int interrupt_read_temperatura( int dev_num, float *temp...
int bulk_transfer( int dev_num );
int get_temparatura( int dev_num );
<
>
>pcsensor.c
/*******************************************************...
* pcsensor.c by Juan Carlos Perez (c) 2011 (cray@isp-sl...
* based on Temper.c by Robert Kavaler (c) 2009 (relavak...
* All rights reserved.
*
* Temper driver for linux. This program can be compiled...
* or as a standalone program (-DUNIT_TEST). The driver ...
* TEMPer usb devices from RDing (www.PCsensor.com).
*
* Redistribution and use in source and binary forms, wi...
* modification, are permitted provided that the followi...
* * Redistributions of source code must retain th...
* notice, this list of conditions and the follo...
*
* THIS SOFTWARE IS PROVIDED BY Juan Carlos Perez ''AS I...
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIM...
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTI...
* DISCLAIMED. IN NO EVENT SHALL Robert kavaler BE LIABL...
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ...
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTI...
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTI...
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRI...
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WA...
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH ...
*
*******************************************************...
#include <usb.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "log_ctrl.h"
#include "pcsensor.h"
#define VERSION "1.0.3"
const static int ReqIntLen=8;
const static int ReqBulkLen=8;
const static int Endpoint_Int_in=0x82; // endpo...
const static int Endpoint_Int_out=0x00; // endpo...
const static int Endpoint_Bulk_in=0x82; // endpo...
const static int Endpoint_Bulk_out=0x00; // endpo...
const static int Timeout=5000; // Timeo...
const static char UTemperatura[] = { 0x01, 0x80, 0x33, 0...
const static char UIni1[] = { 0x01, 0x82, 0x77, 0x01, 0x...
const static char UIni2[] = { 0x01, 0x86, 0xff, 0x01, 0x...
static int Debug=0;
static int Disp_format=0;
static int Mrtg=0;
static float Scale=1.0;
static float Offset=0.0;
static int Disp_dev_name=0;
static int Disp_dev_list=0;
static int Target_bus=-1;
static int Max_dev = MAX_DEV;
static struct usb_bus *Usb_busses;
static usb_dev_handle *Handles[MAX_DEV];
static char *Devlist_bus[MAX_DEV];
static char *Devlist_device[MAX_DEV];
//======================================================...
// 概要:
// USB通信メッセージのダンプを行います。
//
// 引数:
// char *mess メッセージデータ
// int len データ長(バイト)
//
// 戻り値:
// (なし)
//
//======================================================...
void message_dump( char *mess, char *data, int len )
{
int i;
char str[256];
char *p;
p = str;
sprintf( p, "%s, Message length:%d, Data:%02X", ...
p += strlen( str );
for( i=1; i<len; i++ )
{
sprintf( p, " %02X", data[i] & 0xff );
p += 3;
}
log_write( LOG_DEBUG, "%s", str );
}
//======================================================...
// 概要:
// Kernelドライバにすでに組み込まれているデバイスを...
//
// 引数:
// int dev_no デバイス番号
// int interface インタフェース番号
//
// 戻り値:
// int 0: 正常終了
// -1: エラー
//
//======================================================...
int exec_usb_detach( int dev_no, int interface )
{
int ret;
ret = usb_detach_kernel_driver_np( Handles[dev_n...
if( ret )
{
if( errno == ENODATA )
{
log_write( LOG_DEBUG, "Device:[%...
}
else
{
log_write( LOG_DEBUG,
"Detach failed, Device:[...
dev_no,
strerror(errno),
errno
);
}
return( -1 );
}
else
{
log_write( LOG_DEBUG,
"Device[%d]: detach successful",
dev_no
);
return( 0 );
}
}
//======================================================...
// 概要:
// libusbを初期化し対象のセンサを検出します。
// 検出したデバイスをオープンし、各デバイスのハンド...
//
// 引数:
// (なし)
//
// 戻り値:
// int 検出したデバイス数
//
// グローバル変数操作:
// Handles[i] handle;
// Devlist_bus[i] bus->dirname;
// Devlist_device[i] dev->filename;
//======================================================...
int find_usb_sensor_dev( void )
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle;
int i;
memset( Handles, 0, sizeof(Handles) );
i = 0;
for( bus=Usb_busses; bus; bus=bus->next )
{
for( dev=bus->devices; dev; dev=dev->nex...
{
if( dev->descriptor.idVendor == ...
dev->descriptor.idProduc...
)
{
log_write( LOG_DEBUG,
"Found usb devic...
VENDOR_ID,
PRODUCT_ID,
i
);
if( !(handle = usb_open(...
{
log_write( LOG_E...
"Could n...
);
continue;
}
Handles[i] = handle;
Devlist_bus[i] = bus->di...
Devlist_device[i] = dev-...
i++;
if( i == MAX_DEV )
{
break;
}
}
}
}
return(i);
}
//======================================================...
// 概要:
// 対象のUSBデバイスをアクセスできるようにします。
// (コンフィグレーション)
//
// 引数:
// (なし)
//
// 戻り値:
// int セットアップしたデバイス数
//======================================================...
int setup_libusb_access( void )
{
int i = 0;
if( Debug )
{
usb_set_debug( 255 );
}
else
{
usb_set_debug( 0 );
}
usb_init();
usb_find_busses();
usb_find_devices();
Usb_busses = usb_get_busses();
if( !find_usb_sensor_dev() )
{
log_write( LOG_ERR, "Couldn't find the U...
return(0);
}
for( i=0; Handles[i] != NULL && i < Max_dev; i++ )
{
if( usb_set_configuration(Handles[i], 0x...
{
if( exec_usb_detach( i, INTERFAC...
{
if( usb_set_configuratio...
{
log_write( LOG_E...
"Could n...
i
);
return(0);
}
}
}
if( usb_claim_interface(Handles[i], INTE...
{
exec_usb_detach( i, INTERFACE1 );
if( usb_claim_interface(Handles[...
{
log_write( LOG_ERR,
"Could not claim...
i,
INTERFACE1
);
return(0);
}
}
if( usb_claim_interface(Handles[i], INTE...
{
exec_usb_detach( i, INTERFACE2 );
if( usb_claim_interface(Handles[...
{
log_write( LOG_ERR,
"Could not claim...
i,
INTERFACE2
);
return(0);
}
}
}
return(i);
}
//======================================================...
// 概要:
// デフォルトコントロールパイプへの転送のためのメッ...
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int ini_control_transfer( int dev_num )
{
int r;
char str[256];
char question[] = { 0x01,0x01 };
sprintf( str, "ini_control_transfer(), dev:%d ",...
message_dump( str, question, 2 );
r = usb_control_msg( Handles[dev_num], 0x21, 0x0...
if( r < 0 )
{
log_write( LOG_ERR,
"USB control write failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
return( 0 );
}
//======================================================...
// 概要:
// コントロール転送のためのメッセージをセットアップ...
// 引数:
// int dev_num デバイス番号
// char *question メッセージ
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int control_transfer( int dev_num, const char *pquestion )
{
int r;
char str[256];
char question[ReqIntLen];
memcpy( question, pquestion, sizeof(question) );
sprintf( str, "control_transfer(), dev:%d ", dev...
message_dump( str, question, sizeof( question ) );
r = usb_control_msg( Handles[dev_num], 0x21, 0x0...
if( r < 0 )
{
log_write( LOG_ERR,
"USB control write failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
return( 0 );
}
//======================================================...
// 概要:
// インタラプト転送によりメッセージを転送します。
// 引数:
// int dev_num デバイス番号
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int interrupt_transfer( int dev_num )
{
int r;
int i;
char str[256];
char answer[ReqIntLen];
char question[ReqIntLen];
for( i=0;i<ReqIntLen; i++ )
{
question[i]=i;
}
sprintf( str, "interrupt_transfer():write, dev:%...
message_dump( str, question, ReqIntLen );
r = usb_interrupt_write( Handles[dev_num], Endpo...
if( r < 0 )
{
log_write( LOG_ERR,
"USB interrupt write failed:%s[%...
strerror(errno),
errno
);
return( -1 );
}
r = usb_interrupt_read( Handles[dev_num], Endpoi...
if( r != ReqIntLen )
{
log_write( LOG_ERR,
"USB interrupt read failed:%s[%d...
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "interrupt_transfer():read, dev:%d...
message_dump( str, answer, ReqIntLen );
usb_release_interface( Handles[dev_num], 0 );
return( 0 );
}
//======================================================...
// 概要:
// インタラプト転送によりメッセージのリードを行いま...
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int interrupt_read( int dev_num )
{
int r;
char str[256];
char answer[ReqIntLen];
bzero( answer, ReqIntLen );
r = usb_interrupt_read( Handles[dev_num], 0x82, ...
if( r != ReqIntLen )
{
log_write( LOG_ERR,
"USB interrupt read failed:%s[%d...
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "interrupt_read():read, dev:%d ", ...
message_dump( str, answer, ReqIntLen );
return(0);
}
//======================================================...
// 概要:
// 温度を読み取ります。
//
// 引数:
// int dev_num デバイス番号
// float *tempC 摂氏による読み取り温度
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int interrupt_read_temperatura( int dev_num, float *temp...
{
int r;
int temperature;
char str[256];
char answer[ReqIntLen];
bzero( answer, ReqIntLen );
r = usb_interrupt_read( Handles[dev_num], 0x82, ...
if( r != ReqIntLen )
{
log_write( LOG_ERR,
"USB interrupt read failed:%s[%d...
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "interrupt_read():read, dev:%d ", ...
message_dump( str, answer, ReqIntLen );
temperature = (answer[3] & 0xFF) + ((signed char...
*tempC = temperature * (125.0 / 32000.0) * Scale...
return(0);
}
//======================================================...
// 概要:
// バルク転送を行います。
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int bulk_transfer( int dev_num )
{
int r;
char str[256];
char answer[ReqBulkLen];
log_write( LOG_DEBUG, "Data write(NULL)" );
r = usb_bulk_write( Handles[dev_num], Endpoint_B...
if( r < 0 )
{
log_write( LOG_ERR,
"USB bulk write failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
r = usb_bulk_read( Handles[dev_num], Endpoint_Bu...
if( r != ReqBulkLen )
{
log_write( LOG_ERR,
"USB bulk read failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "bulk_transfer():read, dev:%d ", d...
message_dump( str, answer, ReqIntLen );
usb_release_interface( Handles[dev_num], 0 );
return( 0 );
}
//======================================================...
// 概要:
// 温度情報の取得
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
// -2: デバイスが存在しない
//
//======================================================...
int get_temparatura( int dev_num )
{
int ret;
float tempc;
struct tm *local;
time_t t;
if( (ret = setup_libusb_access()) == 0 )
{
return( 0 );
}
if( Handles[dev_num] == NULL )
{
return( 0 );
}
if( Disp_dev_list )
{
printf( "Device:%i is Bus_id:%s Device_i...
dev_num,
Devlist_bus[ dev_num ],
Devlist_device[ dev_num ]
);
}
else if( atoi(Devlist_bus[dev_num]) == Target_bu...
{
if( ini_control_transfer( dev_num ) ) ...
if( control_transfer( dev_num , UTemper...
if( interrupt_read( dev_num ) ) return...
if( control_transfer( dev_num , UIni1 )...
if( interrupt_read( dev_num ) ) return...
if( control_transfer( dev_num , UIni2 )...
if( interrupt_read( dev_num ) ) return...
if( interrupt_read( dev_num ) ) return...
if( control_transfer( dev_num , UTemper...
if( interrupt_read_temperatura( dev_num...
t = time( NULL );
local = localtime( &t );
if( Mrtg )
{
if( Disp_format & 0x02 )
{
printf( "%.4f\n", (9.0 /...
printf( "%.4f\n", (9.0 /...
}
else
{
printf( "%.4f\n", tempc );
printf( "%.4f\n", tempc );
}
printf( "%02d:%02d\n",
local->tm_hour,
local->tm_min
);
printf( "pcsensor\n" );
}
else
{
printf( "%04d/%02d/%02d,%02d:%02...
local->tm_year +1900,
local->tm_mon + 1,
local->tm_mday,
local->tm_hour,
local->tm_min,
local->tm_sec
);
if( Disp_dev_name > 0 )
{
printf( ",Bus:%s/Device:...
}
// printf( "Temperature" );
if( Disp_format == 0 )
{
printf( ",%.4fF", (9.0 /...
}
if( Disp_format & 0x02 )
{
printf( ",%.4f", (9.0 / ...
}
if( Disp_format == 0 )
{
printf( ",%.4fC", tempc );
}
if( Disp_format & 0x01 )
{
printf( ",%.4f", tempc );
}
printf( "\n" );
}
usb_release_interface( Handles[ dev_num ...
usb_release_interface( Handles[ dev_num ...
usb_close( Handles[ dev_num ] );
}
return( 0 );
}
//======================================================...
// 概要:
// メイン関数
// 引数:
// int argc コマンドラインの引数の数
// char **argv 引数リスト
// 戻り値:
// int 実行結果
//
//======================================================...
int main( int argc, char **argv )
{
int c;
int i;
int ret;
char *tok;
char arg[256];
strcpy( arg, argv[0] );
for( i=1; i<argc; i++ )
{
strcat( arg, " " );
strcat( arg, argv[i] );
}
log_write( LOG_INFO, "command = %s", arg );
memset( Handles, 0, sizeof(Handles) );
while ( (c = getopt (argc, argv, "mfcvhla:dB:"))...
switch ( c )
{
case 'v':
// 詳細な情報を表示します。
Debug = 1;
log_write( LOG_DEBUG, "option -v" );
break;
case 'c':
// 摂氏表示を行います。
Disp_format |= 0x01; //Celsius
log_write( LOG_DEBUG, "option -c" );
break;
case 'f':
// 華氏表示を行います。
Disp_format |= 0x02; //Fahrenheit
log_write( LOG_DEBUG, "option -f" );
break;
case 'm':
// MRTG用のデータ形式を出力します。
Mrtg=1;
log_write( LOG_DEBUG, "option -m" );
break;
case 'd':
// デバイスのバス/デバイスIDを含め表示し...
Disp_dev_name++;
log_write( LOG_DEBUG, "option -d" );
break;
case 'l':
// デバイス一覧を表示する
Disp_dev_list++;
log_write( LOG_DEBUG, "option -l" );
break;
case 'B':
// 対象のバスを指定します。
if( (tok = strtok( optarg, "," )) == NUL...
{
log_write( LOG_ERR, "option -B, ...
exit( 1 );
}
Target_bus = atoi( tok );
log_write( LOG_DEBUG, "option -B, target...
break;
case 'a':
// 温度補正データの設定をします。
if( (tok = strtok( optarg, "," )) == NUL...
{
log_write( LOG_ERR, "option -a, ...
exit( 1 );
}
Scale = atof( tok );
if( (tok = strtok( NULL, "," )) == NULL )
{
log_write( LOG_ERR, "option -a, ...
exit( 1 );
}
Offset = atof( tok );
log_write( LOG_DEBUG, "option -a, scale=...
break;
case '?':
case 'h':
printf( "pcsensor version %s\n", VERSION...
printf( " Aviable options:\n ");
printf( " -h help\n" );
printf( " -v verbose\n" );
printf( " -c output only in Celsius...
printf( " -f output only in Fahrenh...
printf( " -a <Scale>,<Offset>\n" );
printf( " compesate temparature:...
printf( " -m output for Mrtg integr...
printf( " -d output with Bus and De...
printf( " -l display device list\n"...
printf( " -B <n>\n" );
printf( " specific bus number\n"...
exit( 1 );
default:
if( isprint (optopt) )
{
log_write( LOG_ERR, "Unknown opt...
fprintf( stderr, "Unknown option...
}
else
{
log_write( LOG_ERR, "Unknown opt...
fprintf (stderr, "Unknown option...
}
exit( 1 );
}
if( optind < argc )
{
log_write( LOG_ERR, "Non-option ARGV-ele...
fprintf( stderr, "Non-option ARGV-elemen...
exit( 1 );
}
for( i=0; i < Max_dev; i++ )
{
int retry = RETRY_CNT;
while( retry )
{
ret = get_temparatura( i );
if( ret == 0 ) break;
sleep(3);
if( retry-- == 1)
{
log_write( LOG_ERR, "Unr...
exit(1);
}
}
}
exit(0);
}
<
-log_ctrl.h
>
/*******************************************************...
** Logging tool
** log_ctrl:
** General purpose logging tools for C lang...
**
**
*******************************************************...
#ifndef _LOG_CTRL_H
#define _LOG_CTRL_H 1
#ifndef _SYS_SYSLOG_H
#include <syslog.h>
#endif
/*******************************************************...
** MACROS
*******************************************************...
// =====================================================...
// log_write( LOG_LEVEL, <function_name>, <messages...
//
// =====================================================...
#define log_write( level, fmt, arg... ) log_write_sub( l...
/*******************************************************...
** Define structs
*******************************************************...
typedef struct _log_code
{
char *name;
int val;
} LOG_CODE;
/*******************************************************...
** for reference only
*******************************************************...
/* ============ Log Priorities (these are ordered) =====...
#define LOG_EMERG 0 system is unusable
#define LOG_ALERT 1 action must be taken imm...
#define LOG_CRIT 2 critical conditions
#define LOG_ERR 3 error conditions
#define LOG_WARNING 4 warning conditions
#define LOG_NOTICE 5 normal but signification...
#define LOG_INFO 6 informational
#define LOG_DEBUG 7 debug-level messages
=======================================================...
/* ============ Log Facilityes (these are ordered) =====...
#define LOG_KERN (0<<3) kernel messages
#define LOG_USER (1<<3) random user-level messages
#define LOG_MAIL (2<<3) mail system
#define LOG_DAEMON (3<<3) system daemons
#define LOG_AUTH (4<<3) security/authorization m...
#define LOG_SYSLOG (5<<3) messages generated inter...
#define LOG_LPR (6<<3) line printer subsystem
#define LOG_NEWS (7<<3) network news subsystem
#define LOG_UUCP (8<<3) UUCP subsystem
#define LOG_CRON (9<<3) UUCP subsystem
#define LOG_AUTHPRIV (10<<3) UUCP subsystem
#define LOG_FTP (11<<3) UUCP subsystem
#define LOG_NTP (12<<3) UUCP subsystem
#define LOG_AUDIT (13<<3) UUCP subsystem
#define LOG_ALERT (14<<3) UUCP subsystem
#define LOG_CLOCK (15<<3) UUCP subsystem
#define LOG_LOCAL0 (16<<3) reserved for local use
#define LOG_LOCAL1 (17<<3) reserved for local use
#define LOG_LOCAL2 (18<<3) reserved for local use
#define LOG_LOCAL3 (19<<3) reserved for local use
#define LOG_LOCAL4 (20<<3) reserved for local use
#define LOG_LOCAL5 (21<<3) reserved for local use
#define LOG_LOCAL6 (22<<3) reserved for local use
#define LOG_LOCAL7 (23<<3) reserved for local use
=======================================================...
/*******************************************************...
** Prototype definitions
*******************************************************...
int get_log_facility( char *facility_name );
void set_log_facility( int code );
void log_write_sub( int level, const char* format, ... );
// =========================================== End of co...
#endif
<
-log_ctrl.c
>
/*******************************************************...
** Logging tool
** log_ctrl:
** General purpose logging tools for C lang...
**
**
*******************************************************...
/*******************************************************...
** includes header files
*******************************************************...
#define _GNU_SOURCE
#include <string.h>
#include <syslog.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "log_ctrl.h"
/*******************************************************...
** Global viables but only use in Logging tool
*******************************************************...
static char *LOG_LEVEL_STR[] =
{
"EMERG",
"ALERT",
"CRIT",
"ERR",
"WARNING",
"NOTICE",
"INFO",
"DEBUG"
};
// =====================================================...
// Log facility code is permitted following codes.
// subset of RFC 3164
// =====================================================...
LOG_CODE FACILITY_NAMES[] =
{
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "user", LOG_USER },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
int LOG_facility_code = LOG_USER; // default facil...
/*******************************************************...
**
** [Name]
** get_log_facility
** [Description]
** get logfacility code
** [Arguments]
** char *facility_name facility name
** [Return Value]
** int LOG_facility_code -1:error,other:facility ...
**
*******************************************************...
int get_log_facility( char *facility_name )
{
char *str;
int i = 0;
int code = -1;
while( (str = FACILITY_NAMES[i].name) != NULL )
{
if( strcmp( str, facility_name ) == 0 )
{
code = FACILITY_NAMES[i].val;
break;
}
i++;
}
return( code );
}
/*******************************************************...
**
** [Name]
** set_log_facility
** [Description]
** set logfacility code
** [Arguments]
** char *facility_name facility name
** [Return Value]
** int LOG_facility_code -1:error,other:facility ...
**
*******************************************************...
void set_log_facility( int code )
{
LOG_facility_code = code;
}
/*******************************************************...
**
** [Name]
** log_write
** [Description]
** writes messages in logfile.
** [Arguments]
** int level log level
** const char* format, ... printf like format
** [Return Value]
** none
**
*******************************************************...
void log_write_sub( int level, const char* format, ... )
{
char *buff;
int size;
va_list ap;
va_start(ap, format);
size = vasprintf( &buff, format, ap );
va_end( ap );
openlog( "pcsensor", LOG_PID, LOG_MAKEPRI(LOG_fa...
syslog( level, "%s;%s\n", LOG_LEVEL_STR[level], ...
closelog();
free( buff );
}
// =========================================== End of co...
<
-Makefileも修正します。
>
all: pcsensor
CC = gcc
CFLAGS = -O2 -Wall -g
pcsensor: pcsensor.o log_ctrl.o -lusb
${CC} ${CFLAGS} -lusb -o pcsensor pcsensor.o log...
pcsensor.o: pcsensor.c pcsensor.h
${CC} ${CFLAGS} -DUNIT_TEST -c -o pcsensor.o pc...
log_ctrl.o: log_ctrl.c log_ctrl.h
${CC} ${CFLAGS} -c -o log_ctrl.o log_ctrl.c
clean:
rm -f pcsensor *.o
rules-install: # must be superuser to d...
cp 99-tempsensor.rules /etc/udev/rules.d
<
***ビルド [#o5aaeb7a]
-Makeします。
>
# make
gcc -O2 -Wall -g -DUNIT_TEST -c -o pcsensor.o pcsensor.c
gcc -O2 -Wall -g -c -o log_ctrl.o log_ctrl.c
gcc -O2 -Wall -g -lusb -o pcsensor pcsensor.o log_ctrl.o
#
<
***動作確認 [#fda0f004]
-デバイスリストを表示します。
>
# ./pcsensor -l
Device:0 is Bus_id:004 Device_id:100
Device:1 is Bus_id:005 Device_id:003
#
<
-バス番号を指定します。
>
# ./pcsensor -c -B 4
2013/10/25,23:07:33,22.6250
#
<
>
>以上で先のtemperと互換になりました。
<
**Webで時系列温度表示 [#p2f72120]
***グラフ表示の方法 [#d109aaf6]
>
>Webでグラフを表示するには、既存のSNMPマネージャに統合し...
<
>
-今後のWebアプリケーションの勉強のために、Javascriptsで記...
-スタンドアロンで動作する(GoogleのAPI等は使用しない)
<
>
>という方針で作成します。ネットでしらべましたが、「highch...
<
***highchartsの入手 [#re5769e8]
-[[highcharts のページ>http://www.highcharts.com/]]より...
商用利用では有料です。
-[[ダウンロードページ>http://www.highcharts.com/download]...
-ファイルを解凍すると以下のように展開されます。
>
# ll
合計 12824
-rw-r--r-- 1 vod users 13080205 10月 19 18:16 Highchart...
drwxr-xr-x 59 vod users 4096 10月 4 15:24 examples
drwxr-xr-x 5 vod users 4096 10月 4 15:24 exporting...
drwxr-xr-x 2 vod users 4096 10月 4 15:24 gfx
drwxr-xr-x 2 vod users 4096 10月 4 15:24 graphics
-rw-r--r-- 1 vod users 4989 10月 4 15:24 index.htm
drwxr-xr-x 5 vod users 4096 10月 4 15:24 js
<
-このうち使用するのは
>
./exporting-server/phantomjs/jquery.1.9.1.min.js
./exporting-server/phantomjs/highcharts.js
<
>
>の2個のファイルです。
<
***コード [#t4159da9]
>
>では、早速試験コードです。ファイルアクセスはPHPで行って...
====================== index.php =======================...
<?php
ini_set( 'display_errors', 1 ); // エラー出力する...
ini_set( 'error_reporting', E_ALL | E_STRICT );
$Temp_data = array (
array( "Server Room", "/opt/temper/dat...
array( "External Air", "/opt/temper/dat...
);
?>
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="./js/jquery.min.js">...
<script type="text/javascript" src="./js/highcharts.js">...
<script type="text/javascript">
var chart;
var options =
{
// 以下によりグラフのオプションを設定
// グラフ全体の設定
chart:
{
renderTo: 'container', // (String)グ...
defaultSeriesType: 'line', // デフォルト...
// line: ...
// area: ...
// spline:...
// column...
// bar: ...
// pie: ...
// scatter...
// backgroundColor: null, // (String)全...
borderWidth: 1 // (Number)グ...
// グラフ...
// borderRadius: ????, // (Number)カ...
// borderColor: '#ffffff', // (String)グ...
// plotBackgroundColor: null // (String)プ...
// inverted: // (Boolean)tr...
// zoomType: // (String)zoo...
// ”x”の他...
},
// タイトルの設定
title:
{
text: '温度グラフ', // (String)タイトルの...
align: 'center' // (String)タイトルの...
// 左寄せ: “left”
// 中央揃え: ...
// 右寄せ: ...
//style: // (CSS Object)タイト...
// ただし位置揃え...
// 上に書いたalig...
//floating: // (Boolena)true にす...
},
// サブタイトルの設定
subtitle:
{
text: '(試行中)',
align: 'center'
},
// 凡例の設定
legend:
{
layout: 'vertical', // (String)複数の系列...
// タテに並べる:ve...
// ヨコに並べる:h...
align: 'right', // (String)凡例の位置...
// left
// center
// right
verticalAlign: 'top', //
// reversed // (Boolean)true にす...
// もっと複雑に指...
// legendIndex を...
// borderWidth // (Number) 枠線の太...
// borderColor // (String) 枠線の色...
// borderRadius // (Number) 枠線の角...
// backgroundColor // (String) 枠線の背...
floating: true // (Boolena)true にす...
},
/*
// グラフにマウスオーバーすると出てくるポップア...
tooltip:
{
formatter: function()
{
return( this.y + '℃' );
},
enabled:true
},
*/
// X軸
xAxis:
{
type: 'datetime', // (String) 軸の種類を...
// linear: (...
// datetime: 時...
// logarithmic ...
title:
{
text: 'date/time' // (String) 軸のタ...
}
// max // (Number) 軸の最...
// minx // (Number) 軸の最...
// lineWidth // (Number) 軸の太...
// lineColor // (String) 軸の太...
//allowDecimals: false, // (Boolean) グラフ...
// categories // (Array) 軸の目盛...
// 指定形式にし...
},
// Y軸
yAxis:
{
type: 'linear',
title:
{
text: '℃'
// style:
// {
// color: '#4572A7'
// }
},
//labels:
//{
// formatter: function()
// {
// return( this.value / 10 + "0");
// }
//},
max: 30,
min: 10,
allowDecimals: false
},
// データ系列
series:
[
<?php
for( $i=0; $i<count($Temp_data); $i++ )
//for( $i=0; $i<2; $i++ )
{
if( $i == 0 )
{
echo " {\n";
}
else
{
echo " ,\n";
echo " {\n";
}
echo " name: '" . $Temp_d...
echo " // color: '#000000...
echo " type: 'line',\n"; ...
echo " data: [\n";
$handle = fopen( $Temp_data[$i][1], "r" );
if( ($line_data = fgetcsv( $handle, 0, "...
{
$plot_date = explode( '/', $line_dat...
$plot_time = explode( ':', $line_dat...
$temp = $line_data[2] * $Temp_data[$...
echo " [Date.UTC(...
echo $plot_time[0] . ", " . $plot_ti...
echo $temp . ']';
}
while( ($line_data = fgetcsv( $handle, 0...
{
$plot_date = explode( '/', $line_dat...
$plot_time = explode( ':', $line_dat...
$temp = $line_data[2] * $Temp_data[$...
echo ", [Date.UTC( " . $plot_date[0]...
echo $plot_time[0] ....
echo $temp . ']';
}
echo "\n";
echo " ]\n";
echo " }\n";
fclose( $handle );
}
?>
]
};
// jQueryのコードはDocumentがReady状態になったタイミ...
// 通常よく使われるbodyのonloadなどでは、ページ上の...
// レンダリングもされた状態で動作し始めるために、ユ...
// 開始されてしまう可能性があります。
// 逆にheadやbodyの中でパース時に実行させてしまって...
// 状態になっていない場合があるため、思わぬ不具合を...
$(document).ready(
function ()
{
chart = new Highcharts.Chart(options);
}
);
</script>
<title>Temper</title>
</head>
<body>
<h1 align="center">温度監視</h1>
<div id="container" style="width:1000px; height:400p...
</body>
</html>
<
***表示例 [#c3c0f09b]
&ref(Temper.JPG,zoom,Temper);
終了行:
*USB温度計 [#m586d8d5]
**はじめに [#md38cef7]
>
>[[安価なUSB温度計が発売されています。>http://www.limemo....
購入後しばらく放置していましたが、いつも電源が入りっぱな...
<
**Linux(CentOS)で温度測定 [#gf917631]
>
>付属のCD-ROMにはWindowsのドライバ、APLが収録されています...
早速、先人の成果を調査すると、[[Ubuntuでの情報>http://www...
ドライバはLinuxでは特にインストールすることなく、認識され...
# dmesg | grep TEMP
input: RDing TEMPerV1.2 as /class/input/input14
input,hidraw0: USB HID v1.10 Keyboard [RDing TEMPerV1.2]...
hiddev96,hidraw96: USB HID v1.10 Device [RDing TEMPerV1....
<
>
# lsusb
Bus 003 Device 001: ID 0000:0000
Bus 006 Device 001: ID 0000:0000
Bus 002 Device 005: ID 0624:0248 Avocent Corp.
Bus 002 Device 001: ID 0000:0000
Bus 004 Device 016: ID 0c45:7401 Microdia
Bus 004 Device 003: ID 0518:0001 EzKEY Corp. USB to PS2 ...
Bus 004 Device 002: ID 067b:2303 Prolific Technology, In...
Bus 004 Device 001: ID 0000:0000
Bus 005 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
<
***gitでtemperを取得 [#p2a3e08f]
-APLはgitのレポジトリにあるため、まず、gitをインストール...
>
# yum install git
Loaded plugins: fastestmirror, priorities, security
Loading mirror speeds from cached hostfile
* base: ftp.jaist.ac.jp
* extras: ftp.jaist.ac.jp
* rpmforge: ftp.kddilabs.jp
* updates: ftp.iij.ad.jp
126 packages excluded due to repository priority protect...
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package git.i386 0:1.7.11.3-1.el5.rf set to be upda...
--> Processing Dependency: perl-Git = 1.7.11.3-1.el5.rf ...
--> Processing Dependency: perl(Git) for package: git
--> Running transaction check
---> Package perl-Git.i386 0:1.7.11.3-1.el5.rf set to be...
--> Processing Dependency: perl(SVN::Ra) for package: pe...
--> Processing Dependency: perl(SVN::Delta) for package:...
--> Processing Dependency: perl(SVN::Client) for package...
--> Processing Dependency: perl(YAML::Any) for package: ...
--> Processing Dependency: perl(SVN::Core) for package: ...
--> Running transaction check
---> Package perl-YAML.noarch 0:0.72-1.el5.rf set to be ...
---> Package subversion-perl.i386 0:1.6.11-11.el5_9 set ...
--> Finished Dependency Resolution
Dependencies Resolved
========================================================...
Package Arch Version ...
========================================================...
Installing:
git i386 1.7.11.3-1.el5.rf...
Installing for dependencies:
perl-Git i386 1.7.11.3-1.el5.rf...
perl-YAML noarch 0.72-1.el5.rf ...
subversion-perl i386 1.6.11-11.el5_9 ...
Transaction Summary
========================================================...
Install 4 Package(s)
Upgrade 0 Package(s)
Total download size: 9.2 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): perl-Git-1.7.11.3-1.el5.rf.i386.rpm ...
(2/4): perl-YAML-0.72-1.el5.rf.noarch.rpm ...
(3/4): subversion-perl-1.6.11-11.el5_9.i386.rpm ...
(4/4): git-1.7.11.3-1.el5.rf.i386.rpm ...
--------------------------------------------------------...
Total ...
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : perl-YAML ...
Installing : subversion-perl ...
Installing : git ...
Installing : perl-Git ...
Installed:
git.i386 0:1.7.11.3-1.el5.rf
Dependency Installed:
perl-Git.i386 0:1.7.11.3-1.el5.rf perl-YAML...
subversion-perl.i386 0:1.6.11-11.el5_9
Complete!
<
-いよいよ、temperを落としてきます。
>
# cd /opt
# git clone git://github.com/bitplane/temper.git
Cloning into 'temper'...
remote: Counting objects: 69, done.
remote: Compressing objects: 100% (42/42), done.
remote: Total 69 (delta 28), reused 61 (delta 24)
Receiving objects: 100% (69/69), 13.39 KiB, done.
Resolving deltas: 100% (28/28), done.
# ll
合計 4
drwxr-xr-x 3 root root 4096 10月 19 10:38 temper
# cd temper/
<
***ビルド [#h275bd88]
-makeします。
>
# make
gcc -Wall temper.c pcsensor.c -o temper -lusb
<
>
>元の記事では、Ubuntuのため、
-build-essential
>をインストールしていますが、CentOSでは不要です。
<
***動作確認 [#zd546662]
-まず、素のままで動作確認します。
>
# ./temper
19-Oct-2013 01:48,28.403656
<
***修正 [#m60a956e]
-元記事にあるように、表示形式とローカライズ(GMT->JST)...
>
# diff -c temper.c.org temper.c
*** temper.c.org 2013-10-19 10:49:15.000000000 +0...
--- temper.c 2013-10-19 11:38:10.000000000 +0900
***************
*** 41,50 ****
struct tm *utc;
time_t t;
t = time(NULL);
! utc = gmtime(&t);
char dt[80];
! strftime(dt, 80, "%d-%b-%Y %H:%M", utc);
printf("%s,%f\n", dt, tempc);
fflush(stdout);
--- 41,52 ----
struct tm *utc;
time_t t;
t = time(NULL);
! //utc = gmtime(&t);
! utc = localtime(&t);
char dt[80];
! //strftime(dt, 80, "%d-%b-%Y %H:%M", utc);
! strftime(dt, 80, "%Y-%m-%d,%H:%M:%S", ut...
printf("%s,%f\n", dt, tempc);
fflush(stdout);
<
-修正が終了したら、リビルドを実施
>
# make
gcc -Wall temper.c pcsensor.c -o temper -lusb
<
***再度動作を確認 [#w0ab4567]
>
# ./temper
2013-10-19,11:41:29,26.732019
<
>
>次はWebからグラフを表示できるようにしましょう。
<
***定期測定 [#n45d28c1]
>
>定期的に温度測定をするため、シェルスクリプトをcronに登録...
<
-スクリプト
>
====================== /opt/temper/record.sh ===========...
#! /bin/sh
/usr/bin/tail -n 300 /opt/temper/data/temper.dat > /opt/...
/opt/temper/temper >> /opt/temper/data/temper.tmp
/bin/mv -f /opt/temper/data/temper.tmp /opt/temper/data/...
<
>
>301エントリーを最大保持します。
<
-cronへの登録
>
# temparature logging
*/15 * * * * /opt/temper/record.sh
<
**問題発生 [#j9d93c41]
>
>temperでは、以下の問題があります。
<
>
>単一のセンサしか制御できません。(2個入りのTEMPerは2個ま...
<
>
>>
+時々エラーが発生し、正常な読み取りができないばかりか、デ...
+温度補正ができません。
+特定のデバイスを指定して測定ができません。
<<
>1.2.については、temper同様、リトライ、補正処理を実施する...
>今回、pcsensorのソースを元に、temperのリトライ機能とバス...
<
***pcsensorの入手 [#w68fae0d]
-[[OSAKANA TAROさんのブログ>http://blog.osakana.net/]]か...
>
# wget http://blog.osakana.net/sw/pcsensor/pcsensor-1.0....
--2013-10-20 22:53:59-- http://blog.osakana.net/sw/pcse...
blog.osakana.net をDNSに問いあわせています... 222.229.47...
blog.osakana.net|222.229.47.46|:80 に接続しています... ...
HTTP による接続要求を送信しました、応答を待っています......
長さ: 12668 (12K) [application/x-gzip]
`pcsensor-1.0.2.tar.gz' に保存中
100%[===================================================...
2013-10-20 22:54:00 (401 KB/s) - `pcsensor-1.0.2.tar.gz'...
#
<
***ソースの修正 [#e16cce5a]
-ソースを修正します修正ポイントは以下のとおりです。
>
+オプション名の変更(省略可能な引数を許可しない)
+リトライの実施
+補正情報をオフセットとスケールに修正
+出力形式をtemperに整合
+バス番号指定による特定デバイス情報のみの表示
<
-まず、一部の定義をヘッダファイルを作成し、移動します。
>
>pcsensor.h
<
>
#define VENDOR_ID 0x0c45
#define PRODUCT_ID 0x7401
#define INTERFACE1 0x00
#define INTERFACE2 0x01
#define MAX_DEV 4
#define RETRY_CNT 3
void message_dump( char *mess, char *data, int len );
int exec_usb_detach( int dev, int iInterface );
int setup_libusb_access( void );
int find_lvr_winusb( void );
int ini_control_transfer( int dev_num );
int control_transfer( int dev_num, const char *pquestion...
int interrupt_transfer( int dev_num );
int interrupt_read( int dev_num );
int interrupt_read_temperatura( int dev_num, float *temp...
int bulk_transfer( int dev_num );
int get_temparatura( int dev_num );
<
>
>pcsensor.c
/*******************************************************...
* pcsensor.c by Juan Carlos Perez (c) 2011 (cray@isp-sl...
* based on Temper.c by Robert Kavaler (c) 2009 (relavak...
* All rights reserved.
*
* Temper driver for linux. This program can be compiled...
* or as a standalone program (-DUNIT_TEST). The driver ...
* TEMPer usb devices from RDing (www.PCsensor.com).
*
* Redistribution and use in source and binary forms, wi...
* modification, are permitted provided that the followi...
* * Redistributions of source code must retain th...
* notice, this list of conditions and the follo...
*
* THIS SOFTWARE IS PROVIDED BY Juan Carlos Perez ''AS I...
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIM...
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTI...
* DISCLAIMED. IN NO EVENT SHALL Robert kavaler BE LIABL...
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ...
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTI...
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTI...
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRI...
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WA...
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH ...
*
*******************************************************...
#include <usb.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "log_ctrl.h"
#include "pcsensor.h"
#define VERSION "1.0.3"
const static int ReqIntLen=8;
const static int ReqBulkLen=8;
const static int Endpoint_Int_in=0x82; // endpo...
const static int Endpoint_Int_out=0x00; // endpo...
const static int Endpoint_Bulk_in=0x82; // endpo...
const static int Endpoint_Bulk_out=0x00; // endpo...
const static int Timeout=5000; // Timeo...
const static char UTemperatura[] = { 0x01, 0x80, 0x33, 0...
const static char UIni1[] = { 0x01, 0x82, 0x77, 0x01, 0x...
const static char UIni2[] = { 0x01, 0x86, 0xff, 0x01, 0x...
static int Debug=0;
static int Disp_format=0;
static int Mrtg=0;
static float Scale=1.0;
static float Offset=0.0;
static int Disp_dev_name=0;
static int Disp_dev_list=0;
static int Target_bus=-1;
static int Max_dev = MAX_DEV;
static struct usb_bus *Usb_busses;
static usb_dev_handle *Handles[MAX_DEV];
static char *Devlist_bus[MAX_DEV];
static char *Devlist_device[MAX_DEV];
//======================================================...
// 概要:
// USB通信メッセージのダンプを行います。
//
// 引数:
// char *mess メッセージデータ
// int len データ長(バイト)
//
// 戻り値:
// (なし)
//
//======================================================...
void message_dump( char *mess, char *data, int len )
{
int i;
char str[256];
char *p;
p = str;
sprintf( p, "%s, Message length:%d, Data:%02X", ...
p += strlen( str );
for( i=1; i<len; i++ )
{
sprintf( p, " %02X", data[i] & 0xff );
p += 3;
}
log_write( LOG_DEBUG, "%s", str );
}
//======================================================...
// 概要:
// Kernelドライバにすでに組み込まれているデバイスを...
//
// 引数:
// int dev_no デバイス番号
// int interface インタフェース番号
//
// 戻り値:
// int 0: 正常終了
// -1: エラー
//
//======================================================...
int exec_usb_detach( int dev_no, int interface )
{
int ret;
ret = usb_detach_kernel_driver_np( Handles[dev_n...
if( ret )
{
if( errno == ENODATA )
{
log_write( LOG_DEBUG, "Device:[%...
}
else
{
log_write( LOG_DEBUG,
"Detach failed, Device:[...
dev_no,
strerror(errno),
errno
);
}
return( -1 );
}
else
{
log_write( LOG_DEBUG,
"Device[%d]: detach successful",
dev_no
);
return( 0 );
}
}
//======================================================...
// 概要:
// libusbを初期化し対象のセンサを検出します。
// 検出したデバイスをオープンし、各デバイスのハンド...
//
// 引数:
// (なし)
//
// 戻り値:
// int 検出したデバイス数
//
// グローバル変数操作:
// Handles[i] handle;
// Devlist_bus[i] bus->dirname;
// Devlist_device[i] dev->filename;
//======================================================...
int find_usb_sensor_dev( void )
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle;
int i;
memset( Handles, 0, sizeof(Handles) );
i = 0;
for( bus=Usb_busses; bus; bus=bus->next )
{
for( dev=bus->devices; dev; dev=dev->nex...
{
if( dev->descriptor.idVendor == ...
dev->descriptor.idProduc...
)
{
log_write( LOG_DEBUG,
"Found usb devic...
VENDOR_ID,
PRODUCT_ID,
i
);
if( !(handle = usb_open(...
{
log_write( LOG_E...
"Could n...
);
continue;
}
Handles[i] = handle;
Devlist_bus[i] = bus->di...
Devlist_device[i] = dev-...
i++;
if( i == MAX_DEV )
{
break;
}
}
}
}
return(i);
}
//======================================================...
// 概要:
// 対象のUSBデバイスをアクセスできるようにします。
// (コンフィグレーション)
//
// 引数:
// (なし)
//
// 戻り値:
// int セットアップしたデバイス数
//======================================================...
int setup_libusb_access( void )
{
int i = 0;
if( Debug )
{
usb_set_debug( 255 );
}
else
{
usb_set_debug( 0 );
}
usb_init();
usb_find_busses();
usb_find_devices();
Usb_busses = usb_get_busses();
if( !find_usb_sensor_dev() )
{
log_write( LOG_ERR, "Couldn't find the U...
return(0);
}
for( i=0; Handles[i] != NULL && i < Max_dev; i++ )
{
if( usb_set_configuration(Handles[i], 0x...
{
if( exec_usb_detach( i, INTERFAC...
{
if( usb_set_configuratio...
{
log_write( LOG_E...
"Could n...
i
);
return(0);
}
}
}
if( usb_claim_interface(Handles[i], INTE...
{
exec_usb_detach( i, INTERFACE1 );
if( usb_claim_interface(Handles[...
{
log_write( LOG_ERR,
"Could not claim...
i,
INTERFACE1
);
return(0);
}
}
if( usb_claim_interface(Handles[i], INTE...
{
exec_usb_detach( i, INTERFACE2 );
if( usb_claim_interface(Handles[...
{
log_write( LOG_ERR,
"Could not claim...
i,
INTERFACE2
);
return(0);
}
}
}
return(i);
}
//======================================================...
// 概要:
// デフォルトコントロールパイプへの転送のためのメッ...
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int ini_control_transfer( int dev_num )
{
int r;
char str[256];
char question[] = { 0x01,0x01 };
sprintf( str, "ini_control_transfer(), dev:%d ",...
message_dump( str, question, 2 );
r = usb_control_msg( Handles[dev_num], 0x21, 0x0...
if( r < 0 )
{
log_write( LOG_ERR,
"USB control write failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
return( 0 );
}
//======================================================...
// 概要:
// コントロール転送のためのメッセージをセットアップ...
// 引数:
// int dev_num デバイス番号
// char *question メッセージ
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int control_transfer( int dev_num, const char *pquestion )
{
int r;
char str[256];
char question[ReqIntLen];
memcpy( question, pquestion, sizeof(question) );
sprintf( str, "control_transfer(), dev:%d ", dev...
message_dump( str, question, sizeof( question ) );
r = usb_control_msg( Handles[dev_num], 0x21, 0x0...
if( r < 0 )
{
log_write( LOG_ERR,
"USB control write failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
return( 0 );
}
//======================================================...
// 概要:
// インタラプト転送によりメッセージを転送します。
// 引数:
// int dev_num デバイス番号
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int interrupt_transfer( int dev_num )
{
int r;
int i;
char str[256];
char answer[ReqIntLen];
char question[ReqIntLen];
for( i=0;i<ReqIntLen; i++ )
{
question[i]=i;
}
sprintf( str, "interrupt_transfer():write, dev:%...
message_dump( str, question, ReqIntLen );
r = usb_interrupt_write( Handles[dev_num], Endpo...
if( r < 0 )
{
log_write( LOG_ERR,
"USB interrupt write failed:%s[%...
strerror(errno),
errno
);
return( -1 );
}
r = usb_interrupt_read( Handles[dev_num], Endpoi...
if( r != ReqIntLen )
{
log_write( LOG_ERR,
"USB interrupt read failed:%s[%d...
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "interrupt_transfer():read, dev:%d...
message_dump( str, answer, ReqIntLen );
usb_release_interface( Handles[dev_num], 0 );
return( 0 );
}
//======================================================...
// 概要:
// インタラプト転送によりメッセージのリードを行いま...
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int interrupt_read( int dev_num )
{
int r;
char str[256];
char answer[ReqIntLen];
bzero( answer, ReqIntLen );
r = usb_interrupt_read( Handles[dev_num], 0x82, ...
if( r != ReqIntLen )
{
log_write( LOG_ERR,
"USB interrupt read failed:%s[%d...
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "interrupt_read():read, dev:%d ", ...
message_dump( str, answer, ReqIntLen );
return(0);
}
//======================================================...
// 概要:
// 温度を読み取ります。
//
// 引数:
// int dev_num デバイス番号
// float *tempC 摂氏による読み取り温度
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int interrupt_read_temperatura( int dev_num, float *temp...
{
int r;
int temperature;
char str[256];
char answer[ReqIntLen];
bzero( answer, ReqIntLen );
r = usb_interrupt_read( Handles[dev_num], 0x82, ...
if( r != ReqIntLen )
{
log_write( LOG_ERR,
"USB interrupt read failed:%s[%d...
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "interrupt_read():read, dev:%d ", ...
message_dump( str, answer, ReqIntLen );
temperature = (answer[3] & 0xFF) + ((signed char...
*tempC = temperature * (125.0 / 32000.0) * Scale...
return(0);
}
//======================================================...
// 概要:
// バルク転送を行います。
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
//======================================================...
int bulk_transfer( int dev_num )
{
int r;
char str[256];
char answer[ReqBulkLen];
log_write( LOG_DEBUG, "Data write(NULL)" );
r = usb_bulk_write( Handles[dev_num], Endpoint_B...
if( r < 0 )
{
log_write( LOG_ERR,
"USB bulk write failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
r = usb_bulk_read( Handles[dev_num], Endpoint_Bu...
if( r != ReqBulkLen )
{
log_write( LOG_ERR,
"USB bulk read failed:%s[%d]",
strerror(errno),
errno
);
return( -1 );
}
sprintf( str, "bulk_transfer():read, dev:%d ", d...
message_dump( str, answer, ReqIntLen );
usb_release_interface( Handles[dev_num], 0 );
return( 0 );
}
//======================================================...
// 概要:
// 温度情報の取得
//
// 引数:
// int dev_num デバイス番号
//
// 戻り値:
// int 0: 成功
// -1: 失敗
// -2: デバイスが存在しない
//
//======================================================...
int get_temparatura( int dev_num )
{
int ret;
float tempc;
struct tm *local;
time_t t;
if( (ret = setup_libusb_access()) == 0 )
{
return( 0 );
}
if( Handles[dev_num] == NULL )
{
return( 0 );
}
if( Disp_dev_list )
{
printf( "Device:%i is Bus_id:%s Device_i...
dev_num,
Devlist_bus[ dev_num ],
Devlist_device[ dev_num ]
);
}
else if( atoi(Devlist_bus[dev_num]) == Target_bu...
{
if( ini_control_transfer( dev_num ) ) ...
if( control_transfer( dev_num , UTemper...
if( interrupt_read( dev_num ) ) return...
if( control_transfer( dev_num , UIni1 )...
if( interrupt_read( dev_num ) ) return...
if( control_transfer( dev_num , UIni2 )...
if( interrupt_read( dev_num ) ) return...
if( interrupt_read( dev_num ) ) return...
if( control_transfer( dev_num , UTemper...
if( interrupt_read_temperatura( dev_num...
t = time( NULL );
local = localtime( &t );
if( Mrtg )
{
if( Disp_format & 0x02 )
{
printf( "%.4f\n", (9.0 /...
printf( "%.4f\n", (9.0 /...
}
else
{
printf( "%.4f\n", tempc );
printf( "%.4f\n", tempc );
}
printf( "%02d:%02d\n",
local->tm_hour,
local->tm_min
);
printf( "pcsensor\n" );
}
else
{
printf( "%04d/%02d/%02d,%02d:%02...
local->tm_year +1900,
local->tm_mon + 1,
local->tm_mday,
local->tm_hour,
local->tm_min,
local->tm_sec
);
if( Disp_dev_name > 0 )
{
printf( ",Bus:%s/Device:...
}
// printf( "Temperature" );
if( Disp_format == 0 )
{
printf( ",%.4fF", (9.0 /...
}
if( Disp_format & 0x02 )
{
printf( ",%.4f", (9.0 / ...
}
if( Disp_format == 0 )
{
printf( ",%.4fC", tempc );
}
if( Disp_format & 0x01 )
{
printf( ",%.4f", tempc );
}
printf( "\n" );
}
usb_release_interface( Handles[ dev_num ...
usb_release_interface( Handles[ dev_num ...
usb_close( Handles[ dev_num ] );
}
return( 0 );
}
//======================================================...
// 概要:
// メイン関数
// 引数:
// int argc コマンドラインの引数の数
// char **argv 引数リスト
// 戻り値:
// int 実行結果
//
//======================================================...
int main( int argc, char **argv )
{
int c;
int i;
int ret;
char *tok;
char arg[256];
strcpy( arg, argv[0] );
for( i=1; i<argc; i++ )
{
strcat( arg, " " );
strcat( arg, argv[i] );
}
log_write( LOG_INFO, "command = %s", arg );
memset( Handles, 0, sizeof(Handles) );
while ( (c = getopt (argc, argv, "mfcvhla:dB:"))...
switch ( c )
{
case 'v':
// 詳細な情報を表示します。
Debug = 1;
log_write( LOG_DEBUG, "option -v" );
break;
case 'c':
// 摂氏表示を行います。
Disp_format |= 0x01; //Celsius
log_write( LOG_DEBUG, "option -c" );
break;
case 'f':
// 華氏表示を行います。
Disp_format |= 0x02; //Fahrenheit
log_write( LOG_DEBUG, "option -f" );
break;
case 'm':
// MRTG用のデータ形式を出力します。
Mrtg=1;
log_write( LOG_DEBUG, "option -m" );
break;
case 'd':
// デバイスのバス/デバイスIDを含め表示し...
Disp_dev_name++;
log_write( LOG_DEBUG, "option -d" );
break;
case 'l':
// デバイス一覧を表示する
Disp_dev_list++;
log_write( LOG_DEBUG, "option -l" );
break;
case 'B':
// 対象のバスを指定します。
if( (tok = strtok( optarg, "," )) == NUL...
{
log_write( LOG_ERR, "option -B, ...
exit( 1 );
}
Target_bus = atoi( tok );
log_write( LOG_DEBUG, "option -B, target...
break;
case 'a':
// 温度補正データの設定をします。
if( (tok = strtok( optarg, "," )) == NUL...
{
log_write( LOG_ERR, "option -a, ...
exit( 1 );
}
Scale = atof( tok );
if( (tok = strtok( NULL, "," )) == NULL )
{
log_write( LOG_ERR, "option -a, ...
exit( 1 );
}
Offset = atof( tok );
log_write( LOG_DEBUG, "option -a, scale=...
break;
case '?':
case 'h':
printf( "pcsensor version %s\n", VERSION...
printf( " Aviable options:\n ");
printf( " -h help\n" );
printf( " -v verbose\n" );
printf( " -c output only in Celsius...
printf( " -f output only in Fahrenh...
printf( " -a <Scale>,<Offset>\n" );
printf( " compesate temparature:...
printf( " -m output for Mrtg integr...
printf( " -d output with Bus and De...
printf( " -l display device list\n"...
printf( " -B <n>\n" );
printf( " specific bus number\n"...
exit( 1 );
default:
if( isprint (optopt) )
{
log_write( LOG_ERR, "Unknown opt...
fprintf( stderr, "Unknown option...
}
else
{
log_write( LOG_ERR, "Unknown opt...
fprintf (stderr, "Unknown option...
}
exit( 1 );
}
if( optind < argc )
{
log_write( LOG_ERR, "Non-option ARGV-ele...
fprintf( stderr, "Non-option ARGV-elemen...
exit( 1 );
}
for( i=0; i < Max_dev; i++ )
{
int retry = RETRY_CNT;
while( retry )
{
ret = get_temparatura( i );
if( ret == 0 ) break;
sleep(3);
if( retry-- == 1)
{
log_write( LOG_ERR, "Unr...
exit(1);
}
}
}
exit(0);
}
<
-log_ctrl.h
>
/*******************************************************...
** Logging tool
** log_ctrl:
** General purpose logging tools for C lang...
**
**
*******************************************************...
#ifndef _LOG_CTRL_H
#define _LOG_CTRL_H 1
#ifndef _SYS_SYSLOG_H
#include <syslog.h>
#endif
/*******************************************************...
** MACROS
*******************************************************...
// =====================================================...
// log_write( LOG_LEVEL, <function_name>, <messages...
//
// =====================================================...
#define log_write( level, fmt, arg... ) log_write_sub( l...
/*******************************************************...
** Define structs
*******************************************************...
typedef struct _log_code
{
char *name;
int val;
} LOG_CODE;
/*******************************************************...
** for reference only
*******************************************************...
/* ============ Log Priorities (these are ordered) =====...
#define LOG_EMERG 0 system is unusable
#define LOG_ALERT 1 action must be taken imm...
#define LOG_CRIT 2 critical conditions
#define LOG_ERR 3 error conditions
#define LOG_WARNING 4 warning conditions
#define LOG_NOTICE 5 normal but signification...
#define LOG_INFO 6 informational
#define LOG_DEBUG 7 debug-level messages
=======================================================...
/* ============ Log Facilityes (these are ordered) =====...
#define LOG_KERN (0<<3) kernel messages
#define LOG_USER (1<<3) random user-level messages
#define LOG_MAIL (2<<3) mail system
#define LOG_DAEMON (3<<3) system daemons
#define LOG_AUTH (4<<3) security/authorization m...
#define LOG_SYSLOG (5<<3) messages generated inter...
#define LOG_LPR (6<<3) line printer subsystem
#define LOG_NEWS (7<<3) network news subsystem
#define LOG_UUCP (8<<3) UUCP subsystem
#define LOG_CRON (9<<3) UUCP subsystem
#define LOG_AUTHPRIV (10<<3) UUCP subsystem
#define LOG_FTP (11<<3) UUCP subsystem
#define LOG_NTP (12<<3) UUCP subsystem
#define LOG_AUDIT (13<<3) UUCP subsystem
#define LOG_ALERT (14<<3) UUCP subsystem
#define LOG_CLOCK (15<<3) UUCP subsystem
#define LOG_LOCAL0 (16<<3) reserved for local use
#define LOG_LOCAL1 (17<<3) reserved for local use
#define LOG_LOCAL2 (18<<3) reserved for local use
#define LOG_LOCAL3 (19<<3) reserved for local use
#define LOG_LOCAL4 (20<<3) reserved for local use
#define LOG_LOCAL5 (21<<3) reserved for local use
#define LOG_LOCAL6 (22<<3) reserved for local use
#define LOG_LOCAL7 (23<<3) reserved for local use
=======================================================...
/*******************************************************...
** Prototype definitions
*******************************************************...
int get_log_facility( char *facility_name );
void set_log_facility( int code );
void log_write_sub( int level, const char* format, ... );
// =========================================== End of co...
#endif
<
-log_ctrl.c
>
/*******************************************************...
** Logging tool
** log_ctrl:
** General purpose logging tools for C lang...
**
**
*******************************************************...
/*******************************************************...
** includes header files
*******************************************************...
#define _GNU_SOURCE
#include <string.h>
#include <syslog.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "log_ctrl.h"
/*******************************************************...
** Global viables but only use in Logging tool
*******************************************************...
static char *LOG_LEVEL_STR[] =
{
"EMERG",
"ALERT",
"CRIT",
"ERR",
"WARNING",
"NOTICE",
"INFO",
"DEBUG"
};
// =====================================================...
// Log facility code is permitted following codes.
// subset of RFC 3164
// =====================================================...
LOG_CODE FACILITY_NAMES[] =
{
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "user", LOG_USER },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
int LOG_facility_code = LOG_USER; // default facil...
/*******************************************************...
**
** [Name]
** get_log_facility
** [Description]
** get logfacility code
** [Arguments]
** char *facility_name facility name
** [Return Value]
** int LOG_facility_code -1:error,other:facility ...
**
*******************************************************...
int get_log_facility( char *facility_name )
{
char *str;
int i = 0;
int code = -1;
while( (str = FACILITY_NAMES[i].name) != NULL )
{
if( strcmp( str, facility_name ) == 0 )
{
code = FACILITY_NAMES[i].val;
break;
}
i++;
}
return( code );
}
/*******************************************************...
**
** [Name]
** set_log_facility
** [Description]
** set logfacility code
** [Arguments]
** char *facility_name facility name
** [Return Value]
** int LOG_facility_code -1:error,other:facility ...
**
*******************************************************...
void set_log_facility( int code )
{
LOG_facility_code = code;
}
/*******************************************************...
**
** [Name]
** log_write
** [Description]
** writes messages in logfile.
** [Arguments]
** int level log level
** const char* format, ... printf like format
** [Return Value]
** none
**
*******************************************************...
void log_write_sub( int level, const char* format, ... )
{
char *buff;
int size;
va_list ap;
va_start(ap, format);
size = vasprintf( &buff, format, ap );
va_end( ap );
openlog( "pcsensor", LOG_PID, LOG_MAKEPRI(LOG_fa...
syslog( level, "%s;%s\n", LOG_LEVEL_STR[level], ...
closelog();
free( buff );
}
// =========================================== End of co...
<
-Makefileも修正します。
>
all: pcsensor
CC = gcc
CFLAGS = -O2 -Wall -g
pcsensor: pcsensor.o log_ctrl.o -lusb
${CC} ${CFLAGS} -lusb -o pcsensor pcsensor.o log...
pcsensor.o: pcsensor.c pcsensor.h
${CC} ${CFLAGS} -DUNIT_TEST -c -o pcsensor.o pc...
log_ctrl.o: log_ctrl.c log_ctrl.h
${CC} ${CFLAGS} -c -o log_ctrl.o log_ctrl.c
clean:
rm -f pcsensor *.o
rules-install: # must be superuser to d...
cp 99-tempsensor.rules /etc/udev/rules.d
<
***ビルド [#o5aaeb7a]
-Makeします。
>
# make
gcc -O2 -Wall -g -DUNIT_TEST -c -o pcsensor.o pcsensor.c
gcc -O2 -Wall -g -c -o log_ctrl.o log_ctrl.c
gcc -O2 -Wall -g -lusb -o pcsensor pcsensor.o log_ctrl.o
#
<
***動作確認 [#fda0f004]
-デバイスリストを表示します。
>
# ./pcsensor -l
Device:0 is Bus_id:004 Device_id:100
Device:1 is Bus_id:005 Device_id:003
#
<
-バス番号を指定します。
>
# ./pcsensor -c -B 4
2013/10/25,23:07:33,22.6250
#
<
>
>以上で先のtemperと互換になりました。
<
**Webで時系列温度表示 [#p2f72120]
***グラフ表示の方法 [#d109aaf6]
>
>Webでグラフを表示するには、既存のSNMPマネージャに統合し...
<
>
-今後のWebアプリケーションの勉強のために、Javascriptsで記...
-スタンドアロンで動作する(GoogleのAPI等は使用しない)
<
>
>という方針で作成します。ネットでしらべましたが、「highch...
<
***highchartsの入手 [#re5769e8]
-[[highcharts のページ>http://www.highcharts.com/]]より...
商用利用では有料です。
-[[ダウンロードページ>http://www.highcharts.com/download]...
-ファイルを解凍すると以下のように展開されます。
>
# ll
合計 12824
-rw-r--r-- 1 vod users 13080205 10月 19 18:16 Highchart...
drwxr-xr-x 59 vod users 4096 10月 4 15:24 examples
drwxr-xr-x 5 vod users 4096 10月 4 15:24 exporting...
drwxr-xr-x 2 vod users 4096 10月 4 15:24 gfx
drwxr-xr-x 2 vod users 4096 10月 4 15:24 graphics
-rw-r--r-- 1 vod users 4989 10月 4 15:24 index.htm
drwxr-xr-x 5 vod users 4096 10月 4 15:24 js
<
-このうち使用するのは
>
./exporting-server/phantomjs/jquery.1.9.1.min.js
./exporting-server/phantomjs/highcharts.js
<
>
>の2個のファイルです。
<
***コード [#t4159da9]
>
>では、早速試験コードです。ファイルアクセスはPHPで行って...
====================== index.php =======================...
<?php
ini_set( 'display_errors', 1 ); // エラー出力する...
ini_set( 'error_reporting', E_ALL | E_STRICT );
$Temp_data = array (
array( "Server Room", "/opt/temper/dat...
array( "External Air", "/opt/temper/dat...
);
?>
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="./js/jquery.min.js">...
<script type="text/javascript" src="./js/highcharts.js">...
<script type="text/javascript">
var chart;
var options =
{
// 以下によりグラフのオプションを設定
// グラフ全体の設定
chart:
{
renderTo: 'container', // (String)グ...
defaultSeriesType: 'line', // デフォルト...
// line: ...
// area: ...
// spline:...
// column...
// bar: ...
// pie: ...
// scatter...
// backgroundColor: null, // (String)全...
borderWidth: 1 // (Number)グ...
// グラフ...
// borderRadius: ????, // (Number)カ...
// borderColor: '#ffffff', // (String)グ...
// plotBackgroundColor: null // (String)プ...
// inverted: // (Boolean)tr...
// zoomType: // (String)zoo...
// ”x”の他...
},
// タイトルの設定
title:
{
text: '温度グラフ', // (String)タイトルの...
align: 'center' // (String)タイトルの...
// 左寄せ: “left”
// 中央揃え: ...
// 右寄せ: ...
//style: // (CSS Object)タイト...
// ただし位置揃え...
// 上に書いたalig...
//floating: // (Boolena)true にす...
},
// サブタイトルの設定
subtitle:
{
text: '(試行中)',
align: 'center'
},
// 凡例の設定
legend:
{
layout: 'vertical', // (String)複数の系列...
// タテに並べる:ve...
// ヨコに並べる:h...
align: 'right', // (String)凡例の位置...
// left
// center
// right
verticalAlign: 'top', //
// reversed // (Boolean)true にす...
// もっと複雑に指...
// legendIndex を...
// borderWidth // (Number) 枠線の太...
// borderColor // (String) 枠線の色...
// borderRadius // (Number) 枠線の角...
// backgroundColor // (String) 枠線の背...
floating: true // (Boolena)true にす...
},
/*
// グラフにマウスオーバーすると出てくるポップア...
tooltip:
{
formatter: function()
{
return( this.y + '℃' );
},
enabled:true
},
*/
// X軸
xAxis:
{
type: 'datetime', // (String) 軸の種類を...
// linear: (...
// datetime: 時...
// logarithmic ...
title:
{
text: 'date/time' // (String) 軸のタ...
}
// max // (Number) 軸の最...
// minx // (Number) 軸の最...
// lineWidth // (Number) 軸の太...
// lineColor // (String) 軸の太...
//allowDecimals: false, // (Boolean) グラフ...
// categories // (Array) 軸の目盛...
// 指定形式にし...
},
// Y軸
yAxis:
{
type: 'linear',
title:
{
text: '℃'
// style:
// {
// color: '#4572A7'
// }
},
//labels:
//{
// formatter: function()
// {
// return( this.value / 10 + "0");
// }
//},
max: 30,
min: 10,
allowDecimals: false
},
// データ系列
series:
[
<?php
for( $i=0; $i<count($Temp_data); $i++ )
//for( $i=0; $i<2; $i++ )
{
if( $i == 0 )
{
echo " {\n";
}
else
{
echo " ,\n";
echo " {\n";
}
echo " name: '" . $Temp_d...
echo " // color: '#000000...
echo " type: 'line',\n"; ...
echo " data: [\n";
$handle = fopen( $Temp_data[$i][1], "r" );
if( ($line_data = fgetcsv( $handle, 0, "...
{
$plot_date = explode( '/', $line_dat...
$plot_time = explode( ':', $line_dat...
$temp = $line_data[2] * $Temp_data[$...
echo " [Date.UTC(...
echo $plot_time[0] . ", " . $plot_ti...
echo $temp . ']';
}
while( ($line_data = fgetcsv( $handle, 0...
{
$plot_date = explode( '/', $line_dat...
$plot_time = explode( ':', $line_dat...
$temp = $line_data[2] * $Temp_data[$...
echo ", [Date.UTC( " . $plot_date[0]...
echo $plot_time[0] ....
echo $temp . ']';
}
echo "\n";
echo " ]\n";
echo " }\n";
fclose( $handle );
}
?>
]
};
// jQueryのコードはDocumentがReady状態になったタイミ...
// 通常よく使われるbodyのonloadなどでは、ページ上の...
// レンダリングもされた状態で動作し始めるために、ユ...
// 開始されてしまう可能性があります。
// 逆にheadやbodyの中でパース時に実行させてしまって...
// 状態になっていない場合があるため、思わぬ不具合を...
$(document).ready(
function ()
{
chart = new Highcharts.Chart(options);
}
);
</script>
<title>Temper</title>
</head>
<body>
<h1 align="center">温度監視</h1>
<div id="container" style="width:1000px; height:400p...
</body>
</html>
<
***表示例 [#c3c0f09b]
&ref(Temper.JPG,zoom,Temper);
ページ名: