esphome 1.0.0 → 1.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/exe/esphome-monitor +4 -12
- data/exe/esphome-serial-proxy +132 -0
- data/lib/esphome/action.rb +55 -0
- data/lib/esphome/api/README.md +3 -0
- data/lib/esphome/api/api.proto +2756 -0
- data/lib/esphome/api/api_options.proto +120 -0
- data/lib/esphome/api/api_options_pb.rb +20 -0
- data/lib/esphome/api/api_pb.rb +229 -0
- data/lib/esphome/api.rb +182 -0
- data/lib/esphome/cli/colors.rb +44 -0
- data/lib/esphome/cli/completion.rb +48 -0
- data/lib/esphome/cli/entities/button.rb +18 -0
- data/lib/esphome/cli/entities/climate.rb +196 -0
- data/lib/esphome/cli/entities/cover.rb +116 -0
- data/lib/esphome/cli/entities/date.rb +27 -0
- data/lib/esphome/cli/entities/date_time.rb +29 -0
- data/lib/esphome/cli/entities/form.rb +111 -0
- data/lib/esphome/cli/entities/lock.rb +20 -0
- data/lib/esphome/cli/entities/menu.rb +83 -0
- data/lib/esphome/cli/entities/number.rb +37 -0
- data/lib/esphome/cli/entities/select.rb +16 -0
- data/lib/esphome/cli/entities/subfields.rb +63 -0
- data/lib/esphome/cli/entities/switch.rb +18 -0
- data/lib/esphome/cli/entities/text.rb +16 -0
- data/lib/esphome/cli/entities/time.rb +40 -0
- data/lib/esphome/cli/entity.rb +78 -0
- data/lib/esphome/cli/monitor.rb +441 -0
- data/lib/esphome/dashboard.rb +86 -0
- data/lib/esphome/device.rb +416 -0
- data/lib/esphome/entities/binary_sensor.rb +66 -0
- data/lib/esphome/entities/button.rb +13 -0
- data/lib/esphome/entities/climate.rb +259 -0
- data/lib/esphome/entities/cover.rb +135 -0
- data/lib/esphome/entities/date.rb +23 -0
- data/lib/esphome/entities/date_time.rb +21 -0
- data/lib/esphome/entities/fan.rb +89 -0
- data/lib/esphome/entities/light.rb +158 -0
- data/lib/esphome/entities/lock.rb +53 -0
- data/lib/esphome/entities/number.rb +56 -0
- data/lib/esphome/entities/select.rb +27 -0
- data/lib/esphome/entities/sensor.rb +49 -0
- data/lib/esphome/entities/switch.rb +24 -0
- data/lib/esphome/entities/text.rb +36 -0
- data/lib/esphome/entities/text_sensor.rb +10 -0
- data/lib/esphome/entities/time.rb +39 -0
- data/lib/esphome/entity.rb +146 -0
- data/lib/esphome/error.rb +28 -0
- data/lib/esphome/serial_proxy.rb +372 -0
- data/lib/esphome/version.rb +5 -0
- data/lib/esphome.rb +5 -0
- data/lib/httpx/plugins/websocket.rb +62 -0
- data/lib/websocket/driver/httpx.rb +74 -0
- metadata +54 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33d62455a361134b7827505b3522fe5793cec979e80341d413faf96dcdb28e71
|
|
4
|
+
data.tar.gz: 5e40a30af957deca20e72bade19dd9920b250816bc3d3e94da3d38704f7f6f3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1aab44a24e5fce3acd11c7d37c0d0995cd70e472bda890012218a3db3f99202f6bd4ffbd5cbadd942957cdf8f929ae862096d5779d16d967cd1e264059795ac3
|
|
7
|
+
data.tar.gz: 03f1fb2e2bee356d445b58d3a38eebb357d5df249d8340a3ca099b5a76447cf1979bf19a93ffd1474b5b283a82880504d3c8f7effc2271eb234d590e5ca5852d
|
data/exe/esphome-monitor
CHANGED
|
@@ -65,18 +65,10 @@ end
|
|
|
65
65
|
if uri
|
|
66
66
|
require "esphome/dashboard"
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
warn "Device not found: #{device_name}"
|
|
73
|
-
exit 1
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
address = device["address"]
|
|
77
|
-
encryption_key = dashboard.encryption_key(device["configuration"])
|
|
78
|
-
unless encryption_key
|
|
79
|
-
warn "No encryption key found for device #{device_name}"
|
|
68
|
+
begin
|
|
69
|
+
address, encryption_key = ESPHome::Dashboard.address_and_encryption_key(uri, device_name)
|
|
70
|
+
rescue ESPHome::DashboardError => e
|
|
71
|
+
warn e.message
|
|
80
72
|
exit 1
|
|
81
73
|
end
|
|
82
74
|
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "io/console"
|
|
5
|
+
require "optparse"
|
|
6
|
+
|
|
7
|
+
require "esphome/cli/completion"
|
|
8
|
+
|
|
9
|
+
if ENV["COMP_LINE"]
|
|
10
|
+
ESPHome::Cli::Completion.run
|
|
11
|
+
exit
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require "esphome/serial_proxy"
|
|
15
|
+
|
|
16
|
+
baud = nil
|
|
17
|
+
data_bits = nil
|
|
18
|
+
parity = nil
|
|
19
|
+
stop_bits = nil
|
|
20
|
+
|
|
21
|
+
opts = OptionParser.new do |opts|
|
|
22
|
+
opts.banner = <<~TEXT
|
|
23
|
+
Usage: esphome-serial-proxy ([<uri>] <device_name> [instance] | <address> <encryption_key> [instance])
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
esphome-serial-proxy my_device
|
|
27
|
+
esphome-serial-proxy http://localhost:6052/ my_device uart0
|
|
28
|
+
esphome-serial-proxy 192.168.1.10 BASE64_ENCRYPTION_KEY 1
|
|
29
|
+
TEXT
|
|
30
|
+
|
|
31
|
+
opts.on("--baud=VALUE", Integer, "Serial baud rate") do |value|
|
|
32
|
+
baud = value
|
|
33
|
+
end
|
|
34
|
+
opts.on("--data-bits=VALUE", Integer, "Serial data bits") do |value|
|
|
35
|
+
data_bits = value
|
|
36
|
+
end
|
|
37
|
+
opts.on("--parity=VALUE", "Serial parity (`none`, `even`, or `odd`)") do |value|
|
|
38
|
+
parity = value.to_sym
|
|
39
|
+
end
|
|
40
|
+
opts.on("--stop-bits=VALUE", Integer, "Serial stop bits") do |value|
|
|
41
|
+
stop_bits = value
|
|
42
|
+
end
|
|
43
|
+
opts.on("-h", "--help", "Show this help message") do
|
|
44
|
+
puts opts
|
|
45
|
+
exit
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
opts.parse!
|
|
49
|
+
|
|
50
|
+
dashboard_uri = nil
|
|
51
|
+
device_name = nil
|
|
52
|
+
address = nil
|
|
53
|
+
encryption_key = nil
|
|
54
|
+
instance = nil
|
|
55
|
+
|
|
56
|
+
if ARGV.size == 1
|
|
57
|
+
dashboard_uri = ESPHome::Dashboard::DEFAULT_URI
|
|
58
|
+
device_name = ARGV[0]
|
|
59
|
+
elsif ARGV.size == 2 && ARGV[0].include?(":")
|
|
60
|
+
dashboard_uri, device_name = ARGV
|
|
61
|
+
elsif ARGV.size == 2
|
|
62
|
+
address, encryption_key = ARGV
|
|
63
|
+
elsif ARGV.size == 3 && ARGV[0].include?(":")
|
|
64
|
+
dashboard_uri, device_name, instance = ARGV
|
|
65
|
+
elsif ARGV.size == 3
|
|
66
|
+
address, encryption_key, instance = ARGV
|
|
67
|
+
else
|
|
68
|
+
warn opts
|
|
69
|
+
exit(-1)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if dashboard_uri
|
|
73
|
+
require "esphome/dashboard"
|
|
74
|
+
|
|
75
|
+
begin
|
|
76
|
+
address, encryption_key = ESPHome::Dashboard.address_and_encryption_key(dashboard_uri, device_name)
|
|
77
|
+
rescue ESPHome::DashboardError => e
|
|
78
|
+
warn e.message
|
|
79
|
+
exit 1
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
stdin_thread = nil
|
|
84
|
+
interactive = $stdin.tty?
|
|
85
|
+
session = proc do
|
|
86
|
+
$stdin.binmode
|
|
87
|
+
$stdout.binmode
|
|
88
|
+
$stderr.binmode
|
|
89
|
+
$stdout.sync = true
|
|
90
|
+
|
|
91
|
+
ESPHome::SerialProxy.open(address,
|
|
92
|
+
encryption_key,
|
|
93
|
+
instance,
|
|
94
|
+
baud:,
|
|
95
|
+
data_bits:,
|
|
96
|
+
parity:,
|
|
97
|
+
stop_bits:) do |proxy|
|
|
98
|
+
stdin_thread = Thread.new do
|
|
99
|
+
Kernel.loop do
|
|
100
|
+
chunk = $stdin.readpartial(64 * 1024)
|
|
101
|
+
if interactive && (eof = chunk.index("\x04"))
|
|
102
|
+
proxy.write(chunk.byteslice(0, eof)) if eof.positive?
|
|
103
|
+
proxy.close
|
|
104
|
+
break
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
proxy.write(chunk)
|
|
108
|
+
end
|
|
109
|
+
rescue EOFError
|
|
110
|
+
nil
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
begin
|
|
114
|
+
Kernel.loop do
|
|
115
|
+
$stdout.write(proxy.readpartial(64 * 1024))
|
|
116
|
+
end
|
|
117
|
+
rescue EOFError
|
|
118
|
+
nil
|
|
119
|
+
ensure
|
|
120
|
+
stdin_thread.kill if stdin_thread&.alive?
|
|
121
|
+
stdin_thread&.join
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
if interactive
|
|
127
|
+
$stdin.raw(intr: true) do
|
|
128
|
+
session.call
|
|
129
|
+
end
|
|
130
|
+
else
|
|
131
|
+
session.call
|
|
132
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ESPHome
|
|
4
|
+
class Action
|
|
5
|
+
class << self
|
|
6
|
+
def from_protobuf(message)
|
|
7
|
+
data = message.data.to_h { |kv| [kv.key, kv.value] }
|
|
8
|
+
data_template = message.data_template.to_h { |kv| [kv.key, kv.value] }
|
|
9
|
+
variables = message.variables.to_h { |kv| [kv.key, kv.value] }
|
|
10
|
+
if message.is_event
|
|
11
|
+
if message.service == TagScanned::SERVICE &&
|
|
12
|
+
data.keys == ["tag_id"] &&
|
|
13
|
+
data_template.empty? &&
|
|
14
|
+
variables.empty?
|
|
15
|
+
TagScanned.new(data["tag_id"])
|
|
16
|
+
else
|
|
17
|
+
Event.new(message.service, data, data_template, variables)
|
|
18
|
+
end
|
|
19
|
+
else
|
|
20
|
+
Action.new(message.service, data, data_template, variables)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
attr_reader :service, :data, :data_template, :variables
|
|
26
|
+
|
|
27
|
+
def initialize(service, data = {}, data_template = {}, variables = {})
|
|
28
|
+
@service = service
|
|
29
|
+
@data = data
|
|
30
|
+
@data_template = data_template
|
|
31
|
+
@variables = variables
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def inspect
|
|
35
|
+
"#<#{self.class.name} service=#{service} " \
|
|
36
|
+
"data=#{data.inspect} " \
|
|
37
|
+
"data_template=#{data_template.inspect} " \
|
|
38
|
+
"variables=#{variables.inspect}>"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class Event < Action; end
|
|
43
|
+
|
|
44
|
+
class TagScanned < Event
|
|
45
|
+
SERVICE = "esphome.tag_scanned"
|
|
46
|
+
|
|
47
|
+
def initialize(tag_id)
|
|
48
|
+
super(SERVICE, { "tag_id" => tag_id })
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def inspect
|
|
52
|
+
"#<#{self.class.name} tag_id=#{data["tag_id"].inspect}>"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
Just copy api.proto from esphome's repository and re-add `option ruby_package = "ESPHome::Api";` at the top.
|
|
2
|
+
Then regenerate with `protoc --ruby_out=. api.proto api_options.proto`, and finally edit the `require` in api_pb.rb to be `require_relative`.
|
|
3
|
+
Be sure to add any new messages to api.rb, and check for changes in the messages themselves.
|