Last active
June 4, 2016 08:55
-
-
Save tako2/966c4d778c6db8dabc7c to your computer and use it in GitHub Desktop.
Log serial text from ToCoStick (TWE - wireless usb device). This code needs python-serial and python-daemon.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# coding: UTF-8 | |
from __future__ import with_statement | |
import sys | |
import serial | |
import os.path | |
import datetime | |
from optparse import OptionParser | |
from daemon import DaemonContext | |
from daemon.pidlockfile import PIDLockFile | |
#============================================================================== | |
# :788115017581000038002899000C04230000FFFFFFFFFFD4 | |
# ^1^2^3^4^5^^^^^^^6^7^^^8^9^^^a^b^c^de1e2e3e4ef^g | |
# | |
# データフォーマット | |
# 1: 送信元の論理デバイスID (0x78 は子機からの通知) | |
# 2: コマンド(0x81: IO状態の通知) | |
# 3: パケット識別子 (アプリケーションIDより生成される) | |
# 4: プロトコルバージョン (0x01 固定) | |
# 5: LQI値、電波強度に応じた値で 0xFF が最大、0x00 が最小 | |
# 6: 送信元の個体識別番号 | |
# 7: 宛先の論理デバイスID | |
# 8: タイムスタンプ (秒64カウント) | |
# 9: 中継フラグ(中継済みなら1) | |
# a: 電源電圧[mV] | |
# b: 未使用 | |
# c: DI の状態ビット。DI1(0x1) DI2(0x2) DI3(0x4) DI4(0x8)。1がOn(Lowレベル)。 | |
# d: DI の変更状態ビット。DI1(0x1) DI2(0x2) DI3(0x4) DI4(0x8)。1が変更対象。 | |
# e1~e4: AD1~AD4の変換値。0~2000[mV]のAD値を16で割った値を格納。 | |
# ef: AD1~AD4の補正値 (LSBから順に2ビットずつ補正値、LSB側が AD1, MSB側が AD4) | |
# g: チェックサム | |
#============================================================================== | |
def parse_twe_message(res): | |
data = {} | |
data['dev_id'] = res[1:3] | |
data['cmd'] = res[3:5] | |
data['pkt_id'] = res[5:7] | |
data['protocol'] = res[7:9] | |
data['lqi'] = res[9:11] | |
data['from'] = res[11:19] | |
data['to_id'] = res[19:21] | |
data['timestamp'] = int(res[21:25], 16) | |
data['relay'] = res[25:27] | |
data['vol'] = int(res[27:31], 16) | |
data['di_st'] = res[33:35] | |
data['di_ch'] = res[35:37] | |
e1 = int(res[37:39], 16) | |
e2 = int(res[39:41], 16) | |
e3 = int(res[41:43], 16) | |
e4 = int(res[43:45], 16) | |
ef = int(res[45:47], 16) | |
data['ad1'] = ((e1 * 4) + (ef & 0x03)) * 4 | |
ef = ef / 4 | |
data['ad2'] = ((e2 * 4) + (ef & 0x03)) * 4 | |
ef = ef / 4 | |
data['ad3'] = ((e3 * 4) + (ef & 0x03)) * 4 | |
ef = ef / 4 | |
data['ad4'] = ((e4 * 4) + (ef & 0x03)) * 4 | |
# chksum = ers[47:49] | |
return data | |
#============================================================================== | |
# Log TWE Message | |
#============================================================================== | |
log_items = ['dev_id', 'cmd', 'pkt_id', 'protocol', 'lqi', 'from', 'to_id', | |
'timestamp', 'relay', 'vol', 'di_st', 'di_ch', | |
'ad1', 'ad2', 'ad3', 'ad4']; | |
def log_twe(devfile, path): | |
twelog = None | |
templog = None | |
try: | |
ser = serial.Serial(devfile, 115200, timeout=1) | |
twelog = open(path + 'twelog.csv', 'a') | |
templog = open(path + 'templog.csv', 'a') | |
temp_val = 0 | |
temp_cnt = 0 | |
temp_min = -1 | |
while True: | |
res = ser.readline() | |
if res.startswith(':'): | |
# print res | |
# Log All Data | |
now = datetime.datetime.today() | |
log = now.strftime('%Y%m%d,%H%M%S') | |
data = parse_twe_message(res) | |
# print data | |
for key in log_items: | |
if isinstance(data[key], int): | |
log += ',' + key + ':' + str(data[key]) | |
else: | |
log += ',' + key + ':' + data[key] | |
log += '\n' | |
twelog.write(log) | |
twelog.flush() | |
# Log Temperature | |
cur_temp = (data['ad1'] - 424) / 6.25 | |
if temp_min < 0 or temp_min == now.minute: | |
#print '+ ' + str(cur_temp) | |
temp_val += cur_temp | |
temp_cnt += 1 | |
else: | |
#print str(temp_val) + ' / ' + str(temp_cnt), | |
temp_val /= temp_cnt | |
temp_val = round(temp_val, 2) | |
#print '= ' + str(temp_val) | |
log = now.strftime('%Y%m%d,%H%M') + ',' + str(temp_val) | |
log += '\n' | |
templog.write(log) | |
templog.flush() | |
#print ' ' + str(cur_temp) | |
temp_val = cur_temp | |
temp_cnt = 1 | |
temp_min = now.minute | |
finally: | |
if twelog is not None: | |
twelog.close() | |
if templog is not None: | |
templog.close() | |
ser.close() | |
############################################################################### | |
if __name__ == '__main__': | |
parser = OptionParser() | |
parser.add_option("-p", "--path", dest="path", | |
help="PATH to write log at", metavar="PATH") | |
parser.add_option("-d", "--daemon", | |
action="store_true", dest="daemon", default=False, | |
help="daemonize") | |
(options, args) = parser.parse_args() | |
if len(args) == 0: | |
devfile = '/dev/ttyUSB0' | |
else: | |
devfile = args[0] | |
if options.path is None: | |
path = os.path.abspath(os.path.dirname(__file__)) + '/' | |
else: | |
path = options.path | |
if not path.endswith('/'): | |
path += '/' | |
if options.daemon: | |
dc = DaemonContext(pidfile=PIDLockFile('/tmp/twelog.pid'), | |
stderr = open('/tmp/twelog.err', 'w+')) | |
with dc: | |
log_twe(devfile, path) | |
else: | |
log_twe(devfile, path) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment