meshtastic 0.0.184 → 0.0.186

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +1 -0
  3. data/Gemfile +2 -1
  4. data/documentation/README.md +5 -0
  5. data/documentation/forwarder.md +149 -0
  6. data/documentation/mesh-interface.md +157 -1
  7. data/documentation/payload-formats.md +187 -0
  8. data/documentation/reticulum.md +89 -0
  9. data/lib/meshtastic/atak.rb +98 -13
  10. data/lib/meshtastic/atak_pb.rb +3 -1
  11. data/lib/meshtastic/config_pb.rb +1 -1
  12. data/lib/meshtastic/field_metadata_pb.rb +1 -1
  13. data/lib/meshtastic/forwarder.rb +190 -0
  14. data/lib/meshtastic/forwarder_pb.rb +77 -0
  15. data/lib/meshtastic/mesh_beacon_pb.rb +1 -1
  16. data/lib/meshtastic/mesh_interface.rb +115 -65
  17. data/lib/meshtastic/mesh_pb.rb +2 -1
  18. data/lib/meshtastic/module_config_pb.rb +1 -1
  19. data/lib/meshtastic/mqtt.rb +4 -34
  20. data/lib/meshtastic/payload_compression.rb +90 -0
  21. data/lib/meshtastic/payload_formats.rb +248 -0
  22. data/lib/meshtastic/reticulum.rb +71 -0
  23. data/lib/meshtastic/serial.rb +1 -19
  24. data/lib/meshtastic/telemetry_pb.rb +2 -2
  25. data/lib/meshtastic/unishox2.rb +467 -0
  26. data/lib/meshtastic/version.rb +1 -1
  27. data/lib/meshtastic.rb +4 -0
  28. data/meshtastic.gemspec +2 -0
  29. data/spec/lib/meshtastic/atak_spec.rb +50 -0
  30. data/spec/lib/meshtastic/bluetooth_spec.rb +14 -0
  31. data/spec/lib/meshtastic/forwarder_pb_spec.rb +11 -0
  32. data/spec/lib/meshtastic/forwarder_spec.rb +97 -0
  33. data/spec/lib/meshtastic/mesh_interface_spec.rb +169 -0
  34. data/spec/lib/meshtastic/mqtt_spec.rb +56 -0
  35. data/spec/lib/meshtastic/payload_compression_spec.rb +43 -0
  36. data/spec/lib/meshtastic/payload_formats_spec.rb +160 -0
  37. data/spec/lib/meshtastic/reticulum_spec.rb +91 -0
  38. data/spec/lib/meshtastic/serial_spec.rb +46 -0
  39. data/spec/lib/meshtastic/tcp_spec.rb +15 -0
  40. data/spec/lib/meshtastic/unishox2_spec.rb +34 -0
  41. data/spec/support/payload_fixtures.rb +123 -0
  42. data/spec/support/reticulum_fixtures.json +12 -0
  43. data/spec/support/tak_codec_fixtures.rb +4 -0
  44. data/spec/support/unishox_fixtures.rb +4 -0
  45. metadata +36 -3
