diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index b40b557b..c70dcb98 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -447,6 +447,7 @@ DDD5BB0A2C285E45007E03CA /* LogDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDetail.swift; sourceTree = ""; }; DDD5BB0C2C285F00007E03CA /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; DDD5BB0F2C285FB3007E03CA /* AppLogFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLogFilter.swift; sourceTree = ""; }; + DDD5BB142C28680D007E03CA /* MeshtasticDataModelV 38.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 38.xcdatamodel"; sourceTree = ""; }; DDD6EEAE29BC024700383354 /* Firmware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Firmware.swift; sourceTree = ""; }; DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeText.swift; sourceTree = ""; }; DDD9E4E3284B208E003777C5 /* UserEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserEntityExtension.swift; sourceTree = ""; }; @@ -1853,6 +1854,7 @@ DD3CC6BA28E366DF00FA9159 /* Meshtastic.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + DDD5BB142C28680D007E03CA /* MeshtasticDataModelV 38.xcdatamodel */, DDD28D372C0CD2670063CFA3 /* MeshtasticDataModelV 37.xcdatamodel */, DD31B04D2BDC6FD30024FA63 /* MeshtasticDataModelV 36.xcdatamodel */, DD268D8C2BCC7D11008073AE /* MeshtasticDataModelV 35.xcdatamodel */, @@ -1891,7 +1893,7 @@ DD5D0A9A2931AD6B00F7EA61 /* MeshtasticDataModelV2.xcdatamodel */, DD3CC6BB28E366DF00FA9159 /* MeshtasticDataModel.xcdatamodel */, ); - currentVersion = DDD28D372C0CD2670063CFA3 /* MeshtasticDataModelV 37.xcdatamodel */; + currentVersion = DDD5BB142C28680D007E03CA /* MeshtasticDataModelV 38.xcdatamodel */; name = Meshtastic.xcdatamodeld; path = Meshtastic/Meshtastic.xcdatamodeld; sourceTree = ""; diff --git a/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 0a15919c..a62998be 100644 --- a/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Meshtastic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "32ea1ad7873163554215310b8eea710c94c63f855b5b01c0b790e7b537747ceb", + "originHash" : "e9855e3a299c14a10f11ee0b8f29e4170b09548533939361223a0f50e7caac8c", "pins" : [ { "identity" : "cocoamqtt", @@ -10,24 +10,6 @@ "version" : "2.1.5" } }, - { - "identity" : "collectionconcurrencykit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git", - "state" : { - "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95", - "version" : "0.2.0" - } - }, - { - "identity" : "cryptoswift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", - "state" : { - "revision" : "c9c3df6ab812de32bae61fc0cd1bf6d45170ebf0", - "version" : "1.8.2" - } - }, { "identity" : "mqttcocoaasyncsocket", "kind" : "remoteSourceControl", @@ -37,15 +19,6 @@ "version" : "1.0.8" } }, - { - "identity" : "sourcekitten", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/SourceKitten.git", - "state" : { - "revision" : "fd4df99170f5e9d7cf9aa8312aa8506e0e7a44e7", - "version" : "0.35.0" - } - }, { "identity" : "sqlite.swift", "kind" : "remoteSourceControl", @@ -64,15 +37,6 @@ "version" : "3.1.2" } }, - { - "identity" : "swift-argument-parser", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-argument-parser.git", - "state" : { - "revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b", - "version" : "1.4.0" - } - }, { "identity" : "swift-protobuf", "kind" : "remoteSourceControl", @@ -81,51 +45,6 @@ "revision" : "ce20dc083ee485524b802669890291c0d8090170", "version" : "1.22.1" } - }, - { - "identity" : "swift-syntax", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", - "state" : { - "revision" : "303e5c5c36d6a558407d364878df131c3546fad8", - "version" : "510.0.2" - } - }, - { - "identity" : "swiftlint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/realm/SwiftLint", - "state" : { - "revision" : "b515723b16eba33f15c4677ee65f3fef2ce8c255", - "version" : "0.55.1" - } - }, - { - "identity" : "swiftytexttable", - "kind" : "remoteSourceControl", - "location" : "https://github.com/scottrhoyt/SwiftyTextTable.git", - "state" : { - "revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3", - "version" : "0.9.0" - } - }, - { - "identity" : "swxmlhash", - "kind" : "remoteSourceControl", - "location" : "https://github.com/drmohundro/SWXMLHash.git", - "state" : { - "revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f", - "version" : "7.0.2" - } - }, - { - "identity" : "yams", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/Yams.git", - "state" : { - "revision" : "9234124cff5e22e178988c18d8b95a8ae8007f76", - "version" : "5.1.2" - } } ], "version" : 3 diff --git a/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion b/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion index 63ed7101..60188826 100644 --- a/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion +++ b/Meshtastic/Meshtastic.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - MeshtasticDataModelV 37.xcdatamodel + MeshtasticDataModelV 38.xcdatamodel diff --git a/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 38.xcdatamodel/contents b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 38.xcdatamodel/contents new file mode 100644 index 00000000..10948c6b --- /dev/null +++ b/Meshtastic/Meshtastic.xcdatamodeld/MeshtasticDataModelV 38.xcdatamodel/contents @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Meshtastic/Protobufs/meshtastic/admin.pb.swift b/Meshtastic/Protobufs/meshtastic/admin.pb.swift index 230f5304..c3f1c12f 100644 --- a/Meshtastic/Protobufs/meshtastic/admin.pb.swift +++ b/Meshtastic/Protobufs/meshtastic/admin.pb.swift @@ -245,6 +245,16 @@ struct AdminMessage { set {payloadVariant = .deleteFileRequest(newValue)} } + /// + /// Set zero and offset for scale chips + var setScale: UInt32 { + get { + if case .setScale(let v)? = payloadVariant {return v} + return 0 + } + set {payloadVariant = .setScale(newValue)} + } + /// /// Set the owner for this node var setOwner: User { @@ -513,6 +523,9 @@ struct AdminMessage { /// Delete the file by the specified path from the device case deleteFileRequest(String) /// + /// Set zero and offset for scale chips + case setScale(UInt32) + /// /// Set the owner for this node case setOwner(User) /// @@ -667,6 +680,10 @@ struct AdminMessage { guard case .deleteFileRequest(let l) = lhs, case .deleteFileRequest(let r) = rhs else { preconditionFailure() } return l == r }() + case (.setScale, .setScale): return { + guard case .setScale(let l) = lhs, case .setScale(let r) = rhs else { preconditionFailure() } + return l == r + }() case (.setOwner, .setOwner): return { guard case .setOwner(let l) = lhs, case .setOwner(let r) = rhs else { preconditionFailure() } return l == r @@ -1039,6 +1056,7 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat 20: .standard(proto: "get_node_remote_hardware_pins_response"), 21: .standard(proto: "enter_dfu_mode_request"), 22: .standard(proto: "delete_file_request"), + 23: .standard(proto: "set_scale"), 32: .standard(proto: "set_owner"), 33: .standard(proto: "set_channel"), 34: .standard(proto: "set_config"), @@ -1274,6 +1292,14 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat self.payloadVariant = .deleteFileRequest(v) } }() + case 23: try { + var v: UInt32? + try decoder.decodeSingularUInt32Field(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .setScale(v) + } + }() case 32: try { var v: User? var hadOneofValue = false @@ -1546,6 +1572,10 @@ extension AdminMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat guard case .deleteFileRequest(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularStringField(value: v, fieldNumber: 22) }() + case .setScale?: try { + guard case .setScale(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 23) + }() case .setOwner?: try { guard case .setOwner(let v)? = self.payloadVariant else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 32) diff --git a/Meshtastic/Protobufs/meshtastic/config.pb.swift b/Meshtastic/Protobufs/meshtastic/config.pb.swift index 90ea2f40..11453fa7 100644 --- a/Meshtastic/Protobufs/meshtastic/config.pb.swift +++ b/Meshtastic/Protobufs/meshtastic/config.pb.swift @@ -630,6 +630,11 @@ struct Config { /// I2C address of INA_2XX to use for reading device battery voltage var deviceBatteryInaAddress: UInt32 = 0 + /// + /// If non-zero, we want powermon log outputs. With the particular (bitfield) sources enabled. + /// Note: we picked an ID of 32 so that lower more efficient IDs can be used for more frequently used options. + var powermonEnables: UInt64 = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -799,6 +804,10 @@ struct Config { /// Should we wake the screen up on accelerometer detected motion or tap var wakeOnTapOrMotion: Bool = false + /// + /// Indicates how to rotate or invert the compass output to accurate display on the display. + var compassOrientation: Config.DisplayConfig.CompassOrientation = .degrees0 + var unknownFields = SwiftProtobuf.UnknownStorage() /// @@ -998,6 +1007,76 @@ struct Config { } + enum CompassOrientation: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// + /// The compass and the display are in the same orientation. + case degrees0 // = 0 + + /// + /// Rotate the compass by 90 degrees. + case degrees90 // = 1 + + /// + /// Rotate the compass by 180 degrees. + case degrees180 // = 2 + + /// + /// Rotate the compass by 270 degrees. + case degrees270 // = 3 + + /// + /// Don't rotate the compass, but invert the result. + case degrees0Inverted // = 4 + + /// + /// Rotate the compass by 90 degrees and invert. + case degrees90Inverted // = 5 + + /// + /// Rotate the compass by 180 degrees and invert. + case degrees180Inverted // = 6 + + /// + /// Rotate the compass by 270 degrees and invert. + case degrees270Inverted // = 7 + case UNRECOGNIZED(Int) + + init() { + self = .degrees0 + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .degrees0 + case 1: self = .degrees90 + case 2: self = .degrees180 + case 3: self = .degrees270 + case 4: self = .degrees0Inverted + case 5: self = .degrees90Inverted + case 6: self = .degrees180Inverted + case 7: self = .degrees270Inverted + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .degrees0: return 0 + case .degrees90: return 1 + case .degrees180: return 2 + case .degrees270: return 3 + case .degrees0Inverted: return 4 + case .degrees90Inverted: return 5 + case .degrees180Inverted: return 6 + case .degrees270Inverted: return 7 + case .UNRECOGNIZED(let i): return i + } + } + + } + init() {} } @@ -1334,6 +1413,10 @@ struct Config { /// Specified PIN for PairingMode.FixedPin var fixedPin: UInt32 = 0 + /// + /// Enables device (serial style logs) over Bluetooth + var deviceLoggingEnabled: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() enum PairingMode: SwiftProtobuf.Enum { @@ -1485,6 +1568,20 @@ extension Config.DisplayConfig.DisplayMode: CaseIterable { ] } +extension Config.DisplayConfig.CompassOrientation: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static let allCases: [Config.DisplayConfig.CompassOrientation] = [ + .degrees0, + .degrees90, + .degrees180, + .degrees270, + .degrees0Inverted, + .degrees90Inverted, + .degrees180Inverted, + .degrees270Inverted, + ] +} + extension Config.LoRaConfig.RegionCode: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. static let allCases: [Config.LoRaConfig.RegionCode] = [ @@ -1553,6 +1650,7 @@ extension Config.DisplayConfig.GpsCoordinateFormat: @unchecked Sendable {} extension Config.DisplayConfig.DisplayUnits: @unchecked Sendable {} extension Config.DisplayConfig.OledType: @unchecked Sendable {} extension Config.DisplayConfig.DisplayMode: @unchecked Sendable {} +extension Config.DisplayConfig.CompassOrientation: @unchecked Sendable {} extension Config.LoRaConfig: @unchecked Sendable {} extension Config.LoRaConfig.RegionCode: @unchecked Sendable {} extension Config.LoRaConfig.ModemPreset: @unchecked Sendable {} @@ -1986,6 +2084,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple 7: .standard(proto: "ls_secs"), 8: .standard(proto: "min_wake_secs"), 9: .standard(proto: "device_battery_ina_address"), + 32: .standard(proto: "powermon_enables"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2002,6 +2101,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple case 7: try { try decoder.decodeSingularUInt32Field(value: &self.lsSecs) }() case 8: try { try decoder.decodeSingularUInt32Field(value: &self.minWakeSecs) }() case 9: try { try decoder.decodeSingularUInt32Field(value: &self.deviceBatteryInaAddress) }() + case 32: try { try decoder.decodeSingularUInt64Field(value: &self.powermonEnables) }() default: break } } @@ -2032,6 +2132,9 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.deviceBatteryInaAddress != 0 { try visitor.visitSingularUInt32Field(value: self.deviceBatteryInaAddress, fieldNumber: 9) } + if self.powermonEnables != 0 { + try visitor.visitSingularUInt64Field(value: self.powermonEnables, fieldNumber: 32) + } try unknownFields.traverse(visitor: &visitor) } @@ -2044,6 +2147,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if lhs.lsSecs != rhs.lsSecs {return false} if lhs.minWakeSecs != rhs.minWakeSecs {return false} if lhs.deviceBatteryInaAddress != rhs.deviceBatteryInaAddress {return false} + if lhs.powermonEnables != rhs.powermonEnables {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2197,6 +2301,7 @@ extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp 8: .same(proto: "displaymode"), 9: .standard(proto: "heading_bold"), 10: .standard(proto: "wake_on_tap_or_motion"), + 11: .standard(proto: "compass_orientation"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2215,6 +2320,7 @@ extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp case 8: try { try decoder.decodeSingularEnumField(value: &self.displaymode) }() case 9: try { try decoder.decodeSingularBoolField(value: &self.headingBold) }() case 10: try { try decoder.decodeSingularBoolField(value: &self.wakeOnTapOrMotion) }() + case 11: try { try decoder.decodeSingularEnumField(value: &self.compassOrientation) }() default: break } } @@ -2251,6 +2357,9 @@ extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp if self.wakeOnTapOrMotion != false { try visitor.visitSingularBoolField(value: self.wakeOnTapOrMotion, fieldNumber: 10) } + if self.compassOrientation != .degrees0 { + try visitor.visitSingularEnumField(value: self.compassOrientation, fieldNumber: 11) + } try unknownFields.traverse(visitor: &visitor) } @@ -2265,6 +2374,7 @@ extension Config.DisplayConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImp if lhs.displaymode != rhs.displaymode {return false} if lhs.headingBold != rhs.headingBold {return false} if lhs.wakeOnTapOrMotion != rhs.wakeOnTapOrMotion {return false} + if lhs.compassOrientation != rhs.compassOrientation {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2306,6 +2416,19 @@ extension Config.DisplayConfig.DisplayMode: SwiftProtobuf._ProtoNameProviding { ] } +extension Config.DisplayConfig.CompassOrientation: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "DEGREES_0"), + 1: .same(proto: "DEGREES_90"), + 2: .same(proto: "DEGREES_180"), + 3: .same(proto: "DEGREES_270"), + 4: .same(proto: "DEGREES_0_INVERTED"), + 5: .same(proto: "DEGREES_90_INVERTED"), + 6: .same(proto: "DEGREES_180_INVERTED"), + 7: .same(proto: "DEGREES_270_INVERTED"), + ] +} + extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Config.protoMessageName + ".LoRaConfig" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ @@ -2471,6 +2594,7 @@ extension Config.BluetoothConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageI 1: .same(proto: "enabled"), 2: .same(proto: "mode"), 3: .standard(proto: "fixed_pin"), + 4: .standard(proto: "device_logging_enabled"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2482,6 +2606,7 @@ extension Config.BluetoothConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageI case 1: try { try decoder.decodeSingularBoolField(value: &self.enabled) }() case 2: try { try decoder.decodeSingularEnumField(value: &self.mode) }() case 3: try { try decoder.decodeSingularUInt32Field(value: &self.fixedPin) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.deviceLoggingEnabled) }() default: break } } @@ -2497,6 +2622,9 @@ extension Config.BluetoothConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageI if self.fixedPin != 0 { try visitor.visitSingularUInt32Field(value: self.fixedPin, fieldNumber: 3) } + if self.deviceLoggingEnabled != false { + try visitor.visitSingularBoolField(value: self.deviceLoggingEnabled, fieldNumber: 4) + } try unknownFields.traverse(visitor: &visitor) } @@ -2504,6 +2632,7 @@ extension Config.BluetoothConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageI if lhs.enabled != rhs.enabled {return false} if lhs.mode != rhs.mode {return false} if lhs.fixedPin != rhs.fixedPin {return false} + if lhs.deviceLoggingEnabled != rhs.deviceLoggingEnabled {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } diff --git a/Meshtastic/Protobufs/meshtastic/mesh.pb.swift b/Meshtastic/Protobufs/meshtastic/mesh.pb.swift index 7d33c743..a8ee777c 100644 --- a/Meshtastic/Protobufs/meshtastic/mesh.pb.swift +++ b/Meshtastic/Protobufs/meshtastic/mesh.pb.swift @@ -114,6 +114,18 @@ enum HardwareModel: SwiftProtobuf.Enum { /// wiphone https://www.wiphone.io/ case wiphone // = 20 + /// + /// WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk + case wioWm1110 // = 21 + + /// + /// RAK2560 Solar base station based on RAK4630 + case rak2560 // = 22 + + /// + /// Heltec HRU-3601: https://heltec.org/project/hru-3601/ + case heltecHru3601 // = 23 + /// /// B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station case stationG1 // = 25 @@ -288,6 +300,10 @@ enum HardwareModel: SwiftProtobuf.Enum { /// ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS case radiomaster900BanditNano // = 64 + /// + /// Heltec Capsule Sensor V3 with ESP32-S3 CPU, Portable LoRa device that can replace GNSS modules or sensors + case heltecCapsuleSensorV3 // = 65 + /// /// ------------------------------------------------------------------------------------------------------------------------------------------ /// Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. @@ -322,6 +338,9 @@ enum HardwareModel: SwiftProtobuf.Enum { case 18: self = .nanoG2Ultra case 19: self = .loraType case 20: self = .wiphone + case 21: self = .wioWm1110 + case 22: self = .rak2560 + case 23: self = .heltecHru3601 case 25: self = .stationG1 case 26: self = .rak11310 case 27: self = .senseloraRp2040 @@ -362,6 +381,7 @@ enum HardwareModel: SwiftProtobuf.Enum { case 62: self = .twcMeshV4 case 63: self = .nrf52PromicroDiy case 64: self = .radiomaster900BanditNano + case 65: self = .heltecCapsuleSensorV3 case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } @@ -390,6 +410,9 @@ enum HardwareModel: SwiftProtobuf.Enum { case .nanoG2Ultra: return 18 case .loraType: return 19 case .wiphone: return 20 + case .wioWm1110: return 21 + case .rak2560: return 22 + case .heltecHru3601: return 23 case .stationG1: return 25 case .rak11310: return 26 case .senseloraRp2040: return 27 @@ -430,6 +453,7 @@ enum HardwareModel: SwiftProtobuf.Enum { case .twcMeshV4: return 62 case .nrf52PromicroDiy: return 63 case .radiomaster900BanditNano: return 64 + case .heltecCapsuleSensorV3: return 65 case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } @@ -463,6 +487,9 @@ extension HardwareModel: CaseIterable { .nanoG2Ultra, .loraType, .wiphone, + .wioWm1110, + .rak2560, + .heltecHru3601, .stationG1, .rak11310, .senseloraRp2040, @@ -503,6 +530,7 @@ extension HardwareModel: CaseIterable { .twcMeshV4, .nrf52PromicroDiy, .radiomaster900BanditNano, + .heltecCapsuleSensorV3, .privateHw, ] } @@ -2701,6 +2729,129 @@ struct NodeRemoteHardwarePin { fileprivate var _pin: RemoteHardwarePin? = nil } +struct ChunkedPayload { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// + /// The ID of the entire payload + var payloadID: UInt32 = 0 + + /// + /// The total number of chunks in the payload + var chunkCount: UInt32 = 0 + + /// + /// The current chunk index in the total + var chunkIndex: UInt32 = 0 + + /// + /// The binary data of the current chunk + var payloadChunk: Data = Data() + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// +/// Wrapper message for broken repeated oneof support +struct resend_chunks { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var chunks: [UInt32] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// +/// Responses to a ChunkedPayload request +struct ChunkedPayloadResponse { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// + /// The ID of the entire payload + var payloadID: UInt32 = 0 + + var payloadVariant: ChunkedPayloadResponse.OneOf_PayloadVariant? = nil + + /// + /// Request to transfer chunked payload + var requestTransfer: Bool { + get { + if case .requestTransfer(let v)? = payloadVariant {return v} + return false + } + set {payloadVariant = .requestTransfer(newValue)} + } + + /// + /// Accept the transfer chunked payload + var acceptTransfer: Bool { + get { + if case .acceptTransfer(let v)? = payloadVariant {return v} + return false + } + set {payloadVariant = .acceptTransfer(newValue)} + } + + /// + /// Request missing indexes in the chunked payload + var resendChunks: resend_chunks { + get { + if case .resendChunks(let v)? = payloadVariant {return v} + return resend_chunks() + } + set {payloadVariant = .resendChunks(newValue)} + } + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum OneOf_PayloadVariant: Equatable { + /// + /// Request to transfer chunked payload + case requestTransfer(Bool) + /// + /// Accept the transfer chunked payload + case acceptTransfer(Bool) + /// + /// Request missing indexes in the chunked payload + case resendChunks(resend_chunks) + + #if !swift(>=4.1) + static func ==(lhs: ChunkedPayloadResponse.OneOf_PayloadVariant, rhs: ChunkedPayloadResponse.OneOf_PayloadVariant) -> Bool { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch (lhs, rhs) { + case (.requestTransfer, .requestTransfer): return { + guard case .requestTransfer(let l) = lhs, case .requestTransfer(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.acceptTransfer, .acceptTransfer): return { + guard case .acceptTransfer(let l) = lhs, case .acceptTransfer(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.resendChunks, .resendChunks): return { + guard case .resendChunks(let l) = lhs, case .resendChunks(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif + } + + init() {} +} + #if swift(>=5.5) && canImport(_Concurrency) extension HardwareModel: @unchecked Sendable {} extension Constants: @unchecked Sendable {} @@ -2736,6 +2887,10 @@ extension Neighbor: @unchecked Sendable {} extension DeviceMetadata: @unchecked Sendable {} extension Heartbeat: @unchecked Sendable {} extension NodeRemoteHardwarePin: @unchecked Sendable {} +extension ChunkedPayload: @unchecked Sendable {} +extension resend_chunks: @unchecked Sendable {} +extension ChunkedPayloadResponse: @unchecked Sendable {} +extension ChunkedPayloadResponse.OneOf_PayloadVariant: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -2765,6 +2920,9 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 18: .same(proto: "NANO_G2_ULTRA"), 19: .same(proto: "LORA_TYPE"), 20: .same(proto: "WIPHONE"), + 21: .same(proto: "WIO_WM1110"), + 22: .same(proto: "RAK2560"), + 23: .same(proto: "HELTEC_HRU_3601"), 25: .same(proto: "STATION_G1"), 26: .same(proto: "RAK11310"), 27: .same(proto: "SENSELORA_RP2040"), @@ -2805,6 +2963,7 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 62: .same(proto: "TWC_MESH_V4"), 63: .same(proto: "NRF52_PROMICRO_DIY"), 64: .same(proto: "RADIOMASTER_900_BANDIT_NANO"), + 65: .same(proto: "HELTEC_CAPSULE_SENSOR_V3"), 255: .same(proto: "PRIVATE_HW"), ] } @@ -4775,3 +4934,169 @@ extension NodeRemoteHardwarePin: SwiftProtobuf.Message, SwiftProtobuf._MessageIm return true } } + +extension ChunkedPayload: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".ChunkedPayload" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "payload_id"), + 2: .standard(proto: "chunk_count"), + 3: .standard(proto: "chunk_index"), + 4: .standard(proto: "payload_chunk"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.payloadID) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.chunkCount) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.chunkIndex) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.payloadChunk) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.payloadID != 0 { + try visitor.visitSingularUInt32Field(value: self.payloadID, fieldNumber: 1) + } + if self.chunkCount != 0 { + try visitor.visitSingularUInt32Field(value: self.chunkCount, fieldNumber: 2) + } + if self.chunkIndex != 0 { + try visitor.visitSingularUInt32Field(value: self.chunkIndex, fieldNumber: 3) + } + if !self.payloadChunk.isEmpty { + try visitor.visitSingularBytesField(value: self.payloadChunk, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ChunkedPayload, rhs: ChunkedPayload) -> Bool { + if lhs.payloadID != rhs.payloadID {return false} + if lhs.chunkCount != rhs.chunkCount {return false} + if lhs.chunkIndex != rhs.chunkIndex {return false} + if lhs.payloadChunk != rhs.payloadChunk {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension resend_chunks: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".resend_chunks" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "chunks"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedUInt32Field(value: &self.chunks) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.chunks.isEmpty { + try visitor.visitPackedUInt32Field(value: self.chunks, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: resend_chunks, rhs: resend_chunks) -> Bool { + if lhs.chunks != rhs.chunks {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension ChunkedPayloadResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".ChunkedPayloadResponse" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "payload_id"), + 2: .standard(proto: "request_transfer"), + 3: .standard(proto: "accept_transfer"), + 4: .standard(proto: "resend_chunks"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.payloadID) }() + case 2: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .requestTransfer(v) + } + }() + case 3: try { + var v: Bool? + try decoder.decodeSingularBoolField(value: &v) + if let v = v { + if self.payloadVariant != nil {try decoder.handleConflictingOneOf()} + self.payloadVariant = .acceptTransfer(v) + } + }() + case 4: try { + var v: resend_chunks? + var hadOneofValue = false + if let current = self.payloadVariant { + hadOneofValue = true + if case .resendChunks(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.payloadVariant = .resendChunks(v) + } + }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if self.payloadID != 0 { + try visitor.visitSingularUInt32Field(value: self.payloadID, fieldNumber: 1) + } + switch self.payloadVariant { + case .requestTransfer?: try { + guard case .requestTransfer(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + }() + case .acceptTransfer?: try { + guard case .acceptTransfer(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularBoolField(value: v, fieldNumber: 3) + }() + case .resendChunks?: try { + guard case .resendChunks(let v)? = self.payloadVariant else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: ChunkedPayloadResponse, rhs: ChunkedPayloadResponse) -> Bool { + if lhs.payloadID != rhs.payloadID {return false} + if lhs.payloadVariant != rhs.payloadVariant {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Meshtastic/Protobufs/meshtastic/powermon.pb.swift b/Meshtastic/Protobufs/meshtastic/powermon.pb.swift new file mode 100644 index 00000000..c6762ef1 --- /dev/null +++ b/Meshtastic/Protobufs/meshtastic/powermon.pb.swift @@ -0,0 +1,179 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: meshtastic/powermon.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs). +///But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us) +struct PowerMon { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Any significant power changing event in meshtastic should be tagged with a powermon state transition. + ///If you are making new meshtastic features feel free to add new entries at the end of this definition. + enum State: SwiftProtobuf.Enum { + typealias RawValue = Int + case none // = 0 + case cpuDeepSleep // = 1 + case cpuLightSleep // = 2 + + /// + ///The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only + ///occasionally. In cases where that rail has multiple devices on it we usually want to have logging on + ///the state of that rail as an independent record. + ///For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen. + /// + ///The log messages will be short and complete (see PowerMon.Event in the protobufs for details). + ///something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states. + ///(We use a bitmask for states so that if a log message gets lost it won't be fatal) + case vext1On // = 4 + case loraRxon // = 8 + case loraTxon // = 16 + case loraRxactive // = 32 + case btOn // = 64 + case ledOn // = 128 + case screenOn // = 256 + case screenDrawing // = 512 + case wifiOn // = 1024 + + /// + ///GPS is actively trying to find our location + ///See GPSPowerState for more details + case gpsActive // = 2048 + case UNRECOGNIZED(Int) + + init() { + self = .none + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .none + case 1: self = .cpuDeepSleep + case 2: self = .cpuLightSleep + case 4: self = .vext1On + case 8: self = .loraRxon + case 16: self = .loraTxon + case 32: self = .loraRxactive + case 64: self = .btOn + case 128: self = .ledOn + case 256: self = .screenOn + case 512: self = .screenDrawing + case 1024: self = .wifiOn + case 2048: self = .gpsActive + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .none: return 0 + case .cpuDeepSleep: return 1 + case .cpuLightSleep: return 2 + case .vext1On: return 4 + case .loraRxon: return 8 + case .loraTxon: return 16 + case .loraRxactive: return 32 + case .btOn: return 64 + case .ledOn: return 128 + case .screenOn: return 256 + case .screenDrawing: return 512 + case .wifiOn: return 1024 + case .gpsActive: return 2048 + case .UNRECOGNIZED(let i): return i + } + } + + } + + init() {} +} + +#if swift(>=4.2) + +extension PowerMon.State: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + static let allCases: [PowerMon.State] = [ + .none, + .cpuDeepSleep, + .cpuLightSleep, + .vext1On, + .loraRxon, + .loraTxon, + .loraRxactive, + .btOn, + .ledOn, + .screenOn, + .screenDrawing, + .wifiOn, + .gpsActive, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension PowerMon: @unchecked Sendable {} +extension PowerMon.State: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "meshtastic" + +extension PowerMon: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".PowerMon" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: PowerMon, rhs: PowerMon) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension PowerMon.State: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "None"), + 1: .same(proto: "CPU_DeepSleep"), + 2: .same(proto: "CPU_LightSleep"), + 4: .same(proto: "Vext1_On"), + 8: .same(proto: "Lora_RXOn"), + 16: .same(proto: "Lora_TXOn"), + 32: .same(proto: "Lora_RXActive"), + 64: .same(proto: "BT_On"), + 128: .same(proto: "LED_On"), + 256: .same(proto: "Screen_On"), + 512: .same(proto: "Screen_Drawing"), + 1024: .same(proto: "Wifi_On"), + 2048: .same(proto: "GPS_Active"), + ] +} diff --git a/Meshtastic/Protobufs/meshtastic/telemetry.pb.swift b/Meshtastic/Protobufs/meshtastic/telemetry.pb.swift index 7ddb75dc..f6116cf9 100644 --- a/Meshtastic/Protobufs/meshtastic/telemetry.pb.swift +++ b/Meshtastic/Protobufs/meshtastic/telemetry.pb.swift @@ -120,6 +120,14 @@ enum TelemetrySensorType: SwiftProtobuf.Enum { /// /// AHT10 Integrated temperature and humidity sensor case aht10 // = 23 + + /// + /// DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) + case dfrobotLark // = 24 + + /// + /// NAU7802 Scale Chip or compatible + case nau7802 // = 25 case UNRECOGNIZED(Int) init() { @@ -152,6 +160,8 @@ enum TelemetrySensorType: SwiftProtobuf.Enum { case 21: self = .ltr390Uv case 22: self = .tsl25911Fn case 23: self = .aht10 + case 24: self = .dfrobotLark + case 25: self = .nau7802 default: self = .UNRECOGNIZED(rawValue) } } @@ -182,6 +192,8 @@ enum TelemetrySensorType: SwiftProtobuf.Enum { case .ltr390Uv: return 21 case .tsl25911Fn: return 22 case .aht10: return 23 + case .dfrobotLark: return 24 + case .nau7802: return 25 case .UNRECOGNIZED(let i): return i } } @@ -217,6 +229,8 @@ extension TelemetrySensorType: CaseIterable { .ltr390Uv, .tsl25911Fn, .aht10, + .dfrobotLark, + .nau7802, ] } @@ -302,6 +316,27 @@ struct EnvironmentMetrics { /// VEML7700 high accuracy white light(irradiance) not calibrated digital 16-bit resolution sensor. var whiteLux: Float = 0 + /// + /// Infrared lux + var irLux: Float = 0 + + /// + /// Ultraviolet lux + var uvLux: Float = 0 + + /// + /// Wind direction in degrees + /// 0 degrees = North, 90 = East, etc... + var windDirection: UInt32 = 0 + + /// + /// Wind speed in m/s + var windSpeed: Float = 0 + + /// + /// Weight in KG + var weight: Float = 0 + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -503,6 +538,26 @@ struct Telemetry { init() {} } +/// +/// NAU7802 Telemetry configuration, for saving to flash +struct Nau7802Config { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// + /// The offset setting for the NAU7802 + var zeroOffset: Int32 = 0 + + /// + /// The calibration factor for the NAU7802 + var calibrationFactor: Float = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + #if swift(>=5.5) && canImport(_Concurrency) extension TelemetrySensorType: @unchecked Sendable {} extension DeviceMetrics: @unchecked Sendable {} @@ -511,6 +566,7 @@ extension PowerMetrics: @unchecked Sendable {} extension AirQualityMetrics: @unchecked Sendable {} extension Telemetry: @unchecked Sendable {} extension Telemetry.OneOf_Variant: @unchecked Sendable {} +extension Nau7802Config: @unchecked Sendable {} #endif // swift(>=5.5) && canImport(_Concurrency) // MARK: - Code below here is support for the SwiftProtobuf runtime. @@ -543,6 +599,8 @@ extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding { 21: .same(proto: "LTR390UV"), 22: .same(proto: "TSL25911FN"), 23: .same(proto: "AHT10"), + 24: .same(proto: "DFROBOT_LARK"), + 25: .same(proto: "NAU7802"), ] } @@ -615,6 +673,11 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple 8: .same(proto: "distance"), 9: .same(proto: "lux"), 10: .standard(proto: "white_lux"), + 11: .standard(proto: "ir_lux"), + 12: .standard(proto: "uv_lux"), + 13: .standard(proto: "wind_direction"), + 14: .standard(proto: "wind_speed"), + 15: .same(proto: "weight"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -633,6 +696,11 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple case 8: try { try decoder.decodeSingularFloatField(value: &self.distance) }() case 9: try { try decoder.decodeSingularFloatField(value: &self.lux) }() case 10: try { try decoder.decodeSingularFloatField(value: &self.whiteLux) }() + case 11: try { try decoder.decodeSingularFloatField(value: &self.irLux) }() + case 12: try { try decoder.decodeSingularFloatField(value: &self.uvLux) }() + case 13: try { try decoder.decodeSingularUInt32Field(value: &self.windDirection) }() + case 14: try { try decoder.decodeSingularFloatField(value: &self.windSpeed) }() + case 15: try { try decoder.decodeSingularFloatField(value: &self.weight) }() default: break } } @@ -669,6 +737,21 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.whiteLux != 0 { try visitor.visitSingularFloatField(value: self.whiteLux, fieldNumber: 10) } + if self.irLux != 0 { + try visitor.visitSingularFloatField(value: self.irLux, fieldNumber: 11) + } + if self.uvLux != 0 { + try visitor.visitSingularFloatField(value: self.uvLux, fieldNumber: 12) + } + if self.windDirection != 0 { + try visitor.visitSingularUInt32Field(value: self.windDirection, fieldNumber: 13) + } + if self.windSpeed != 0 { + try visitor.visitSingularFloatField(value: self.windSpeed, fieldNumber: 14) + } + if self.weight != 0 { + try visitor.visitSingularFloatField(value: self.weight, fieldNumber: 15) + } try unknownFields.traverse(visitor: &visitor) } @@ -683,6 +766,11 @@ extension EnvironmentMetrics: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if lhs.distance != rhs.distance {return false} if lhs.lux != rhs.lux {return false} if lhs.whiteLux != rhs.whiteLux {return false} + if lhs.irLux != rhs.irLux {return false} + if lhs.uvLux != rhs.uvLux {return false} + if lhs.windDirection != rhs.windDirection {return false} + if lhs.windSpeed != rhs.windSpeed {return false} + if lhs.weight != rhs.weight {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -959,3 +1047,41 @@ extension Telemetry: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation return true } } + +extension Nau7802Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Nau7802Config" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "zeroOffset"), + 2: .same(proto: "calibrationFactor"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self.zeroOffset) }() + case 2: try { try decoder.decodeSingularFloatField(value: &self.calibrationFactor) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.zeroOffset != 0 { + try visitor.visitSingularInt32Field(value: self.zeroOffset, fieldNumber: 1) + } + if self.calibrationFactor != 0 { + try visitor.visitSingularFloatField(value: self.calibrationFactor, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Nau7802Config, rhs: Nau7802Config) -> Bool { + if lhs.zeroOffset != rhs.zeroOffset {return false} + if lhs.calibrationFactor != rhs.calibrationFactor {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift index 0b71dcb3..980ed8f4 100644 --- a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift +++ b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift @@ -5,8 +5,8 @@ // Copyright (c) Garth Vander Houwen 8/18/22. // -import SwiftUI import OSLog +import SwiftUI struct BluetoothConfig: View { @Environment(\.managedObjectContext) var context @@ -18,6 +18,7 @@ struct BluetoothConfig: View { @State var mode = 0 @State var fixedPin = "123456" @State var shortPin = false + @State var deviceLoggingEnabled = false var pinLength: Int = 6 let numberFormatter: NumberFormatter = { let formatter = NumberFormatter() @@ -68,18 +69,24 @@ struct BluetoothConfig: View { .foregroundColor(.red) } } + + Toggle(isOn: $deviceLoggingEnabled) { + Label("Device Logging Enabled", systemImage: "ladybug") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) } } .disabled(self.bleManager.connectedPeripheral == nil || node?.bluetoothConfig == nil) SaveConfigButton(node: node, hasChanges: $hasChanges) { - let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context) - if connectedNode != nil { + if let myNodeNum = bleManager.connectedPeripheral?.num, + let connectedNode = getNodeInfo(id: myNodeNum, context: context) { var bc = Config.BluetoothConfig() bc.enabled = enabled bc.mode = BluetoothModes(rawValue: mode)?.protoEnumValue() ?? Config.BluetoothConfig.PairingMode.randomPin bc.fixedPin = UInt32(fixedPin) ?? 123456 - let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0) + bc.deviceLoggingEnabled = deviceLoggingEnabled + let adminMessageId = bleManager.saveBluetoothConfig(config: bc, fromUser: connectedNode.user!, toUser: node!.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) if adminMessageId > 0 { // Should show a saved successfully alert once I know that to be true // for now just disable the button after a successful save @@ -90,21 +97,26 @@ struct BluetoothConfig: View { } .navigationTitle("bluetooth.config") - .navigationBarItems(trailing: - ZStack { - ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?") - }) + .navigationBarItems( + trailing: ZStack { + ConnectedDevice( + bluetoothOn: bleManager.isSwitchedOn, + deviceConnected: bleManager.connectedPeripheral != nil, + name: bleManager.connectedPeripheral?.shortName ?? "?" + ) + } + ) .onAppear { if self.bleManager.context == nil { self.bleManager.context = context } setBluetoothValues() // Need to request a BluetoothConfig from the remote node before allowing changes - if bleManager.connectedPeripheral != nil && node?.bluetoothConfig == nil { + if let connectedPeripheral = bleManager.connectedPeripheral, let node, node.bluetoothConfig == nil { Logger.mesh.info("empty bluetooth config") - let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context) - if node != nil && connectedNode != nil { - _ = bleManager.requestBluetoothConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0) + let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context) + if let connectedNode { + _ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0) } } } @@ -123,11 +135,17 @@ struct BluetoothConfig: View { if newFixedPin != String(node!.bluetoothConfig!.fixedPin) { hasChanges = true } } } + .onChange(of: deviceLoggingEnabled) { newDeviceLogging in + if node != nil && node!.bluetoothConfig != nil { + if newDeviceLogging != node!.bluetoothConfig!.deviceLoggingEnabled { hasChanges = true } + } + } } func setBluetoothValues() { self.enabled = node?.bluetoothConfig?.enabled ?? true self.mode = Int(node?.bluetoothConfig?.mode ?? 0) self.fixedPin = String(node?.bluetoothConfig?.fixedPin ?? 123456) + self.deviceLoggingEnabled = node?.bluetoothConfig?.deviceLoggingEnabled ?? false self.hasChanges = false } } diff --git a/protobufs b/protobufs index 1c3029f2..4da558d0 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 1c3029f2868e5fc49809fd378f6c0c66aee0eaf4 +Subproject commit 4da558d0f73c46ef91b74431facee73c09affbfc