cosmosc2-kasa-plug 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +9 -0
- data/README.md +24 -0
- data/Rakefile +34 -0
- data/plugin.txt +9 -0
- data/targets/PLUG/cmd_tlm/plug_cmds.txt +16 -0
- data/targets/PLUG/cmd_tlm/plug_tlm.txt +11 -0
- data/targets/PLUG/lib/kasa_interface.rb +127 -0
- data/targets/PLUG/lib/kasa_protocol.rb +43 -0
- data/targets/PLUG/screens/status.txt +5 -0
- data/targets/PLUG/target.txt +5 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 146ebc6050d7cfa29d272af27814cae1eb3de6ce1e4da13cb70703eca05ad0c4
|
4
|
+
data.tar.gz: a2e9f4ab507e3eb05e0b4b16621efd62b1b264fc597854c61643568d1648cf8c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9bad9abc5595c0aabf88c00d8af47c4c3636d36f2257377ec5f379979cf9827e10453b2b538418777a844d35f199c87b73f46fb3966623dd69465a3c0ddd14a3
|
7
|
+
data.tar.gz: 49336d1f6079d2ea368aa7a9088533bb9adc41d11476bb14d84256421aa644aa7511ae78a0453e09bf3bf24732cda71f7826a6a70927b53cf38f0b92ed865bf7
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright 2021 Ryan Melton
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## COSMOS v5 Kasa Plug Plugin
|
2
|
+
|
3
|
+
This plugin provides an Interface and Target for connecting to Kasa / TP-Link Smart Home Wifi Plugs
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
1. Plug in your Kasa Plug and connect it to your Wifi network using the Kasa App
|
8
|
+
|
9
|
+
2. Determine the IP Address of Your Kasa Plug using Your Home Router (or other methods)
|
10
|
+
|
11
|
+
3. Install the plugin .gem file to the COSMOS Admin Page and Enter the IP Address
|
12
|
+
|
13
|
+
## Contributing
|
14
|
+
|
15
|
+
Contributing is easy.
|
16
|
+
|
17
|
+
1. Fork the project
|
18
|
+
2. Create a feature branch
|
19
|
+
3. Make your changes
|
20
|
+
4. Submit a pull request
|
21
|
+
|
22
|
+
## License
|
23
|
+
|
24
|
+
The MIT License - See LICENSE.txt
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
# Copyright 2021 Ball Aerospace & Technologies Corp.
|
4
|
+
# All Rights Reserved.
|
5
|
+
#
|
6
|
+
# This program is free software; you can modify and/or redistribute it
|
7
|
+
# under the terms of the GNU Affero General Public License
|
8
|
+
# as published by the Free Software Foundation; version 3 with
|
9
|
+
# attribution addendums as found in the LICENSE.txt
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# This program may also be used under the terms of a commercial or
|
17
|
+
# enterprise edition license of COSMOS if purchased from the
|
18
|
+
# copyright holder
|
19
|
+
|
20
|
+
PLUGIN_NAME = Dir['*.gemspec'][0].split('.')[0..-2].join('.')
|
21
|
+
|
22
|
+
task :warn_version do
|
23
|
+
unless ENV['VERSION']
|
24
|
+
puts "Warning: VERSION is required for releases: rake <task> VERSION=X.X.X"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
task :build => [:warn_version] do
|
29
|
+
_, platform, *_ = RUBY_PLATFORM.split("-")
|
30
|
+
if platform == 'mswin32' or platform == 'mingw32'
|
31
|
+
puts "Warning: Building gem on Windows will lose file permissions"
|
32
|
+
end
|
33
|
+
system("gem build #{PLUGIN_NAME}")
|
34
|
+
end
|
data/plugin.txt
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
COMMAND <%= target_name %> INFO BIG_ENDIAN "Gets the telemetry from the plug"
|
2
|
+
DISABLE_MESSAGES
|
3
|
+
APPEND_ID_PARAMETER DATA 0 STRING '{"system":{"get_sysinfo":{}}}' "Info Command to Plug"
|
4
|
+
|
5
|
+
COMMAND <%= target_name %> ON BIG_ENDIAN "Turns the plug on"
|
6
|
+
APPEND_ID_PARAMETER DATA 0 STRING '{"system":{"set_relay_state":{"state":1}}}' "On Command to Plug"
|
7
|
+
|
8
|
+
COMMAND <%= target_name %> OFF BIG_ENDIAN "Turns the plug off"
|
9
|
+
APPEND_ID_PARAMETER DATA 0 STRING '{"system":{"set_relay_state":{"state":0}}}' "Off Command to Plug"
|
10
|
+
|
11
|
+
COMMAND <%= target_name %> LED_ON BIG_ENDIAN "Turns the plugs led on"
|
12
|
+
APPEND_ID_PARAMETER DATA 0 STRING '{"system":{"set_led_off":{"off":0}}}' "Info Command to Plug"
|
13
|
+
|
14
|
+
COMMAND <%= target_name %> LED_OFF BIG_ENDIAN "Turns the plugs led off"
|
15
|
+
APPEND_ID_PARAMETER DATA 0 STRING '{"system":{"set_led_off":{"off":1}}}' "Info Command to Plug"
|
16
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
TELEMETRY <%= target_name %> STATUS BIG_ENDIAN "Status of the Plug"
|
2
|
+
APPEND_ID_ITEM PACKET_ID 8 UINT 1 "Packet Id"
|
3
|
+
APPEND_ITEM RELAY 8 UINT "Relay State"
|
4
|
+
STATE ON 1
|
5
|
+
STATE OFF 0
|
6
|
+
APPEND_ITEM LED 8 UINT "LED State"
|
7
|
+
STATE ON 1
|
8
|
+
STATE OFF 0
|
9
|
+
|
10
|
+
TELEMETRY <%= target_name %> RESPONSE BIG_ENDIAN "Response from the Plug"
|
11
|
+
APPEND_ITEM DATA 0 STRING "Response data"
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
require 'cosmos'
|
4
|
+
require 'cosmos/interfaces/tcpip_client_interface'
|
5
|
+
require 'json'
|
6
|
+
require_relative 'kasa_protocol'
|
7
|
+
|
8
|
+
module Cosmos
|
9
|
+
class KasaInterface < TcpipClientInterface
|
10
|
+
def initialize (hostname, port, polling_period_seconds = 30, write_timeout = 10.0, read_timeout = nil)
|
11
|
+
super(hostname, port, port, write_timeout, read_timeout, 'LENGTH', 0, 32, 4)
|
12
|
+
add_protocol(KasaProtocol, [], :READ_WRITE)
|
13
|
+
@status_packet = nil
|
14
|
+
@polling_period_seconds = polling_period_seconds.to_i
|
15
|
+
@polling_thread = nil
|
16
|
+
@polling_thread_run = true
|
17
|
+
@polling_thread_sleeper = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def connect
|
21
|
+
super()
|
22
|
+
|
23
|
+
if @polling_period_seconds > 0
|
24
|
+
@polling_thread_run = true
|
25
|
+
@polling_thread_sleeper = Sleeper.new
|
26
|
+
@polling_thread = Thread.new do
|
27
|
+
while @polling_thread_run
|
28
|
+
send_info_command()
|
29
|
+
break if @polling_thread_sleeper.sleep(@polling_period_seconds)
|
30
|
+
end
|
31
|
+
rescue => err
|
32
|
+
Logger.instance.error("Polling thread unexpectedly died : #{@name}")
|
33
|
+
raise err
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def disconnect
|
39
|
+
if @polling_thread
|
40
|
+
@polling_thread_run = false
|
41
|
+
@polling_thread_sleeper.cancel
|
42
|
+
@polling_thread.join
|
43
|
+
@polling_thread = nil
|
44
|
+
@polling_thread_sleeper = nil
|
45
|
+
end
|
46
|
+
super()
|
47
|
+
end
|
48
|
+
|
49
|
+
def write(packet)
|
50
|
+
result = super(packet)
|
51
|
+
# Follow every non-INFO command with an INFO command
|
52
|
+
send_info_command() if packet.packet_name != 'INFO'
|
53
|
+
return result
|
54
|
+
end
|
55
|
+
|
56
|
+
def read
|
57
|
+
if @status_packet
|
58
|
+
packet = @status_packet
|
59
|
+
@status_packet = nil
|
60
|
+
return packet
|
61
|
+
end
|
62
|
+
packet = super()
|
63
|
+
|
64
|
+
# Info Command Results Format
|
65
|
+
# {
|
66
|
+
# "system":
|
67
|
+
# {
|
68
|
+
# "get_sysinfo":
|
69
|
+
# {
|
70
|
+
# "sw_ver":"1.0.3 Build 201015 Rel.142523",
|
71
|
+
# "hw_ver":"5.0","model":"HS103(US)",
|
72
|
+
# "deviceId":"8006E861C909AAF4BABED171339873F91E67E71C",
|
73
|
+
# "oemId":"211C91F3C6FA93568D818524FE170CEC",
|
74
|
+
# "hwId":"B25CBC5351DD892EA69AB42199F59E41",
|
75
|
+
# "rssi":-51,
|
76
|
+
# "latitude_i":400299,
|
77
|
+
# "longitude_i":-1050636,
|
78
|
+
# "alias":"Plug1",
|
79
|
+
# "status":"new",
|
80
|
+
# "mic_type":"IOT.SMARTPLUGSWITCH",
|
81
|
+
# "feature":"TIM",
|
82
|
+
# "mac":"00:31:92:43:F4:35",
|
83
|
+
# "updating":0,
|
84
|
+
# "led_off":1,
|
85
|
+
# "relay_state":0,
|
86
|
+
# "on_time":0,
|
87
|
+
# "icon_hash":"",
|
88
|
+
# "dev_name":"Smart Wi-Fi Plug Mini",
|
89
|
+
# "active_mode":"none",
|
90
|
+
# "next_action":{"type":-1},
|
91
|
+
# "err_code":0
|
92
|
+
# }
|
93
|
+
# }
|
94
|
+
# }
|
95
|
+
|
96
|
+
if packet
|
97
|
+
json_hash = JSON.parse(packet.buffer(false))
|
98
|
+
system = json_hash['system']
|
99
|
+
if system
|
100
|
+
get_sysinfo = system['get_sysinfo']
|
101
|
+
if get_sysinfo
|
102
|
+
@status_packet = System.telemetry.packet(@target_names[0], 'STATUS')
|
103
|
+
@status_packet.write('PACKET_ID', 1)
|
104
|
+
relay = get_sysinfo['relay_state']
|
105
|
+
@status_packet.write('RELAY', relay)
|
106
|
+
led_off = get_sysinfo['led_off']
|
107
|
+
if led_off == 0
|
108
|
+
led = 1
|
109
|
+
else
|
110
|
+
led = 0
|
111
|
+
end
|
112
|
+
@status_packet.write('LED', led)
|
113
|
+
@status_packet.received_time = nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
return packet
|
119
|
+
end
|
120
|
+
|
121
|
+
def send_info_command
|
122
|
+
info_command = System.commands.packet(@target_names[0], 'INFO').dup
|
123
|
+
info_command.restore_defaults
|
124
|
+
write(info_command)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
require 'cosmos/interfaces/protocols/protocol'
|
4
|
+
|
5
|
+
module Cosmos
|
6
|
+
|
7
|
+
# Performs the TPLink SmartHome Protocol
|
8
|
+
class KasaProtocol < Protocol
|
9
|
+
|
10
|
+
def read_data(data)
|
11
|
+
return super(data) if data.length <= 0
|
12
|
+
return kasa_decode(data)
|
13
|
+
end
|
14
|
+
|
15
|
+
def write_data(data)
|
16
|
+
return kasa_encode(data)
|
17
|
+
end
|
18
|
+
|
19
|
+
def kasa_encode(string)
|
20
|
+
key = 171
|
21
|
+
result = [string.length].pack("N")
|
22
|
+
string.each_byte do |byte|
|
23
|
+
a = key ^ byte
|
24
|
+
key = a
|
25
|
+
result << a
|
26
|
+
end
|
27
|
+
return result
|
28
|
+
end
|
29
|
+
|
30
|
+
def kasa_decode(string)
|
31
|
+
key = 171
|
32
|
+
result = ""
|
33
|
+
string[4..-1].each_byte do |byte|
|
34
|
+
a = key ^ byte
|
35
|
+
key = byte
|
36
|
+
result << [a].pack("C")
|
37
|
+
end
|
38
|
+
return result
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cosmosc2-kasa-plug
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Melton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: cosmos
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: " This plugin an Interface and Target to Connect COSMOS to a Kasa
|
28
|
+
Smart Plug\n"
|
29
|
+
email:
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- LICENSE.txt
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- plugin.txt
|
38
|
+
- targets/PLUG/cmd_tlm/plug_cmds.txt
|
39
|
+
- targets/PLUG/cmd_tlm/plug_tlm.txt
|
40
|
+
- targets/PLUG/lib/kasa_interface.rb
|
41
|
+
- targets/PLUG/lib/kasa_protocol.rb
|
42
|
+
- targets/PLUG/screens/status.txt
|
43
|
+
- targets/PLUG/target.txt
|
44
|
+
homepage: https://github.com/ryanmelt/cosmosc2-kasa-plug
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubygems_version: 3.1.6
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: COSMOS Plugin to Connect to Kasa Smart Plugs
|
67
|
+
test_files: []
|