@@ -0,0 +1,248 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ipaddr'
4
+
5
+ module Meshtastic
6
+ # Stateless binary application decoders; see documentation/payload-formats.md.
7
+ module PayloadFormats
8
+ PORTS = { AUDIO_APP: 9, IP_TUNNEL_APP: 33, ZPS_APP: 68, CAYENNE_APP: 77, LORA_OTA_APP: 79 }.freeze
9
+ LPP_TYPES = {
10
+ 0 => [:digital_input, 1, false, 1, nil],
11
+ 1 => [:digital_output, 1, false, 1, nil],
12
+ 2 => [:analog_input, 2, true, 100, nil],
13
+ 3 => [:analog_output, 2, true, 100, nil],
14
+ 101 => [:illuminance, 2, false, 1, 'lux'],
15
+ 102 => [:presence, 1, false, 1, nil],
16
+ 103 => [:temperature, 2, true, 10, 'C'],
17
+ 104 => [:relative_humidity, 1, false, 2, '%'],
18
+ 113 => [:accelerometer, 6, true, 1000, 'g'],
19
+ 115 => [:barometric_pressure, 2, false, 10, 'hPa'],
20
+ 134 => [:gyrometer, 6, true, 100, 'degrees/s'],
21
+ 136 => [:gps, 9, true, 1, nil]
22
+ }.freeze
23
+
24
+ public_class_method def self.decode(opts = {})
25
+ port = opts[:portnum]
26
+ port = PORTS[port.to_sym] if port.is_a?(String) || port.is_a?(Symbol)
27
+ raw = opts[:payload]
28
+ raise ArgumentError, 'payload must be a binary String' unless raw.is_a?(String)
29
+
30
+ raw = raw.b
31
+ result = { portnum: port, raw: raw }
32
+ parsed = case port
33
+ when 9 then audio(payload: raw)
34
+ when 33 then ip(payload: raw)
35
+ when 68 then zps(payload: raw, profile: opts[:zps_profile])
36
+ when 77 then cayenne(payload: raw)
37
+ when 79 then ota(payload: raw)
38
+ else { status: :unsupported, format: :opaque, error: 'no verified schema for this port' }
39
+ end
40
+ parsed.merge!(pcm_audio(audio: parsed)) if port == 9 && opts[:pcm] && parsed[:status] == :decoded
41
+ result.merge(parsed)
42
+ rescue ArgumentError => e
43
+ raise unless raw.is_a?(String)
44
+
45
+ result.merge(status: :malformed, error: e.message)
46
+ end
47
+
48
+ private_class_method def self.cayenne(opts = {})
49
+ raw = opts[:payload]
50
+ records = []
51
+ offset = 0
52
+ while offset < raw.bytesize
53
+ raise ArgumentError, 'truncated Cayenne channel/type' if raw.bytesize - offset < 2
54
+
55
+ channel, type = raw.byteslice(offset, 2).unpack('CC')
56
+ definition = LPP_TYPES[type]
57
+ unless definition
58
+ return { format: :cayenne_lpp, status: :unsupported, records: records,
59
+ error: "unknown Cayenne type #{type}", undecoded_offset: offset, remainder: raw.byteslice(offset..) }
60
+ end
61
+ name, length, signed, divisor, unit = definition
62
+ data = raw.byteslice(offset + 2, length)
63
+ raise ArgumentError, "truncated Cayenne #{name}" unless data && data.bytesize == length
64
+
65
+ width = length > 2 ? length / 3 : length
66
+ values = data.bytes.each_slice(width).map do |bytes|
67
+ value = bytes.reduce(0) { |memo, byte| (memo << 8) | byte }
68
+ value -= 1 << (width * 8) if signed && bytes.first >= 128
69
+ value.fdiv(divisor)
70
+ end
71
+ value = if type == 136
72
+ { latitude: values[0] / 10_000, longitude: values[1] / 10_000, altitude: values[2] / 100 }
73
+ elsif length == 6
74
+ %i[x y z].zip(values).to_h
75
+ else
76
+ values.first
77
+ end
78
+ records << { channel: channel, type: type, name: name, value: value, unit: unit }
79
+ offset += length + 2
80
+ end
81
+ { format: :cayenne_lpp, status: :decoded, records: records }
82
+ end
83
+
84
+ private_class_method def self.zps(opts = {})
85
+ unless opts[:profile] == :esp32_legacy
86
+ return { format: :opaque, status: :unsupported,
87
+ error: 'ZPS has no stable port-68 schema; select zps_profile: :esp32_legacy only for that experimental dialect' }
88
+ end
89
+ raw = opts[:payload]
90
+ raise ArgumentError, 'experimental ZPS needs two header words and up to twenty uint64 records' unless (16..176).cover?(raw.bytesize) && (raw.bytesize % 8).zero?
91
+
92
+ words = raw.unpack('Q<*')
93
+ header, position = words.shift(2)
94
+ records = words.map do |word|
95
+ channel = (word >> 48) & 255
96
+ { kind: channel == 255 ? :ble : :wifi, address: format('%012x', word & 0xffffffffffff).scan(/../).join(':'),
97
+ channel: channel, rssi: -(word >> 56) }
98
+ end
99
+ result = { format: :zps, status: :decoded, profile: :esp32_legacy, timestamp: header & 0xffffffff,
100
+ header_word: header, position_word: position, records: records }
101
+ if header.anybits?(0x800000000000)
102
+ longitude, latitude = [position].pack('Q<').unpack('l<2')
103
+ result[:position] = { latitude_i: latitude, longitude_i: longitude, pdop: (header >> 40) & 0x7f }
104
+ end
105
+ result
106
+ end
107
+
108
+ private_class_method def self.ip(opts = {})
109
+ raw = opts[:payload]
110
+ raise ArgumentError, 'empty IP packet' if raw.empty?
111
+
112
+ version = raw.getbyte(0) >> 4
113
+ result = { format: :ip, status: :decoded, version: version }
114
+ case version
115
+ when 4
116
+ raise ArgumentError, 'truncated IPv4 header' if raw.bytesize < 20
117
+
118
+ header_length = (raw.getbyte(0) & 15) * 4
119
+ total_length = raw.byteslice(2, 2).unpack1('n')
120
+ raise ArgumentError, 'invalid IPv4 header/total length' unless header_length.between?(20, total_length) && raw.bytesize == total_length
121
+
122
+ flags_offset = raw.byteslice(6, 2).unpack1('n')
123
+ header = raw.byteslice(0, header_length)
124
+ sum = header.unpack('n*').sum
125
+ sum = (sum & 0xffff) + (sum >> 16) while sum > 0xffff
126
+ result.merge(header_length: header_length, total_length: total_length, dscp_ecn: raw.getbyte(1),
127
+ identification: raw.byteslice(4, 2).unpack1('n'), flags: flags_offset >> 13,
128
+ fragment_offset: (flags_offset & 0x1fff) * 8, ttl: raw.getbyte(8), protocol: raw.getbyte(9),
129
+ checksum: raw.byteslice(10, 2).unpack1('n'), header_checksum_valid: sum == 0xffff,
130
+ source: IPAddr.new_ntoh(raw.byteslice(12, 4)).to_s,
131
+ destination: IPAddr.new_ntoh(raw.byteslice(16, 4)).to_s,
132
+ options: raw.byteslice(20, header_length - 20), body: raw.byteslice(header_length..))
133
+ when 6
134
+ raise ArgumentError, 'truncated IPv6 header' if raw.bytesize < 40
135
+
136
+ length = raw.byteslice(4, 2).unpack1('n')
137
+ return result.merge(status: :unsupported, error: 'IPv6 jumbogram extension not decoded') if length.zero? && raw.bytesize > 40
138
+ raise ArgumentError, 'invalid IPv6 payload length' unless raw.bytesize == length + 40
139
+
140
+ first = raw.unpack1('N')
141
+ result.merge(header_length: 40, payload_length: length, total_length: length + 40,
142
+ traffic_class: (first >> 20) & 255, flow_label: first & 0xfffff,
143
+ next_header: raw.getbyte(6), hop_limit: raw.getbyte(7),
144
+ source: IPAddr.new_ntoh(raw.byteslice(8, 16)).to_s,
145
+ destination: IPAddr.new_ntoh(raw.byteslice(24, 16)).to_s, body: raw.byteslice(40..))
146
+ else
147
+ result.merge(status: :unsupported, error: 'unknown IP version')
148
+ end
149
+ end
150
+
151
+ private_class_method def self.audio(opts = {})
152
+ raw = opts[:payload]
153
+ raise ArgumentError, 'Codec2 needs C0 DE C2 magic and mode byte' unless raw.bytesize >= 4 && raw.byteslice(0, 3) == "\xC0\xDE\xC2".b
154
+
155
+ mode = raw.getbyte(3)
156
+ rates = [3200, 2400, 1600, 1400, 1300, 1200, 700, 700, 700]
157
+ bits = [64, 48, 64, 56, 52, 48, 28, 28, 28][mode]
158
+ result = { format: :codec2, mode: mode, pcm_decoded: false, encoded: raw.byteslice(4..) }
159
+ return result.merge(status: :unsupported, error: 'unknown Codec2 mode') unless bits
160
+
161
+ width = (bits + 7) / 8
162
+ raise ArgumentError, 'truncated Codec2 frame' unless (result[:encoded].bytesize % width).zero?
163
+
164
+ frames = result[:encoded].bytes.each_slice(width).map { |bytes| bytes.pack('C*') }
165
+ result.merge(status: :decoded, bitrate: rates[mode], bits_per_frame: bits, bytes_per_frame: width,
166
+ samples_per_frame: mode < 2 ? 160 : 320, sample_rate: 8000, frames: frames)
167
+ end
168
+
169
+ private_class_method def self.pcm_audio(opts = {})
170
+ require 'fiddle'
171
+
172
+ audio = opts[:audio]
173
+ library = Fiddle.dlopen('libcodec2.so')
174
+ pointer = Fiddle::TYPE_VOIDP
175
+ integer = Fiddle::TYPE_INT
176
+ create = Fiddle::Function.new(library['codec2_create'], [integer], pointer)
177
+ destroy = Fiddle::Function.new(library['codec2_destroy'], [pointer], Fiddle::TYPE_VOID)
178
+ samples = Fiddle::Function.new(library['codec2_samples_per_frame'], [pointer], integer)
179
+ bits = Fiddle::Function.new(library['codec2_bits_per_frame'], [pointer], integer)
180
+ decode = Fiddle::Function.new(library['codec2_decode'], [pointer, pointer, pointer], Fiddle::TYPE_VOID)
181
+ context = create.call(audio[:mode])
182
+ return { pcm_decoded: false, pcm_error: 'installed libcodec2 does not support this mode' } if context.null?
183
+
184
+ return { pcm_decoded: false, pcm_error: 'native Codec2 geometry differs from wire profile' } unless samples.call(context) == audio[:samples_per_frame] && bits.call(context) == audio[:bits_per_frame]
185
+
186
+ pcm = audio[:frames].map do |frame|
187
+ buffer = "\0".b * (audio[:samples_per_frame] * 2)
188
+ decode.call(context, buffer, frame)
189
+ buffer.unpack('s*').pack('s<*')
190
+ end.join.b
191
+ { pcm_decoded: true, pcm_encoding: :s16le, pcm: pcm }
192
+ rescue LoadError, StandardError => e
193
+ # Optional native decoding must never discard already decoded framing.
194
+ { pcm_decoded: false, pcm_error: e.message }
195
+ ensure
196
+ destroy.call(context) if context && !context.null?
197
+ end
198
+
199
+ private_class_method def self.ota(opts = {})
200
+ raw = opts[:payload]
201
+ raise ArgumentError, 'OTA frame must contain 8..233 bytes' unless (8..233).cover?(raw.bytesize)
202
+
203
+ type, session, index, offset, total = raw.unpack('CCv3')
204
+ names = %i[unknown start manifest block proof request ack done abort load load_commit announce]
205
+ body = raw.byteslice(8..)
206
+ result = { format: :ota_common, status: :decoded, type: names[type] || :unknown,
207
+ type_id: type, session: session, index: index, offset: offset, total: total,
208
+ body: body, signature_verified: false }
209
+ case type
210
+ when 1
211
+ raise ArgumentError, 'OTA START needs 12 bytes' unless body.bytesize == 12
212
+
213
+ result[:start] = %i[block_size block_count payload_length manifest_length signature_length].zip(body.unpack('vvVvv')).to_h
214
+ when 2, 3, 4
215
+ raise ArgumentError, 'OTA fragment exceeds logical unit' if offset + body.bytesize > total
216
+ when 5, 6, 7, 8, 10
217
+ raise ArgumentError, 'OTA control frame has unexpected body' unless body.empty?
218
+ when 9
219
+ raise ArgumentError, 'OTA LOAD needs 8-byte prefix' if body.bytesize < 8
220
+
221
+ length, position = body.unpack('V2')
222
+ chunk = body.byteslice(8..)
223
+ raise ArgumentError, 'OTA LOAD chunk exceeds package' if position + chunk.bytesize > length
224
+
225
+ result[:load] = { total_length: length, offset: position, chunk: chunk }
226
+ else
227
+ result.merge!(status: :unsupported, error: 'OTA body schema not established for this frame type')
228
+ end
229
+ result
230
+ end
231
+
232
+ public_class_method def self.authors
233
+ 'Meshtastic Ruby contributors'
234
+ end
235
+
236
+ public_class_method def self.help
237
+ puts "# Decode a binary application payload without modifying its bytes.
238
+ #{self}.decode(
239
+ portnum: 'required - numeric or named Meshtastic application port',
240
+ payload: 'required - raw binary application payload String',
241
+ pcm: 'optional - decode Codec2 to s16le audio using installed libcodec2; default false',
242
+ zps_profile: 'optional - select :esp32_legacy for the experimental little-endian ZPS dialect'
243
+ )
244
+ # Identify the module authors.
245
+ #{self}.authors"
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Meshtastic
4
+ # Framing for landandair/RNS_Over_Meshtastic, not an RNS plaintext decoder.
5
+ module Reticulum
6
+ public_class_method def self.decode_chunks(opts = {})
7
+ chunks = opts[:chunks]
8
+ limit = opts.fetch(:max_bytes, 564)
9
+ raise ArgumentError, 'Reticulum byte limit must be 1..564' unless limit.is_a?(Integer) && (1..564).cover?(limit)
10
+ raise ArgumentError, 'Reticulum requires 1..128 grouped chunks' unless chunks.is_a?(Array) && (1..128).cover?(chunks.length)
11
+
12
+ fragments = chunks.map { |payload| decode_packet(payload: payload) }.sort_by { |frame| frame[:index] }
13
+ raise ArgumentError, 'Reticulum control cannot be reassembled' unless fragments.all? { |frame| frame[:format] == :reticulum_fragment }
14
+ raise ArgumentError, 'Reticulum mixed message indexes' unless fragments.map { |frame| frame[:message_index] }.uniq.length == 1
15
+ raise ArgumentError, 'Reticulum duplicate or conflicting position' unless fragments.map { |frame| frame[:index] }.uniq.length == fragments.length
16
+
17
+ finals = fragments.select { |frame| frame[:final] }
18
+ raise ArgumentError, 'Reticulum missing or conflicting final count' unless finals.length == 1
19
+
20
+ count = finals.first[:count]
21
+ raise ArgumentError, 'Reticulum missing or out-of-range fragments' unless fragments.map { |frame| frame[:index] } == (1..count).to_a
22
+ raise ArgumentError, 'Reticulum reassembly exceeds byte limit' if fragments.sum { |frame| frame[:body].bytesize } > limit
23
+
24
+ { format: :reticulum_packet, complete: true, message_index: fragments.first[:message_index],
25
+ count: fragments.last[:count], body: fragments.map { |frame| frame[:body] }.join.b,
26
+ raw_chunks: fragments.map { |frame| frame[:raw] }, fragments: fragments }
27
+ end
28
+
29
+ public_class_method def self.authors
30
+ '0day Inc.; tunnel protocol: landandair/RNS_Over_Meshtastic'
31
+ end
32
+
33
+ public_class_method def self.help
34
+ puts "USAGE:
35
+ # Decode one port 76 tunnel frame without inner RNS interpretation.
36
+ #{self}.decode_packet(
37
+ payload: 'required - binary String including the two-byte header or REQ prefix'
38
+ )
39
+ # Reassemble an explicitly isolated complete message without persistent state.
40
+ #{self}.decode_chunks(
41
+ chunks: 'required - array of wire Strings from one sender/channel/connection/message generation',
42
+ max_bytes: 'optional - aggregate body byte ceiling, integer 1..564, default 564'
43
+ )
44
+ # List authors and protocol attribution.
45
+ #{self}.authors
46
+ "
47
+ end
48
+
49
+ public_class_method def self.decode_packet(opts = {})
50
+ payload = opts[:payload]
51
+ raise ArgumentError, 'Reticulum payload must be a binary String' unless payload.is_a?(String)
52
+ raise ArgumentError, 'Reticulum wire length must be 3..202 bytes' unless (3..202).cover?(payload.bytesize)
53
+
54
+ bytes = payload.b
55
+ request = bytes.start_with?('REQ')
56
+ raise ArgumentError, 'Reticulum REQ must contain exactly five bytes' if request && bytes.bytesize != 5
57
+
58
+ message_index, position = bytes.byteslice(request ? 3 : 0, 2).unpack('Cc')
59
+ raise ArgumentError, 'Reticulum position must not be zero' if position.zero?
60
+
61
+ if request
62
+ return { format: :reticulum_request, message_index: message_index, position: position,
63
+ index: position.abs, raw: bytes, complete: false }
64
+ end
65
+ { format: :reticulum_fragment, message_index: message_index, position: position,
66
+ index: position.abs, count: position.negative? ? -position : nil,
67
+ final: position.negative?, complete: position == -1,
68
+ raw: bytes, body: bytes.byteslice(2..) }
69
+ end
70
+ end
71
+ end
@@ -459,25 +459,7 @@ module Meshtastic
459
459
 
