tp_link_smartplug 0.1.0.alpha1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23a1848523acc948dd653d39fa3b9cec937bdba9d2a0ad6970308bac4af64d8d
4
- data.tar.gz: dd4d4a0fda92aeabfdc7adfb5f751f1b957438b168e5c96efaf4950d69e1bb3d
3
+ metadata.gz: c2553721065bc41fadca17408f6baacfa4fab953ec5df3e33d778c967910892f
4
+ data.tar.gz: 8b16c4709a255057a9db1f98b1e825d6e79eda470423a14e16da655db4be44f5
5
5
  SHA512:
6
- metadata.gz: e2259524ac344b200b19d4824178dfe18b5b7d92c8fbead1b3a4c40f3c073a3078b529f73bf035c4e1505f9827c9323f2f5c8e98f8076270783ed701d1ce6058
7
- data.tar.gz: 24ae9be641e069804c884abd18594ee8a2c355370033c06c36091dff990c0846325cc9878c1e08550658e88fabebe42e98ce60b0edf82cc57f71006b0b5d1753
6
+ metadata.gz: e9bf31292404284bc0705955133b20fcdf75bd34cf7e10e71b84e9332834c92f03697df54bfc472ae0502165771b64402c1c31cbdc1759414975a5820d5aaa80
7
+ data.tar.gz: a137ee0a57e53f4d85aa6841ac58cfdf1d14d29bf5e800759398a8d6767bb9e4b8b3a4a4249f002ea446ebc6d1e863f1f7de6e4cf10d80c0562ed7800d555cf2
@@ -1,7 +1,11 @@
1
- # frozen_string_literal: true
1
+ require_relative 'tp_link_smartplug/_base'
2
+ require_relative 'tp_link_smartplug/command'
3
+ require_relative 'tp_link_smartplug/device'
4
+ require_relative 'tp_link_smartplug/helpers'
5
+ require_relative 'tp_link_smartplug/message'
6
+ require_relative 'tp_link_smartplug/version'
2
7
 
3
- require 'tp_link_smartplug/command'
4
- require 'tp_link_smartplug/device'
5
- require 'tp_link_smartplug/helpers'
6
- require 'tp_link_smartplug/message'
7
- require 'tp_link_smartplug/version'
8
+ # Top level module
9
+ #
10
+ # @author Ben Hughes
11
+ module TpLinkSmartplug; end
@@ -0,0 +1,17 @@
1
+ require_relative 'helpers'
2
+
3
+ module TpLinkSmartplug
4
+ # Base plug class.
5
+ #
6
+ # @author Ben Hughes
7
+ class Base
8
+ include TpLinkSmartplug::Helpers
9
+
10
+ def initialize; end
11
+ end
12
+
13
+ # Base plug error class.
14
+ #
15
+ # @author Ben Hughes
16
+ class BaseError < StandardError; end
17
+ end
@@ -1,31 +1,29 @@
1
- # frozen_string_literal: true
2
-
3
1
  module TpLinkSmartplug
4
2
  # Module containing the static commands for the plug
5
3
  module Command
6
4
  # Plug information command
7
- INFO = '{"system":{"get_sysinfo":{}}}'
5
+ INFO = '{"system":{"get_sysinfo":{}}}'.freeze
8
6
  # Plug output on command
9
- ON = '{"system":{"set_relay_state":{"state":1}}}'
7
+ ON = '{"system":{"set_relay_state":{"state":1}}}'.freeze
10
8
  # Plug output off command
11
- OFF = '{"system":{"set_relay_state":{"state":0}}}'
9
+ OFF = '{"system":{"set_relay_state":{"state":0}}}'.freeze
12
10
  # Plug cloud info command
13
- CLOUDINFO = '{"cnCloud":{"get_info":{}}}'
11
+ CLOUDINFO = '{"cnCloud":{"get_info":{}}}'.freeze
14
12
  # Plug WLAN SSID scan command
15
- WLANSCAN = '{"netif":{"get_scaninfo":{"refresh":0}}}'
13
+ WLANSCAN = '{"netif":{"get_scaninfo":{"refresh":0}}}'.freeze
16
14
  # Plug time command
17
- TIME = '{"time":{"get_time":{}}}'
15
+ TIME = '{"time":{"get_time":{}}}'.freeze
18
16
  # Plug schedule command
19
- SCHEDULE = '{"schedule":{"get_rules":{}}}'
17
+ SCHEDULE = '{"schedule":{"get_rules":{}}}'.freeze
20
18
  # Plug countdown command
21
- COUNTDOWN = '{"count_down":{"get_rules":{}}}'
19
+ COUNTDOWN = '{"count_down":{"get_rules":{}}}'.freeze
22
20
  # Plug antitheft command
