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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +5 -0
- data/Guardfile +70 -0
- data/LICENSE.md +201 -0
- data/README.md +38 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/tamashii-agent +95 -0
- data/lib/tamashii/agent.rb +18 -0
- data/lib/tamashii/agent/adapter/base.rb +28 -0
- data/lib/tamashii/agent/adapter/buzzer.rb +21 -0
- data/lib/tamashii/agent/adapter/card_reader.rb +20 -0
- data/lib/tamashii/agent/buzzer.rb +35 -0
- data/lib/tamashii/agent/card_reader.rb +57 -0
- data/lib/tamashii/agent/common.rb +13 -0
- data/lib/tamashii/agent/common/loggable.rb +18 -0
- data/lib/tamashii/agent/component.rb +71 -0
- data/lib/tamashii/agent/config.rb +26 -0
- data/lib/tamashii/agent/connection.rb +231 -0
- data/lib/tamashii/agent/device/fake_buzzer.rb +30 -0
- data/lib/tamashii/agent/device/fake_card_reader.rb +37 -0
- data/lib/tamashii/agent/device/pi_buzzer.rb +70 -0
- data/lib/tamashii/agent/handler.rb +10 -0
- data/lib/tamashii/agent/handler/base.rb +15 -0
- data/lib/tamashii/agent/handler/buzzer.rb +14 -0
- data/lib/tamashii/agent/handler/request_pool_response.rb +14 -0
- data/lib/tamashii/agent/handler/system.rb +14 -0
- data/lib/tamashii/agent/master.rb +113 -0
- data/lib/tamashii/agent/request_pool.rb +80 -0
- data/lib/tamashii/agent/request_pool/request.rb +38 -0
- data/lib/tamashii/agent/request_pool/response.rb +18 -0
- data/lib/tamashii/agent/version.rb +5 -0
- data/tamashii-agent.gemspec +46 -0
- metadata +252 -0
@@ -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,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/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
|