esphome 1.1.1 → 1.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7290628c333abc933faa1582a521381217a7c518b0db41cd476f61644f90fa1a
4
- data.tar.gz: 52a9eda4cff49e44c4695bd7b0bb9e911052cca5178f5a6092810845bf638909
3
+ metadata.gz: 7692692de1d32a122a21c669572fec6232e0fccf0876251548259d446de6727c
4
+ data.tar.gz: c20a4ac0dad1f3243bd274652474c1a6566dd274578c54939e0b228e19aba8f1
5
5
  SHA512:
6
- metadata.gz: 29309825cb9b36c0a1991e41435c64fdad4d33d6472873aadec652cd1d76841e8dae3929f5f4b56a9998834af62f57bbcc550efe1482c00e65b3f4ca69bec9ea
7
- data.tar.gz: c1eabdd29c70ce725e5949a6b2450a9f5c9087f10d45c1fe060f4a644c1a27b2f4c62ff599ab659b430a2083176730de2d4dd6d5af1b9e2d219243b2a20113b8
6
+ metadata.gz: 460d61c2a970646fb80a651b4dfc87c9a2755fb76f428514cb514ab71e49c34e0c49ab99c201c0cf3ff1431dcb63657ae318ca768c4b0f76b5bfef53c0009f5f
7
+ data.tar.gz: 17b8f36fddc959d299590ac3ed9746e9b876499216c70b89a912cd675cd5e03641c01c09321f6ef2856f701a94f7c9e51bb53ad73e566eb2d35ad1373518fa86
data/exe/esphome-monitor CHANGED
@@ -17,6 +17,9 @@ connection_log_level = :warn
17
17
  device_log_level = :debug
18
18
  dump_config = false
19
19
  port = 6053
20
+ diagnostic_entities = false
21
+ config_entities = true
22
+ states = false
20
23
  opts = OptionParser.new do |opts|
21
24
  opts.banner = <<~TEXT
22
25
  Usage: esphome-monitor ([<uri>] <device_name> | <address> <encryption_key>)
@@ -43,6 +46,15 @@ opts = OptionParser.new do |opts|
43
46
  opts.on("--dump-config", "Dump device configuration on connect (requires log streaming at info level)") do
44
47
  dump_config = true
45
48
  end
49
+ opts.on("--[no-]diagnostic-entities", "include diagnostic entities (default off)") do |v|
50
+ diagnostic_entities = v
51
+ end
52
+ opts.on("--[no-]config-entities", "include configuration entities (default on)") do |v|
53
+ config_entities = v
54
+ end
55
+ opts.on("--[no-]states", "Log entity state changes (default off)") do |v|
56
+ states = v
57
+ end
46
58
  opts.on("-h", "--help", "Show this help message") do
47
59
  puts opts
48
60
  exit
@@ -75,4 +87,12 @@ end
75
87
 
76
88
  device = ESPHome::Device.new(address, encryption_key, port:)
77
89
 
78
- ESPHome::Cli::Monitor.run(device, connection_log_level:, device_log_level:, log_level:, actions:, dump_config:)
90
+ ESPHome::Cli::Monitor.run(device,
91
+ connection_log_level:,
92
+ device_log_level:,
93
+ log_level:,
94
+ actions:,
95
+ dump_config:,
96
+ diagnostic_entities:,
97
+ config_entities:,
98
+ states:)
@@ -47,7 +47,10 @@ module ESPHome
47
47
  device_log_level: nil,
48
48
  connection_log_level: nil,
49
49
  log_level: nil,
50
- dump_config: false)
50
+ dump_config: false,
51
+ diagnostic_entities: true,
52
+ config_entities: true,
53
+ states: false)
51
54
  @device = device
52
55
  @win = nil
53
56
  @entities_by_key = {}
@@ -61,6 +64,9 @@ module ESPHome
61
64
  @logger = LoggerWrapper.new(self, level: log_level || Logger::INFO)
62
65
  @actions = actions
63
66
  @dump_config = dump_config
67
+ @diagnostic_entities = diagnostic_entities
68
+ @config_entities = config_entities
69
+ @states = states
64
70
  @winch_trapped = false
65
71
  @logwin = nil
66
72
  @screen_initialized = false
@@ -79,9 +85,17 @@ module ESPHome
79
85
 
80
86
  def run
81
87
  @device.on_message do |entity_or_log_line|
