-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpf100-meter.rb
executable file
·106 lines (94 loc) · 2.63 KB
/
pf100-meter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
require 'hidapi'
class PF100Meter
VENDOR_ID = 0x04b4
PRODUCT_ID = 0x5500
def initialize
@connected = false
connect
end
def connect
@usb = HIDAPI::open(VENDOR_ID, PRODUCT_ID)
if(!@usb) then
@connected = false
else
@connected = true
@usb.blocking = false
end
end
def self.setup
HIDAPI::SetupTaskHelper.new(
VENDOR_ID, # vendor_id
PRODUCT_ID, # product_id
"Microlife PF100", # simple_name
0 # interface
).run
end
def connected?
@connected
end
def send(packet)
@usb.write packet.to_s
end
def receive
full_data = []
tries = 4
while(tries > 0) do
tries -= 1
raw_data = @usb.read
if(!raw_data or raw_data == "") then
sleep 0.25
next
end
tries += 1
full_data.push raw_data
# break if we have "OK" at the end of the last data sub-packet
type, data = PF100Packet::from_s(raw_data)
break if full_data[-2..-1] == [79, 75]
end
return nil if full_data == ""
PF100Packet.new(full_data)
end
def expect_response(expected_packet)
response = receive
return nil if !response or response.type == nil
return true if response == expected_packet
# TODO: this should be more elegant
puts "Received unexpected message from PF100, aborting."
Kernel.exit(2)
end
def ping
ping_pkt = PF100Packet.new(:request, [0x2c, 0x7b, 0x7d])
send ping_pkt
pong_pkt = PF100Packet.new(:response, [0x2c, 0x7b, 0x00, 0x00, 0x20, 0x56, 0x7d])
expect_response pong_pkt
end
def get_records
get_records_pkt = PF100Packet.new(:request, [0x2f, 0x7b, 0x7d, 0xf8, 0x4f, 0x60, 0xff])
send get_records_pkt
records_pkt = receive
raw_records = records_pkt.data
records = Array.new
while(true)
record = raw_records.shift(12)
break if record == []
year = "20#{record[2].to_s(16)}".to_i
month = record[3].to_s(16).to_i
day = record[4].to_s(16).to_i
hour = record[5].to_s(16).to_i
minute = record[6].to_s(16).to_i
pef_right = record[7].to_s(16).to_i
pef_left = record[8].to_s(16).to_i
pef = sprintf("%d%02d", pef_left, pef_right).to_i
fev_right = record[9].to_s(16).to_i
fev_left = record[10].to_s(16).to_i
fev = sprintf("%d.%02d", fev_left, fev_right).to_f
records.push PF100Record.new(year, month, day, hour, minute, pef, fev)
end
records
end
def clear_all_data
clear_pkt = PF100Packet.new(:request, [0x2d, 0x7b, 0x7d, 0x7e, 0x53, 0x60, 0xff])
send clear_pkt
expect_response PF100Packet.new(:response, [])
end
end