microgear 0.0.1

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/microgear.rb +238 -0
  3. metadata +72 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27c051ae1ca0e033e71a235d0d5ea688a2b168f0
4
+ data.tar.gz: e4f2bb3fd3791bbb30eeb41a51c72d51d89405d2
5
+ SHA512:
6
+ metadata.gz: 6a9d4f99491981de62ed636976c730236a0e73deea8d31c681b3282674e4f9c4268cf7d40672bac20ad411ae006e88ec273b1d4c13e146b3858c49a5cd4d61de
7
+ data.tar.gz: 283449bdf84b0fba083757dbae9516fb3ed6cc9b123d0ec32857ce51a2f3e8b153f017ba9ad68555ba6b76dc076bad3b657871e8d3e661b73d854e56580763c9
@@ -0,0 +1,238 @@
1
+ require "logger"
2
+ require "uri"
3
+ require "oauth"
4
+ require "securerandom"
5
+ require "openssl"
6
+ require "base64"
7
+ require "fiber"
8
+ require "mqtt"
9
+
10
+ require_relative "microgear/cache"
11
+
12
+ class Microgear
13
+
14
+ MINTOKDELAYTIME = 100;
15
+ MAXTOKDELAYTIME = 15000;
16
+ MGREV = 'NJ1';
17
+
18
+ GEARAUTHSITE = "http://61.91.14.29:8080/"
19
+ GEARAUTHREQUESTTOKENENDPOINT = "/oauth/request_token"
20
+ GEARAUTHACCESSTOKENENDPOINT = "/oauth/access_token"
21
+
22
+ def initialize(gearkey,gearsecret, appid, args = {})
23
+ @logger = Logger.new(STDERR)
24
+ @logger = Logger.new(STDOUT)
25
+ if args[:debugmode]
26
+ @logger.level = Logger::DEBUG
27
+ else
28
+ @logger.level = Logger::INFO
29
+ end
30
+
31
+ @gearkey = gearkey
32
+ @gearsecret = gearsecret
33
+
34
+ @appid = appid
35
+ @gearname = nil
36
+
37
+ @accesstoken = nil
38
+ @requesttoken = nil
39
+ @client = nil
40
+ @scope = args[:scope] || ""
41
+
42
+ @gearexaddress = nil
43
+ @gearexport = nil
44
+
45
+ @subscriptions = []
46
+ @callbacks = {}
47
+ end
48
+
49
+ def connect
50
+ get_token
51
+ @logger.info @accesstoken
52
+ @logger.debug "gearID : "+@appid
53
+ nonce = SecureRandom.hex(8)
54
+ hkey = @accesstoken["secret"]+"&"+@gearsecret
55
+ conn_opts = {
56
+ host: @gearexaddress,
57
+ username: @gearkey+'%'+Time.now.to_i.to_s,
58
+ client_id: @accesstoken["token"],
59
+ keep_alive: 10
60
+ }
61
+ digest = OpenSSL::Digest.new('sha1')
62
+ conn_opts[:password] = Base64.encode64(OpenSSL::HMAC.digest(digest, hkey, @accesstoken["token"]+"%"+conn_opts[:username])).strip
63
+ @logger.debug "mqttuser : "+conn_opts[:username]
64
+ @logger.debug "mqttpassword : "+conn_opts[:password]
65
+ @subscriptions.push('/piegear/'+conn_opts[:client_id]+'/#')
66
+ @mqtt_loop = Fiber.new do
67
+ MQTT::Client.connect(conn_opts) do |client|
68
+ @logger.info "Connected"
69
+ gear_state = Fiber.yield [:started,nil]
70
+ @logger.debug "auto subscribe "+@subscriptions.join(",")
71
+ client.subscribe(*@subscriptions)
72
+ loop do
73
+ case gear_state[0]
74
+ when :idle
75
+ unless client.queue_empty?
76
+ topic,message = client.get
77
+ if topic
78
+ Fiber.yield [:message, [topic,message]]
79
+ end
80
+ end
81
+ when :subscribe
82
+ client.subscribe(*gear_state[1])
83
+ when :unsubscribe
84
+ client.unsubscribe(*gear_state[1])
85
+ when :publish
86
+ client.publish(*gear_state[1])
87
+ if @subscriptions.include? gear_state[1][0]
88
+ topic,message = client.get
89
+ if topic and @callbacks[topic]
90
+ @callbacks[topic].call(topic,message)
91
+ end
92
+ end
93
+ when :close
94
+ client.close
95
+ Fiber.yield [:exit, nil]
96
+ end
97
+ gear_state = Fiber.yield [:ready, nil]
98
+ end
99
+ end
100
+ end
101
+ loop do
102
+ if @mqtt_loop.alive?
103
+ mqtt_state = @mqtt_loop.resume [:idle, nil]
104
+ case mqtt_state[0]
105
+ when :started
106
+ gear_state = [:started, nil]
107
+ when :message
108
+ if mqtt_state[1][1].index("/piegear/") == 0
109
+ @logger.debug '* control message > '+mqtt_state[1][1]+' : '+mqtt_state[1][2]
110
+ else
111
+ if @callbacks[mqtt_state[1][0]]
112
+ @callbacks[mqtt_state[1][0]].call(*mqtt_state[1])
113
+ end
114
+ end
115
+ when :ready
116
+ if block_given?
117
+ yield
118
+ end
119
+ when :exit
120
+ break
121
+ end
122
+ else
123
+ break
124
+ end
125
+ end
126
+ end
127
+
128
+ def subscribe(topic, &callback)
129
+ topic = "/"+@appid+topic
130
+ unless @subscriptions.include? topic
131
+ @subscriptions.push(topic)
132
+ end
133
+ if callback.class == Proc
134
+ @callbacks[topic] = callback
135
+ end
136
+ if @mqtt_loop
137
+ @mqtt_loop.resume [:subscribe, [topic]]
138
+ end
139
+ end
140
+
141
+ def unsubscribe(topic)
142
+ @logger.debug @subscriptions.index('/'+@appid+topic)
143
+ @logger.debug @subscriptions.join ","
144
+ if @subscriptions.index('/'+@appid+topic)
145
+ @subscriptions.delete('/'+@appid+topic)
146
+ if @mqtt_loop
147
+ @mqtt_loop.resume [:unsubscribe, ["/"+@appid+topic]]
148
+ end
149
+ end
150
+ end
151
+
152
+ def setname(name, &callback)
153
+ if @gearname
154
+ unsubscribe('/gearname/'+@gearname)
155
+ end
156
+ @gearname = name
157
+ subscribe('/gearname/'+name, &callback)
158
+ end
159
+
160
+ def publish(topic,message)
161
+ if @mqtt_loop and @mqtt_loop.alive?
162
+ @mqtt_loop.resume [:publish, ['/'+@appid+topic, message]]
163
+ else
164
+ raise IOError, "You must connect before publish!"
165
+ end
166
+
167
+ end
168
+
169
+ def chat(who, message)
170
+ publish('/gearname/'+who, message)
171
+ end
172
+
173
+ private
174
+ def get_token
175
+ @logger.debug "Check stored token"
176
+ cache = Cache.get_item("microgear.cache")
177
+ unless cache
178
+ cache = Cache.set_item("microgear.cache", {"_" => {}})
179
+ end
180
+ @logger.debug cache.to_json
181
+ @accesstoken = cache["_"]["accesstoken"]
182
+ if @accesstoken
183
+ endpoint = URI(@accesstoken["endpoint"])
184
+ @gearexaddress = endpoint.host
185
+ @gearexport = endpoint.port
186
+ else
187
+ @requesttoken = cache["_"]["requesttoken"];
188
+ if @requesttoken
189
+ #send requesttoken to obtain accesstoken
190
+ @logger.debug "already has request token"
191
+ @logger.debug "Requesting an access token."
192
+ consumer = OAuth::Consumer.new(@gearkey,@gearsecret,
193
+ :site => GEARAUTHSITE,
194
+ :request_token_path => GEARAUTHREQUESTTOKENENDPOINT,
195
+ :access_token_path => GEARAUTHACCESSTOKENENDPOINT)
196
+ token = OAuth::RequestToken.new consumer, @requesttoken["token"], @requesttoken["secret"]
197
+ access_token = token.get_access_token({oauth_verifier: @requesttoken["verifier"]}) do |args|
198
+ @logger.info args
199
+ end
200
+ cache["_"]["accesstoken"] = {
201
+ token: access_token.token,
202
+ secret: access_token.secret,
203
+ appkey: results.appkey,
204
+ endpoint: results.endpoint
205
+ }
206
+ @accesstoken = cache["_"]["accesstoken"]
207
+ @logger.debug cache
208
+ Cache.set_item("microgear.cache", cache)
209
+ else
210
+ @logger.debug "Requesting a request token."
211
+ consumer = OAuth::Consumer.new(@gearkey,@gearsecret,
212
+ :site => GEARAUTHSITE,
213
+ :request_token_path => GEARAUTHREQUESTTOKENENDPOINT,
214
+ :access_token_path => GEARAUTHACCESSTOKENENDPOINT,
215
+ )
216
+ verifier = SecureRandom.hex(4)
217
+ token = consumer.get_request_token({oauth_callback: "scope=#{@scope}&appid=#{@appid}&verifier=#{verifier}"})
218
+ cache["_"]["requesttoken"] = {
219
+ token: token.token,
220
+ secret: token.secret,
221
+ verifier: verifier
222
+ }
223
+ @requesttoken = cache["_"]["requesttoken"]
224
+ @logger.debug @requesttoken
225
+ access_token = token.get_access_token({oauth_verifier:verifier})
226
+ cache["_"]["accesstoken"] = {
227
+ token: access_token.token,
228
+ secret: access_token.secret,
229
+ appkey: access_token.params[:appkey],
230
+ endpoint: access_token.params[:endpoint]
231
+ }
232
+ @accesstoken = cache["_"]["accesstoken"]
233
+ @logger.debug cache
234
+ Cache.set_item("microgear.cache", cache)
235
+ end
236
+ end
237
+ end
238
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: microgear
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ridnarong Promya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: oauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.4.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: mqtt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Microgear library for NetPIE platform
42
+ email: ridnarong.promya@nectec.or.th
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/microgear.rb
48
+ homepage: http://rubygems.org/gems/microgear
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.4.7
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Microgear library
72
+ test_files: []