460
460
  message[:public_key] = Base64.strict_encode64(message[:public_key]) if message[:public_key].to_s.length.positive? && !(message[:public_key].ascii_only? && message[:public_key] =~ %r{\A[A-Za-z0-9+/]+=*\z})
461
461
 
462
- encrypted_message = message[:encrypted]
463
- if encrypted_message.to_s.length.positive? && psks.any?
464
- packet_id = message[:id]
465
- packet_from = message[:from]
466
- nonce_packet_id = [packet_id].pack('V').ljust(8, "\x00")
467
- nonce_from_node = [packet_from].pack('V').ljust(8, "\x00")
468
- nonce = "#{nonce_packet_id}#{nonce_from_node}"
469
-
470
- psk = psks[:LongFast] || psks[psks.keys.first]
471
- dec_psk = Base64.strict_decode64(psk)
472
-
473
- cipher = OpenSSL::Cipher.new(dec_psk.length == 32 ? 'AES-256-CTR' : 'AES-128-CTR')
474
- cipher.decrypt
475
- cipher.key = dec_psk
476
- cipher.iv = nonce
477
- decrypted = cipher.update(encrypted_message) + cipher.final
478
- message[:decoded] = Meshtastic::Data.decode(decrypted).to_h
479
- message[:encrypted] = :decrypted
480
- end
462
+ Meshtastic::MeshInterface.new.decrypt_packet(message: message, psks: psks)
481
463
 
