tamashii-agent 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,30 @@
1
+ require 'tamashii/agent/common'
2
+ module Tamashii
3
+ module Agent
4
+ module Device
5
+ class FakeBuzzer
6
+ include Common::Loggable
7
+
8
+ def initialize
9
+ logger.debug "Initialized"
10
+ end
11
+
12
+ def play_ok
13
+ logger.debug "Played: OK"
14
+ end
15
+
16
+ def play_no
17
+ logger.debug "Played: No"
18
+ end
19
+
20
+ def play_error
21
+ logger.debug "Played: Error"
22
+ end
23
+
24
+ def stop
25
+ logger.debug "Stopped"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ require 'tamashii/agent/common'
2
+ module Tamashii
3
+ module Agent
4
+ module Device
5
+ class FakeCardReader
6
+ include Common::Loggable
7
+
8
+ def initialize(*args)
9
+ logger.debug "Initialized"
10
+ @last_time = Time.now
11
+ end
12
+
13
+ def picc_request(*args)
14
+ if Time.now - @last_time > 2
15
+ @last_time = Time.now
16
+ if rand > 0.5
17
+ logger.debug "Fake Card Generated"
18
+ return true
19
+ else
20
+ return false
21
+ end
22
+ else
23
+ return false
24
+ end
25
+ end
26
+
27
+ def picc_select(*args)
28
+ [Array.new(4){ rand(256)}, "sak"]
29
+ end
30
+
31
+ def picc_halt(*args)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,70 @@
1
+ require 'pi_piper'
2
+ module Tamashii
3
+ module Agent
4
+ module Device
5
+ class PIBuzzer
6
+ SHORT_PLAY_TIME = 0.2
7
+ LONG_PLAY_TIME = 0.5
8
+ REPEAT_INTERVAL = 0.1
9
+ LOW_FREQ = 0.7
10
+
11
+ attr_reader :pwm
12
+
13
+ def initialize
14
+ @pwm = PiPiper::Pwm.new pin: 18 #, mode: :markspace
15
+ @pwm.off
16
+ @pwm.value = 1.0
17
+ end
18
+
19
+ def play(value = 1.0)
20
+ @pwm.value = value
21
+ @pwm.on
22
+ end
23
+
24
+ def stop
25
+ @pwm.off
26
+ end
27
+
28
+ def play_short(value = 1.0)
29
+ play_time(SHORT_PLAY_TIME,value)
30
+ end
31
+
32
+ def play_long(value = 1.0)
33
+ play_time(LONG_PLAY_TIME,value)
34
+ end
35
+
36
+ def play_time(time, value = 1.0)
37
+ play(value)
38
+ sleep time
39
+ stop
40
+ end
41
+
42
+ def play_repeat_short(repeat, repeat_interval = REPEAT_INTERVAL)
43
+ repeat.times do
44
+ play_short
45
+ sleep repeat_interval
46
+ end
47
+ end
48
+
49
+ def play_repeat_long(repeat, repeat_interval = REPEAT_INTERVAL)
50
+ repeat.times do
51
+ play_long
52
+ sleep repeat_interval
53
+ end
54
+ end
55
+
56
+ def play_ok
57
+ play_repeat_short(1)
58
+ end
59
+
60
+ def play_no
61
+ play_repeat_short(3)
62
+ end
63
+
64
+ def play_error
65
+ play_repeat_long(3)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,10 @@
1
+ require 'tamashii/agent/handler/request_pool_response'
2
+ require 'tamashii/agent/handler/system'
3
+ require 'tamashii/agent/handler/buzzer'
4
+
5
+ module Tamashii
6
+ module Agent
7
+ module Handler
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ require 'tamashii/common'
2
+
3
+ module Tamashii
4
+ module Agent
5
+ module Handler
6
+ class Base < Tamashii::Handler
7
+ def initialize(*args, &block)
8
+ super(*args, &block)
9
+ @connection = self.env[:connection]
10
+ @master = @connection.master
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require 'tamashii/agent/common'
2
+ require 'tamashii/agent/handler/base'
3
+
4
+ module Tamashii
5
+ module Agent
6
+ module Handler
7
+ class Buzzer < Base
8
+ def resolve(data)
9
+ @master.send_event(EVENT_BEEP, data)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'tamashii/agent/handler/base'
2
+ require 'tamashii/agent/request_pool'
3
+
4
+ module Tamashii
5
+ module Agent
6
+ module Handler
7
+ class RequestPoolResponse < Base
8
+ def resolve(data)
9
+ @connection.request_pool.add_response(RequestPool::Response.new(self.type, data))
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'tamashii/agent/common'
2
+ require 'tamashii/agent/handler/base'
3
+
4
+ module Tamashii
5
+ module Agent
6
+ module Handler
7
+ class System < Base
8
+ def resolve(data)
9
+ @master.send_event(EVENT_SYSTEM_COMMAND, type.to_s)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,113 @@
1
+ require 'tamashii/agent/connection'
2
+ require 'tamashii/agent/buzzer'
3
+ require 'tamashii/agent/card_reader'
4
+
5
+ require 'thread'
6
+
7
+ module Tamashii
8
+ module Agent
9
+ class Master < Component
10
+
11
+ attr_reader :serial_number
12
+
13
+ def initialize(host, port)
14
+ super()
15
+ logger.info "Starting Tamashii::Agent #{Tamashii::Agent::VERSION} in #{Config.env} mode"
16
+ @host = host
17
+ @port = port
18
+ @serial_number = get_serial_number
19
+ logger.info "Serial number: #{@serial_number}"
20
+ create_components
21
+ end
22
+
23
+ def get_serial_number
24
+ File.open("/proc/cpuinfo") do |f|
25
+ content = f.read
26
+ if content =~ /Serial\s*:\s*(\w+)/
27
+ return $1
28
+ end
29
+ end
30
+ # Cannot get serial number
31
+ if Config.env == "test"
32
+ return "TEST_PID_#{Process.pid}"
33
+ else
34
+ return nil
35
+ end
36
+ end
37
+
38
+ def create_components
39
+ @components = {}
40
+ @components[:connection] = create_component(Connection, self, @host, @port)
41
+ @components[:buzzer] = create_component(Buzzer)
42
+ @components[:card_reader] = create_component(CardReader, self)
43
+ end
44
+
45
+ def create_component(class_name, *args)
46
+ c = class_name.new(*args)
47
+ logger.info "Starting component: #{class_name}"
48
+ yield c if block_given?
49
+ c.run
50
+ c
51
+ end
52
+
53
+ # override
54
+ def process_event(ev_type, ev_body)
55
+ super
56
+ case ev_type
57
+ when EVENT_SYSTEM_COMMAND
58
+ logger.info "System command code: #{ev_body}"
59
+ case ev_body.to_i
60
+ when Tamashii::Type::REBOOT
61
+ system_reboot
62
+ when Tamashii::Type::POWEROFF
63
+ system_poweroff
64
+ when Tamashii::Type::RESTART
65
+ system_restart
66
+ when Tamashii::Type::UPDATE
67
+ system_update
68
+ end
69
+ when EVENT_CONNECTION_NOT_READY
70
+ broadcast_event(EVENT_BEEP, "error")
71
+ else
72
+ broadcast_event(ev_type, ev_body)
73
+ end
74
+ end
75
+
76
+ def system_reboot
77
+ logger.info "Rebooting..."
78
+ system("reboot &")
79
+ end
80
+
81
+ def system_poweroff
82
+ logger.info "Powering Off..."
83
+ system("poweroff &")
84
+ end
85
+
86
+ def system_restart
87
+ logger.info "Restarting..."
88
+ system("systemctl restart tamashii-agent.service &")
89
+ end
90
+
91
+ def system_update
92
+ logger.info "Updating..."
93
+ system("gem update tamashii-agent")
94
+ system_restart
95
+ end
96
+
97
+ # override
98
+ def stop
99
+ super
100
+ @components.each_value do |c|
101
+ c.stop
102
+ end
103
+ end
104
+
105
+
106
+ def broadcast_event(ev_type, ev_body)
107
+ @components.each_value do |c|
108
+ c.send_event(ev_type, ev_body)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,80 @@
1
+ require 'tamashii/agent/common'
2
+ require 'tamashii/agent/request_pool/request'
3
+ require 'tamashii/agent/request_pool/response'
4
+
5
+
6
+ module Tamashii
7
+ module Agent
8
+ class RequestPool
9
+ include Common::Loggable
10
+ def initialize
11
+ @pool = {}
12
+ @handlers = {}
13
+ end
14
+
15
+ def set_handler(sym, method)
16
+ @handlers[sym] = method
17
+ end
18
+
19
+ def call_handler(sym, *args)
20
+ if handle?(sym)
21
+ @handlers[sym].call(*args)
22
+ else
23
+ logger.warn "WARN: un-handled event: #{sym}"
24
+ end
25
+ end
26
+
27
+ def handle?(sym)
28
+ @handlers.has_key? sym
29
+ end
30
+
31
+ def add_request(req, timedout = 3)
32
+ @pool[req.id] = {req: req, timestamp: Time.now, timedout: timedout}
33
+ try_send_request(req)
34
+ end
35
+
36
+ def add_response(res)
37
+ # find the same id
38
+ req_data = @pool[res.id]
39
+ if req_data
40
+ @pool.delete(res.id)
41
+ call_handler(:request_meet, req_data[:req], res)
42
+ else
43
+ # unmatched response
44
+ # discard
45
+ logger.warn "WARN: un-matched response (id=#{res.id}): #{res.inspect}"
46
+ end
47
+ end
48
+
49
+ def update
50
+ process_pending
51
+ check_timedout
52
+ end
53
+
54
+ def check_timedout
55
+ now = Time.now
56
+ @pool.each do |id, req_data|
57
+ if now - req_data[:timestamp] >= req_data[:timedout]
58
+ # timedout
59
+ @pool.delete(id)
60
+ call_handler(:request_timedout, req_data[:req])
61
+ end
62
+ end
63
+ end
64
+
65
+ def process_pending
66
+ @pool.each_value do |data|
67
+ try_send_request(data[:req]) unless data[:req].sent?
68
+ end
69
+ end
70
+
71
+ def try_send_request(req)
72
+ if handle?(:send_request)
73
+ req.sent! if call_handler(:send_request, req)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+
@@ -0,0 +1,38 @@
1
+ require 'json'
2
+ module Tamashii
3
+ module Agent
4
+ class RequestPool
5
+ class Request
6
+ attr_accessor :id
7
+ attr_accessor :ev_type
8
+ attr_accessor :ev_body
9
+ attr_accessor :state
10
+
11
+ STATE_PENDING = :pending
12
+ STATE_SENT = :sent
13
+
14
+ def initialize(ev_type, ev_body, id)
15
+ @ev_type = ev_type
16
+ @ev_body = ev_body
17
+ @id = id
18
+ @state = STATE_PENDING
19
+ end
20
+
21
+ def wrap_body
22
+ {
23
+ id: @id,
24
+ ev_body: @ev_body
25
+ }.to_json
26
+ end
27
+
28
+ def sent!
29
+ @state = STATE_SENT
30
+ end
31
+
32
+ def sent?
33
+ @state == STATE_SENT
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end