82
- if entity_or_log_line.respond_to?(:key) && (entity_wrapper = @entities_by_key[entity_or_log_line.key])
83
- entity_wrapper.touch
84
- queue_ui_event(:entity, entity_wrapper)
88
+ if entity_or_log_line.respond_to?(:key)
89
+ key = entity_or_log_line.key
90
+ if (entity_wrapper = @entities_by_key[key])
91
+ entity_wrapper.touch
92
+ log_entity_state(entity_wrapper.__getobj__) if @states
93
+ queue_ui_event(:entity, entity_wrapper)
94
+ elsif @device.entities.key?(key)
95
+ # ignored diagnostic or config entity
96
+ else
97
+ logger.warn("Unexpected entity #{entity_or_log_line.inspect}")
98
+ end
85
99
  elsif entity_or_log_line.is_a?(Action)
86
100
  logger.info(entity_or_log_line.inspect)
87
101
  else
@@ -91,10 +105,16 @@ module ESPHome
91
105
 
92
106
  @device.on_connect do
93
107
  logger.info("Connected")
94
- @name_width = @device.entities.values.map { |e| e.name.length }.max || 0
108
+ entities = @device.entities.values.select do |entity|
109
+ next false if entity.entity_category == :diagnostic && !@diagnostic_entities
110
+ next false if entity.entity_category == :config && !@config_entities
111
+
112
+ true
113
+ end
114
+ @name_width = entities.map { |e| e.name.length }.max || 0
95
115
  @entities_by_key = {}
96
116
  @entities = []
97
- @device.entities.values.sort_by(&:name).each_with_index do |entity, idx|
117
+ entities.sort_by(&:name).each_with_index do |entity, idx|
98
118
  simple_name = entity.class.name.split("::").last
99
119
  entity_class = if Entities.const_defined?(simple_name)
100
120
  Entities.const_get(simple_name, false)
@@ -190,6 +210,11 @@ module ESPHome
190
210
  @device.disconnect
191
211
  end
192
212
 
213
+ def log_entity_state(entity)
214
+ type = entity.class.name.split("::").last.gsub(/[A-Z]/) { |c| "_#{c.downcase}" }[1..]
215
+ add(nil, "\e[36m[S][#{type}]: '#{entity.name}' >> #{entity.formatted_state}\e[0m")
216
+ end
217
+
193
218
  def add(_level, message = nil, progname = nil, render: true)
194
219
  if message.nil?
195
220
  message = if block_given?
@@ -246,7 +246,6 @@ module ESPHome
246
246
  elsif message.is_a?(Api::DisconnectRequest)
247
247
  send(Api::DisconnectResponse.new)
248
248
  disconnected
249
- @on_disconnect_callback.each(&:call)
250
249
  elsif message.is_a?(Api::DisconnectResponse)
251
250
  disconnected
252
251
  elsif message.is_a?(Api::PingResponse)
@@ -346,10 +345,12 @@ module ESPHome
346
345
  end
347
346
 
348
347
  def disconnected
348
+ was_connected = connected?
349
349
  @socket&.close
350
350
  @socket = nil
351
351
  @noise = nil
352
352
  @entities = nil
353
+ @on_disconnect_callback.each(&:call) if was_connected
353
354
  end
354
355
 
355
356
  def write_frame(data)
@@ -47,6 +47,9 @@ module ESPHome
47
47
  loop_thread = io.instance_variable_set(:@loop_thread, Thread.new do
48
48
  Thread.current.report_on_exception = false
49
49
  device.loop
50
+ rescue ConnectionClosedError, NotConnectedError
51
+ # Readers observe the disconnect as EOF; joining the loop must not mask it.
52
+ nil
50
53
  rescue IOError
51
54
  raise unless io.closed?
52
55
  end)
@@ -257,6 +260,7 @@ module ESPHome
257
260
  loop do
258
261
  data = @mutex.synchronize do
259
262
  raise EOFError if @closed && @buffer.empty?
263
+ raise EOFError, "serial proxy disconnected" if @buffer.empty? && !device.connected?
260
264
 
261
265
  @buffer.slice!(0, maxlen) unless @buffer.empty?
262
266
  end
@@ -281,7 +285,8 @@ module ESPHome
281
285
 
282
286
  deadline = monotonic_time + timeout if timeout
283
287
  Kernel.loop do
284
- return nil if @closed || !device.connected?
288
+ return nil if @closed
289
+ raise EOFError, "serial proxy disconnected" unless device.connected?
285
290
 
286
291
  remaining = deadline && (deadline - monotonic_time)
287
292
  return nil if deadline && remaining <= 0
@@ -361,6 +366,8 @@ module ESPHome
361
366
  result = yield
362
367
  return result unless result.nil?
363
368
 
369
+ raise EOFError, "serial proxy disconnected" unless device.connected?
370
+
364
371
  @data_ready.wait(@mutex)
365
372
  end
366
373
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ESPHome
4
- VERSION = "1.1.1"
4
+ VERSION = "1.2.1"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: esphome
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-07-26 00:00:00.000000000 Z
10
+ date: 2026-11-05 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: curses