482
464
  if message[:decoded]
483
465
  payload = message[:decoded][:payload]
@@ -5,7 +5,7 @@
5
5
  require 'google/protobuf'
6
6
 
7
7
 
8
- descriptor_data = "\n\x1ameshtastic/telemetry.proto\x12\nmeshtastic\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xa9\x11\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12\x1a\n\rsoil_moisture\x18\x15 \x01(\rH\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12 \n\x14one_wire_temperature\x18\x17 \x03(\x02\x42\x02\x18\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch0\x18\x18 \x01(\x02H\x16\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch1\x18\x19 \x01(\x02H\x17\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch2\x18\x1a \x01(\x02H\x18\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch3\x18\x1b \x01(\x02H\x19\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch4\x18\x1c \x01(\x02H\x1a\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch5\x18\x1d \x01(\x02H\x1b\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch6\x18\x1e \x01(\x02H\x1c\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch7\x18\x1f \x01(\x02H\x1d\x88\x01\x01\x12%\n\x18one_wire_temperature_ch0\x18 \x01(\x02H\x1e\x88\x01\x01\x12%\n\x18one_wire_temperature_ch1\x18! \x01(\x02H\x1f\x88\x01\x01\x12%\n\x18one_wire_temperature_ch2\x18\" \x01(\x02H \x88\x01\x01\x12%\n\x18one_wire_temperature_ch3\x18# \x01(\x02H!\x88\x01\x01\x12%\n\x18one_wire_temperature_ch4\x18$ \x01(\x02H\"\x88\x01\x01\x12%\n\x18one_wire_temperature_ch5\x18% \x01(\x02H#\x88\x01\x01\x12%\n\x18one_wire_temperature_ch6\x18& \x01(\x02H$\x88\x01\x01\x12%\n\x18one_wire_temperature_ch7\x18\' \x01(\x02H%\x88\x01\x01\x12&\n\x19lightning_strike_count_1h\x18( \x01(\rH&\x88\x01\x01\x12\"\n\x15lightning_distance_km\x18) \x01(\x02H\'\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperatureB\x12\n\x10_adc_voltage_ch0B\x12\n\x10_adc_voltage_ch1B\x12\n\x10_adc_voltage_ch2B\x12\n\x10_adc_voltage_ch3B\x12\n\x10_adc_voltage_ch4B\x12\n\x10_adc_voltage_ch5B\x12\n\x10_adc_voltage_ch6B\x12\n\x10_adc_voltage_ch7B\x1b\n\x19_one_wire_temperature_ch0B\x1b\n\x19_one_wire_temperature_ch1B\x1b\n\x19_one_wire_temperature_ch2B\x1b\n\x19_one_wire_temperature_ch3B\x1b\n\x19_one_wire_temperature_ch4B\x1b\n\x19_one_wire_temperature_ch5B\x1b\n\x19_one_wire_temperature_ch6B\x1b\n\x19_one_wire_temperature_ch7B\x1c\n\x1a_lightning_strike_count_1hB\x18\n\x16_lightning_distance_kmJ\x04\x08*\x10\x39R\x07soil_phR\x02phR\x17\x65lectrical_conductivityR\x08salinityR\x08nitrogenR\nphosphorusR\tpotassiumR\x10\x64issolved_oxygenR\x03orpR\x16\x63hemical_oxygen_demandR\tturbidityR\x07nitrateR\x08\x61mmoniumR\x19\x62iochemical_oxygen_demandR\x10solar_irradiance\"\x98\x05\n\x10SoilWaterMetrics\x12\x14\n\x07soil_ph\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x0f\n\x02ph\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12$\n\x17\x65lectrical_conductivity\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x15\n\x08salinity\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x15\n\x08nitrogen\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x17\n\nphosphorus\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x16\n\tpotassium\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x1d\n\x10\x64issolved_oxygen\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03orp\x18\t \x01(\x02H\x08\x88\x01\x01\x12#\n\x16\x63hemical_oxygen_demand\x18\n \x01(\x02H\t\x88\x01\x01\x12\x16\n\tturbidity\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x14\n\x07nitrate\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x15\n\x08\x61mmonium\x18\r \x01(\x02H\x0c\x88\x01\x01\x12&\n\x19\x62iochemical_oxygen_demand\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x1d\n\x10solar_irradiance\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x42\n\n\x08_soil_phB\x05\n\x03_phB\x1a\n\x18_electrical_conductivityB\x0b\n\t_salinityB\x0b\n\t_nitrogenB\r\n\x0b_phosphorusB\x0c\n\n_potassiumB\x13\n\x11_dissolved_oxygenB\x06\n\x04_orpB\x19\n\x17_chemical_oxygen_demandB\x0c\n\n_turbidityB\n\n\x08_nitrateB\x0b\n\t_ammoniumB\x1c\n\x1a_biochemical_oxygen_demandB\x13\n\x11_solar_irradiance\"\xd6\x05\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x1c\n\x0b\x63h4_voltage\x18\x07 \x01(\x02\x42\x02\x18\x01H\x06\x88\x01\x01\x12\x1c\n\x0b\x63h4_current\x18\x08 \x01(\x02\x42\x02\x18\x01H\x07\x88\x01\x01\x12\x1c\n\x0b\x63h5_voltage\x18\t \x01(\x02\x42\x02\x18\x01H\x08\x88\x01\x01\x12\x1c\n\x0b\x63h5_current\x18\n \x01(\x02\x42\x02\x18\x01H\t\x88\x01\x01\x12\x1c\n\x0b\x63h6_voltage\x18\x0b \x01(\x02\x42\x02\x18\x01H\n\x88\x01\x01\x12\x1c\n\x0b\x63h6_current\x18\x0c \x01(\x02\x42\x02\x18\x01H\x0b\x88\x01\x01\x12\x1c\n\x0b\x63h7_voltage\x18\r \x01(\x02\x42\x02\x18\x01H\x0c\x88\x01\x01\x12\x1c\n\x0b\x63h7_current\x18\x0e \x01(\x02\x42\x02\x18\x01H\r\x88\x01\x01\x12\x1c\n\x0b\x63h8_voltage\x18\x0f \x01(\x02\x42\x02\x18\x01H\x0e\x88\x01\x01\x12\x1c\n\x0b\x63h8_current\x18\x10 \x01(\x02\x42\x02\x18\x01H\x0f\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_currentB\x0e\n\x0c_ch4_voltageB\x0e\n\x0c_ch4_currentB\x0e\n\x0c_ch5_voltageB\x0e\n\x0c_ch5_currentB\x0e\n\x0c_ch6_voltageB\x0e\n\x0c_ch6_currentB\x0e\n\x0c_ch7_voltageB\x0e\n\x0c_ch7_currentB\x0e\n\x0c_ch8_voltageB\x0e\n\x0c_ch8_current\"\xe3\t\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x10\n\x03\x63o2\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x1c\n\x0f\x63o2_temperature\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x19\n\x0c\x63o2_humidity\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x1e\n\x11\x66orm_formaldehyde\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x1a\n\rform_humidity\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x1d\n\x10\x66orm_temperature\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x1a\n\rpm40_standard\x18\x13 \x01(\rH\x12\x88\x01\x01\x12\x1b\n\x0eparticles_40um\x18\x14 \x01(\rH\x13\x88\x01\x01\x12\x1b\n\x0epm_temperature\x18\x15 \x01(\x02H\x14\x88\x01\x01\x12\x18\n\x0bpm_humidity\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12\x17\n\npm_voc_idx\x18\x17 \x01(\x02H\x16\x88\x01\x01\x12\x17\n\npm_nox_idx\x18\x18 \x01(\x02H\x17\x88\x01\x01\x12\x1a\n\rparticles_tps\x18\x19 \x01(\x02H\x18\x88\x01\x01\x12\x1c\n\x0fpm_status_flags\x18\x1a \x01(\rH\x19\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100umB\x06\n\x04_co2B\x12\n\x10_co2_temperatureB\x0f\n\r_co2_humidityB\x14\n\x12_form_formaldehydeB\x10\n\x0e_form_humidityB\x13\n\x11_form_temperatureB\x10\n\x0e_pm40_standardB\x11\n\x0f_particles_40umB\x11\n\x0f_pm_temperatureB\x0e\n\x0c_pm_humidityB\r\n\x0b_pm_voc_idxB\r\n\x0b_pm_nox_idxB\x10\n\x0e_particles_tpsB\x12\n\x10_pm_status_flags\"\xff\x02\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\x12\x13\n\x0bnum_rx_dupe\x18\t \x01(\r\x12\x14\n\x0cnum_tx_relay\x18\n \x01(\r\x12\x1d\n\x15num_tx_relay_canceled\x18\x0b \x01(\r\x12\x18\n\x10heap_total_bytes\x18\x0c \x01(\r\x12\x17\n\x0fheap_free_bytes\x18\r \x01(\r\x12\x16\n\x0enum_tx_dropped\x18\x0e \x01(\r\x12\x13\n\x0bnoise_floor\x18\x0f \x01(\x05\"\xe4\x01\n\x16TrafficManagementStats\x12\x19\n\x11packets_inspected\x18\x01 \x01(\r\x12\x1c\n\x14position_dedup_drops\x18\x02 \x01(\r\x12\x1b\n\x13nodeinfo_cache_hits\x18\x03 \x01(\r\x12\x18\n\x10rate_limit_drops\x18\x04 \x01(\r\x12\x1c\n\x14unknown_packet_drops\x18\x05 \x01(\r\x12\x1d\n\x15hop_exhausted_packets\x18\x06 \x01(\r\x12\x1d\n\x15router_hops_preserved\x18\x07 \x01(\r\"{\n\rHealthMetrics\x12\x16\n\theart_bpm\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04spO2\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x18\n\x0btemperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0c\n\n_heart_bpmB\x07\n\x05_spO2B\x0e\n\x0c_temperature\"\x91\x02\n\x0bHostMetrics\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x15\n\rfreemem_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x64iskfree1_bytes\x18\x03 \x01(\x04\x12\x1c\n\x0f\x64iskfree2_bytes\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x64iskfree3_bytes\x18\x05 \x01(\x04H\x01\x88\x01\x01\x12\r\n\x05load1\x18\x06 \x01(\r\x12\r\n\x05load5\x18\x07 \x01(\r\x12\x0e\n\x06load15\x18\x08 \x01(\r\x12\x18\n\x0buser_string\x18\t \x01(\tH\x02\x88\x01\x01\x42\x12\n\x10_diskfree2_bytesB\x12\n\x10_diskfree3_bytesB\x0e\n\x0c_user_string\"\xa2\x04\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12\x33\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\x19.meshtastic.DeviceMetricsH\x00\x12=\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\x1e.meshtastic.EnvironmentMetricsH\x00\x12<\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32\x1d.meshtastic.AirQualityMetricsH\x00\x12\x31\n\rpower_metrics\x18\x05 \x01(\x0b\x32\x18.meshtastic.PowerMetricsH\x00\x12-\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x16.meshtastic.LocalStatsH\x00\x12\x33\n\x0ehealth_metrics\x18\x07 \x01(\x0b\x32\x19.meshtastic.HealthMetricsH\x00\x12/\n\x0chost_metrics\x18\x08 \x01(\x0b\x32\x17.meshtastic.HostMetricsH\x00\x12\x46\n\x18traffic_management_stats\x18\t \x01(\x0b\x32\".meshtastic.TrafficManagementStatsH\x00\x12:\n\x12soil_water_metrics\x18\x0b \x01(\x0b\x32\x1c.meshtastic.SoilWaterMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02\"%\n\x0c\x41S3935Config\x12\x15\n\rtuning_cap_pf\x18\x01 \x01(\r\"\xf0\x01\n\nSEN5XState\x12\x1a\n\x12last_cleaning_time\x18\x01 \x01(\r\x12\x1b\n\x13last_cleaning_valid\x18\x02 \x01(\x08\x12\x15\n\rone_shot_mode\x18\x03 \x01(\x08\x12\x1b\n\x0evoc_state_time\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x0fvoc_state_valid\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x1c\n\x0fvoc_state_array\x18\x06 \x01(\x06H\x02\x88\x01\x01\x42\x11\n\x0f_voc_state_timeB\x12\n\x10_voc_state_validB\x12\n\x10_voc_state_array\"\xf0\x01\n\nSEN6XState\x12\x1a\n\x12last_cleaning_time\x18\x01 \x01(\r\x12\x1b\n\x13last_cleaning_valid\x18\x02 \x01(\x08\x12\x15\n\rone_shot_mode\x18\x03 \x01(\x08\x12\x1b\n\x0evoc_state_time\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x0fvoc_state_valid\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x1c\n\x0fvoc_state_array\x18\x06 \x01(\x06H\x02\x88\x01\x01\x42\x11\n\x0f_voc_state_timeB\x12\n\x10_voc_state_validB\x12\n\x10_voc_state_array*\x9a\x06\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\r\n\x05SHTC3\x10\x07\x1a\x02\x08\x01\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\r\n\x05SHT31\x10\x0c\x1a\x02\x08\x01\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\r\n\x05SHT4X\x10\x11\x1a\x02\x08\x01\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x12\x11\n\rCUSTOM_SENSOR\x10\x1d\x12\x0c\n\x08MAX30102\x10\x1e\x12\x0c\n\x08MLX90614\x10\x1f\x12\t\n\x05SCD4X\x10 \x12\x0b\n\x07RADSENS\x10!\x12\n\n\x06INA226\x10\"\x12\x10\n\x0c\x44\x46ROBOT_RAIN\x10#\x12\n\n\x06\x44PS310\x10$\x12\x0c\n\x08RAK12035\x10%\x12\x0c\n\x08MAX17261\x10&\x12\x0b\n\x07PCT2075\x10\'\x12\x0b\n\x07\x41\x44S1X15\x10(\x12\x0f\n\x0b\x41\x44S1X15_ALT\x10)\x12\t\n\x05SFA30\x10*\x12\t\n\x05SEN5X\x10+\x12\x0b\n\x07TSL2561\x10,\x12\n\n\x06\x42H1750\x10-\x12\x0b\n\x07HDC1080\x10.\x12\r\n\x05SHT21\x10/\x1a\x02\x08\x01\x12\t\n\x05STC31\x10\x30\x12\t\n\x05SCD30\x10\x31\x12\t\n\x05SHTXX\x10\x32\x12\n\n\x06\x44S248X\x10\x33\x12\r\n\tMMC5983MA\x10\x34\x12\r\n\tICM42607P\x10\x35\x12\t\n\x05SPA06\x10\x36\x12\n\n\x06HM330X\x10\x37\x12\t\n\x05SEN6X\x10\x38\x12\n\n\x06\x41S3935\x10\x39\x42\x65\n\x14org.meshtastic.protoB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
8
+ descriptor_data = "\n\x1ameshtastic/telemetry.proto\x12\nmeshtastic\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xa9\x11\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12\x1a\n\rsoil_moisture\x18\x15 \x01(\rH\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12 \n\x14one_wire_temperature\x18\x17 \x03(\x02\x42\x02\x18\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch0\x18\x18 \x01(\x02H\x16\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch1\x18\x19 \x01(\x02H\x17\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch2\x18\x1a \x01(\x02H\x18\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch3\x18\x1b \x01(\x02H\x19\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch4\x18\x1c \x01(\x02H\x1a\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch5\x18\x1d \x01(\x02H\x1b\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch6\x18\x1e \x01(\x02H\x1c\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch7\x18\x1f \x01(\x02H\x1d\x88\x01\x01\x12%\n\x18one_wire_temperature_ch0\x18 \x01(\x02H\x1e\x88\x01\x01\x12%\n\x18one_wire_temperature_ch1\x18! \x01(\x02H\x1f\x88\x01\x01\x12%\n\x18one_wire_temperature_ch2\x18\" \x01(\x02H \x88\x01\x01\x12%\n\x18one_wire_temperature_ch3\x18# \x01(\x02H!\x88\x01\x01\x12%\n\x18one_wire_temperature_ch4\x18$ \x01(\x02H\"\x88\x01\x01\x12%\n\x18one_wire_temperature_ch5\x18% \x01(\x02H#\x88\x01\x01\x12%\n\x18one_wire_temperature_ch6\x18& \x01(\x02H$\x88\x01\x01\x12%\n\x18one_wire_temperature_ch7\x18\' \x01(\x02H%\x88\x01\x01\x12&\n\x19lightning_strike_count_1h\x18( \x01(\rH&\x88\x01\x01\x12\"\n\x15lightning_distance_km\x18) \x01(\x02H\'\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperatureB\x12\n\x10_adc_voltage_ch0B\x12\n\x10_adc_voltage_ch1B\x12\n\x10_adc_voltage_ch2B\x12\n\x10_adc_voltage_ch3B\x12\n\x10_adc_voltage_ch4B\x12\n\x10_adc_voltage_ch5B\x12\n\x10_adc_voltage_ch6B\x12\n\x10_adc_voltage_ch7B\x1b\n\x19_one_wire_temperature_ch0B\x1b\n\x19_one_wire_temperature_ch1B\x1b\n\x19_one_wire_temperature_ch2B\x1b\n\x19_one_wire_temperature_ch3B\x1b\n\x19_one_wire_temperature_ch4B\x1b\n\x19_one_wire_temperature_ch5B\x1b\n\x19_one_wire_temperature_ch6B\x1b\n\x19_one_wire_temperature_ch7B\x1c\n\x1a_lightning_strike_count_1hB\x18\n\x16_lightning_distance_kmJ\x04\x08*\x10\x39R\x07soil_phR\x02phR\x17\x65lectrical_conductivityR\x08salinityR\x08nitrogenR\nphosphorusR\tpotassiumR\x10\x64issolved_oxygenR\x03orpR\x16\x63hemical_oxygen_demandR\tturbidityR\x07nitrateR\x08\x61mmoniumR\x19\x62iochemical_oxygen_demandR\x10solar_irradiance\"\x98\x05\n\x10SoilWaterMetrics\x12\x14\n\x07soil_ph\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x0f\n\x02ph\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12$\n\x17\x65lectrical_conductivity\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x15\n\x08salinity\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x15\n\x08nitrogen\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x17\n\nphosphorus\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x16\n\tpotassium\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x1d\n\x10\x64issolved_oxygen\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03orp\x18\t \x01(\x02H\x08\x88\x01\x01\x12#\n\x16\x63hemical_oxygen_demand\x18\n \x01(\x02H\t\x88\x01\x01\x12\x16\n\tturbidity\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x14\n\x07nitrate\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x15\n\x08\x61mmonium\x18\r \x01(\x02H\x0c\x88\x01\x01\x12&\n\x19\x62iochemical_oxygen_demand\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x1d\n\x10solar_irradiance\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x42\n\n\x08_soil_phB\x05\n\x03_phB\x1a\n\x18_electrical_conductivityB\x0b\n\t_salinityB\x0b\n\t_nitrogenB\r\n\x0b_phosphorusB\x0c\n\n_potassiumB\x13\n\x11_dissolved_oxygenB\x06\n\x04_orpB\x19\n\x17_chemical_oxygen_demandB\x0c\n\n_turbidityB\n\n\x08_nitrateB\x0b\n\t_ammoniumB\x1c\n\x1a_biochemical_oxygen_demandB\x13\n\x11_solar_irradiance\"\xd6\x05\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x1c\n\x0b\x63h4_voltage\x18\x07 \x01(\x02\x42\x02\x18\x01H\x06\x88\x01\x01\x12\x1c\n\x0b\x63h4_current\x18\x08 \x01(\x02\x42\x02\x18\x01H\x07\x88\x01\x01\x12\x1c\n\x0b\x63h5_voltage\x18\t \x01(\x02\x42\x02\x18\x01H\x08\x88\x01\x01\x12\x1c\n\x0b\x63h5_current\x18\n \x01(\x02\x42\x02\x18\x01H\t\x88\x01\x01\x12\x1c\n\x0b\x63h6_voltage\x18\x0b \x01(\x02\x42\x02\x18\x01H\n\x88\x01\x01\x12\x1c\n\x0b\x63h6_current\x18\x0c \x01(\x02\x42\x02\x18\x01H\x0b\x88\x01\x01\x12\x1c\n\x0b\x63h7_voltage\x18\r \x01(\x02\x42\x02\x18\x01H\x0c\x88\x01\x01\x12\x1c\n\x0b\x63h7_current\x18\x0e \x01(\x02\x42\x02\x18\x01H\r\x88\x01\x01\x12\x1c\n\x0b\x63h8_voltage\x18\x0f \x01(\x02\x42\x02\x18\x01H\x0e\x88\x01\x01\x12\x1c\n\x0b\x63h8_current\x18\x10 \x01(\x02\x42\x02\x18\x01H\x0f\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_currentB\x0e\n\x0c_ch4_voltageB\x0e\n\x0c_ch4_currentB\x0e\n\x0c_ch5_voltageB\x0e\n\x0c_ch5_currentB\x0e\n\x0c_ch6_voltageB\x0e\n\x0c_ch6_currentB\x0e\n\x0c_ch7_voltageB\x0e\n\x0c_ch7_currentB\x0e\n\x0c_ch8_voltageB\x0e\n\x0c_ch8_current\"\xe3\t\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x10\n\x03\x63o2\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x1c\n\x0f\x63o2_temperature\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x19\n\x0c\x63o2_humidity\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x1e\n\x11\x66orm_formaldehyde\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x1a\n\rform_humidity\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x1d\n\x10\x66orm_temperature\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x1a\n\rpm40_standard\x18\x13 \x01(\rH\x12\x88\x01\x01\x12\x1b\n\x0eparticles_40um\x18\x14 \x01(\rH\x13\x88\x01\x01\x12\x1b\n\x0epm_temperature\x18\x15 \x01(\x02H\x14\x88\x01\x01\x12\x18\n\x0bpm_humidity\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12\x17\n\npm_voc_idx\x18\x17 \x01(\x02H\x16\x88\x01\x01\x12\x17\n\npm_nox_idx\x18\x18 \x01(\x02H\x17\x88\x01\x01\x12\x1a\n\rparticles_tps\x18\x19 \x01(\x02H\x18\x88\x01\x01\x12\x1c\n\x0fpm_status_flags\x18\x1a \x01(\rH\x19\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100umB\x06\n\x04_co2B\x12\n\x10_co2_temperatureB\x0f\n\r_co2_humidityB\x14\n\x12_form_formaldehydeB\x10\n\x0e_form_humidityB\x13\n\x11_form_temperatureB\x10\n\x0e_pm40_standardB\x11\n\x0f_particles_40umB\x11\n\x0f_pm_temperatureB\x0e\n\x0c_pm_humidityB\r\n\x0b_pm_voc_idxB\r\n\x0b_pm_nox_idxB\x10\n\x0e_particles_tpsB\x12\n\x10_pm_status_flags\"\xff\x02\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\x12\x13\n\x0bnum_rx_dupe\x18\t \x01(\r\x12\x14\n\x0cnum_tx_relay\x18\n \x01(\r\x12\x1d\n\x15num_tx_relay_canceled\x18\x0b \x01(\r\x12\x18\n\x10heap_total_bytes\x18\x0c \x01(\r\x12\x17\n\x0fheap_free_bytes\x18\r \x01(\r\x12\x16\n\x0enum_tx_dropped\x18\x0e \x01(\r\x12\x13\n\x0bnoise_floor\x18\x0f \x01(\x05\"\xe4\x01\n\x16TrafficManagementStats\x12\x19\n\x11packets_inspected\x18\x01 \x01(\r\x12\x1c\n\x14position_dedup_drops\x18\x02 \x01(\r\x12\x1b\n\x13nodeinfo_cache_hits\x18\x03 \x01(\r\x12\x18\n\x10rate_limit_drops\x18\x04 \x01(\r\x12\x1c\n\x14unknown_packet_drops\x18\x05 \x01(\r\x12\x1d\n\x15hop_exhausted_packets\x18\x06 \x01(\r\x12\x1d\n\x15router_hops_preserved\x18\x07 \x01(\r\"{\n\rHealthMetrics\x12\x16\n\theart_bpm\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04spO2\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x18\n\x0btemperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0c\n\n_heart_bpmB\x07\n\x05_spO2B\x0e\n\x0c_temperature\"\x91\x02\n\x0bHostMetrics\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x15\n\rfreemem_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x64iskfree1_bytes\x18\x03 \x01(\x04\x12\x1c\n\x0f\x64iskfree2_bytes\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x64iskfree3_bytes\x18\x05 \x01(\x04H\x01\x88\x01\x01\x12\r\n\x05load1\x18\x06 \x01(\r\x12\r\n\x05load5\x18\x07 \x01(\r\x12\x0e\n\x06load15\x18\x08 \x01(\r\x12\x18\n\x0buser_string\x18\t \x01(\tH\x02\x88\x01\x01\x42\x12\n\x10_diskfree2_bytesB\x12\n\x10_diskfree3_bytesB\x0e\n\x0c_user_string\"\xa2\x04\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12\x33\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\x19.meshtastic.DeviceMetricsH\x00\x12=\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\x1e.meshtastic.EnvironmentMetricsH\x00\x12<\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32\x1d.meshtastic.AirQualityMetricsH\x00\x12\x31\n\rpower_metrics\x18\x05 \x01(\x0b\x32\x18.meshtastic.PowerMetricsH\x00\x12-\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x16.meshtastic.LocalStatsH\x00\x12\x33\n\x0ehealth_metrics\x18\x07 \x01(\x0b\x32\x19.meshtastic.HealthMetricsH\x00\x12/\n\x0chost_metrics\x18\x08 \x01(\x0b\x32\x17.meshtastic.HostMetricsH\x00\x12\x46\n\x18traffic_management_stats\x18\t \x01(\x0b\x32\".meshtastic.TrafficManagementStatsH\x00\x12:\n\x12soil_water_metrics\x18\x0b \x01(\x0b\x32\x1c.meshtastic.SoilWaterMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02\"$\n\x0b\x41S3935State\x12\x15\n\rtuning_cap_pf\x18\x01 \x01(\r\"\xf0\x01\n\nSEN5XState\x12\x1a\n\x12last_cleaning_time\x18\x01 \x01(\r\x12\x1b\n\x13last_cleaning_valid\x18\x02 \x01(\x08\x12\x15\n\rone_shot_mode\x18\x03 \x01(\x08\x12\x1b\n\x0evoc_state_time\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x0fvoc_state_valid\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x1c\n\x0fvoc_state_array\x18\x06 \x01(\x06H\x02\x88\x01\x01\x42\x11\n\x0f_voc_state_timeB\x12\n\x10_voc_state_validB\x12\n\x10_voc_state_array\"\xf0\x01\n\nSEN6XState\x12\x1a\n\x12last_cleaning_time\x18\x01 \x01(\r\x12\x1b\n\x13last_cleaning_valid\x18\x02 \x01(\x08\x12\x15\n\rone_shot_mode\x18\x03 \x01(\x08\x12\x1b\n\x0evoc_state_time\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x0fvoc_state_valid\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x1c\n\x0fvoc_state_array\x18\x06 \x01(\x06H\x02\x88\x01\x01\x42\x11\n\x0f_voc_state_timeB\x12\n\x10_voc_state_validB\x12\n\x10_voc_state_array*\x9a\x06\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\r\n\x05SHTC3\x10\x07\x1a\x02\x08\x01\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\r\n\x05SHT31\x10\x0c\x1a\x02\x08\x01\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\r\n\x05SHT4X\x10\x11\x1a\x02\x08\x01\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x12\x11\n\rCUSTOM_SENSOR\x10\x1d\x12\x0c\n\x08MAX30102\x10\x1e\x12\x0c\n\x08MLX90614\x10\x1f\x12\t\n\x05SCD4X\x10 \x12\x0b\n\x07RADSENS\x10!\x12\n\n\x06INA226\x10\"\x12\x10\n\x0c\x44\x46ROBOT_RAIN\x10#\x12\n\n\x06\x44PS310\x10$\x12\x0c\n\x08RAK12035\x10%\x12\x0c\n\x08MAX17261\x10&\x12\x0b\n\x07PCT2075\x10\'\x12\x0b\n\x07\x41\x44S1X15\x10(\x12\x0f\n\x0b\x41\x44S1X15_ALT\x10)\x12\t\n\x05SFA30\x10*\x12\t\n\x05SEN5X\x10+\x12\x0b\n\x07TSL2561\x10,\x12\n\n\x06\x42H1750\x10-\x12\x0b\n\x07HDC1080\x10.\x12\r\n\x05SHT21\x10/\x1a\x02\x08\x01\x12\t\n\x05STC31\x10\x30\x12\t\n\x05SCD30\x10\x31\x12\t\n\x05SHTXX\x10\x32\x12\n\n\x06\x44S248X\x10\x33\x12\r\n\tMMC5983MA\x10\x34\x12\r\n\tICM42607P\x10\x35\x12\t\n\x05SPA06\x10\x36\x12\n\n\x06HM330X\x10\x37\x12\t\n\x05SEN6X\x10\x38\x12\n\n\x06\x41S3935\x10\x39\x42\x65\n\x14org.meshtastic.protoB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3"
9
9
 
10
10
  pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
11
  pool.add_serialized_file(descriptor_data)
@@ -22,7 +22,7 @@ module Meshtastic
22
22
  HostMetrics = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.HostMetrics").msgclass
23
23
  Telemetry = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Telemetry").msgclass
24
24
  Nau7802Config = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.Nau7802Config").msgclass
25
- AS3935Config = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.AS3935Config").msgclass
25
+ AS3935State = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.AS3935State").msgclass
26
26
  SEN5XState = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.SEN5XState").msgclass
27
27
  SEN6XState = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.SEN6XState").msgclass
28
28
  TelemetrySensorType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("meshtastic.TelemetrySensorType").enummodule