23
- ANTITHEFT = '{"anti_theft":{"get_rules":{}}}'
21
+ ANTITHEFT = '{"anti_theft":{"get_rules":{}}}'.freeze
24
22
  # Plug reboot command
25
- REBOOT = '{"system":{"reboot":{"delay":1}}}'
23
+ REBOOT = '{"system":{"reboot":{"delay":1}}}'.freeze
26
24
  # Plug reset command
27
- RESET = '{"system":{"reset":{"delay":1}}}'
25
+ RESET = '{"system":{"reset":{"delay":1}}}'.freeze
28
26
  # Plug energy command
29
- ENERGY = '{"emeter":{"get_realtime":{}}}'
27
+ ENERGY = '{"emeter":{"get_realtime":{}}}'.freeze
30
28
  end
31
29
  end
@@ -1,10 +1,7 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'socket'
4
2
  require 'ipaddr'
5
3
  require 'json'
6
- require 'tp_link_smartplug/helpers'
7
- require 'tp_link_smartplug/message'
4
+ require_relative './message'
8
5
 
9
6
  module TpLinkSmartplug
10
7
  # Provides an object to represent to a plug
@@ -14,22 +11,22 @@ module TpLinkSmartplug
14
11
  # @attr [Integer] port Port to connect to on the plug
15
12
  # @attr [Integer] timeout Timeout value for connecting and sending commands to the plug
16
13
  # @attr [true, false] debug Control debug logging
17
- class Device
14
+ class Device < TpLinkSmartplug::Base
18
15
  include TpLinkSmartplug::Helpers
19
16
  include TpLinkSmartplug::Message
20
17
 
21
- attr_accessor :address
22
- attr_accessor :port
23
- attr_accessor :timeout
24
- attr_accessor :debug
18
+ attr_accessor :address, :port, :timeout, :poll_auto_close, :debug
25
19
 
26
20
  def initialize(address:, port: 9999)
21
+ super()
22
+
27
23
  @address = IPAddr.new(address, Socket::AF_INET)
28
24
  @port = port
29
25
  @timeout = 3
30
26
  @debug = false
31
- @sockaddr = Addrinfo.getaddrinfo(address.to_s, port, Socket::PF_INET, :STREAM, 6).first.to_sockaddr
27
+ @sockaddr = Addrinfo.getaddrinfo(@address.to_s, @port, Socket::PF_INET, :STREAM, 6).first.to_sockaddr
32
28
  @socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
29
+ @poll_auto_close = true
33
30
  end
34
31
 
35
32
  # Open connection to plug
@@ -42,23 +39,32 @@ module TpLinkSmartplug
42
39
 
43
40
  begin
44
41
  @socket.connect_nonblock(@sockaddr)
42
+ debug_message('Connected') if @debug
45
43
  rescue IO::WaitWritable
46
44
  if IO.select(nil, [@socket], nil, timeout)
47
45
  begin
48
46
  @socket.connect_nonblock(@sockaddr)
49
47
  rescue Errno::EISCONN
50
- debug_message('Connected') if debug
48
+ debug_message('Connected') if @debug
49
+ rescue Errno::ECONNREFUSED
50
+ @socket.close
51
+ raise TpLinkSmartplug::DeviceError, "Connection refused connecting to address #{@address}, port #{@port}!"
51
52
  rescue StandardError => e
52
53
  disconnect
53
- debug_message('Unexpected exception encountered.') if debug
54
- raise e
54
+ debug_message("Unexpected exception encountered. Error: #{e}") if @debug
55
+ raise
55
56
  end
56
57
  else
57
58
  @socket.close
58
- raise "Connection timeout connecting to address #{@address}, port #{@port}."
59
+ raise TpLinkSmartplug::DeviceError, "Connection timeout connecting to address #{@address}, port #{@port}."
59
60
  end
60
61
  rescue Errno::EISCONN
61
- debug_message('Connected') if debug
62
+ debug_message('Connected') if @debug
63
+ rescue Errno::EINPROGRESS
64
+ debug_message('Connection in progress') if @debug
65
+ retry
66
+ rescue Errno::ECONNREFUSED
67
+ raise TpLinkSmartplug::DeviceError, "Connection refused connecting to address #{@address}, port #{@port}."
62
68
  end
63
69
  end
64
70
 
@@ -68,21 +74,23 @@ module TpLinkSmartplug
68
74
  @socket.close unless @socket.closed?
69
75
  end
70
76
 
71
- # Return connection state
77
+ alias_method :close, :disconnect
78
+
79
+ # Return connection state open
72
80
  #
73
81
  # @return [True, False]
74
82
  def open?
75
83
  !@socket.closed?
76
84
  end
77
85
 
78
- # Return connection state
86
+ # Return connection state closed
79
87
  #
