ewelink 2.0.0 → 2.1.0
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 +4 -4
- data/VERSION +1 -1
- data/lib/ewelink/api.rb +77 -9
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c58323e838b9fbbdca7c7ee0fdf22d1e7950c627fb4fcf8851b3263e69ce883
|
4
|
+
data.tar.gz: 475d05f731b079f7734fde4dd93ec8f151077d6e5b716a86e611f11bdbb8d49b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50ba5474e9012f219e380c47515d599da29a72b50cc26c36a19e253623c997e429a32c1b279619eef0e2d8b7f454fccde519500f998575c38d028ac86e6c1ba4
|
7
|
+
data.tar.gz: 122f2997897893b395cd04204e3e169d90bac15fc1a9eaabbf31def8da1c7f754bd502341411727364a79011379791a89031e9d42090d22bf96be233a24a5958
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.0
|
data/lib/ewelink/api.rb
CHANGED
@@ -11,6 +11,7 @@ module Ewelink
|
|
11
11
|
URL = 'https://#{region}-api.coolkit.cc:8080'
|
12
12
|
UUID_NAMESPACE = 'e25750fb-3710-41af-b831-23224f4dd609';
|
13
13
|
VERSION = 8
|
14
|
+
WEB_SOCKET_PING_TOLERANCE_FACTOR = 1.5
|
14
15
|
WEB_SOCKET_WAIT_INTERVAL = 0.2.seconds
|
15
16
|
|
16
17
|
attr_reader :email, :password, :phone_number
|
@@ -41,6 +42,7 @@ module Ewelink
|
|
41
42
|
'ts' => 0,
|
42
43
|
'userAgent' => 'app',
|
43
44
|
}
|
45
|
+
Ewelink.logger.debug(self.class.name) { "Pressing RF bridge button #{button[:uuid].inspect}" }
|
44
46
|
send_to_web_socket(JSON.generate(params))
|
45
47
|
true
|
46
48
|
end
|
@@ -48,10 +50,17 @@ module Ewelink
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def reload
|
51
|
-
Ewelink.logger.debug(self.class.name) { 'Reloading API (authentication token, devices, region,...)' }
|
53
|
+
Ewelink.logger.debug(self.class.name) { 'Reloading API (authentication token, devices, region, connections,...)' }
|
52
54
|
dispose_web_socket
|
53
55
|
@switches_statuses.clear
|
54
|
-
[
|
56
|
+
[
|
57
|
+
:@api_keys,
|
58
|
+
:@authentication_token,
|
59
|
+
:@devices,
|
60
|
+
:@region,
|
61
|
+
:@rf_bridge_buttons,
|
62
|
+
:@switches,
|
63
|
+
].each do |variable|
|
55
64
|
remove_instance_variable(variable) if instance_variable_defined?(variable)
|
56
65
|
end
|
57
66
|
self
|
@@ -103,10 +112,12 @@ module Ewelink
|
|
103
112
|
'userAgent' => 'app',
|
104
113
|
}
|
105
114
|
web_socket_wait_for(-> { web_socket_authenticated? }) do
|
115
|
+
Ewelink.logger.debug(self.class.name) { "Checking switch #{switch[:uuid].inspect} status" }
|
106
116
|
send_to_web_socket(JSON.generate(params))
|
107
117
|
end
|
108
118
|
end
|
109
119
|
web_socket_wait_for(-> { !@switches_statuses[switch[:uuid]].nil? }) do
|
120
|
+
Ewelink.logger.debug(self.class.name) { "Switch #{switch[:uuid].inspect} is #{@switches_statuses[switch[:uuid]]}" }
|
110
121
|
@switches_statuses[switch[:uuid]] == 'on'
|
111
122
|
end
|
112
123
|
end
|
@@ -151,9 +162,11 @@ module Ewelink
|
|
151
162
|
'ts' => 0,
|
152
163
|
'userAgent' => 'app',
|
153
164
|
}
|
165
|
+
Ewelink.logger.debug(self.class.name) { "Turning switch #{switch[:uuid].inspect} #{on ? 'on' : 'off'}" }
|
154
166
|
send_to_web_socket(JSON.generate(params))
|
155
|
-
true
|
156
167
|
end
|
168
|
+
switch_on?(switch[:uuid]) # Waiting for switch status update
|
169
|
+
true
|
157
170
|
end
|
158
171
|
|
159
172
|
private
|
@@ -210,13 +223,31 @@ module Ewelink
|
|
210
223
|
|
211
224
|
def dispose_web_socket
|
212
225
|
@web_socket_authenticated_api_keys = Set.new
|
213
|
-
|
226
|
+
|
227
|
+
if @web_socket_ping_thread
|
228
|
+
if Thread.current == @web_socket_ping_thread
|
229
|
+
Thread.current[:stop] = true
|
230
|
+
else
|
231
|
+
@web_socket_ping_thread.kill
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
if @web_socket.present?
|
214
236
|
begin
|
215
237
|
@web_socket.close if @web_socket.open?
|
216
238
|
rescue
|
217
239
|
# Ignoring close errors
|
218
240
|
end
|
219
|
-
|
241
|
+
end
|
242
|
+
|
243
|
+
[
|
244
|
+
:@last_web_socket_pong_at,
|
245
|
+
:@web_socket_ping_interval,
|
246
|
+
:@web_socket_ping_thread,
|
247
|
+
:@web_socket_url,
|
248
|
+
:@web_socket,
|
249
|
+
].each do |variable|
|
250
|
+
remove_instance_variable(variable) if instance_variable_defined?(variable)
|
220
251
|
end
|
221
252
|
end
|
222
253
|
|
@@ -256,6 +287,10 @@ module Ewelink
|
|
256
287
|
end
|
257
288
|
|
258
289
|
def send_to_web_socket(data)
|
290
|
+
if web_socket_outdated_ping?
|
291
|
+
Ewelink.logger.warn(self.class.name) { 'WebSocket ping is outdated' }
|
292
|
+
dispose_web_socket
|
293
|
+
end
|
259
294
|
web_socket.send(data)
|
260
295
|
rescue
|
261
296
|
dispose_web_socket
|
@@ -290,16 +325,42 @@ module Ewelink
|
|
290
325
|
|
291
326
|
web_socket.on(:message) do |message|
|
292
327
|
api.instance_eval do
|
293
|
-
|
328
|
+
if message.data == 'pong'
|
329
|
+
Ewelink.logger.debug(self.class.name) { "Received WebSocket #{message.data.inspect} message" }
|
330
|
+
@last_web_socket_pong_at = Time.now
|
331
|
+
next
|
332
|
+
end
|
333
|
+
|
334
|
+
begin
|
335
|
+
response = JSON.parse(message.data)
|
336
|
+
rescue => e
|
337
|
+
Ewelink.logger.error(self.class.name) { "WebSocket JSON parse error" }
|
338
|
+
next
|
339
|
+
end
|
294
340
|
|
295
341
|
if response.key?('error') && response['error'] != 0
|
296
342
|
Ewelink.logger.error(self.class.name) { "WebSocket message error: #{message.data}" }
|
297
343
|
next
|
298
344
|
end
|
299
345
|
|
346
|
+
if !@web_socket_ping_thread && response.key?('config') && response['config'].key?('hbInterval')
|
347
|
+
@last_web_socket_pong_at = Time.now
|
348
|
+
# @web_socket_ping_interval = response['config']['hbInterval']
|
349
|
+
@web_socket_ping_interval = 30.seconds
|
350
|
+
Ewelink.logger.debug(self.class.name) { "Creating thread for WebSocket ping every #{@web_socket_ping_interval} seconds" }
|
351
|
+
@web_socket_ping_thread = Thread.new do
|
352
|
+
loop do
|
353
|
+
break if Thread.current[:stop]
|
354
|
+
sleep(@web_socket_ping_interval)
|
355
|
+
Ewelink.logger.debug(self.class.name) { 'Sending WebSocket ping' }
|
356
|
+
send_to_web_socket('ping')
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
300
361
|
if response['apikey'].present? && !@web_socket_authenticated_api_keys.include?(response['apikey'])
|
301
362
|
@web_socket_authenticated_api_keys << response['apikey']
|
302
|
-
Ewelink.logger.debug(self.class.name) { "WebSocket successfully authenticated API key: #{response['apikey'].inspect}" }
|
363
|
+
Ewelink.logger.debug(self.class.name) { "WebSocket successfully authenticated API key: #{response['apikey'].truncate(16).inspect}" }
|
303
364
|
end
|
304
365
|
|
305
366
|
if response['deviceid'].present? && response['params'].is_a?(Hash) && response['params']['switch'].present?
|
@@ -324,7 +385,7 @@ module Ewelink
|
|
324
385
|
'userAgent' => 'app',
|
325
386
|
'version' => VERSION,
|
326
387
|
}
|
327
|
-
Ewelink.logger.debug(self.class.name) { "Authenticating WebSocket API key: #{api_key.inspect}" }
|
388
|
+
Ewelink.logger.debug(self.class.name) { "Authenticating WebSocket API key: #{api_key.truncate(16).inspect}" }
|
328
389
|
send_to_web_socket(JSON.generate(params))
|
329
390
|
end
|
330
391
|
end
|
@@ -338,6 +399,10 @@ module Ewelink
|
|
338
399
|
api_keys == @web_socket_authenticated_api_keys
|
339
400
|
end
|
340
401
|
|
402
|
+
def web_socket_outdated_ping?
|
403
|
+
@last_web_socket_pong_at.present? && @web_socket_ping_interval.present? && @last_web_socket_pong_at < (@web_socket_ping_interval * WEB_SOCKET_PING_TOLERANCE_FACTOR).seconds.ago
|
404
|
+
end
|
405
|
+
|
341
406
|
def web_socket_sequence
|
342
407
|
(Time.now.to_f * 1000).round.to_s
|
343
408
|
end
|
@@ -365,7 +430,10 @@ module Ewelink
|
|
365
430
|
web_socket # Initializes WebSocket
|
366
431
|
Timeout.timeout(TIMEOUT) do
|
367
432
|
loop do
|
368
|
-
|
433
|
+
if condition.call
|
434
|
+
return yield if block_given?
|
435
|
+
return true
|
436
|
+
end
|
369
437
|
sleep(WEB_SOCKET_WAIT_INTERVAL)
|
370
438
|
end
|
371
439
|
end
|