esphome 0.1.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 +7 -0
- data/exe/esphome-monitor +157 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1caa16ccd3799a2a3139eb844270d03908ad2a90e039545fe22965e44e2a4631
|
4
|
+
data.tar.gz: a2112bfaf0021a412a49850b755656f9ae4690ed1433729c30274c88ec2d4396
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 86a427ef2f9ce500abd913bc435cd10e8951f539122723699606f840f3cd9bc9f7e0babdf7b0572c1137e144c5bb392277bbfb61777bdd755789a59e8e709b73
|
7
|
+
data.tar.gz: 1625c81170abda661eaacf6938d5e54dbcab261b21397d5da870276be09c046432b16c8596580c41dbdf11e83e68629b2272b308bcbbc32bc4194104488a009e
|
data/exe/esphome-monitor
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "curses"
|
5
|
+
require "esphome"
|
6
|
+
require "time"
|
7
|
+
|
8
|
+
ANSI_COLOR_MAP = {
|
9
|
+
30 => Curses::COLOR_BLACK,
|
10
|
+
31 => Curses::COLOR_RED,
|
11
|
+
32 => Curses::COLOR_GREEN,
|
12
|
+
33 => Curses::COLOR_YELLOW,
|
13
|
+
34 => Curses::COLOR_BLUE,
|
14
|
+
35 => Curses::COLOR_MAGENTA,
|
15
|
+
36 => Curses::COLOR_CYAN,
|
16
|
+
37 => Curses::COLOR_WHITE
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
# Regex to match ANSI color codes (like \e[31m)
|
20
|
+
ANSI_ESCAPE_REGEX = /\e\[(\d+(?:;\d+)*)m/
|
21
|
+
|
22
|
+
def parse_sgr_codes(codes)
|
23
|
+
color = nil
|
24
|
+
attr = Curses::A_NORMAL
|
25
|
+
|
26
|
+
codes.each do |code|
|
27
|
+
code = code.to_i
|
28
|
+
if ANSI_COLOR_MAP.key?(code)
|
29
|
+
color = ANSI_COLOR_MAP[code]
|
30
|
+
elsif code == 1
|
31
|
+
attr |= Curses::A_BOLD
|
32
|
+
elsif code == 4
|
33
|
+
attr |= Curses::A_UNDERLINE
|
34
|
+
elsif code.zero?
|
35
|
+
attr = Curses::A_NORMAL
|
36
|
+
color = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
[color, attr]
|
41
|
+
end
|
42
|
+
|
43
|
+
def parse_ansi_and_render(line)
|
44
|
+
@win.clrtoeol
|
45
|
+
current_color = nil
|
46
|
+
current_attr = Curses::A_NORMAL
|
47
|
+
|
48
|
+
line.split(ANSI_ESCAPE_REGEX).each_with_index do |part, i|
|
49
|
+
if i.odd?
|
50
|
+
codes = part.split(";").map(&:to_i)
|
51
|
+
current_color, current_attr = parse_sgr_codes(codes)
|
52
|
+
elsif current_color
|
53
|
+
pair_id = current_color + 1
|
54
|
+
@win.attron(Curses.color_pair(pair_id) | current_attr) do
|
55
|
+
@win.addstr(part)
|
56
|
+
end
|
57
|
+
else
|
58
|
+
@win.attron(current_attr) do
|
59
|
+
@win.addstr(part)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
@device = ESPHome::Device.new(ARGV[0], ARGV[1], logger: Logger.new(IO::NULL))
|
66
|
+
|
67
|
+
def print_entity(entity, clear_line: true)
|
68
|
+
return unless @entities.key?(entity.key) # has an unsupported entity
|
69
|
+
|
70
|
+
@win.setpos(@entities[entity.key] + 3, 0)
|
71
|
+
@win.clrtoeol if clear_line
|
72
|
+
name = "#{entity.class.name.split("::").last} - #{entity.name}"
|
73
|
+
@win.addstr("#{name.ljust(40)}: [#{Time.now.strftime("%H:%M:%S")}] #{entity.formatted_state}")
|
74
|
+
end
|
75
|
+
|
76
|
+
def visible_lines
|
77
|
+
@win.maxy - @entities.size - 5
|
78
|
+
end
|
79
|
+
|
80
|
+
def render_log(visible_lines = nil)
|
81
|
+
visible_lines ||= self.visible_lines
|
82
|
+
|
83
|
+
@log_lines.each_with_index do |log_line, idx|
|
84
|
+
break if idx >= visible_lines
|
85
|
+
|
86
|
+
@win.setpos(@entities.size + 4 + idx, 0)
|
87
|
+
|
88
|
+
parse_ansi_and_render(log_line)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def render_all
|
93
|
+
@win.clear
|
94
|
+
@win.setpos(0, 0)
|
95
|
+
@win.addstr("ESPHome")
|
96
|
+
@win.setpos(1, 0)
|
97
|
+
@win.addstr("#{@device.friendly_name.ljust(45)} (#{@device.esphome_version} - #{@device.compilation_time})")
|
98
|
+
@win.setpos(2, 0)
|
99
|
+
@win.addstr("=" * 80)
|
100
|
+
|
101
|
+
@device.entities.each_value do |entity|
|
102
|
+
next unless entity.is_a?(ESPHome::Entity::HasState)
|
103
|
+
|
104
|
+
print_entity(entity, clear_line: false)
|
105
|
+
end
|
106
|
+
|
107
|
+
render_log
|
108
|
+
|
109
|
+
@win.refresh
|
110
|
+
end
|
111
|
+
|
112
|
+
Signal.trap("SIGWINCH") do
|
113
|
+
render_all
|
114
|
+
end
|
115
|
+
|
116
|
+
@log_lines = []
|
117
|
+
|
118
|
+
@device.on_message do |entity_or_log_line|
|
119
|
+
if entity_or_log_line.is_a?(String)
|
120
|
+
visible_lines = self.visible_lines
|
121
|
+
@log_lines << "[#{Time.now.strftime("%H:%M:%S")}]#{entity_or_log_line}"
|
122
|
+
@log_lines.shift if @log_lines.size > [20, visible_lines].max
|
123
|
+
|
124
|
+
render_log
|
125
|
+
else
|
126
|
+
print_entity(entity_or_log_line)
|
127
|
+
end
|
128
|
+
@win.refresh
|
129
|
+
end
|
130
|
+
|
131
|
+
@device.connect
|
132
|
+
|
133
|
+
@entities = {}
|
134
|
+
@device.entities.values.grep(ESPHome::Entity::HasState).sort_by(&:name).each_with_index do |entity, idx|
|
135
|
+
@entities[entity.key] = idx
|
136
|
+
end
|
137
|
+
|
138
|
+
Curses.init_screen
|
139
|
+
begin
|
140
|
+
Curses.noecho
|
141
|
+
Curses.start_color
|
142
|
+
Curses.use_default_colors
|
143
|
+
@win = Curses.stdscr
|
144
|
+
ANSI_COLOR_MAP.each_value do |color|
|
145
|
+
Curses.init_pair(color + 1, color, -1)
|
146
|
+
end
|
147
|
+
|
148
|
+
render_all
|
149
|
+
|
150
|
+
@device.stream_states
|
151
|
+
@device.stream_log(dump_config: true)
|
152
|
+
@device.loop
|
153
|
+
rescue Interrupt
|
154
|
+
# exitting
|
155
|
+
ensure
|
156
|
+
Curses.close_screen
|
157
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: esphome
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cody Cutrer
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-07-01 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: curses
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.5'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '1.5'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: google-protobuf
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '4.31'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4.31'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: logger
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.7'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.7'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: noise-ruby
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.10'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.10'
|
68
|
+
email:
|
69
|
+
- cody@cutrer.us
|
70
|
+
executables:
|
71
|
+
- esphome-monitor
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- exe/esphome-monitor
|
76
|
+
homepage: https://github.com/ccutrer/esphome-ruby
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata:
|
80
|
+
homepage_uri: https://github.com/ccutrer/esphome-ruby
|
81
|
+
rubygems_mfa_required: 'true'
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 3.1.0
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubygems_version: 3.6.3
|
97
|
+
specification_version: 4
|
98
|
+
summary: ESPHome Library and CLI for Ruby
|
99
|
+
test_files: []
|