Class: Kasa::Protocol
- Inherits:
-
Object
- Object
- Kasa::Protocol
- Defined in:
- lib/kasa/protocol.rb
Overview
TP link protocol
Constant Summary collapse
- START_KEY =
171
- TIMEOUT =
2
- KASA_PORT =
9999
Class Method Summary collapse
-
.decode(line) ⇒ Object
Decrypt and decode.
-
.encode(plain) ⇒ Object
Encrypt and encode.
-
.get(ip, location:, value: nil, extra: {}) ⇒ Object
get result from request.
-
.request_to_hash(location, value) ⇒ Object
convert location and value to a hash.
-
.strip_location(location, response) ⇒ Object
strip away the request location from the response.
-
.transport(ip, request) ⇒ Object
Open socket and send request and response.
-
.validate(response) ⇒ Object
examine error code.
Class Method Details
.decode(line) ⇒ Object
Decrypt and decode
82 83 84 85 86 87 88 89 90 |
# File 'lib/kasa/protocol.rb', line 82 def self.decode(line) key = START_KEY line.unpack('C*').map do |enc_byte| byte = key ^ enc_byte key = enc_byte byte end.pack('C*') end |
.encode(plain) ⇒ Object
Encrypt and encode
71 72 73 74 75 76 77 78 79 |
# File 'lib/kasa/protocol.rb', line 71 def self.encode(plain) key = START_KEY enc_bytes = plain.unpack('C*').map do |byte| key = key ^ byte key end ([enc_bytes.length] + enc_bytes).pack('I>C*') end |
.get(ip, location:, value: nil, extra: {}) ⇒ Object
get result from request
14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/kasa/protocol.rb', line 14 def self.get(ip, location:, value: nil, extra: {}) request = request_to_hash location, value request.merge! extra encoded_response = Timeout.timeout(TIMEOUT) do transport(ip, encode(request.to_json)) end response = JSON.parse decode(encoded_response) response = strip_location(location, response) validate response response end |
.request_to_hash(location, value) ⇒ Object
convert location and value to a hash
45 46 47 48 49 50 51 52 53 |
# File 'lib/kasa/protocol.rb', line 45 def self.request_to_hash(location, value) request = value location = location.split('/').reject(&:empty?).reverse location.each do |e| request = { e => request } end request end |
.strip_location(location, response) ⇒ Object
strip away the request location from the response
35 36 37 38 39 40 41 42 |
# File 'lib/kasa/protocol.rb', line 35 def self.strip_location(location, response) location = location.split('/').reject(&:empty?) location.each do |j| response = (response[j] or response) end response end |
.transport(ip, request) ⇒ Object
Open socket and send request and response
56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/kasa/protocol.rb', line 56 def self.transport(ip, request) Socket.tcp(ip, KASA_PORT) do |s| s.write request result_length = s.recv(4).unpack1('I>') result = '' while result_length.positive? result += s.recv(1024) result_length -= 1024 end result end end |
.validate(response) ⇒ Object
examine error code
30 31 32 |
# File 'lib/kasa/protocol.rb', line 30 def self.validate(response) raise response.to_json if response.is_a?(Hash) && response['err_code']&.negative? end |