80
88
  # @return [True, False]
81
89
  def closed?
82
90
  @socket.closed?
83
91
  end
84
92
 
85
- # Polls a plug with a command
93
+ # Polls plug with a command
86
94
  #
87
95
  # @param command [String] the command to send to the plug
88
96
  # @return [Hash] the output from the plug command
@@ -102,16 +110,18 @@ module TpLinkSmartplug
102
110
  rescue IO::WaitReadable
103
111
  IO.select([@socket])
104
112
  retry
105
- ensure
106
- disconnect unless closed?
107
113
  end
108
114
 
109
- raise 'Error occured during disconnect' unless closed?
110
- raise 'No data received' if data.nil? || data.empty?
115
+ if @poll_auto_close && !closed?
116
+ disconnect
117
+ raise 'Error occured during disconnect' unless closed?
118
+ end
119
+
120
+ raise 'No data received' if nil_or_empty?(data)
111
121
 
112
- debug_message("Received Raw: #{data}") if debug
122
+ debug_message("Received Raw: #{data}") if @debug
113
123
  data = decrypt(data[4..data.length])
114
- debug_message("Received Decrypted: #{data}") if debug
124
+ debug_message("Received Decrypted: #{data}") if @debug
115
125
 
116
126
  data
117
127
  end
@@ -164,11 +174,13 @@ module TpLinkSmartplug
164
174
  :antitheft,
165
175
  :reboot,
166
176
  :reset,
167
- :energy
177
+ :energy,
168
178
  ].each do |method|
169
179
  define_method method do
170
180
  JSON.parse(poll(command: TpLinkSmartplug::Command.const_get(method.upcase)))
171
181
  end
172
182
  end
173
183
  end
184
+
185
+ class DeviceError < TpLinkSmartplug::BaseError; end
174
186
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'time'
4
2
 
5
3
  module TpLinkSmartplug
@@ -10,7 +8,16 @@ module TpLinkSmartplug
10
8
  # @param string [String] the message to be formatted for debug output
11
9
  def debug_message(string)
12
10
  caller_method = caller_locations(1..1).first.label
13
- STDOUT.puts(Time.now.strftime('%Y-%m-%d %H:%M:%S: ').concat("#{caller_method}: ").concat(string))
11
+ $stdout.puts(Time.now.strftime('%Y-%m-%d %H:%M:%S: ').concat("#{caller_method}: ").concat(string))
12
+ end
13
+
14
+ # Tests a variable for nil or empty status
15
+ #
16
+ # @param v the variable to be tested
17
+ def nil_or_empty?(value)
18
+ return true if value.nil? || (value.respond_to?(:empty?) && value.empty?)
19
+
20
+ false
14
21
  end
15
22
  end
16
23
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: false
2
-
3
1
  module TpLinkSmartplug
4
2
  # Helper methods for plug communication messages
5
3
  module Message
@@ -1,7 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
1
  # @author Ben Hughes
4
2
  module TpLinkSmartplug
5
3
  # Gem version
6
- VERSION = '0.0.1'
4
+ VERSION = '0.2.0'.freeze
7
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tp_link_smartplug
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Hughes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-08 00:00:00.000000000 Z
11
+ date: 2021-01-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Control and retrieve data from a TP-Link HS100/110 (Metered) Smartplug
14
14
  email: bmhughes@bmhughes.co.uk
@@ -17,6 +17,7 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - "./lib/tp_link_smartplug.rb"
20
+ - "./lib/tp_link_smartplug/_base.rb"
20
21
  - "./lib/tp_link_smartplug/command.rb"
21
22
  - "./lib/tp_link_smartplug/device.rb"
22
23
  - "./lib/tp_link_smartplug/helpers.rb"
@@ -25,7 +26,8 @@ files:
25
26
  homepage: https://github.com/bmhughes/tp_link_smartplug
26
27
  licenses:
27
28
  - Apache-2.0
28
- metadata: {}
29
+ metadata:
30
+ github_repo: ssh://github.com/bmhughes/tp_link_smartplug
29
31
  post_install_message:
30
32
  rdoc_options: []
31
33
  require_paths:
@@ -37,12 +39,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
37
39
  version: '2.5'
38
40
  required_rubygems_version: !ruby/object:Gem::Requirement
39
41
  requirements:
40
- - - ">"
42
+ - - ">="
41
43
  - !ruby/object:Gem::Version
42
- version: 1.3.1
44
+ version: '0'
43
45
  requirements: []
44
- rubyforge_project:
45
- rubygems_version: 2.7.7
46
+ rubygems_version: 3.1.4
46
47
  signing_key:
47
48
  specification_version: 4
48
49
  summary: TP-Link HS100/110 Smart Plug interaction library