diff --git a/Localizable.xcstrings b/Localizable.xcstrings index 834f3238..de4df376 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -2,7 +2,7 @@ "sourceLanguage" : "en", "strings" : { "" : { - + "shouldTranslate" : false }, "\t%@" : { "localizations" : { @@ -220,7 +220,8 @@ "value" : "%1$@ - %2$@" } } - } + }, + "shouldTranslate" : false }, "%@ - %@ - %@" : { "localizations" : { @@ -254,7 +255,8 @@ "value" : "%1$@ - %2$@ - %3$@" } } - } + }, + "shouldTranslate" : false }, "%@ - %@ Towards %@ Back" : { "localizations" : { @@ -390,7 +392,8 @@ "value" : "%1$@ (%2$@)" } } - } + }, + "shouldTranslate" : false }, "%@ %@" : { "localizations" : { @@ -424,7 +427,8 @@ "value" : "%1$@ %2$@" } } - } + }, + "shouldTranslate" : false }, "%@ %lld" : { "localizations" : { @@ -458,7 +462,8 @@ "value" : "%1$@ %2$lld" } } - } + }, + "shouldTranslate" : false }, "%@ away" : { "localizations" : { @@ -668,13 +673,13 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Die App wird automatisch wieder zum präferierten Gerät verbinden, sobald es in Reichweite kommt." } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ L'application se reconnectera automatiquement à la radio en favori dès qu'elle sera à nouveau disponible." } }, @@ -692,13 +697,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Aplikacja automatycznie ponownie połączy się z preferowanym radiem, jeśli wróci w zasięg." } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Appen kommer automatiskt att återansluta till den föredragna radion om den kommer inom räckhåll igen." } }, @@ -722,17 +727,17 @@ } } }, - "%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re-connecting to the radio." : { + "%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re-connecting to the radio." : { "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Dieser Fehler kann üblicherweise behoben werden, indem man unter Einstellungen > Bluetooth die Verbindung manuell löscht und sich erneut mit dem Gerät verbindet." } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Cette erreur ne peut généralement pas être corrigée sans aller dans Réglages > Bluetooth et faire > Oublier cet appareil, puis reconnecter la radio." } }, @@ -750,13 +755,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Ten błąd zwykle nie może być naprawiony bez zapomnienia urządzenia w Ustawienia > Bluetooth i ponownego połączenia z radiem." } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "%@ Detta fel kan vanligtvis inte åtgärdas utan att glömma enheten under Inställningar > Bluetooth och återansluta till radion." } }, @@ -846,7 +851,8 @@ "value" : "%1$@: %2$lld / %3$lld" } } - } + }, + "shouldTranslate" : false }, "%@%%" : { "localizations" : { @@ -2220,23 +2226,69 @@ } } }, - "Airtime" : { + "After" : { "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", - "value" : "Airtime" - } - }, - "fr" : { - "stringUnit" : { - "state" : "needs_review", - "value" : "Temps d'émission" + "state" : "translated", + "value" : "Nach" } }, "he" : { "stringUnit" : { "state" : "needs_review", + "value" : "After" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dopo" + } + }, + "pl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "After" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Efter" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Након" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "之後" + } + } + } + }, + "Airtime" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Airtime" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Temps d'émission" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", "value" : "זמן אוויר" } }, @@ -2248,13 +2300,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Czas nadawania" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Sändningstid" } }, @@ -2688,19 +2740,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Immer an" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "En permanence" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "תמיד דלוק" } }, @@ -2712,13 +2764,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Zawsze włączone" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Alltid på" } }, @@ -2774,19 +2826,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Ambient Lighting" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Lumière ambiante" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "תאורת סביבה" } }, @@ -2804,7 +2856,7 @@ }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Omgivningsbelysning" } }, @@ -2832,19 +2884,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Ambient Lighting Config" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Configuration de la lumière ambiante" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הגדרות תאורת סביבה" } }, @@ -2862,7 +2914,7 @@ }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguration av omgivningsbelysning" } }, @@ -3154,19 +3206,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bist Du sicher?" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Êtes-vous sûr ?" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "האם אתה בטוח?" } }, @@ -3178,13 +3230,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Jesteś pewny?" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Är du säker?" } }, @@ -3290,19 +3342,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Geräte in der Nähe" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Radios disponibles" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "מכשירים זמינים" } }, @@ -3314,13 +3366,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Dostępne radia" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Tillgängliga radioapparater" } }, @@ -3466,19 +3518,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Batterie Ladung" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Niveau de batterie" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "רמת סוללה" } }, @@ -3490,13 +3542,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Poziom naładowania baterii" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Batterinivå" } }, @@ -3580,19 +3632,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "BLE Name" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Nom du BLE" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "שם בלוטוס" } }, @@ -3604,13 +3656,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Nazwa BLE" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "BLE-namn" } }, @@ -3638,19 +3690,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Die Bluetooth Pin muss 6 Stellen lang sein." } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Le code pin BLE doit avoir 6 chiffres." } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "קוד בלוטוס חייבת להיות בת 6 ספרות." } }, @@ -3662,13 +3714,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Pin BLE musi mieć długość 6 cyfr." } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "BLE-PIN måste vara 6 siffror lång." } }, @@ -3810,19 +3862,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth Konfiguration" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Configuration Bluetooth" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הגדרות בלוטוס" } }, @@ -3834,13 +3886,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguracja Bluetooth" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth-konfiguration" } }, @@ -3868,19 +3920,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth ist aus" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Le Bluetooth est arrêté" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "בלוטוס כבוי" } }, @@ -3892,13 +3944,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth jest wyłączony" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bluetooth är avstängt" } }, @@ -4048,19 +4100,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bytes" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Octets" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "בייטים" } }, @@ -4072,13 +4124,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bajty" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Bytes" } }, @@ -4162,19 +4214,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Abbrechen" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Annuler" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "בטל" } }, @@ -4186,13 +4238,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Anuluj" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Avbryt" } }, @@ -4220,19 +4272,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Canned Messages" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Messages préformatés" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הודעות קבועות" } }, @@ -4244,13 +4296,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Gotowe wiadomości" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Fördefinierade meddelanden" } }, @@ -4278,19 +4330,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Canned Messages Config" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Configuration des messages préformatés" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "הגדרות הודעות קבועות" } }, @@ -4302,13 +4354,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguracja gotowych wiadomości" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Konfiguration av fördefinierade meddelanden" } }, @@ -4332,198 +4384,6 @@ } } }, - "canned.messages.preset.cardkb" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / RAK Tastenfeld" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Clavier M5 Stack Card KB / RAK" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / Tastiera RAK" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack Card KB / RAK Keypad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 стек картица KB / RAK тастатура" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5 Stack 卡片键盘 / RAK 键盘" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "M5Stack 卡片鍵盤 / RAK 鍵盤" - } - } - } - }, - "canned.messages.preset.manual" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manuelle Konfiguration" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manual Configuration" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration manuelle" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרה ידנית" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configurazione manuale" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguracja ręczna" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manuell konfiguration" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ручна конфигурација" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "手动配置" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "手動設定" - } - } - } - }, - "canned.messages.preset.rakrotary" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Drehimpulsgeber Modul" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary Encoder Module" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Module d'encodage rotatif RAK" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary Encoder Module" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Modulo encoder rotativo RAK" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Moduł kodera obrotowego RAK" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary Encoder-modul" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK Rotary енкодер модул" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK 编码器" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "RAK 旋轉編碼器" - } - } - } - }, "Carousel Interval" : { "localizations" : { "it" : { @@ -4716,19 +4576,19 @@ "localizations" : { "de" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Kanal" } }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Canal" } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "ערוץ" } }, @@ -4740,13 +4600,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Kanał" } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Kanal" } }, @@ -5194,215 +5054,7 @@ } } }, - "Channel Utilization %@%%" : { - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Utilizzo del canale %@%%" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "頻道利用率 %@%%" - } - } - } - }, - "channel.role.disabled" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Deaktiviert" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disabled" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Désactivé" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "כבוי" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disattivato" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wyłączony" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inaktiverad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Онемогућено" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "禁用" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "關閉" - } - } - } - }, - "channel.role.primary" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primär" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primary" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Principal" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "עיקרי" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primario" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Podstawowy" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Primär" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Примарни" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "主要" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "主要" - } - } - } - }, - "channel.role.secondary" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sekundär" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secondary" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secondaire" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "משני" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secondario" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wtórny" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sekundär" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Секундарни" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "次要" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "次要" - } - } - } - }, - "channel.utilization" : { + "Channel Utilization" : { "localizations" : { "de" : { "stringUnit" : { @@ -5410,12 +5062,6 @@ "value" : "Kanalbelegung" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Channel Utilization" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -5466,7 +5112,23 @@ } } }, - "channels" : { + "Channel Utilization %@%%" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Utilizzo del canale %@%%" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "頻道利用率 %@%%" + } + } + } + }, + "Channels" : { "localizations" : { "de" : { "stringUnit" : { @@ -5474,12 +5136,6 @@ "value" : "Kanäle" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Channels" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -5658,29 +5314,7 @@ } } }, - "Clear Log" : { - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancella registro" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Очисти логове" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "清除 Log 檔" - } - } - } - }, - "clear.app.data" : { + "Clear App Data" : { "localizations" : { "de" : { "stringUnit" : { @@ -5688,12 +5322,6 @@ "value" : "App Daten löschen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Clear App Data" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -5744,6 +5372,28 @@ } } }, + "Clear Log" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancella registro" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Очисти логове" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "清除 Log 檔" + } + } + } + }, "Client" : { "localizations" : { "it" : { @@ -5884,7 +5534,7 @@ } } }, - "close" : { + "Close" : { "localizations" : { "de" : { "stringUnit" : { @@ -5892,12 +5542,6 @@ "value" : "Schließen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Close" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -6076,122 +5720,6 @@ } } }, - "config.module.paxcounter.enabled.description" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Quando è abilitato, il modulo PAX Counter conta il numero di persone che passano utilizzando il WiFi e il Bluetooth. Per il funzionamento del contatore PAX, sia il WiFI che il Bluetooth devono essere disattivati." - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "När aktiverad räknar PAX-räknarmodulen antalet personer som passerar med WiFi och Bluetooth. Både WiFi och Bluetooth måste vara aktiverade för att PAX-räknaren ska fungera." - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Када је омогућен, модул бројача пролазника броји број људи који пролазе користећи ВајФај и Блутут. И ВајФај и Блутут морају бити онемогућени да би бројач пролазника радио." - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用 PAX 计数器模块时,通过使用 WiFi 和蓝牙来计算经过的人数。为了使 PAX 计数器正常工作,必须将 WiFi 和蓝牙都禁用。" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "啟用後,人流計數器模組將透過 WiFi 和藍牙計算經過的人數。必須停用 WiFi 和藍牙才能讓 PAX 計數器正常工作。" - } - } - } - }, - "config.module.paxcounter.settings" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contatore PAX" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Counter" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX Räknare" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Бројач пролазника" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX 计数器" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "PAX 計數器" - } - } - } - }, "config.module.paxcounter.title" : { "localizations" : { "de" : { @@ -6250,64 +5778,6 @@ } } }, - "config.module.paxcounter.updateinterval" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Intervallo di aggiornamento" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update Interval" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Uppdateringsintervall" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Интервал ажурирања" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "更新间隔" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "更新時間間隔" - } - } - } - }, "config.module.paxcounter.updateinterval.description" : { "localizations" : { "de" : { @@ -6638,116 +6108,6 @@ } } }, - "config.power.settings" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Strom" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Potenza" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Power" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ström" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Снага" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "电源" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "休眠" - } - } - } - }, - "config.power.shutdown.after.secs" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nach" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "After" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "After" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dopo" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "After" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Efter" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Након" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "之後" - } - } - } - }, "config.power.shutdown.on.power.loss" : { "localizations" : { "de" : { @@ -8280,7 +7640,7 @@ } } }, - "default" : { + "Default" : { "localizations" : { "de" : { "stringUnit" : { @@ -8288,12 +7648,6 @@ "value" : "Standard" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Default" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -8344,34 +7698,6 @@ } } }, - "Default" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Predefinito" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Подразумевано" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "預設" - } - } - } - }, "default.128x64.screen.layout" : { "localizations" : { "en" : { @@ -10238,13 +9564,13 @@ }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Noeud d'infrastructure qui étend la couverture du réseau en relayant les messages avec un minimum de surcharge. Invisible dans la liste des noeuds." } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "מכשיר תשתית להרחבת המש על ידי העברת הודעות עם דאטה נוסף מינימלי." } }, @@ -10256,13 +9582,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Przekaźnik - Pakiety siatki będą preferować trasowanie przez ten węzeł. Ta rola eliminuje niepotrzebny nadmiar, taki jak NodeInfo, DeviceTelemetry i inne pakiety siatki, skutkując tym, że urządzenie nie będzie widoczne jako część sieci. Proszę zobaczyć tryb Rebroadcast dla dodatkowych ustawień specyficznych dla tej roli." } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Infrastrukturnod för att utöka nätverkstäckningen genom att vidarebefordra meddelanden med minimal overhead. Syns inte i Noder-listan." } }, @@ -10302,13 +9628,13 @@ }, "fr" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Noeud d'infrastructure qui étend la couverture du réseau en relayant les messages. Visible dans la liste des noeuds." } }, "he" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "מכשיר תשתית להרחבת המש על ידי העברת הודעות. מופיע ברשימת מכשירים." } }, @@ -10320,13 +9646,13 @@ }, "pl" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Router - Pakiety siatki będą preferować trasowanie przez ten węzeł. Zakłada, że urządzenie będzie działać samodzielnie, umieszczone w miejscu z przewagą zasięgu. UWAGA: Radia BLE/Wi-Fi i ekran OLED zostaną uśpione." } }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Infrastrukturnod för att utöka nätverkstäckningen genom att vidarebefordra meddelanden. Synlig i Noder-listan." } }, @@ -10390,7 +9716,7 @@ }, "se" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "Kombination av både ROUTER och CLIENT. Inte för mobila enheter." } }, @@ -10913,13 +10239,37 @@ "de" : { "stringUnit" : { "state" : "translated", - "value" : "Ausgeschaltet" + "value" : "Deaktiviert" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Désactivé" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "כבוי" } }, "it" : { "stringUnit" : { "state" : "translated", - "value" : "Disabili" + "value" : "Disattivato" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wyłączony" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inaktiverad" } }, "sr" : { @@ -10937,7 +10287,7 @@ "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "已停用" + "value" : "關閉" } } } @@ -10950,12 +10300,6 @@ "value" : "Trennen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disconnect" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -11014,12 +10358,6 @@ "value" : "Tastatur ausblenden" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Dismiss" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -11078,12 +10416,6 @@ "value" : "Display (Device Screen)" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -11134,6 +10466,58 @@ } } }, + "Display Config" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration de l'écran" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרות צג" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione del display" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguracja Wyświetlacza" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Skärmkonfiguration" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Подешавања приказа" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "屏幕配置" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "螢幕設定" + } + } + } + }, "Display Fahrenheit" : { "localizations" : { "it" : { @@ -11218,128 +10602,6 @@ } } }, - "display.config" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display Config" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configuration de l'écran" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הגדרות צג" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configurazione del display" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Konfiguracja Wyświetlacza" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Skärmkonfiguration" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Подешавања приказа" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "屏幕配置" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "螢幕設定" - } - } - } - }, - "distance" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Entfernung" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Distance" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Distance" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מרחק" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Distanza" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Odległość" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Distans" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Раздаљина" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "距离" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "距離" - } - } - } - }, "Distance" : { "localizations" : { "de" : { @@ -11564,17 +10826,11 @@ } } }, - "echo" : { + "Echo" : { "localizations" : { "de" : { "stringUnit" : { - "state" : "translated", - "value" : "Echo" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Echo" } }, @@ -11598,7 +10854,7 @@ }, "pl" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Echo" } }, @@ -11622,7 +10878,7 @@ }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Echo" } } @@ -11796,12 +11052,6 @@ "value" : "Aktiviert" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enabled" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -11996,7 +11246,7 @@ } } }, - "encrypted" : { + "Encrypted" : { "localizations" : { "de" : { "stringUnit" : { @@ -12004,12 +11254,6 @@ "value" : "Verschlüsselt" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Encrypted" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -12060,40 +11304,6 @@ } } }, - "Encrypted" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verschlüsselt" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Crittografato" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Шифровано" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "加密" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "已加密" - } - } - } - }, "Encryption Enabled" : { "localizations" : { "it" : { @@ -12422,12 +11632,6 @@ }, "European Union 433MHz" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "European Union 433MHz" - } - }, "it" : { "stringUnit" : { "state" : "translated", @@ -12450,12 +11654,6 @@ }, "European Union 868MHz" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "European Union 868MHz" - } - }, "it" : { "stringUnit" : { "state" : "translated", @@ -13090,7 +12288,7 @@ } } }, - "finish" : { + "Finish" : { "localizations" : { "de" : { "stringUnit" : { @@ -13098,12 +12296,6 @@ "value" : "Beenden" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Finish" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -13250,7 +12442,7 @@ } } }, - "firmware.version" : { + "Firmware Version" : { "localizations" : { "de" : { "stringUnit" : { @@ -13258,12 +12450,6 @@ "value" : "Firmware Version" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Firmware Version" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -13436,12 +12622,6 @@ "value" : "Feste PIN" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Fixed PIN" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -14624,174 +13804,6 @@ } } }, - "gpsmode.disabled" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ausgeschaltet" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disabled" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Désactivé" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "כבוי" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Disabili" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inaktiverad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Онемогућен" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "禁用" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "已停用" - } - } - } - }, - "gpsmode.enabled" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eingeschaltet" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enabled" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Activé" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "מופעל" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Abilitato" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aktiverad" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Омогућен" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "启用" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "已啟用" - } - } - } - }, - "gpsmode.notPresent" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Not Present" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Absent" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "לא קיים" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Non presente" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Inte närvarande" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Није пристуно" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "不存在" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "無模組" - } - } - } - }, "Group Message" : { "localizations" : { "de" : { @@ -15386,7 +14398,7 @@ } } }, - "How often sensor metrics are sent out over the mesh. Default is 30 minutes." : { + "How often environment metrics are sent out over the mesh. Default is 30 minutes." : { "localizations" : { "it" : { "stringUnit" : { @@ -16056,7 +15068,7 @@ } } }, - "include" : { + "Include" : { "localizations" : { "de" : { "stringUnit" : { @@ -16064,12 +15076,6 @@ "value" : "Include" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Include" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -16186,15 +15192,9 @@ }, "India" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "India" - } - }, "it" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "India" } }, @@ -18572,12 +17572,6 @@ }, "Japan" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Japan" - } - }, "it" : { "stringUnit" : { "state" : "translated", @@ -18750,12 +17744,6 @@ }, "Korea" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Korea" - } - }, "it" : { "stringUnit" : { "state" : "translated", @@ -19292,70 +18280,6 @@ } } }, - "log.message" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachricht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messaggio" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Порука" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - } - } - }, "log.process" : { "localizations" : { "de" : { @@ -19668,6 +18592,28 @@ } } }, + "Long Range - Fast" : { + "localizations" : { + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "A lungo raggio - Veloce" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Дугачки домет - Брзо" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "Long Range - Fast" + } + } + } + }, "Long Name" : { "localizations" : { "de" : { @@ -19764,30 +18710,24 @@ } } }, - "long.range.fast" : { + "Long Range - Slow" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Long Range - Fast" - } - }, "it" : { "stringUnit" : { "state" : "translated", - "value" : "A lungo raggio - Veloce" + "value" : "Lungo raggio - Lento" } }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Дугачки домет - Брзо" + "value" : "Дугачки домет - Споро" } }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "Long Range - Fast" + "value" : "Long Range - Slow" } } } @@ -19820,34 +18760,6 @@ } } }, - "long.range.slow" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Long Range - Slow" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Lungo raggio - Lento" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Дугачки домет - Споро" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "Long Range - Slow" - } - } - } - }, "Longitude" : { "localizations" : { "de" : { @@ -20168,6 +19080,70 @@ } } }, + "M5 Stack Card KB / RAK Keypad" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack Card KB / RAK Tastenfeld" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack Card KB / RAK Keypad" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clavier M5 Stack Card KB / RAK" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack Card KB / RAK Keypad" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack Card KB / Tastiera RAK" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack Card KB / RAK Keypad" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack Card KB / RAK Keypad" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 стек картица KB / RAK тастатура" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5 Stack 卡片键盘 / RAK 键盘" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "M5Stack 卡片鍵盤 / RAK 鍵盤" + } + } + } + }, "Malaysia 433mhz" : { "localizations" : { "en" : { @@ -20252,6 +19228,64 @@ } } }, + "Manual Configuration" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Manuelle Konfiguration" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configuration manuelle" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "הגדרה ידנית" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurazione manuale" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konfiguracja ręczna" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Manuell konfiguration" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ручна конфигурација" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "手动配置" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "手動設定" + } + } + } + }, "map" : { "localizations" : { "de" : { @@ -23102,70 +22136,6 @@ } } }, - "message" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachricht" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Message" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעה" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messaggio" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Wiadomość" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meddelande" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Порука" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "消息" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "訊息" - } - } - } - }, "Message" : { "localizations" : { "de" : { @@ -23550,7 +22520,7 @@ } } }, - "mode" : { + "Mode" : { "localizations" : { "de" : { "stringUnit" : { @@ -23558,15 +22528,9 @@ "value" : "Modus" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Mode" - } - }, "fr" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Mode" } }, @@ -23706,70 +22670,6 @@ } } }, - "mqtt" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "MQTT" - } - } - } - }, "MQTT" : { "localizations" : { "it" : { @@ -23970,70 +22870,6 @@ } } }, - "name" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Name" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Name" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nom" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "שם" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nome" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nazwa" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Namn" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Име" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "名称" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "名稱" - } - } - } - }, "Name" : { "localizations" : { "de" : { @@ -25060,6 +23896,52 @@ } } }, + "Not Present" : { + "localizations" : { + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Absent" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "לא קיים" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Non presente" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Inte närvarande" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Није пристуно" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "不存在" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "無模組" + } + } + } + }, "not.connected" : { "localizations" : { "de" : { @@ -26050,16 +24932,6 @@ } } }, - "password" : { - "localizations" : { - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "密碼" - } - } - } - }, "Password" : { "localizations" : { "de" : { @@ -26068,12 +24940,6 @@ "value" : "Passwort" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Password" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -26082,7 +24948,7 @@ }, "he" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "סיסמא" } }, @@ -26188,6 +25054,58 @@ } } }, + "PAX Counter" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "PAX Counter" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX Counter" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Contatore PAX" + } + }, + "pl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "PAX Counter" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX Räknare" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Бројач пролазника" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 计数器" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "PAX 計數器" + } + } + } + }, "paxcounter.ble" : { "localizations" : { "en" : { @@ -26756,7 +25674,7 @@ } } }, - "position" : { + "Position" : { "localizations" : { "de" : { "stringUnit" : { @@ -27142,22 +26060,52 @@ }, "Power" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Strom" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "Power" + } + }, "it" : { "stringUnit" : { "state" : "translated", "value" : "Potenza" } }, + "pl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Power" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ström" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Снага" } }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "电源" + } + }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", - "value" : "電源" + "value" : "休眠" } } } @@ -27424,16 +26372,52 @@ }, "Primary" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Primär" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Principal" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "עיקרי" + } + }, "it" : { "stringUnit" : { "state" : "translated", "value" : "Primario" } }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Podstawowy" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Primär" + } + }, "sr" : { "stringUnit" : { "state" : "translated", - "value" : "Основни" + "value" : "Примарни" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "主要" } }, "zh-Hant-TW" : { @@ -27657,7 +26641,7 @@ "it" : { "stringUnit" : { "state" : "translated", - "value" : "DIPARTIMENTO DELLA DIFESA" + "value" : "Alimentato" } }, "sr" : { @@ -27776,6 +26760,64 @@ } } }, + "RAK Rotary Encoder" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Drehimpulsgeber Modul" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Module d'encodage rotatif RAK" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Rotary Encoder Module" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Modulo encoder rotativo RAK" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Kodera obrotowego RAK" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Rotary Encoder-modul" + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK Rotary енкодер модул" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK 编码器" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "RAK 旋轉編碼器" + } + } + } + }, "range.test" : { "localizations" : { "de" : { @@ -28694,12 +27736,6 @@ "value" : "Antworten" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reply" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -29036,6 +28072,9 @@ } }, "ringtone" : { + + }, + "Ringtone" : { "localizations" : { "de" : { "stringUnit" : { @@ -29043,12 +28082,6 @@ "value" : "Klingelton" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ringtone" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -30709,15 +29742,9 @@ }, "Russia" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Russia" - } - }, "it" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Russia" } }, @@ -31283,18 +30310,60 @@ }, "Secondary" : { "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sekundär" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secondary" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secondaire" + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "משני" + } + }, "it" : { "stringUnit" : { "state" : "translated", "value" : "Secondario" } }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Wtórny" + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sekundär" + } + }, "sr" : { "stringUnit" : { "state" : "translated", "value" : "Секундарни" } }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "次要" + } + }, "zh-Hant-TW" : { "stringUnit" : { "state" : "translated", @@ -32009,7 +31078,7 @@ } } }, - "Sensor Metrics" : { + "Environment Metrics" : { "localizations" : { "it" : { "stringUnit" : { @@ -32165,17 +31234,11 @@ } } }, - "serial" : { + "Serial" : { "localizations" : { "de" : { "stringUnit" : { - "state" : "translated", - "value" : "Serial" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Serial" } }, @@ -32349,70 +31412,6 @@ } } }, - "serial.mode.default" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Default" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Défaut" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "ברירת מחדל" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Predefinito" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Domyślny" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Standard" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Основни" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "默认" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "預設" - } - } - } - }, "serial.mode.nmea" : { "localizations" : { "de" : { @@ -32893,7 +31892,7 @@ } } }, - "settings" : { + "Settings" : { "localizations" : { "de" : { "stringUnit" : { @@ -32901,12 +31900,6 @@ "value" : "Einstellungen" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Settings" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -32957,22 +31950,6 @@ } } }, - "Settings" : { - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Impostazioni" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "設定" - } - } - } - }, "Share QR Code & Link" : { "localizations" : { "de" : { @@ -33875,7 +32852,7 @@ } } }, - "standard" : { + "Standard" : { "localizations" : { "de" : { "stringUnit" : { @@ -34339,15 +33316,9 @@ }, "Taiwan" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Taiwan" - } - }, "it" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Taiwan" } }, @@ -34395,12 +33366,6 @@ "value" : "Tapback Antwort" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tapback Response" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -35413,12 +34378,6 @@ }, "Thailand" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Thailand" - } - }, "it" : { "stringUnit" : { "state" : "translated", @@ -36335,7 +35294,7 @@ } } }, - "timeout" : { + "Timeout" : { "localizations" : { "de" : { "stringUnit" : { @@ -36343,12 +35302,6 @@ "value" : "Zeitlimit erreicht" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Timeout" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -36399,28 +35352,6 @@ } } }, - "timestamp" : { - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "timestamp" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "временска ознака" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "時間戳記" - } - } - } - }, "Timestamp" : { "localizations" : { "de" : { @@ -36429,12 +35360,6 @@ "value" : "Zeitstempel" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Timestamp" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -36955,70 +35880,6 @@ } } }, - "tip.messages.title" : { - "localizations" : { - "de" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nachrichten" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages" - } - }, - "fr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages" - } - }, - "he" : { - "stringUnit" : { - "state" : "translated", - "value" : "הודעות" - } - }, - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messaggi" - } - }, - "pl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Messages" - } - }, - "se" : { - "stringUnit" : { - "state" : "translated", - "value" : "Meddelanden" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Поруке" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "消息" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "訊息" - } - } - } - }, "TLS Enabled" : { "localizations" : { "it" : { @@ -37535,12 +36396,6 @@ }, "United States" : { "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "United States" - } - }, "it" : { "stringUnit" : { "state" : "translated", @@ -37583,39 +36438,11 @@ } } }, - "unknown" : { - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "sconosciuto" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "непознато" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "未知" - } - } - } - }, "Unknown" : { "localizations" : { "de" : { "stringUnit" : { - "state" : "translated", - "value" : "Unknown" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Unknown" } }, @@ -37669,7 +36496,7 @@ } } }, - "unknown.age" : { + "Unknown Age" : { "localizations" : { "de" : { "stringUnit" : { @@ -37677,12 +36504,6 @@ "value" : "Unbekanntes alter" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unknown Age" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -37733,7 +36554,7 @@ } } }, - "unset" : { + "Unset" : { "localizations" : { "de" : { "stringUnit" : { @@ -37741,12 +36562,6 @@ "value" : "Unset" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unset" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -38075,63 +36890,35 @@ } } }, - "uptime" : { + "Uptime" : { "localizations" : { "de" : { "stringUnit" : { - "state" : "translated", - "value" : "Uptime" - } - }, - "en" : { - "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Uptime" } }, "it" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Tempo di attività" } }, "se" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Drifttid" } }, "sr" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "Време рада" } }, "zh-Hant-TW" : { "stringUnit" : { - "state" : "translated", - "value" : "已開機時間" - } - } - } - }, - "Uptime" : { - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tempo di attività" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Време рада" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "已開機時間" } } @@ -38265,7 +37052,7 @@ } } }, - "user" : { + "User" : { "localizations" : { "de" : { "stringUnit" : { @@ -38273,12 +37060,6 @@ "value" : "Benutzer" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "User" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -38449,12 +37230,6 @@ "value" : "Benutzername" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Username" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -38775,7 +37550,7 @@ } } }, - "voltage" : { + "Voltage" : { "localizations" : { "de" : { "stringUnit" : { @@ -38783,12 +37558,6 @@ "value" : "Voltage" } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Voltage" - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -38839,28 +37608,6 @@ } } }, - "Voltage" : { - "localizations" : { - "it" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tensione" - } - }, - "sr" : { - "stringUnit" : { - "state" : "translated", - "value" : "Напон" - } - }, - "zh-Hant-TW" : { - "stringUnit" : { - "state" : "translated", - "value" : "電壓" - } - } - } - }, "Volts %@" : { "localizations" : { "it" : { @@ -38885,12 +37632,6 @@ "value" : "Warte..." } }, - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Waiting. . ." - } - }, "fr" : { "stringUnit" : { "state" : "translated", @@ -39209,6 +37950,58 @@ } } }, + "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." + } + }, + "he" : { + "stringUnit" : { + "state" : "translated", + "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quando è abilitato, il modulo PAX Counter conta il numero di persone che passano utilizzando il WiFi e il Bluetooth. Per il funzionamento del contatore PAX, sia il WiFI che il Bluetooth devono essere disattivati." + } + }, + "pl" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work." + } + }, + "se" : { + "stringUnit" : { + "state" : "translated", + "value" : "När aktiverad räknar PAX-räknarmodulen antalet personer som passerar med WiFi och Bluetooth. Både WiFi och Bluetooth måste vara aktiverade för att PAX-räknaren ska fungera." + } + }, + "sr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Када је омогућен, модул бројача пролазника броји број људи који пролазе користећи ВајФај и Блутут. И ВајФај и Блутут морају бити онемогућени да би бројач пролазника радио." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "启用 PAX 计数器模块时,通过使用 WiFi 和蓝牙来计算经过的人数。为了使 PAX 计数器正常工作,必须将 WiFi 和蓝牙都禁用。" + } + }, + "zh-Hant-TW" : { + "stringUnit" : { + "state" : "translated", + "value" : "啟用後,人流計數器模組將透過 WiFi 和藍牙計算經過的人數。必須停用 WiFi 和藍牙才能讓 PAX 計數器正常工作。" + } + } + } + }, "When using in GPIO mode, keep the output on for this long. " : { "localizations" : { "it" : { diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 62cf1085..39426e2f 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -56,7 +56,6 @@ B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B399E8A32B6F486400E4488E /* RetryButton.swift */; }; B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3E905B02B71F7F300654D07 /* TextMessageField.swift */; }; BC47C2EF2CE0017D008245CA /* MessageNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC47C2EE2CE0017D008245CA /* MessageNodeIntent.swift */; }; - BC5EBA3C2D002A2000C442FF /* MessageNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC5EBA3B2D002A2000C442FF /* MessageNodeIntent.swift */; }; BC6B45FF2CB2F98900723CEB /* SaveChannelSettingsIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */; }; BCB613812C67290800485544 /* SendWaypointIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613802C67290800485544 /* SendWaypointIntent.swift */; }; BCB613832C672A2600485544 /* MessageChannelIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613822C672A2600485544 /* MessageChannelIntent.swift */; }; @@ -146,7 +145,6 @@ DD8EBF43285058FA00426DCA /* DisplayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8EBF42285058FA00426DCA /* DisplayConfig.swift */; }; DD8ED9C52898D51F00B3B0AB /* NetworkConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8ED9C42898D51F00B3B0AB /* NetworkConfig.swift */; }; DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */; }; - DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD90860D26F69BAE00DC5189 /* NodeMap.swift */; }; DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */; }; DD93800B2BA3F968008BEC06 /* NodeMapContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD93800A2BA3F968008BEC06 /* NodeMapContent.swift */; }; DD93800E2BA74D0C008BEC06 /* ChannelForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */; }; @@ -437,7 +435,6 @@ DD8ED9C42898D51F00B3B0AB /* NetworkConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConfig.swift; sourceTree = ""; }; DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoutingError.swift; sourceTree = ""; }; DD90860A26F645B700DC5189 /* Meshtastic.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Meshtastic.entitlements; sourceTree = ""; }; - DD90860D26F69BAE00DC5189 /* NodeMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMap.swift; sourceTree = ""; }; DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotificationManager.swift; sourceTree = ""; }; DD93800A2BA3F968008BEC06 /* NodeMapContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMapContent.swift; sourceTree = ""; }; DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelForm.swift; sourceTree = ""; }; @@ -731,7 +728,6 @@ DDDB263E2AABEE20003AFCB7 /* NodeList.swift */, DD769E0228D18BF0001A3F05 /* DeviceMetricsLog.swift */, DDAD49EC2AFB39DC00B4425D /* MeshMap.swift */, - DD90860D26F69BAE00DC5189 /* NodeMap.swift */, DD73FD1028750779000852D6 /* PositionLog.swift */, DD4F23CC28779A3C001D37CB /* EnvironmentMetricsLog.swift */, 6DEDA5592A957B8E00321D2E /* DetectionSensorLog.swift */, @@ -1240,7 +1236,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1540; - LastUpgradeCheck = 1600; + LastUpgradeCheck = 1630; TargetAttributes = { 25F5D5C62C4375A8008036E3 = { CreatedOnToolsVersion = 15.4; @@ -1404,7 +1400,6 @@ DDC4D568275499A500A4208E /* Persistence.swift in Sources */, DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */, DD77093B2AA1ABB8007A8BF0 /* BluetoothTips.swift in Sources */, - DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */, D9C9839D2B79CFD700BDBE6A /* TextMessageSize.swift in Sources */, DDC94FCE29CF55310082EA6E /* RtttlConfig.swift in Sources */, DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */, @@ -1486,7 +1481,6 @@ 251926872C3BAE2200249DF5 /* NodeAlertsButton.swift in Sources */, DDA1C48E28DB49D3009933EC /* ChannelRoles.swift in Sources */, DDD5BB092C285DDC007E03CA /* AppLog.swift in Sources */, - BC5EBA3C2D002A2000C442FF /* MessageNodeIntent.swift in Sources */, DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */, 233E99C52D84A0B600CC3A77 /* CompactWidget.swift in Sources */, DDC1B81A2AB5377B00C71E39 /* MessagesTips.swift in Sources */, @@ -1608,7 +1602,6 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; @@ -1632,7 +1625,6 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.0; @@ -1682,6 +1674,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_USER_SCRIPT_SANDBOXING = NO; @@ -1746,6 +1739,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -1782,7 +1776,6 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Meshtastic/Preview Content\""; - DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = Meshtastic/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Meshtastic; @@ -1792,7 +1785,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.23; + MARKETING_VERSION = 2.6.0; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1816,7 +1809,6 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"Meshtastic/Preview Content\""; - DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = Meshtastic/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Meshtastic; @@ -1826,7 +1818,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.5.23; + MARKETING_VERSION = 2.6.0; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; @@ -1847,7 +1839,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Widgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Widgets; @@ -1858,7 +1849,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.23; + MARKETING_VERSION = 2.6.0; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1880,7 +1871,6 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = GCH7VS5Y9R; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Widgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Widgets; @@ -1891,7 +1881,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.5.23; + MARKETING_VERSION = 2.6.0; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme b/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme index 508a6cab..53ea5ca7 100644 --- a/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme +++ b/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme @@ -1,6 +1,6 @@ some IntentResult & ProvidesDialog { if !BLEManager.shared.isConnected { throw AppIntentErrors.AppIntentError.notConnected } - + let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) - + do { guard let fetchedNode = try PersistenceController.shared.container.viewContext.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity], fetchedNode.count == 1 else { throw $nodeNum.needsValueError("Could not find node") } - + let nodeInfo = fetchedNode[0] if let latitude = nodeInfo.latestPosition?.coordinate.latitude, let longitude = nodeInfo.latestPosition?.coordinate.longitude { - + let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") - + if let mapURL = url, UIApplication.shared.canOpenURL(mapURL) { // Request to continue in foreground before opening the app try await requestToContinueInForeground() - + // Open Apple Maps for navigation UIApplication.shared.open(mapURL, options: [:], completionHandler: nil) return .result(dialog: "Navigating to node location.") diff --git a/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift b/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift index 902a66cc..095112ff 100644 --- a/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift +++ b/Meshtastic/AppIntents/SaveChannelSettingsIntent.swift @@ -29,12 +29,9 @@ struct SaveChannelSettingsIntent: AppIntent { if channelUrl.absoluteString.lowercased().contains("meshtastic.org/e/#") { // Split the URL to get the portion after "#" let components = channelUrl.absoluteString.components(separatedBy: "#") - // Add channels flag based on the URL query parameter (if present) let addChannels = Bool(channelUrl["add"] ?? "false") ?? false - var channelSettings: String? - // Extract the Base64 encoded channel settings (after "#") if let lastComponent = components.last { channelSettings = lastComponent.components(separatedBy: "?").first // Ignore any query parameters @@ -44,7 +41,6 @@ struct SaveChannelSettingsIntent: AppIntent { if let channelSettings = channelSettings { // Call the BLEManager to save the channel settings let saveResult = BLEManager.shared.saveChannelSet(base64UrlString: channelSettings, addChannels: addChannels) - if !saveResult { throw AppIntentErrors.AppIntentError.message("Failed to save the channel settings.") } diff --git a/Meshtastic/Enums/AppSettingsEnums.swift b/Meshtastic/Enums/AppSettingsEnums.swift index b12a10a6..0d84269a 100644 --- a/Meshtastic/Enums/AppSettingsEnums.swift +++ b/Meshtastic/Enums/AppSettingsEnums.swift @@ -19,7 +19,7 @@ enum MeshMapTypes: Int, CaseIterable, Identifiable { var description: String { switch self { case .standard: - return "standard".localized + return "Standard".localized case .mutedStandard: return "standard.muted".localized case .hybrid: diff --git a/Meshtastic/Enums/CannedMessagesConfigEnums.swift b/Meshtastic/Enums/CannedMessagesConfigEnums.swift index f197eced..7209c8ed 100644 --- a/Meshtastic/Enums/CannedMessagesConfigEnums.swift +++ b/Meshtastic/Enums/CannedMessagesConfigEnums.swift @@ -19,11 +19,11 @@ enum ConfigPresets: Int, CaseIterable, Identifiable { switch self { case .unset: - return "canned.messages.preset.manual".localized + return "Manual Configuration".localized case .rakRotaryEncoder: - return "canned.messages.preset.rakrotary".localized + return "RAK Rotary Encoder".localized case .cardKB: - return "canned.messages.preset.cardkb".localized + return "M5 Stack Card KB / RAK Keypad".localized } } } diff --git a/Meshtastic/Enums/ChannelRoles.swift b/Meshtastic/Enums/ChannelRoles.swift index 186cff0b..ea1c0e8b 100644 --- a/Meshtastic/Enums/ChannelRoles.swift +++ b/Meshtastic/Enums/ChannelRoles.swift @@ -19,11 +19,11 @@ enum ChannelRoles: Int, CaseIterable, Identifiable { switch self { case .disabled: - return "channel.role.disabled".localized + return "Disabled".localized case .primary: - return "channel.role.primary".localized + return "Primary".localized case .secondary: - return "channel.role.secondary".localized + return "Secondary".localized } } func protoEnumValue() -> Channel.Role { diff --git a/Meshtastic/Enums/DeviceEnums.swift b/Meshtastic/Enums/DeviceEnums.swift index 4e0bdf27..5eb48564 100644 --- a/Meshtastic/Enums/DeviceEnums.swift +++ b/Meshtastic/Enums/DeviceEnums.swift @@ -144,7 +144,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable { case allSkipDecoding = 1 case localOnly = 2 case knownOnly = 3 - case corePortnums = 4 + case none = 4 + case corePortnums = 5 var id: Int { self.rawValue } @@ -158,6 +159,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable { return "Local Only" case .knownOnly: return "Known Only" + case .none: + return "None" case .corePortnums: return "Core Portnums Only" } @@ -172,6 +175,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable { return "Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels." case .knownOnly: return "Ignores observed messages from foreign meshes like Local Only, but takes it step further by also ignoring messages from nodes not already in the node's known list." + case .none: + return "Only permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role." case .corePortnums: return "Only rebroadcasts packets from the core portnums: NodeInfo, Text, Position, Telemetry, and Routing." } @@ -187,6 +192,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable { return Config.DeviceConfig.RebroadcastMode.localOnly case .knownOnly: return Config.DeviceConfig.RebroadcastMode.knownOnly + case .none: + return Config.DeviceConfig.RebroadcastMode.none case .corePortnums: return Config.DeviceConfig.RebroadcastMode.corePortnumsOnly } diff --git a/Meshtastic/Enums/IntervalEnums.swift b/Meshtastic/Enums/IntervalEnums.swift index 0f967f28..976c8c92 100644 --- a/Meshtastic/Enums/IntervalEnums.swift +++ b/Meshtastic/Enums/IntervalEnums.swift @@ -22,7 +22,7 @@ enum NagIntervals: Int, CaseIterable, Identifiable { var description: String { switch self { case .unset: - return "unset".localized + return "Unset".localized case .oneSecond: return "interval.one.second".localized case .fiveSeconds: @@ -59,7 +59,7 @@ enum OutputIntervals: Int, CaseIterable, Identifiable { switch self { case .unset: - return "unset".localized + return "Unset".localized case .oneSecond: return "interval.one.second".localized case .twoSeconds: diff --git a/Meshtastic/Enums/LoraConfigEnums.swift b/Meshtastic/Enums/LoraConfigEnums.swift index e6cd4dae..479d1fe7 100644 --- a/Meshtastic/Enums/LoraConfigEnums.swift +++ b/Meshtastic/Enums/LoraConfigEnums.swift @@ -291,9 +291,9 @@ enum ModemPresets: Int, CaseIterable, Identifiable { var description: String { switch self { case .longFast: - return "long.range.fast".localized + return "Long Range - Fast".localized case .longSlow: - return "long.range.slow".localized + return "Long Range - Slow".localized case .longModerate: return "long.range.moderate".localized case .vLongSlow: diff --git a/Meshtastic/Enums/PositionConfigEnums.swift b/Meshtastic/Enums/PositionConfigEnums.swift index 4853d050..6ee5059c 100644 --- a/Meshtastic/Enums/PositionConfigEnums.swift +++ b/Meshtastic/Enums/PositionConfigEnums.swift @@ -110,11 +110,11 @@ enum GpsMode: Int, CaseIterable, Equatable { var description: String { switch self { case .disabled: - return "gpsmode.disabled".localized + return "Disabled".localized case .enabled: - return "gpsmode.enabled".localized + return "Enabled".localized case .notPresent: - return "gpsmode.notPresent".localized + return "Not Present".localized } } func protoEnumValue() -> Config.PositionConfig.GpsMode { diff --git a/Meshtastic/Enums/SerialConfigEnums.swift b/Meshtastic/Enums/SerialConfigEnums.swift index ff937207..2d31725b 100644 --- a/Meshtastic/Enums/SerialConfigEnums.swift +++ b/Meshtastic/Enums/SerialConfigEnums.swift @@ -31,7 +31,7 @@ enum SerialBaudRates: Int, CaseIterable, Identifiable { switch self { case .baudDefault: - return "default".localized + return "Default".localized case .baud110: return "110 Baud" case .baud300: @@ -118,7 +118,7 @@ enum SerialModeTypes: Int, CaseIterable, Identifiable { var description: String { switch self { case .default: - return "serial.mode.default".localized + return "Default".localized case .simple: return "serial.mode.simple".localized case .proto: @@ -166,7 +166,7 @@ enum SerialTimeoutIntervals: Int, CaseIterable, Identifiable { var description: String { switch self { case .unset: - return "unset".localized + return "Unset".localized case .oneSecond: return "interval.one.second".localized case .fiveSeconds: diff --git a/Meshtastic/Export/CsvDocument.swift b/Meshtastic/Export/CsvDocument.swift index f4bb04ac..7133633e 100644 --- a/Meshtastic/Export/CsvDocument.swift +++ b/Meshtastic/Export/CsvDocument.swift @@ -20,13 +20,10 @@ struct CsvDocument: FileDocument { } init(configuration: ReadConfiguration) throws { - if let data = configuration.file.regularFileContents { - - csvData = String(decoding: data, as: UTF8.self) + csvData = String(data: data, encoding: .utf8) ?? "" } else { - throw CocoaError(.fileReadCorruptFile) } } diff --git a/Meshtastic/Export/WriteCsvFile.swift b/Meshtastic/Export/WriteCsvFile.swift index 66835b4a..badc6f9b 100644 --- a/Meshtastic/Export/WriteCsvFile.swift +++ b/Meshtastic/Export/WriteCsvFile.swift @@ -14,7 +14,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mma").replacingOccurrences(of: ",", with: "") if metricsType == 0 { // Create Device Metrics Header - csvString = "\("battery.level".localized), \("Voltage".localized), \("channel.utilization".localized), \("airtime".localized), \("uptime".localized), \("Timestamp".localized)" + csvString = "\("battery.level".localized), \("Voltage".localized), \("Channel Utilization".localized), \("airtime".localized), \("Uptime".localized), \("Timestamp".localized)" for dm in telemetry where dm.metricsType == 0 { csvString += "\n" csvString += dm.batteryLevel?.formatted(.number.grouping(.never)) ?? "" @@ -27,7 +27,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin csvString += ", " csvString += dm.uptimeSeconds?.formatted(.number.grouping(.never)) ?? "" csvString += ", " - csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } } else if metricsType == 1 { // Create Environment Telemetry Header @@ -44,7 +44,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin csvString += ", " csvString += dm.gasResistance?.formatted(.number.grouping(.never)) ?? "" csvString += ", " - csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } } else if metricsType == 2 { // Create Power Metrics Header @@ -63,7 +63,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin csvString += ", " csvString += dm.powerCh3Current?.formatted(.number.grouping(.never)) ?? "" csvString += ", " - csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } } return csvString @@ -121,7 +121,7 @@ func paxToCsvFile(pax: [PaxCounterEntity]) -> String { csvString += ", " csvString += String(p.uptime) csvString += ", " - csvString += p.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += p.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } return csvString } @@ -150,7 +150,7 @@ func positionToCsvFile(positions: [PositionEntity]) -> String { csvString += ", " csvString += String(pos.snr) csvString += ", " - csvString += pos.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized + csvString += pos.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized } return csvString } diff --git a/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift b/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift index a9eea507..4e05bcd6 100644 --- a/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift +++ b/Meshtastic/Extensions/CoreData/PositionEntityExtension.swift @@ -89,6 +89,6 @@ extension PositionEntity { extension PositionEntity: MKAnnotation { public var coordinate: CLLocationCoordinate2D { nodeCoordinate ?? LocationsHandler.DefaultLocation } - public var title: String? { nodePosition?.user?.shortName ?? "unknown".localized } + public var title: String? { nodePosition?.user?.shortName ?? "Unknown".localized } public var subtitle: String? { time?.formatted() } } diff --git a/Meshtastic/Extensions/Date.swift b/Meshtastic/Extensions/Date.swift index d8cdd30f..25bf034d 100644 --- a/Meshtastic/Extensions/Date.swift +++ b/Meshtastic/Extensions/Date.swift @@ -13,7 +13,7 @@ extension Date { if self.timeIntervalSince1970 > 0 && self < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { formatted() } else { - "unknown.age".localized + "Unknown Age".localized } } @@ -23,7 +23,7 @@ extension Date { if self.timeIntervalSince1970 > 0 && self < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { return dateformat.string(from: self) } else { - return "unknown.age".localized + return "Unknown Age".localized } } func relativeTimeOfDay() -> String { diff --git a/Meshtastic/Extensions/OSLogEntryLog.swift b/Meshtastic/Extensions/OSLogEntryLog.swift index fe2dc2cf..c60c7aca 100644 --- a/Meshtastic/Extensions/OSLogEntryLog.swift +++ b/Meshtastic/Extensions/OSLogEntryLog.swift @@ -18,7 +18,7 @@ extension OSLogEntryLog.Level { case .notice: "⚠️ Notice" case .error: "🚨 Error" case .fault: "💥 Fault" - @unknown default: "default" + @unknown default: "Default".localized } } var color: Color { diff --git a/Meshtastic/Extensions/UserDefaults.swift b/Meshtastic/Extensions/UserDefaults.swift index ac13f24b..e1ca67f9 100644 --- a/Meshtastic/Extensions/UserDefaults.swift +++ b/Meshtastic/Extensions/UserDefaults.swift @@ -72,6 +72,7 @@ extension UserDefaults { case firmwareVersion case environmentEnableWeatherKit case enableAdministration + case mapReportingOptIn case testIntEnum } @@ -148,6 +149,9 @@ extension UserDefaults { @UserDefault(.enableAdministration, defaultValue: false) static var enableAdministration: Bool + @UserDefault(.mapReportingOptIn, defaultValue: false) + static var mapReportingOptIn: Bool + @UserDefault(.testIntEnum, defaultValue: .one) static var testIntEnum: TestIntEnum } diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 9f633f30..63a4cc68 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -231,7 +231,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate cancelPeripheralConnection() if errorCode == 14 { // Peer removed pairing information // Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that - lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re pairing the radio.".localized, e.localizedDescription) + lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re pairing the radio.".localized, e.localizedDescription) Logger.services.error("🚨 [BLE] Failed to connect: \(peripheral.name ?? "Unknown".localized) Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)") } else { lastConnectionError = "🚨 \(e.localizedDescription)" @@ -261,7 +261,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate Notification( id: (peripheral.identifier.uuidString), title: "Radio Disconnected".localized, - subtitle: "\(peripheral.name ?? "unknown".localized)", + subtitle: "\(peripheral.name ?? "Unknown".localized)", content: e.localizedDescription, target: "bluetooth", path: "meshtastic:///bluetooth" @@ -273,7 +273,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)") } else if errorCode == 14 { // Peer removed pairing information // Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that - lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re-connecting to the radio.".localized, e.localizedDescription) + lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re-connecting to the radio.".localized, e.localizedDescription) Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized) Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)") } else { if UserDefaults.preferredPeripheralId == peripheral.identifier.uuidString { @@ -281,7 +281,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate Notification( id: (peripheral.identifier.uuidString), title: "Radio Disconnected".localized, - subtitle: "\(peripheral.name ?? "unknown".localized)", + subtitle: "\(peripheral.name ?? "Unknown".localized)", content: e.localizedDescription, target: "bluetooth", path: "meshtastic:///bluetooth" @@ -428,7 +428,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return 0 } - let messageDescription = "🛎️ [Device Metadata] Requested for node \(toUser.longName ?? "unknown".localized) by \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ [Device Metadata] Requested for node \(toUser.longName ?? "Unknown".localized) by \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -477,7 +477,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate traceRoute.node = receivingNode do { try context.save() - Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "unknown".localized), privacy: .public)") + Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "Unknown".localized), privacy: .public)") } catch { context.rollback() let nsError = error as NSError @@ -503,7 +503,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return } else { - let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized + let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized let logString = String.localizedStringWithFormat("mesh.log.wantconfig %@".localized, nodeName) Logger.mesh.info("🛎️ \(logString, privacy: .public)") // BLE Characteristics discovered, issue wantConfig @@ -579,7 +579,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if let error { - Logger.services.error("🚫 [BLE] didUpdateValueFor Characteristic error \(error.localizedDescription, privacy: .public)") let errorCode = (error as NSError).code if errorCode == 5 || errorCode == 15 { @@ -633,14 +632,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } catch { Logger.services.error("💥 \(error.localizedDescription, privacy: .public) \(characteristic.value!, privacy: .public)") } - // Publish mqttClientProxyMessages received on the from radio if decodedInfo.payloadVariant == FromRadio.OneOf_PayloadVariant.mqttClientProxyMessage(decodedInfo.mqttClientProxyMessage) { - let message = CocoaMQTTMessage( - topic: decodedInfo.mqttClientProxyMessage.topic, - payload: [UInt8](decodedInfo.mqttClientProxyMessage.data), - retained: decodedInfo.mqttClientProxyMessage.retained - ) + let message = CocoaMQTTMessage(topic: decodedInfo.mqttClientProxyMessage.topic, payload: [UInt8](decodedInfo.mqttClientProxyMessage.data), retained: decodedInfo.mqttClientProxyMessage.retained) mqttManager.mqttClientProxy?.publish(message) } else if decodedInfo.payloadVariant == FromRadio.OneOf_PayloadVariant.clientNotification(decodedInfo.clientNotification) { if decodedInfo.clientNotification.hasReplyID { @@ -686,8 +680,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if myInfo != nil { UserDefaults.preferredPeripheralNum = Int(myInfo?.myNodeNum ?? 0) connectedPeripheral.num = myInfo?.myNodeNum ?? 0 - connectedPeripheral.name = myInfo?.bleName ?? "unknown".localized - connectedPeripheral.longName = myInfo?.bleName ?? "unknown".localized + connectedPeripheral.name = myInfo?.bleName ?? "Unknown".localized + connectedPeripheral.longName = myInfo?.bleName ?? "Unknown".localized let newConnection = Int64(UserDefaults.preferredPeripheralNum) != Int64(decodedInfo.myInfo.myNodeNum) if newConnection { // Onboard a new device connection here @@ -702,7 +696,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if self.connectedPeripheral != nil && self.connectedPeripheral.num == nodeInfo.num { if nodeInfo.user != nil { connectedPeripheral.shortName = nodeInfo.user?.shortName ?? "?" - connectedPeripheral.longName = nodeInfo.user?.longName ?? "unknown".localized + connectedPeripheral.longName = nodeInfo.user?.longName ?? "Unknown".localized } } } @@ -782,13 +776,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate adminAppPacket(packet: decodedInfo.packet, context: context) case .replyApp: Logger.mesh.info("🕸️ MESH PACKET received for Reply App handling as a text message") - textMessageAppPacket( - packet: decodedInfo.packet, - wantRangeTestPackets: wantRangeTestPackets, - connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), - context: context, - appState: appState - ) + textMessageAppPacket(packet: decodedInfo.packet, wantRangeTestPackets: wantRangeTestPackets, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context, appState: appState) case .ipTunnelApp: Logger.mesh.info("🕸️ MESH PACKET received for IP Tunnel App UNHANDLED UNHANDLED") case .serialApp: @@ -873,13 +861,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } hopNodes.append(traceRouteHop) - let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized)) + let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "Unknown".localized)) let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : "" let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized routeString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> " } let destinationHop = TraceRouteHopEntity(context: context) - destinationHop.name = traceRoute?.node?.user?.longName ?? "unknown".localized + destinationHop.name = traceRoute?.node?.user?.longName ?? "Unknown".localized destinationHop.time = Date() // If nil, set to unknown, INT8_MIN (-128) then divide by 4 destinationHop.snr = Float(routingMessage.snrTowards.last ?? -128) / 4 @@ -892,14 +880,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } hopNodes.append(destinationHop) /// Add the destination node to the end of the route towards string and the beginning of the route back string - routeString += "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)" + routeString += "\(traceRoute?.node?.user?.longName ?? "Unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)" traceRoute?.routeText = routeString // Default to -1 only fill in if routeBack is valid below traceRoute?.hopsBack = -1 // Only if hopStart is set and there is an SNR entry if decodedInfo.packet.hopStart > 0 && routingMessage.snrBack.count > 0 { traceRoute?.hopsBack = Int32(routingMessage.routeBack.count) - var routeBackString = "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> " + var routeBackString = "\(traceRoute?.node?.user?.longName ?? "Unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> " for (index, node) in routingMessage.routeBack.enumerated() { var hopNode = getNodeInfo(id: Int64(node), context: context) if hopNode == nil && hopNode?.num ?? 0 > 0 && node != 4294967295 { @@ -930,7 +918,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } hopNodes.append(traceRouteHop) - let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized)) + let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "Unknown".localized)) let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : "" let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized routeBackString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> " @@ -950,7 +938,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate id: (UUID().uuidString), title: "Traceroute Complete", subtitle: "TR received back from \(destinationHop.name ?? "unknown")", - content: "Hops from: \(tr.hopsTowards), Hops back: \(tr.hopsBack)\n\(tr.routeText ?? "unknown".localized)\n\(tr.routeBackText ?? "unknown".localized)", + content: "Hops from: \(tr.hopsTowards), Hops back: \(tr.hopsBack)\n\(tr.routeText ?? "Unknown".localized)\n\(tr.routeBackText ?? "Unknown".localized)", target: "nodes", path: "meshtastic:///nodes?nodenum=\(connectedNode.user?.num ?? 0)" ) @@ -1069,7 +1057,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if preferredPeripheral != nil && preferredPeripheral?.peripheral != nil { connectTo(peripheral: preferredPeripheral!.peripheral) } - let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized + let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized let logString = String.localizedStringWithFormat("mesh.log.textmessage.send.failed %@".localized, nodeName) Logger.mesh.info("🚫 \(logString, privacy: .public)") @@ -1304,7 +1292,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Set Fixed Postion Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Set Fixed Postion Admin Message to: \(fromUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1329,7 +1317,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Remove Fixed Position Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Remove Fixed Position Admin Message to: \(fromUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1434,7 +1422,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1462,7 +1450,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1490,7 +1478,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return false } - let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1519,7 +1507,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return false } automaticallyReconnect = false - let messageDescription = "🚀 Sent enter DFU mode Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent enter DFU mode Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1547,7 +1535,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate return false } - let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1574,7 +1562,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)" + let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -1617,7 +1605,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🎛️ Requested Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🎛️ Requested Channel \(channel.index) for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1641,7 +1629,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Channel \(channel.index) for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1790,7 +1778,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } else { return 0 } - let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1972,7 +1960,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Ham Parameters for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Ham Parameters for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return Int64(meshPacket.id) } @@ -1998,7 +1986,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertBluetoothConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) @@ -2029,7 +2017,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertDeviceConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) return Int64(meshPacket.id) @@ -2059,7 +2047,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertDisplayConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) return Int64(meshPacket.id) @@ -2088,7 +2076,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.payload = adminData dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) @@ -2120,7 +2108,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertPositionConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2151,7 +2139,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertPowerConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2184,7 +2172,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertNetworkConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2217,7 +2205,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Security Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Security Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertSecurityConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2249,7 +2237,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertAmbientLightingModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2281,7 +2269,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2314,7 +2302,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { @@ -2347,7 +2335,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertDetectionSensorModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2378,7 +2366,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2409,7 +2397,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertPaxCounterModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2440,7 +2428,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertRtttlConfigPacket(ringtone: ringtone, nodeNum: toUser.num, context: context) @@ -2474,7 +2462,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertMqttModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2504,7 +2492,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertRangeTestModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) @@ -2537,7 +2525,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertSerialModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2568,7 +2556,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertStoreForwardModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2599,7 +2587,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.portnum = PortNum.adminApp meshPacket.decoded = dataMessage - let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "unknown".localized)" + let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { upsertTelemetryModuleConfigPacket(config: config, nodeNum: toUser.num, context: context) return Int64(meshPacket.id) @@ -2629,7 +2617,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(toUser.longName ?? "unknown".localized))" + let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(toUser.longName ?? "Unknown".localized))" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { @@ -2735,7 +2723,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Device Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Device Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true @@ -2765,7 +2753,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Display Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Display Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true @@ -2795,7 +2783,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested LoRa Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested LoRa Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { @@ -2826,7 +2814,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate dataMessage.wantResponse = true meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Network Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Network Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true @@ -2856,7 +2844,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Position Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Position Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2885,7 +2873,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Power Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Power Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2914,7 +2902,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Security Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Security Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2943,7 +2931,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Ambient Lighting Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Ambient Lighting Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -2972,7 +2960,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3001,7 +2989,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3030,7 +3018,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3059,7 +3047,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested RTTTL Ringtone Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested RTTTL Ringtone Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3088,7 +3076,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Range Test Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Range Test Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3146,7 +3134,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Detection Sensor Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Detection Sensor Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3175,7 +3163,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3204,7 +3192,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Store and Forward Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Store and Forward Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3234,7 +3222,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate meshPacket.decoded = dataMessage - let messageDescription = "🛎️ Requested Telemetry Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)" + let messageDescription = "🛎️ Requested Telemetry Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { return true } @@ -3448,7 +3436,7 @@ extension BLEManager: CBCentralManagerDelegate { case .unsupported: status = "BLE is unsupported" default: - status = "default" + status = "Default".localized } Logger.services.info("📜 [BLE] Bluetooth status: \(status, privacy: .public)") } diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 83f0b8ef..bcc4659b 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -625,7 +625,7 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana let routingError = RoutingError(rawValue: routingMessage.errorReason.rawValue) - let routingErrorString = routingError?.display ?? "unknown".localized + let routingErrorString = routingError?.display ?? "Unknown".localized let logString = String.localizedStringWithFormat("mesh.log.routing.message %@ %@".localized, String(packet.decoded.requestID), routingErrorString) Logger.mesh.info("🕸️ \(logString, privacy: .public)") @@ -686,20 +686,15 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManagedObjectContext) { if let telemetryMessage = try? Telemetry(serializedBytes: packet.decoded.payload) { - let logString = String.localizedStringWithFormat("mesh.log.telemetry.received %@".localized, String(packet.from)) Logger.mesh.info("📈 \(logString, privacy: .public)") - if telemetryMessage.variant != Telemetry.OneOf_Variant.deviceMetrics(telemetryMessage.deviceMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.environmentMetrics(telemetryMessage.environmentMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.localStats(telemetryMessage.localStats) && telemetryMessage.variant != Telemetry.OneOf_Variant.powerMetrics(telemetryMessage.powerMetrics) { /// Other unhandled telemetry packets return } - let telemetry = TelemetryEntity(context: context) - let fetchNodeTelemetryRequest = NodeInfoEntity.fetchRequest() fetchNodeTelemetryRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from)) - do { let fetchedNode = try context.fetch(fetchNodeTelemetryRequest) if fetchedNode.count == 1 { @@ -756,7 +751,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage Logger.statistics.info("📈 [Mesh Statistics] Channel Utilization: \(telemetryMessage.localStats.channelUtilization, privacy: .public) Airtime: \(telemetryMessage.localStats.airUtilTx, privacy: .public) Packets Sent: \(telemetryMessage.localStats.numPacketsTx, privacy: .public) Packets Received: \(telemetryMessage.localStats.numPacketsRx, privacy: .public) Bad Packets Received: \(telemetryMessage.localStats.numPacketsRxBad, privacy: .public) Nodes Online: \(telemetryMessage.localStats.numOnlineNodes, privacy: .public) of \(telemetryMessage.localStats.numTotalNodes, privacy: .public) nodes for Node: \(packet.from.toHex(), privacy: .public)") } else if telemetryMessage.variant == Telemetry.OneOf_Variant.powerMetrics(telemetryMessage.powerMetrics) { Logger.data.info("📈 [Power Metrics] Received for Node: \(packet.from.toHex(), privacy: .public)") - telemetry.powerCh1Voltage = telemetryMessage.powerMetrics.hasCh1Voltage.then(telemetryMessage.powerMetrics.ch1Voltage) telemetry.powerCh1Current = telemetryMessage.powerMetrics.hasCh1Current.then(telemetryMessage.powerMetrics.ch1Current) telemetry.powerCh2Voltage = telemetryMessage.powerMetrics.hasCh2Voltage.then(telemetryMessage.powerMetrics.ch2Voltage) @@ -764,7 +758,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage telemetry.powerCh3Voltage = telemetryMessage.powerMetrics.hasCh3Voltage.then(telemetryMessage.powerMetrics.ch3Voltage) telemetry.powerCh3Current = telemetryMessage.powerMetrics.hasCh3Current.then(telemetryMessage.powerMetrics.ch3Current) telemetry.metricsType = 2 - } telemetry.snr = packet.rxSnr telemetry.rssi = packet.rxRssi @@ -781,7 +774,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage fetchedNode[0].telemetries = mutableTelemetries.copy() as? NSOrderedSet } try context.save() - Logger.data.info("💾 [TelemetryEntity] of type \(MetricsTypes(rawValue: Int(telemetry.metricsType))?.name ?? "Unknown Metrics Type", privacy: .public) Saved for Node: \(packet.from.toHex(), privacy: .public)") if telemetry.metricsType == 0 { // Connected Device Metrics @@ -980,7 +972,7 @@ func textMessageAppPacket( manager.notifications = [ Notification( id: ("notification.id.\(newMessage.messageId)"), - title: "\(newMessage.fromUser?.longName ?? "unknown".localized)", + title: "\(newMessage.fromUser?.longName ?? "Unknown".localized)", subtitle: "AKA \(newMessage.fromUser?.shortName ?? "?")", content: messageText!, target: "messages", @@ -992,7 +984,7 @@ func textMessageAppPacket( ) ] manager.schedule() - Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)") + Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown".localized, privacy: .public)") } } else if newMessage.fromUser != nil && newMessage.toUser == nil { let fetchMyInfoRequest = MyInfoEntity.fetchRequest() @@ -1011,7 +1003,7 @@ func textMessageAppPacket( manager.notifications = [ Notification( id: ("notification.id.\(newMessage.messageId)"), - title: "\(newMessage.fromUser?.longName ?? "unknown".localized)", + title: "\(newMessage.fromUser?.longName ?? "Unknown".localized)", subtitle: "AKA \(newMessage.fromUser?.shortName ?? "?")", content: messageText!, target: "messages", @@ -1023,7 +1015,7 @@ func textMessageAppPacket( ) ] manager.schedule() - Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)") + Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown".localized, privacy: .public)") } } } diff --git a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift index 6dc1854b..cf21d92e 100644 --- a/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift +++ b/Meshtastic/Helpers/Mqtt/MqttClientProxyManager.swift @@ -43,18 +43,18 @@ class MqttClientProxyManager { let port = defaultServerPort let username = node.mqttConfig?.username let password = node.mqttConfig?.password - // if host == defaultServerAddress { - //username = ProcessInfo.processInfo.environment["PUBLIC_MQTT_USERNAME"] - //password = ProcessInfo.processInfo.environment["PUBLIC_MQTT_PASSWORD"] - // } let root = node.mqttConfig?.root?.count ?? 0 > 0 ? node.mqttConfig?.root : "msh" let prefix = root! topic = prefix + "/2/e" + "/#" - let qos = CocoaMQTTQoS(rawValue: UInt8(1))! - connect(host: host, port: port, useSsl: useSsl, username: username, password: password, topic: topic, qos: qos, cleanSession: true) + // Require opt in to map report terms to connect + if node.mqttConfig?.mapReportingEnabled ?? false && UserDefaults.mapReportingOptIn || !(node.mqttConfig?.mapReportingEnabled ?? false) { + connect(host: host, port: port, useSsl: useSsl, username: username, password: password, topic: topic) + } else { + delegate?.onMqttError(message: "MQTT Map Reporting Terms need to be accepted.") + } } } - func connect(host: String, port: Int, useSsl: Bool, username: String?, password: String?, topic: String?, qos: CocoaMQTTQoS, cleanSession: Bool) { + func connect(host: String, port: Int, useSsl: Bool, username: String?, password: String?, topic: String?) { guard !host.isEmpty else { delegate?.onMqttDisconnected() return @@ -67,7 +67,7 @@ class MqttClientProxyManager { mqttClient.username = username mqttClient.password = password mqttClient.keepAlive = 60 - mqttClient.cleanSession = cleanSession + mqttClient.cleanSession = true if debugLog { mqttClient.logLevel = .debug } diff --git a/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift b/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift index ab68c4cc..42e35ce0 100644 --- a/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift +++ b/Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift @@ -41,7 +41,6 @@ class MetricsChartSeries: ObservableObject { // Used for scaling the Y-axis let initialYAxisRange: ClosedRange? let minumumYAxisSpan: Float? - // Main initializer init( id: String, diff --git a/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift b/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift index fb68af92..1def5f47 100644 --- a/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift +++ b/Meshtastic/Model/Metrics Visualization/MetricsSeriesList.swift @@ -67,12 +67,12 @@ class MetricsSeriesList: ObservableObject, RandomAccessCollection, RangeReplacea for aSeries in self.visible { var seriesUpper = range[aSeries]?.upperBound ?? -.infinity var seriesLower = range[aSeries]?.lowerBound ?? .infinity - + if let value = aSeries.valueFor(te) { // Update the global bounds if value > globalUpper {globalUpper = value} if value < globalLower {globalLower = value} - + // Update the series bounds if necessary if value > seriesUpper || value < seriesLower { if value > seriesUpper { diff --git a/Meshtastic/Persistence/UpdateCoreData.swift b/Meshtastic/Persistence/UpdateCoreData.swift index e5e7bd87..b2673477 100644 --- a/Meshtastic/Persistence/UpdateCoreData.swift +++ b/Meshtastic/Persistence/UpdateCoreData.swift @@ -200,7 +200,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) Notification( id: (UUID().uuidString), title: "New Node".localized, - subtitle: "\(newUser.longName ?? "unknown".localized)", + subtitle: "\(newUser.longName ?? "Unknown".localized)", content: "New Node has been discovered".localized, target: "nodes", path: "meshtastic:///nodes?nodenum=\(newUser.num)" diff --git a/Meshtastic/Tips/MessagesTips.swift b/Meshtastic/Tips/MessagesTips.swift index ddbe9feb..a470dcaa 100644 --- a/Meshtastic/Tips/MessagesTips.swift +++ b/Meshtastic/Tips/MessagesTips.swift @@ -13,7 +13,7 @@ struct MessagesTip: Tip { return "tip.messages" } var title: Text { - Text("tip.messages.title") + Text("Messages") } var message: Text? { Text("tip.messages.message") diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 880faf8d..8e04f857 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -64,10 +64,10 @@ struct Connect: View { if node != nil { Text(connectedPeripheral.longName.addingVariationSelectors).font(.title2) } - Text("BLE Name").font(.callout)+Text(": \(bleManager.connectedPeripheral?.peripheral.name?.addingVariationSelectors ?? "unknown".localized)") + Text("BLE Name").font(.callout)+Text(": \(bleManager.connectedPeripheral?.peripheral.name?.addingVariationSelectors ?? "Unknown".localized)") .font(.callout).foregroundColor(Color.gray) if node != nil { - Text("firmware.version").font(.callout)+Text(": \(node?.metadata?.firmwareVersion ?? "unknown".localized)") + Text("Firmware Version").font(.callout)+Text(": \(node?.metadata?.firmwareVersion ?? "Unknown".localized)") .font(.callout).foregroundColor(Color.gray) } if bleManager.isSubscribed { @@ -121,7 +121,7 @@ struct Connect: View { #endif Text("Num: \(String(node!.num))") Text("Short Name: \(node?.user?.shortName ?? "?")") - Text("Long Name: \(node?.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Long Name: \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") Text("BLE RSSI: \(connectedPeripheral.rssi)") Button { diff --git a/Meshtastic/Views/Bluetooth/InvalidVersion.swift b/Meshtastic/Views/Bluetooth/InvalidVersion.swift index ba94e7c1..6a82581b 100644 --- a/Meshtastic/Views/Bluetooth/InvalidVersion.swift +++ b/Meshtastic/Views/Bluetooth/InvalidVersion.swift @@ -49,7 +49,7 @@ struct InvalidVersion: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) diff --git a/Meshtastic/Views/ContentView.swift b/Meshtastic/Views/ContentView.swift index 50734893..1c8a395d 100644 --- a/Meshtastic/Views/ContentView.swift +++ b/Meshtastic/Views/ContentView.swift @@ -25,7 +25,7 @@ struct ContentView: View { unreadDirectMessages: $appState.unreadDirectMessages ) .tabItem { - Label("messages", systemImage: "message") + Label("Messages", systemImage: "message") } .tag(NavigationState.Tab.messages) .badge(appState.totalUnreadMessages) @@ -54,7 +54,7 @@ struct ContentView: View { router: appState.router ) .tabItem { - Label("settings", systemImage: "gear") + Label("Settings", systemImage: "gear") .font(.title) } .tag(NavigationState.Tab.settings) diff --git a/Meshtastic/Views/Helpers/CircleText.swift b/Meshtastic/Views/Helpers/CircleText.swift index c9ee41c6..f85decf4 100644 --- a/Meshtastic/Views/Helpers/CircleText.swift +++ b/Meshtastic/Views/Helpers/CircleText.swift @@ -10,11 +10,11 @@ struct CircleText: View { var text: String var color: Color var circleSize: CGFloat = 45 - var node: NodeInfoEntity? = nil - + var node: NodeInfoEntity? + var body: some View { if let node = node { - NavigationStack{ + NavigationStack { NavigationLink(destination: NodeDetail(node: node)) { circleContent } diff --git a/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift b/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift index 42411cc1..a999dae0 100644 --- a/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift +++ b/Meshtastic/Views/Helpers/Compact Widgets/CompactWidget.swift @@ -31,7 +31,7 @@ import SwiftUI WeightCompactWidget(weight: "123", unit: "kg") SoilTemperatureCompactWidget(temperature: "23", unit: "°C") SoilMoistureCompactWidget(moisture: "23", unit: "%") - + let rain: Float = 10.1 let locale = NSLocale.current as NSLocale let usesMetricSystem = locale.usesMetricSystem // Returns true for metric (mm), false for imperial (inches) diff --git a/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift b/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift index b5cd7232..582a1c26 100644 --- a/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift +++ b/Meshtastic/Views/Helpers/Compact Widgets/RadiationCompactWidget.swift @@ -16,7 +16,7 @@ struct RadiationCompactWidget: View { HStack(alignment: .firstTextBaseline) { Text(verbatim: "☢") .font(.system(size: 30, design: .monospaced)) - .foregroundColor(.accentColor) + .tint(.accentColor) Text("Radiation") .textCase(.uppercase) .font(.callout) diff --git a/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift b/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift index 4918c7b6..3cac48bf 100644 --- a/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift +++ b/Meshtastic/Views/Helpers/Compact Widgets/WeatherConditionsCompactWidget.swift @@ -39,4 +39,3 @@ struct WeatherConditionsCompactWidget: View { } } } - diff --git a/Meshtastic/Views/Helpers/DateTimeText.swift b/Meshtastic/Views/Helpers/DateTimeText.swift index 517772fe..38e386f3 100644 --- a/Meshtastic/Views/Helpers/DateTimeText.swift +++ b/Meshtastic/Views/Helpers/DateTimeText.swift @@ -24,7 +24,7 @@ struct DateTimeText: View { if dateTime != nil && dateTime! >= sixMonthsAgo! { Text(" \(dateTime!.formattedDate(format: dateFormatString))") } else { - Text("unknown.age") + Text("Unknown Age") } } } diff --git a/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift b/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift index fd0f0414..1b9263c5 100644 --- a/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift +++ b/Meshtastic/Views/Helpers/Help/DirectMessagesHelp.swift @@ -50,7 +50,7 @@ struct DirectMessagesHelp: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Helpers/MQTTIcon.swift b/Meshtastic/Views/Helpers/MQTTIcon.swift index 914c6043..7d6c653a 100644 --- a/Meshtastic/Views/Helpers/MQTTIcon.swift +++ b/Meshtastic/Views/Helpers/MQTTIcon.swift @@ -29,7 +29,7 @@ struct MQTTIcon: View { VStack(spacing: 0.5) { Text("Topic: \(topic)".localized) .padding(20) - Button("close", action: { self.isPopoverOpen = false }).padding([.bottom], 20) + Button("Close", action: { self.isPopoverOpen = false }).padding([.bottom], 20) } .presentationCompactAdaptation(.popover) }) diff --git a/Meshtastic/Views/Helpers/PowerMetrics.swift b/Meshtastic/Views/Helpers/PowerMetrics.swift index 7f9fdcdd..e85c0f6a 100644 --- a/Meshtastic/Views/Helpers/PowerMetrics.swift +++ b/Meshtastic/Views/Helpers/PowerMetrics.swift @@ -69,8 +69,8 @@ struct PowerMetrics: View { } enum PowerMetricType: String { - case current = "current" - case voltage = "voltage" + case current = "Current" + case voltage = "Voltage" } struct PowerMetricCompactWidget: View { diff --git a/Meshtastic/Views/Messages/ChannelList.swift b/Meshtastic/Views/Messages/ChannelList.swift index 426cb0c7..f4194dc3 100644 --- a/Meshtastic/Views/Messages/ChannelList.swift +++ b/Meshtastic/Views/Messages/ChannelList.swift @@ -154,6 +154,6 @@ struct ChannelList: View { .listStyle(.plain) } } - .navigationTitle("channels") + .navigationTitle("Channels") } } diff --git a/Meshtastic/Views/Messages/ChannelMessageList.swift b/Meshtastic/Views/Messages/ChannelMessageList.swift index 59d68e9e..6093d9eb 100644 --- a/Meshtastic/Views/Messages/ChannelMessageList.swift +++ b/Meshtastic/Views/Messages/ChannelMessageList.swift @@ -14,19 +14,16 @@ struct ChannelMessageList: View { @EnvironmentObject var appState: AppState @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager - // Keyboard State @FocusState var messageFieldFocused: Bool - @ObservedObject var myInfo: MyInfoEntity @ObservedObject var channel: ChannelEntity @State private var replyMessageId: Int64 = 0 @AppStorage("preferredPeripheralNum") private var preferredPeripheralNum = -1 - // Scroll state - @State private var showScrollToBottomButton = false - @State private var hasReachedBottom = false - @State private var gotFirstUnreadMessage: Bool = false + @State private var showScrollToBottomButton = false + @State private var hasReachedBottom = false + @State private var gotFirstUnreadMessage: Bool = false @State private var messageToHighlight: Int64 = 0 @@ -82,7 +79,7 @@ struct ChannelMessageList: View { let isDetectionSensorMessage = message.portNum == Int32(PortNum.detectionSensorApp.rawValue) if !currentUser && message.fromUser != nil { - Text("\(message.fromUser?.longName ?? "unknown".localized ) (\(message.fromUser?.userId ?? "?"))") + Text("\(message.fromUser?.longName ?? "Unknown".localized ) (\(message.fromUser?.userId ?? "?"))") .font(.caption) .foregroundColor(.gray) .offset(y: 8) @@ -143,7 +140,7 @@ struct ChannelMessageList: View { .frame(maxWidth: .infinity) .id(message.messageId) .onAppear { - if gotFirstUnreadMessage{ + if gotFirstUnreadMessage { if !message.read { message.read = true do { @@ -209,7 +206,6 @@ struct ChannelMessageList: View { showScrollToBottomButton = true } } - // Scroll to bottom button if showScrollToBottomButton { Button { @@ -241,7 +237,7 @@ struct ChannelMessageList: View { ToolbarItem(placement: .principal) { HStack { CircleText(text: String(channel.index), color: .accentColor, circleSize: 44).fixedSize() - Text(String(channel.name ?? "unknown".localized).camelCaseToWords()).font(.headline) + Text(String(channel.name ?? "Unknown".localized).camelCaseToWords()).font(.headline) } } ToolbarItem(placement: .navigationBarTrailing) { diff --git a/Meshtastic/Views/Messages/MessageText.swift b/Meshtastic/Views/Messages/MessageText.swift index 002d2c4c..c8a994c3 100644 --- a/Meshtastic/Views/Messages/MessageText.swift +++ b/Meshtastic/Views/Messages/MessageText.swift @@ -73,7 +73,6 @@ struct MessageText: View { } else { EmptyView() } - } .contextMenu { MessageContextMenuItems( diff --git a/Meshtastic/Views/Messages/Messages.swift b/Meshtastic/Views/Messages/Messages.swift index 1267d3e2..6142617b 100644 --- a/Meshtastic/Views/Messages/Messages.swift +++ b/Meshtastic/Views/Messages/Messages.swift @@ -35,7 +35,7 @@ struct Messages: View { List(selection: $router.navigationState.messages) { NavigationLink(value: MessagesNavigationState.channels()) { Label { - Text("channels") + Text("Channels") .badge(unreadChannelMessages) .font(.title2) .padding() diff --git a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift index e6d7a15b..a9e9c993 100644 --- a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift +++ b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift @@ -43,6 +43,21 @@ struct TextMessageField: View { } } + ZStack { + TextField("message", text: $typingMessage, axis: .vertical) + .onChange(of: typingMessage) { _, value in + totalBytes = value.utf8.count + // Only mess with the value if it is too big + while totalBytes > Self.maxbytes { + typingMessage = String(typingMessage.dropLast()) + totalBytes = typingMessage.utf8.count + } + } + } + Text("Replying to a message") + + } + } ZStack { TextField("message", text: $typingMessage, axis: .vertical) .onChange(of: typingMessage) { _, value in diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index b0602d5f..2888a54e 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -93,7 +93,7 @@ struct UserList: View { Image(systemName: "lock.open.fill") .foregroundColor(.yellow) } - Text(user.longName ?? "unknown".localized) + Text(user.longName ?? "Unknown".localized) .font(.headline) .allowsTightening(true) Spacer() diff --git a/Meshtastic/Views/Messages/UserMessageList.swift b/Meshtastic/Views/Messages/UserMessageList.swift index e1861240..686decaf 100644 --- a/Meshtastic/Views/Messages/UserMessageList.swift +++ b/Meshtastic/Views/Messages/UserMessageList.swift @@ -20,7 +20,6 @@ struct UserMessageList: View { // View State Items @ObservedObject var user: UserEntity @State private var replyMessageId: Int64 = 0 - // Scroll state @State private var showScrollToBottomButton = false @State private var hasReachedBottom = false @@ -195,7 +194,6 @@ struct UserMessageList: View { showScrollToBottomButton = true } } - // Scroll to bottom button if showScrollToBottomButton { Button { diff --git a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift index 9ebce292..0d739c49 100644 --- a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift +++ b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift @@ -121,7 +121,7 @@ struct DeviceMetricsLog: View { Table(deviceMetrics, selection: $selection, sortOrder: $sortOrder) { TableColumn("Battery Level") { dm in HStack { - Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized) + Text(dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized) .font(.caption) .fontWeight(.semibold) Spacer() @@ -165,7 +165,7 @@ struct DeviceMetricsLog: View { // dm.voltage.map { Text("\(String(format: "%.2f", $0))") } ?? Text("--") Text("\(dm.voltage?.formatted(.number.precision(.fractionLength(2))) ?? Constants.nilValueIndicator)") } - TableColumn("channel.utilization") { dm in + TableColumn("Channel Utilization") { dm in dm.channelUtilization.map { channelUtilization in // Text("\(String(format: "%.2f", channelUtilization))%") Text("\(channelUtilization.formatted(.number.precision(.fractionLength(2))))%") @@ -188,7 +188,7 @@ struct DeviceMetricsLog: View { } .width(min: 100) TableColumn("Timestamp") { dm in - Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized) + Text(dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized) } .width(min: 180) } diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift index 127a31d7..c5495c10 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/DeleteNodeButton.swift @@ -49,7 +49,7 @@ struct DeleteNodeButton: View { connectedNodeNum: connectedNode.num ) if !success { - Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "unknown".localized, privacy: .public)") + Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "Unknown".localized, privacy: .public)") } else { dismiss() } diff --git a/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift b/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift index 78917082..403d1b98 100644 --- a/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift +++ b/Meshtastic/Views/Nodes/Helpers/Actions/NavigateToButton.swift @@ -14,45 +14,43 @@ struct NavigateToButton: View { var node: NodeInfoEntity var body: some View { - Button { - guard let userNum = node.user?.num else { - Logger.services.error("NavigateToAction: Selected node does not exist") + Button { + guard let userNum = node.user?.num else { + Logger.services.error("NavigateToAction: Selected node does not exist") + return + } + Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum, privacy: .public)") + + let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") + fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(userNum)) + + do { + let fetchedNodes = try PersistenceController.shared.container.viewContext.fetch(fetchRequest) + guard let nodeInfo = fetchedNodes.first else { + Logger.services.error("NavigateToAction: Node with userNum \(userNum, privacy: .public) not found in Core Data") return } - - Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum, privacy: .public)") - - let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") - fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(userNum)) - - do { - let fetchedNodes = try PersistenceController.shared.container.viewContext.fetch(fetchRequest) - - guard let nodeInfo = fetchedNodes.first else { - Logger.services.error("NavigateToAction: Node with userNum \(userNum, privacy: .public) not found in Core Data") - return - } - if let latitude = nodeInfo.latestPosition?.latitude, - let longitude = nodeInfo.latestPosition?.longitude { - if let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") { - UIApplication.shared.open(url, options: [:], completionHandler: nil) - } else { - Logger.services.error("Failed to create URL for navigation") - } + if let latitude = nodeInfo.latestPosition?.latitude, + let longitude = nodeInfo.latestPosition?.longitude { + if let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") { + UIApplication.shared.open(url, options: [:], completionHandler: nil) } else { - Logger.services.warning("NavigateToAction: Node \(userNum, privacy: .public) has invalid or missing coordinates") + Logger.services.error("Failed to create URL for navigation") } - } catch { - Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum, privacy: .public): \(error.localizedDescription, privacy: .public)") - } - } label: { - Label { - Text("Navigate to node") - } icon: { - Image(systemName: "map") - .symbolRenderingMode(.hierarchical) + } else { + Logger.services.warning("NavigateToAction: Node \(userNum, privacy: .public) has invalid or missing coordinates") } + } catch { + Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum, privacy: .public): \(error.localizedDescription, privacy: .public)") + } + } label: { + Label { + Text("Navigate to node") + } icon: { + Image(systemName: "map") + .symbolRenderingMode(.hierarchical) } } + } } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift index 088787b9..85db444a 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift @@ -111,7 +111,7 @@ Spacer() Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift index 36d9a915..f5a2f84c 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift @@ -189,7 +189,7 @@ struct NodeMapSwiftUI: View { UIApplication.shared.isIdleTimerDisabled = false } }} - .navigationBarTitle(String((node.user?.shortName ?? "unknown".localized) + (" \(node.positions?.count ?? 0) points")), displayMode: .inline) + .navigationBarTitle(String((node.user?.shortName ?? "Unknown".localized) + (" \(node.positions?.count ?? 0) points")), displayMode: .inline) .navigationBarItems(trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift index 880a4074..97df2327 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift @@ -23,7 +23,7 @@ struct PositionPopover: View { var body: some View { // Node Color from node.num let nodeColor = UIColor(hex: UInt32(position.nodePosition?.num ?? 0)) - NavigationStack{ + NavigationStack { VStack { HStack { ZStack { @@ -105,7 +105,6 @@ struct PositionPopover: View { .foregroundColor(.primary) .font(idiom == .phone ? .callout : .body) } - } icon: { Image(systemName: "mountain.2.fill") .symbolRenderingMode(.hierarchical) @@ -180,7 +179,6 @@ struct PositionPopover: View { } .padding(.bottom, 5) if position.nodePosition?.viaMqtt ?? false { - Label { Text("MQTT") .font(idiom == .phone ? .callout : .body) @@ -234,7 +232,7 @@ struct PositionPopover: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift b/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift index 8c8feb32..736c2114 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/WaypointForm.swift @@ -338,7 +338,7 @@ struct WaypointForm: View { if LocationsHandler.currentLocation.distance(from: LocationsHandler.DefaultLocation) > 0.0 { let metersAway = waypoint.coordinate.distance(from: LocationsHandler.currentLocation) Label { - Text("distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))") + Text("Distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))") .foregroundColor(.primary) } icon: { Image(systemName: "lines.measurement.horizontal") @@ -354,7 +354,7 @@ struct WaypointForm: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift index ffd86987..0f14331d 100644 --- a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift +++ b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultColumns.swift @@ -220,7 +220,6 @@ extension MetricsColumnList { ) } ?? Text(Constants.nilValueIndicator) }), - // Rainfall 24-hour MetricsTableColumn( id: "rainfall24H", @@ -334,7 +333,7 @@ extension MetricsColumnList { .replacingOccurrences(of: ",", with: "") Text( time?.formattedDate(format: dateFormatString) - ?? "unknown.age".localized + ?? "Unknown Age".localized ) }) ]) diff --git a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift index d3762845..b2590b51 100644 --- a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift +++ b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift @@ -80,7 +80,7 @@ extension MetricsSeriesList { .alignsMarkStylesWithPlotArea() } }), - + // Barometric Pressure Series Configuration MetricsChartSeries( id: "barometricPressure", @@ -106,7 +106,7 @@ extension MetricsSeriesList { .alignsMarkStylesWithPlotArea() } }), - + // Indoor Air Quality Series Configuration MetricsChartSeries( id: "iaq", @@ -134,7 +134,7 @@ extension MetricsSeriesList { .alignsMarkStylesWithPlotArea() } }), - + // Lux MetricsChartSeries( id: "lux", @@ -460,7 +460,7 @@ extension MetricsSeriesList { .lineStyle(StrokeStyle(lineWidth: 4)) .alignsMarkStylesWithPlotArea() } - }), + }) ]) } } diff --git a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift index 1f384cb2..24cc6f96 100644 --- a/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/Metrics Columns/MetricsColumnDetail.swift @@ -63,7 +63,7 @@ struct MetricsColumnDetail: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift index 10c0b569..43cb0d5a 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift @@ -120,14 +120,14 @@ struct NodeDetail: View { if let metadata = node.metadata { HStack { Label { - Text("firmware.version") + Text("Firmware Version") } icon: { Image(systemName: "memorychip") .symbolRenderingMode(.multicolor) } Spacer() - Text(metadata.firmwareVersion ?? "unknown".localized) + Text(metadata.firmwareVersion ?? "Unknown".localized) } } @@ -147,7 +147,7 @@ struct NodeDetail: View { if let dm = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")).lastObject as? TelemetryEntity, let uptimeSeconds = dm.uptimeSeconds { HStack { Label { - Text("\("uptime".localized)") + Text("\("Uptime".localized)") } icon: { Image(systemName: "checkmark.circle.fill") .foregroundColor(.green) @@ -195,7 +195,7 @@ struct NodeDetail: View { Spacer() if dateFormatRelative, let text = Self.relativeFormatter.string(for: lastHeard) { - if lastHeard.formatted() != "unknown.age".localized { + if lastHeard.formatted() != "Unknown Age".localized { Text(text) .textSelection(.enabled) } @@ -214,7 +214,7 @@ struct NodeDetail: View { // to use with WeatherKit, or has actual data in the most recent EnvironmentMetrics entity // that will be rendered in this section. if node.hasPositions && UserDefaults.environmentEnableWeatherKit - || node.hasDataForLatestEnvironmentMetrics(attributes: ["iaq", "temperature", "relativeHumidity", "barometricPressure", "windSpeed", "radiation", "weight", "distance", "soilTemperature", "soilMoisture"]) { + || node.hasDataForLatestEnvironmentMetrics(attributes: ["iaq", "temperature", "relativeHumidity", "barometricPressure", "windSpeed", "radiation", "weight", "Distance", "soilTemperature", "soilMoisture"]) { Section("Environment") { if !node.hasEnvironmentMetrics { LocalWeatherConditions(location: node.latestPosition?.nodeLocation) @@ -520,7 +520,7 @@ struct NodeDetail: View { } } .listStyle(.insetGrouped) - .navigationBarTitle(String(node.user?.longName?.addingVariationSelectors ?? "unknown".localized), displayMode: .inline) + .navigationBarTitle(String(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized), displayMode: .inline) } } } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift index 6a8f468a..07f3d92c 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeInfoItem.swift @@ -74,7 +74,7 @@ struct NodeInfoItem: View { } Spacer() if user.hwModel != "UNSET" { - Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized))) + Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "Unset".localized))) } else { Text(String("incomplete".localized)) } diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift index a29a0749..063e073a 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListFilter.swift @@ -192,7 +192,7 @@ struct NodeListFilter: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift index cabfabc6..c01d86de 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeListItem.swift @@ -64,7 +64,7 @@ struct NodeListItem: View { let (image, color) = userKeyStatus IconAndText(systemName: image, imageColor: color, - text: node.user?.longName?.addingVariationSelectors ?? "unknown".localized, + text: node.user?.longName?.addingVariationSelectors ?? "Unknown".localized, textColor: .primary) if node.favorite { Spacer() @@ -77,14 +77,14 @@ struct NodeListItem: View { imageColor: .green, text: "connected".localized) } - if node.lastHeard?.timeIntervalSince1970 ?? 0 > 0 && node.lastHeard! < Calendar.current.date(byAdding: .year, value: 1, to: Date())!{ + if node.lastHeard?.timeIntervalSince1970 ?? 0 > 0 && node.lastHeard! < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { IconAndText(systemName: node.isOnline ? "checkmark.circle.fill" : "moon.circle.fill", imageColor: node.isOnline ? .green : .orange, - text: node.lastHeard?.formatted() ?? "unknown.age".localized) + text: node.lastHeard?.formatted() ?? "Unknown Age".localized) } let role = DeviceRoles(rawValue: Int(node.user?.role ?? 0)) IconAndText(systemName: role?.systemName ?? "figure", - text: "Role: \(role?.name ?? "unknown".localized)") + text: "Role: \(role?.name ?? "Unknown".localized)") if node.isStoreForwardRouter { IconAndText(systemName: "envelope.arrow.triangle.branch", renderingMode: .multicolor, diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 49b2d3a1..b4713dbd 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -65,10 +65,7 @@ struct NodeList: View { var nodes: FetchedResults var connectedNode: NodeInfoEntity? { - getNodeInfo( - id: bleManager.connectedPeripheral?.num ?? 0, - context: context - ) + getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context) } @ViewBuilder @@ -78,19 +75,11 @@ struct NodeList: View { ) -> some View { /// Allow users to mute notifications for a node even if they are not connected if let user = node.user { - NodeAlertsButton( - context: context, - node: node, - user: user - ) + NodeAlertsButton(context: context, node: node, user: user) } if let connectedNode { /// Favoriting a node requires being connected - FavoriteNodeButton( - bleManager: bleManager, - context: context, - node: node - ) + FavoriteNodeButton(bleManager: bleManager, context: context, node: node) /// Don't show message, trace route, position exchange or delete context menu items for the connected node if connectedNode.num != node.num { if !node.viaMqtt || node.viaMqtt && node.hopsAway == 0 { @@ -237,7 +226,7 @@ struct NodeList: View { if deleteNode != nil { let success = bleManager.removeNode(node: deleteNode!, connectedNodeNum: Int64(bleManager.connectedPeripheral?.num ?? -1)) if !success { - Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "unknown".localized, privacy: .public)") + Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "Unknown".localized, privacy: .public)") } } } diff --git a/Meshtastic/Views/Nodes/NodeMap.swift b/Meshtastic/Views/Nodes/NodeMap.swift deleted file mode 100644 index e81fc224..00000000 --- a/Meshtastic/Views/Nodes/NodeMap.swift +++ /dev/null @@ -1,233 +0,0 @@ -//// -//// NodeMap.swift -//// MeshtasticApple -//// -//// Created by Garth Vander Houwen on 8/7/21. -//// -// -//import SwiftUI -//import MapKit -//import CoreLocation -//import CoreData -// -//struct NodeMap: View { -// @Environment(\.managedObjectContext) var context -// @EnvironmentObject var bleManager: BLEManager -// -// @ObservedObject -// var router: Router -// @State var selectedMapLayer: MapLayer = UserDefaults.mapLayer -// @State var enableMapRecentering: Bool = UserDefaults.enableMapRecentering -// @State var enableMapRouteLines: Bool = UserDefaults.enableMapRouteLines -// @State var enableMapNodeHistoryPins: Bool = UserDefaults.enableMapNodeHistoryPins -// @State var enableOfflineMaps: Bool = UserDefaults.enableOfflineMaps -// @State var selectedTileServer: MapTileServer = UserDefaults.mapTileServer -// @State var enableOverlayServer: Bool = UserDefaults.enableOverlayServer -// @State var selectedOverlayServer: MapOverlayServer = UserDefaults.mapOverlayServer -// @State var mapTilesAboveLabels: Bool = UserDefaults.mapTilesAboveLabels -// let fromDate: NSDate = Calendar.current.date(byAdding: .month, value: -1, to: Date())! as NSDate -// @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "time", ascending: true)], -// predicate: NSPredicate(format: "nodePosition != nil", Calendar.current.date(byAdding: .day, value: -7, to: Date())! as NSDate), animation: .none) -// private var positions: FetchedResults -// @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "name", ascending: false)], -// predicate: NSPredicate( -// format: "expire == nil || expire >= %@", Date() as NSDate -// ), animation: .none) -// private var waypoints: FetchedResults -// @State var waypointCoordinate: WaypointCoordinate? -// @State var selectedTracking: UserTrackingModes = .none -// @State var isPresentingInfoSheet: Bool = false -// @State private var customMapOverlay: MapViewSwiftUI.CustomMapOverlay? = MapViewSwiftUI.CustomMapOverlay( -// mapName: "offlinemap", -// tileType: "png", -// canReplaceMapContent: true -// ) -// var body: some View { -// NavigationStack { -// ZStack { -// MapViewSwiftUI( -// onLongPress: { coord in -// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: coord, waypointId: 0) -// }, onWaypointEdit: { wpId in -// if wpId > 0 { -// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: nil, waypointId: Int64(wpId)) -// } -// }, -// selectedMapLayer: selectedMapLayer, -// positions: Array(positions), -// waypoints: Array(waypoints), -// userTrackingMode: selectedTracking.MKUserTrackingModeValue(), -// showNodeHistory: enableMapNodeHistoryPins, -// showRouteLines: enableMapRouteLines, -// customMapOverlay: self.customMapOverlay -// ) -// VStack(alignment: .trailing) { -// HStack(alignment: .top) { -// Spacer() -// MapButtons(tracking: $selectedTracking, isPresentingInfoSheet: $isPresentingInfoSheet) -// .padding(.trailing, 8) -// .padding(.top, 16) -// } -// Spacer() -// TileDownloadStatus() -// .padding(.trailing, 16) -// .padding(.bottom, 20) -// } -// } -// .ignoresSafeArea(.all, edges: [.top, .leading, .trailing]) -// .frame(maxHeight: .infinity) -// .sheet(item: $waypointCoordinate, content: { wpc in -// WaypointFormMapKit(coordinate: wpc) -// .presentationDetents([.medium, .large]) -// .presentationDragIndicator(.automatic) -// }) -// .sheet(isPresented: $isPresentingInfoSheet) { -// VStack { -// Form { -// Section(header: Text("Map Options")) { -// Picker(selection: $selectedMapLayer, label: Text("")) { -// ForEach(MapLayer.allCases, id: \.self) { layer in -// if layer == MapLayer.offline && enableOfflineMaps { -// Text(layer.localized) -// } else if layer != MapLayer.offline { -// Text(layer.localized) -// } -// } -// } -// .pickerStyle(SegmentedPickerStyle()) -// .onChange(of: selectedMapLayer) { _, newMapLayer in -// UserDefaults.mapLayer = newMapLayer -// } -// .padding(.top, 5) -// .padding(.bottom, 5) -// Toggle(isOn: $enableMapRecentering) { -// Label("map.recentering", systemImage: "camera.metering.center.weighted") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableMapRecentering.toggle() -// UserDefaults.enableMapRecentering = self.enableMapRecentering -// } -// Toggle(isOn: $enableMapNodeHistoryPins) { -// Label("Show Node History", systemImage: "building.columns.fill") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableMapNodeHistoryPins.toggle() -// UserDefaults.enableMapNodeHistoryPins = self.enableMapNodeHistoryPins -// } -// Toggle(isOn: $enableMapRouteLines) { -// Label("Show Route Lines", systemImage: "road.lanes") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableMapRouteLines.toggle() -// UserDefaults.enableMapRouteLines = self.enableMapRouteLines -// } -// let locale = Locale.current -// if locale.region?.identifier ?? "no locale" == "US" { -// Toggle(isOn: $enableOverlayServer) { -// Label("Show Weather", systemImage: "cloud.fill") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.enableOverlayServer.toggle() -// UserDefaults.enableOverlayServer = self.enableOverlayServer -// } -// if enableOverlayServer { -// Picker(selection: $selectedOverlayServer, -// label: Text("Radar")) { -// ForEach(MapOverlayServer.allCases, id: \.self) { mos in -// Text(mos.description) -// .font(.footnote) -// } -// } -// .pickerStyle(DefaultPickerStyle()) -// .onChange(of: (selectedOverlayServer)) { _, newSelectedOverlayServer in -// UserDefaults.mapOverlayServer = newSelectedOverlayServer -// } -// Text(LocalizedStringKey(selectedOverlayServer.attribution)) -// .font(.footnote) -// .foregroundColor(.gray) -// .padding(0) -// } -// } -// } -// Section(header: Text("Offline Maps")) { -// Toggle(isOn: $enableOfflineMaps) { -// Text("Enable Offline Maps") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onChange(of: enableOfflineMaps) { _, newEnableOfflineMaps in -// UserDefaults.enableOfflineMaps = newEnableOfflineMaps -// if !enableOfflineMaps { -// if self.selectedMapLayer == .offline { -// self.selectedMapLayer = .standard -// } -// } -// } -// if enableOfflineMaps { -// VStack(alignment: .leading) { -// Picker(selection: $selectedTileServer, -// label: Text("Tile Server")) { -// ForEach(MapTileServer.allCases, id: \.self) { tsl in -// Text(tsl.description) -// } -// } -// .pickerStyle(DefaultPickerStyle()) -// .onChange(of: (selectedTileServer)) { _, newSelectedTileServer in -// UserDefaults.mapTileServer = newSelectedTileServer -// } -// Text("Attribution:") -// .fontWeight(.semibold) -// .font(.footnote) -// Text(LocalizedStringKey(selectedTileServer.attribution)) -// .font(.footnote) -// .foregroundColor(.gray) -// .padding(0) -// Divider() -// Toggle(isOn: $mapTilesAboveLabels) { -// Text("Tiles above Labels") -// } -// .toggleStyle(SwitchToggleStyle(tint: .accentColor)) -// .onTapGesture { -// self.mapTilesAboveLabels.toggle() -// UserDefaults.mapTilesAboveLabels = self.mapTilesAboveLabels -// } -// } -// } -// } -// } -// #if targetEnvironment(macCatalyst) -// Button { -// isPresentingInfoSheet = false -// } label: { -// Label("close", systemImage: "xmark") -// } -// .buttonStyle(.bordered) -// .buttonBorderShape(.capsule) -// .controlSize(.large) -// .padding(.bottom) -// #endif -// } -// .presentationDetents([enableOfflineMaps || enableOverlayServer ? .large : .medium]) -// .presentationDragIndicator(.visible) -// } -// } -// .navigationBarItems(leading: -// MeshtasticLogo(), trailing: -// ZStack { -// ConnectedDevice( -// bluetoothOn: bleManager.isSwitchedOn, -// deviceConnected: bleManager.connectedPeripheral != nil, -// name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : -// "?") -// }) -// .onAppear(perform: { -// UIApplication.shared.isIdleTimerDisabled = true -// }) -// .onDisappear(perform: { -// UIApplication.shared.isIdleTimerDisabled = false -// }) -// } -//} diff --git a/Meshtastic/Views/Nodes/PaxCounterLog.swift b/Meshtastic/Views/Nodes/PaxCounterLog.swift index 37ca7c30..ff579eca 100644 --- a/Meshtastic/Views/Nodes/PaxCounterLog.swift +++ b/Meshtastic/Views/Nodes/PaxCounterLog.swift @@ -98,14 +98,14 @@ struct PaxCounterLog: View { TableColumn("paxcounter.total") { pc in Text("\(pc.wifi + pc.ble)") } - TableColumn("uptime") { pc in + TableColumn("Uptime") { pc in let now = Date.now let later = now + TimeInterval(pc.uptime) let components = (now..= 0 ? String(localized: "\(route.hopsBack) Hops") : String(localized: "unknown") + let hopBackString = route.hopsBack >= 0 ? String(localized: "\(route.hopsBack) Hops") : String(localized: "Unknown") Text("\(routeTime) - \(hopTowardsString) Towards \(hopBackString) Back") .font(.caption) } else if route.sent { @@ -78,14 +78,14 @@ struct TraceRouteLog: View { if selectedRoute != nil { if selectedRoute?.response ?? false && selectedRoute?.hopsTowards ?? 0 >= 0 { Label { - Text("Route: \(selectedRoute?.routeText ?? "unknown".localized)") + Text("Route: \(selectedRoute?.routeText ?? "Unknown".localized)") } icon: { Image(systemName: "signpost.right") .symbolRenderingMode(.hierarchical) } .font(.title3) Label { - Text("Route Back: \(selectedRoute?.routeBackText ?? "unknown".localized)") + Text("Route Back: \(selectedRoute?.routeBackText ?? "Unknown".localized)") } icon: { Image(systemName: "signpost.left") .symbolRenderingMode(.hierarchical) @@ -94,7 +94,7 @@ struct TraceRouteLog: View { } else if !(selectedRoute?.sent ?? true) { Label { VStack { - Text("Trace route to \(selectedRoute?.node?.user?.longName ?? "unknown".localized) was not sent.") + Text("Trace route to \(selectedRoute?.node?.user?.longName ?? "Unknown".localized) was not sent.") .font(idiom == .phone ? .body : .largeTitle) .fontWeight(.semibold) Text("Trace Route was rate limited. You can send a trace route a maximum of once every thirty seconds.") @@ -109,7 +109,7 @@ struct TraceRouteLog: View { } else { Label { VStack { - Text("Trace route sent to \(selectedRoute?.node?.user?.longName ?? "unknown".localized)") + Text("Trace route sent to \(selectedRoute?.node?.user?.longName ?? "Unknown".localized)") .font(idiom == .phone ? .body : .largeTitle) .fontWeight(.semibold) Text("A Trace Route was sent, no response has been received.") diff --git a/Meshtastic/Views/Settings/About.swift b/Meshtastic/Views/Settings/About.swift index 84fa4b83..f6854bcb 100644 --- a/Meshtastic/Views/Settings/About.swift +++ b/Meshtastic/Views/Settings/About.swift @@ -14,7 +14,6 @@ struct AboutMeshtastic: View { var body: some View { VStack { - List { Section(header: Text("What is Meshtastic?")) { Text("An open source, off-grid, decentralized, mesh network that runs on affordable, low-power radios.") @@ -44,7 +43,7 @@ struct AboutMeshtastic: View { Button("Review the app") { if let scene = UIApplication.shared.connectedScenes .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene { - SKStoreReviewController.requestReview(in: scene) + AppStore.requestReview(in: scene) } } .font(.title2) diff --git a/Meshtastic/Views/Settings/AppLog.swift b/Meshtastic/Views/Settings/AppLog.swift index 53a32e07..5c49f7c4 100644 --- a/Meshtastic/Views/Settings/AppLog.swift +++ b/Meshtastic/Views/Settings/AppLog.swift @@ -35,7 +35,7 @@ struct AppLog: View { if idiom == .phone { Table(logs, selection: $selection, sortOrder: $sortOrder) { - TableColumn("log.message", value: \.composedMessage) { value in + TableColumn("Message", value: \.composedMessage) { value in Text(value.composedMessage) .foregroundStyle(value.level.color) .font(.caption) @@ -86,7 +86,7 @@ struct AppLog: View { .width(min: 85, max: 110) TableColumn("log.category", value: \.category) .width(min: 80, max: 130) - TableColumn("log.message", value: \.composedMessage) { value in + TableColumn("Message", value: \.composedMessage) { value in Text(value.composedMessage) .foregroundStyle(value.level.color) .font(.body) @@ -270,4 +270,4 @@ extension AppLog { } } -extension OSLogEntry: Identifiable { } +extension OSLogEntry: @retroactive Identifiable { } diff --git a/Meshtastic/Views/Settings/AppSettings.swift b/Meshtastic/Views/Settings/AppSettings.swift index 7ba7d3f9..e16fb31b 100644 --- a/Meshtastic/Views/Settings/AppSettings.swift +++ b/Meshtastic/Views/Settings/AppSettings.swift @@ -43,7 +43,7 @@ struct AppSettings: View { Button { isPresentingCoreDataResetConfirm = true } label: { - Label("clear.app.data", systemImage: "trash") + Label("Clear App Data", systemImage: "trash") .foregroundColor(.red) } .confirmationDialog( diff --git a/Meshtastic/Views/Settings/Channels.swift b/Meshtastic/Views/Settings/Channels.swift index 551b9ab4..861f0cb3 100644 --- a/Meshtastic/Views/Settings/Channels.swift +++ b/Meshtastic/Views/Settings/Channels.swift @@ -230,7 +230,7 @@ struct Channels: View { Button { goBack() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -279,7 +279,7 @@ struct Channels: View { .padding() } } - .navigationTitle("channels") + .navigationTitle("Channels") .navigationBarItems(trailing: ZStack { ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?") diff --git a/Meshtastic/Views/Settings/Channels/ChannelForm.swift b/Meshtastic/Views/Settings/Channels/ChannelForm.swift index 06a4a260..92f1b8e2 100644 --- a/Meshtastic/Views/Settings/Channels/ChannelForm.swift +++ b/Meshtastic/Views/Settings/Channels/ChannelForm.swift @@ -30,7 +30,7 @@ struct ChannelForm: View { Form { Section(header: Text("channel details")) { HStack { - Text("name") + Text("Name") Spacer() TextField( "Channel Name", @@ -128,7 +128,7 @@ struct ChannelForm: View { } } - Section(header: Text("position")) { + Section(header: Text("Position")) { VStack(alignment: .leading) { Toggle(isOn: $positionsEnabled) { Label(channelRole == 1 ? "Positions Enabled" : "Allow Position Requests", systemImage: positionsEnabled ? "mappin" : "mappin.slash") @@ -170,7 +170,7 @@ struct ChannelForm: View { } } } - Section(header: Text("mqtt")) { + Section(header: Text("MQTT")) { Toggle(isOn: $uplink) { Label("Uplink Enabled", systemImage: "arrowshape.up") } diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index 3fdc73b9..807aa673 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -30,11 +30,9 @@ struct DeviceConfig: View { @State var ledHeartbeatEnabled = true @State var tripleClickAsAdHocPing = true @State var tzdef = "" - @State private var showRouterWarning = false @State private var confirmWarning = false - var body: some View { VStack { Form { @@ -149,7 +147,7 @@ struct DeviceConfig: View { Picker("Button GPIO", selection: $buttonGPIO) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -159,7 +157,7 @@ struct DeviceConfig: View { Picker("Buzzer GPIO", selection: $buzzerGPIO) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } diff --git a/Meshtastic/Views/Settings/Config/DisplayConfig.swift b/Meshtastic/Views/Settings/Config/DisplayConfig.swift index 88839956..d6f14135 100644 --- a/Meshtastic/Views/Settings/Config/DisplayConfig.swift +++ b/Meshtastic/Views/Settings/Config/DisplayConfig.swift @@ -153,7 +153,7 @@ struct DisplayConfig: View { } } - .navigationTitle("display.config") + .navigationTitle("Display Config") .navigationBarItems( trailing: ZStack { ConnectedDevice( diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index e95d524f..20a62136 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -103,7 +103,7 @@ struct CannedMessagesConfig: View { Picker("Pin A", selection: $inputbrokerPinA) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -118,7 +118,7 @@ struct CannedMessagesConfig: View { Picker("Pin B", selection: $inputbrokerPinB) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -133,7 +133,7 @@ struct CannedMessagesConfig: View { Picker("Press Pin", selection: $inputbrokerPinPress) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } diff --git a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift index 21e24177..bdbffa39 100644 --- a/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/DetectionSensorConfig.swift @@ -108,7 +108,7 @@ struct DetectionSensorConfig: View { Picker("GPIO Pin to monitor", selection: $monitorPin) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } diff --git a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift index 01d2f247..fc1835fb 100644 --- a/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/ExternalNotificationConfig.swift @@ -82,7 +82,7 @@ struct ExternalNotificationConfig: View { Picker("Output pin GPIO", selection: $output) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -138,7 +138,7 @@ struct ExternalNotificationConfig: View { Picker("Output pin buzzer GPIO ", selection: $outputBuzzer) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -148,7 +148,7 @@ struct ExternalNotificationConfig: View { Picker("Output pin vibra GPIO", selection: $outputVibra) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index 21297a16..217205cd 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -30,8 +30,8 @@ struct MQTTConfig: View { @State var mqttConnected: Bool = false @State var defaultTopic = "msh/US" @State var nearbyTopics = [String]() - @State var mapReportingOptIn = false @State var mapReportingEnabled = false + @AppStorage("mapReportingOptIn") private var mapReportingOptIn: Bool = false @State var mapPublishIntervalSecs = 3600 @State var mapPositionPrecision: Double = 14.0 @@ -266,7 +266,7 @@ struct MQTTConfig: View { mqtt.encryptionEnabled = self.encryptionEnabled mqtt.jsonEnabled = self.jsonEnabled mqtt.tlsEnabled = self.tlsEnabled - mqtt.mapReportingEnabled = (self.mapReportingEnabled && self.mapReportingOptIn) + mqtt.mapReportingEnabled = self.mapReportingEnabled mqtt.mapReportSettings.positionPrecision = UInt32(self.mapPositionPrecision) mqtt.mapReportSettings.publishIntervalSecs = UInt32(self.mapPublishIntervalSecs) let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0) @@ -388,7 +388,6 @@ struct MQTTConfig: View { } if let placemarks = placemarks, let placemark = placemarks.first { - let cc = locale.region?.identifier ?? "UNK" /// Country Topic unless your region is a country if !(region?.isCountry ?? false) { let countryTopic = defaultTopic + "/" + (placemark.isoCountryCode ?? "") diff --git a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift index 5f78379e..5ef89a17 100644 --- a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift @@ -27,12 +27,12 @@ struct PaxCounterConfig: View { Section { Toggle(isOn: $enabled) { Label("Enabled", systemImage: "figure.walk.motion") - Text("config.module.paxcounter.enabled.description") + Text("When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .listRowSeparator(.visible) if enabled { - Picker("config.module.paxcounter.updateinterval", selection: $paxcounterUpdateInterval) { + Picker("Update Interval", selection: $paxcounterUpdateInterval) { ForEach(UpdateIntervals.allCases) { at in if at.rawValue >= 300 { Text(at.description) diff --git a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift index d8ca379d..47dca015 100644 --- a/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/SerialConfig.swift @@ -41,7 +41,7 @@ struct SerialConfig: View { .toggleStyle(SwitchToggleStyle(tint: .accentColor)) Toggle(isOn: $echo) { - Label("echo", systemImage: "repeat") + Label("Echo", systemImage: "repeat") Text("If set, any packets you send will be echoed back to your device.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) @@ -53,7 +53,7 @@ struct SerialConfig: View { } .pickerStyle(DefaultPickerStyle()) .listRowSeparator(/*@START_MENU_TOKEN@*/.visible/*@END_MENU_TOKEN@*/) - Picker("timeout", selection: $timeout ) { + Picker("Timeout", selection: $timeout ) { ForEach(SerialTimeoutIntervals.allCases) { sti in Text(sti.description) } @@ -64,7 +64,7 @@ struct SerialConfig: View { .foregroundColor(.gray) .font(.callout) - Picker("mode", selection: $mode ) { + Picker("Mode", selection: $mode ) { ForEach(SerialModeTypes.allCases) { smt in Text(smt.description) } @@ -76,7 +76,7 @@ struct SerialConfig: View { Picker("Receive data (rxd) GPIO pin", selection: $rxd) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -88,7 +88,7 @@ struct SerialConfig: View { Picker("Transmit data (txd) GPIO pin", selection: $txd) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift index 3f2e66f6..d3bbf314 100644 --- a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift @@ -50,7 +50,7 @@ struct StoreForwardConfig: View { Text("Send a heartbeat to advertise the server's presence.") } Picker("Number of records", selection: $records) { - Text("unset").tag(0) + Text("Unset").tag(0) Text("25").tag(25) Text("50").tag(50) Text("75").tag(75) @@ -58,7 +58,7 @@ struct StoreForwardConfig: View { } .pickerStyle(DefaultPickerStyle()) Picker("History Return Max", selection: $historyReturnMax) { - Text("unset").tag(0) + Text("Unset").tag(0) Text("25").tag(25) Text("50").tag(50) Text("75").tag(75) @@ -66,7 +66,7 @@ struct StoreForwardConfig: View { } .pickerStyle(DefaultPickerStyle()) Picker("History Return Window", selection: $historyReturnWindow) { - Text("unset").tag(0) + Text("Unset").tag(0) Text("One Minute").tag(60) Text("Five Minutes").tag(300) Text("Ten Minutes").tag(600) diff --git a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift index 6d78316c..3f7f0dcf 100644 --- a/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/TelemetryConfig.swift @@ -46,7 +46,7 @@ struct TelemetryConfig: View { .foregroundColor(.gray) .font(.callout) .listRowSeparator(.visible) - Picker("Sensor Metrics", selection: $environmentUpdateInterval ) { + Picker("Environment Metrics", selection: $environmentUpdateInterval ) { ForEach(UpdateIntervals.allCases) { ui in if ui.rawValue >= 900 { Text(ui.description) @@ -55,7 +55,7 @@ struct TelemetryConfig: View { } .pickerStyle(DefaultPickerStyle()) .listRowSeparator(.hidden) - Text("How often sensor metrics are sent out over the mesh. Default is 30 minutes.") + Text("How often environment metrics are sent out over the mesh. Default is 30 minutes.") .foregroundColor(.gray) .font(.callout) } diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift index b8e51fe3..566bbbf5 100644 --- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift +++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift @@ -60,8 +60,8 @@ struct NetworkConfig: View { } .keyboardType(.default) HStack { - Label("password", systemImage: "wallet.pass") - TextField("password", text: $wifiPsk) + Label("Password", systemImage: "wallet.pass") + TextField("Password", text: $wifiPsk) .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift index db0574c7..136d52bd 100644 --- a/Meshtastic/Views/Settings/Config/PositionConfig.swift +++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift @@ -114,7 +114,7 @@ struct PositionConfig: View { Picker("Minimum Distance", selection: $broadcastSmartMinimumDistance) { ForEach(10..<151) { if $0 == 0 { - Text("unset") + Text("Unset") } else { if $0.isMultiple(of: 5) { Text("\($0)") @@ -139,7 +139,6 @@ struct PositionConfig: View { ForEach(GpsMode.allCases, id: \.self) { at in Text(at.description) .tag(at.id) - } } .pickerStyle(SegmentedPickerStyle()) @@ -210,7 +209,7 @@ struct PositionConfig: View { } Toggle(isOn: $includeTimestamp) { // 128 - Label("timestamp", systemImage: "clock") + Label("Timestamp", systemImage: "clock") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .onChange(of: includeTimestamp) { _, newIncludeTimestamp in @@ -283,7 +282,7 @@ struct PositionConfig: View { Picker("GPS Receive GPIO", selection: $rxGpio) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -293,7 +292,7 @@ struct PositionConfig: View { Picker("GPS Transmit GPIO", selection: $txGpio) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -303,7 +302,7 @@ struct PositionConfig: View { Picker("GPS EN GPIO", selection: $gpsEnGpio) { ForEach(0..<49) { if $0 == 0 { - Text("unset") + Text("Unset") } else { Text("Pin \($0)") } @@ -314,7 +313,6 @@ struct PositionConfig: View { .font(.caption) } } - var saveButton: some View { SaveConfigButton(node: node, hasChanges: $hasChanges) { if fixedPosition && !supportedVersion { @@ -399,11 +397,7 @@ struct PositionConfig: View { .navigationTitle("position.config") .navigationBarItems( trailing: ZStack { - ConnectedDevice( - bluetoothOn: bleManager.isSwitchedOn, - deviceConnected: bleManager.connectedPeripheral != nil, - name: bleManager.connectedPeripheral?.shortName ?? "?" - ) + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: bleManager.connectedPeripheral?.shortName ?? "?") } ) .onFirstAppear { diff --git a/Meshtastic/Views/Settings/Config/PowerConfig.swift b/Meshtastic/Views/Settings/Config/PowerConfig.swift index abd2e30f..0c94e646 100644 --- a/Meshtastic/Views/Settings/Config/PowerConfig.swift +++ b/Meshtastic/Views/Settings/Config/PowerConfig.swift @@ -42,7 +42,7 @@ struct PowerConfig: View { } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) if shutdownOnPowerLoss { - Picker("config.power.shutdown.after.secs", selection: $shutdownAfterSecs) { + Picker("After", selection: $shutdownAfterSecs) { ForEach(PowerIntervals.allCases) { at in Text(at.description) } @@ -50,7 +50,7 @@ struct PowerConfig: View { .pickerStyle(DefaultPickerStyle()) } } header: { - Text("config.power.settings") + Text("Power") } if currentDevice?.architecture == .esp32 || currentDevice?.architecture == .esp32S3 { Section { diff --git a/Meshtastic/Views/Settings/Config/SaveConfigButton.swift b/Meshtastic/Views/Settings/Config/SaveConfigButton.swift index 3b185129..0c948a28 100644 --- a/Meshtastic/Views/Settings/Config/SaveConfigButton.swift +++ b/Meshtastic/Views/Settings/Config/SaveConfigButton.swift @@ -24,7 +24,7 @@ struct SaveConfigButton: View { isPresented: $isPresentingSaveConfirm, titleVisibility: .visible ) { - let nodeName = node?.user?.longName ?? "unknown".localized + let nodeName = node?.user?.longName ?? "Unknown".localized let buttonText = String.localizedStringWithFormat("save.config %@".localized, nodeName) Button(buttonText) { onConfirmation() diff --git a/Meshtastic/Views/Settings/Firmware.swift b/Meshtastic/Views/Settings/Firmware.swift index b0c9c08f..ad885d86 100644 --- a/Meshtastic/Views/Settings/Firmware.swift +++ b/Meshtastic/Views/Settings/Firmware.swift @@ -77,7 +77,7 @@ struct Firmware: View { Text("Get the latest stable firmware") .fixedSize(horizontal: false, vertical: true) .font(.callout) - Link("\(latestStable?.title ?? "unknown".localized)", destination: URL(string: "\(latestStable?.zipURL ?? "https://meshtastic.org")")!) + Link("\(latestStable?.title ?? "Unknown".localized)", destination: URL(string: "\(latestStable?.zipURL ?? "https://meshtastic.org")")!) .font(.caption) Link("Release Notes", destination: URL(string: "\(latestStable?.pageURL ?? "https://meshtastic.org")")!) .font(.caption) @@ -86,7 +86,7 @@ struct Firmware: View { Text("Get the latest alpha firmware") .fixedSize(horizontal: false, vertical: true) .font(.callout) - Link("\(latestAlpha?.title ?? "unknown".localized)", destination: URL(string: "\(latestAlpha?.zipURL ?? "https://meshtastic.org")")!) + Link("\(latestAlpha?.title ?? "Unknown".localized)", destination: URL(string: "\(latestAlpha?.zipURL ?? "https://meshtastic.org")")!) .font(.caption) Link("Release Notes", destination: URL(string: "\(latestAlpha?.pageURL ?? "https://meshtastic.org")")!) .font(.caption) diff --git a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift index e6371672..eadf8e41 100644 --- a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift +++ b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift @@ -136,7 +136,7 @@ struct AppLogFilter: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/Logs/LogDetail.swift b/Meshtastic/Views/Settings/Logs/LogDetail.swift index ca5d17d6..864e3c62 100644 --- a/Meshtastic/Views/Settings/Logs/LogDetail.swift +++ b/Meshtastic/Views/Settings/Logs/LogDetail.swift @@ -124,7 +124,7 @@ struct LogDetail: View { /// message Label { - Text("log.message".localized + ":") + Text("Message".localized + ":") .font(idiom == .phone ? .caption : .title) .frame(width: idiom == .phone ? 115 : 190, alignment: .trailing) Text(log.composedMessage) @@ -151,7 +151,7 @@ struct LogDetail: View { Button { dismiss() } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/RouteRecorder.swift b/Meshtastic/Views/Settings/RouteRecorder.swift index 8cee2eeb..58190878 100644 --- a/Meshtastic/Views/Settings/RouteRecorder.swift +++ b/Meshtastic/Views/Settings/RouteRecorder.swift @@ -250,7 +250,7 @@ struct RouteRecorder: View { } isShowingDetails = false } label: { - Label("finish", systemImage: "flag.checkered") + Label("Finish", systemImage: "flag.checkered") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) @@ -261,7 +261,7 @@ struct RouteRecorder: View { Button(role: .cancel) { isShowingDetails = false } label: { - Label("close", systemImage: "xmark") + Label("Close", systemImage: "xmark") } .buttonStyle(.bordered) .buttonBorderShape(.capsule) diff --git a/Meshtastic/Views/Settings/Routes.swift b/Meshtastic/Views/Settings/Routes.swift index 7e6407bc..138fab99 100644 --- a/Meshtastic/Views/Settings/Routes.swift +++ b/Meshtastic/Views/Settings/Routes.swift @@ -200,7 +200,7 @@ struct Routes: View { .foregroundColor(Color.gray) } .onAppear { - name = selectedRoute?.name ?? "unknown".localized + name = selectedRoute?.name ?? "Unknown".localized notes = selectedRoute?.notes ?? "" enabled = selectedRoute?.enabled ?? false color = Color(UIColor(hex: UInt32(selectedRoute?.color ?? 0))) diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index 8ebcfd83..45c9f54a 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -78,7 +78,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.channels) { Label { - Text("channels") + Text("Channels") } icon: { Image(systemName: "fibrechannel") } @@ -108,7 +108,7 @@ struct Settings: View { Section("device.configuration") { NavigationLink(value: SettingsNavigationState.user) { Label { - Text("user") + Text("User") } icon: { Image(systemName: "person.crop.rectangle.fill") } @@ -148,7 +148,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.position) { Label { - Text("position") + Text("Position") } icon: { Image(systemName: "location") } @@ -156,7 +156,7 @@ struct Settings: View { NavigationLink(value: SettingsNavigationState.power) { Label { - Text("config.power.settings") + Text("Power") } icon: { Image(systemName: "bolt.fill") } @@ -209,7 +209,7 @@ struct Settings: View { if isModuleSupported(.mqttConfig) { NavigationLink(value: SettingsNavigationState.mqtt) { Label { - Text("mqtt") + Text("MQTT") } icon: { Image(systemName: "dot.radiowaves.up.forward") } @@ -229,7 +229,7 @@ struct Settings: View { if isModuleSupported(.paxcounterConfig) { NavigationLink(value: SettingsNavigationState.paxCounter) { Label { - Text("config.module.paxcounter.settings") + Text("PAX Counter") } icon: { Image(systemName: "figure.walk.motion") } @@ -239,7 +239,7 @@ struct Settings: View { if isModuleSupported(.audioConfig) { NavigationLink(value: SettingsNavigationState.ringtone) { Label { - Text("ringtone") + Text("Ringtone") } icon: { Image(systemName: "music.note.list") } @@ -249,7 +249,7 @@ struct Settings: View { if isModuleSupported(.serialConfig) { NavigationLink(value: SettingsNavigationState.serial) { Label { - Text("serial") + Text("Serial") } icon: { Image(systemName: "terminal") } @@ -388,14 +388,14 @@ struct Settings: View { /// Connected Node if node.num == bleManager.connectedPeripheral?.num ?? 0 { Label { - Text("BLE: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("BLE: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } icon: { Image(systemName: "antenna.radiowaves.left.and.right") } .tag(Int(node.num)) } else if node.canRemoteAdmin && UserDefaults.enableAdministration && node.sessionPasskey != nil { /// Nodes using the new PKI system Label { - Text("Remote PKI Admin: \(node.user?.longName ?? "unknown".localized)") + Text("Remote PKI Admin: \(node.user?.longName ?? "Unknown".localized)") } icon: { Image(systemName: "av.remote") } @@ -403,21 +403,21 @@ struct Settings: View { .tag(Int(node.num)) } else if !UserDefaults.enableAdministration && node.metadata != nil { /// Nodes using the old admin system Label { - Text("Remote Legacy Admin: \(node.user?.longName ?? "unknown".localized)") + Text("Remote Legacy Admin: \(node.user?.longName ?? "Unknown".localized)") } icon: { Image(systemName: "av.remote") } .tag(Int(node.num)) } else if UserDefaults.enableAdministration && node.user?.pkiEncrypted ?? false { Label { - Text("Request PKI Admin: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Request PKI Admin: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } icon: { Image(systemName: "rectangle.and.hand.point.up.left") } .tag(Int(node.num)) } else if !UserDefaults.enableAdministration { Label { - Text("Request Legacy Admin: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Request Legacy Admin: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } icon: { Image(systemName: "rectangle.and.hand.point.up.left") } @@ -442,7 +442,7 @@ struct Settings: View { TipView(AdminChannelTip(), arrowEdge: .top) } else { if bleManager.connectedPeripheral != nil { - Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "unknown".localized)") + Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)") } } } @@ -542,7 +542,7 @@ struct Settings: View { } } } - .navigationTitle("settings") + .navigationTitle("Settings") .navigationBarItems( leading: MeshtasticLogo().onLongPressGesture(minimumDuration: 1.0) { self.moduleOverride.toggle() diff --git a/Meshtastic/Views/Settings/ShareChannels.swift b/Meshtastic/Views/Settings/ShareChannels.swift index 7ea643ae..71707792 100644 --- a/Meshtastic/Views/Settings/ShareChannels.swift +++ b/Meshtastic/Views/Settings/ShareChannels.swift @@ -62,7 +62,7 @@ struct ShareChannels: View { Grid { GridRow { Spacer() - Text("include") + Text("Include") .font(.caption) .fontWeight(.bold) .padding(.trailing) @@ -70,7 +70,7 @@ struct ShareChannels: View { .font(.caption) .fontWeight(.bold) .padding(.trailing) - Text("encrypted") + Text("Encrypted") .font(.caption) .fontWeight(.bold) } diff --git a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift index 5a9a75a5..e450d566 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/admin.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/admin.proto @@ -25,7 +24,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// This message is handled by the Admin module and is responsible for all settings/channel read/write operations. /// This message is used to do settings operations to both remote AND local nodes. /// (Prior to 1.2 these operations were done via special ToRadio operations) -public struct AdminMessage: @unchecked Sendable { +public struct AdminMessage { // 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. @@ -564,7 +563,7 @@ public struct AdminMessage: @unchecked Sendable { /// /// TODO: REPLACE - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Send the specified channel in the response to this message /// NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present) @@ -729,11 +728,225 @@ public struct AdminMessage: @unchecked Sendable { /// Tell the node to reset the nodedb. case nodedbReset(Int32) + #if !swift(>=4.1) + public static func ==(lhs: AdminMessage.OneOf_PayloadVariant, rhs: AdminMessage.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 (.getChannelRequest, .getChannelRequest): return { + guard case .getChannelRequest(let l) = lhs, case .getChannelRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getChannelResponse, .getChannelResponse): return { + guard case .getChannelResponse(let l) = lhs, case .getChannelResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getOwnerRequest, .getOwnerRequest): return { + guard case .getOwnerRequest(let l) = lhs, case .getOwnerRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getOwnerResponse, .getOwnerResponse): return { + guard case .getOwnerResponse(let l) = lhs, case .getOwnerResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getConfigRequest, .getConfigRequest): return { + guard case .getConfigRequest(let l) = lhs, case .getConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getConfigResponse, .getConfigResponse): return { + guard case .getConfigResponse(let l) = lhs, case .getConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getModuleConfigRequest, .getModuleConfigRequest): return { + guard case .getModuleConfigRequest(let l) = lhs, case .getModuleConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getModuleConfigResponse, .getModuleConfigResponse): return { + guard case .getModuleConfigResponse(let l) = lhs, case .getModuleConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getCannedMessageModuleMessagesRequest, .getCannedMessageModuleMessagesRequest): return { + guard case .getCannedMessageModuleMessagesRequest(let l) = lhs, case .getCannedMessageModuleMessagesRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getCannedMessageModuleMessagesResponse, .getCannedMessageModuleMessagesResponse): return { + guard case .getCannedMessageModuleMessagesResponse(let l) = lhs, case .getCannedMessageModuleMessagesResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceMetadataRequest, .getDeviceMetadataRequest): return { + guard case .getDeviceMetadataRequest(let l) = lhs, case .getDeviceMetadataRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceMetadataResponse, .getDeviceMetadataResponse): return { + guard case .getDeviceMetadataResponse(let l) = lhs, case .getDeviceMetadataResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getRingtoneRequest, .getRingtoneRequest): return { + guard case .getRingtoneRequest(let l) = lhs, case .getRingtoneRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getRingtoneResponse, .getRingtoneResponse): return { + guard case .getRingtoneResponse(let l) = lhs, case .getRingtoneResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceConnectionStatusRequest, .getDeviceConnectionStatusRequest): return { + guard case .getDeviceConnectionStatusRequest(let l) = lhs, case .getDeviceConnectionStatusRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getDeviceConnectionStatusResponse, .getDeviceConnectionStatusResponse): return { + guard case .getDeviceConnectionStatusResponse(let l) = lhs, case .getDeviceConnectionStatusResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setHamMode, .setHamMode): return { + guard case .setHamMode(let l) = lhs, case .setHamMode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getNodeRemoteHardwarePinsRequest, .getNodeRemoteHardwarePinsRequest): return { + guard case .getNodeRemoteHardwarePinsRequest(let l) = lhs, case .getNodeRemoteHardwarePinsRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getNodeRemoteHardwarePinsResponse, .getNodeRemoteHardwarePinsResponse): return { + guard case .getNodeRemoteHardwarePinsResponse(let l) = lhs, case .getNodeRemoteHardwarePinsResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.enterDfuModeRequest, .enterDfuModeRequest): return { + guard case .enterDfuModeRequest(let l) = lhs, case .enterDfuModeRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.deleteFileRequest, .deleteFileRequest): return { + 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 (.backupPreferences, .backupPreferences): return { + guard case .backupPreferences(let l) = lhs, case .backupPreferences(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.restorePreferences, .restorePreferences): return { + guard case .restorePreferences(let l) = lhs, case .restorePreferences(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeBackupPreferences, .removeBackupPreferences): return { + guard case .removeBackupPreferences(let l) = lhs, case .removeBackupPreferences(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 + }() + case (.setChannel, .setChannel): return { + guard case .setChannel(let l) = lhs, case .setChannel(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setConfig, .setConfig): return { + guard case .setConfig(let l) = lhs, case .setConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setModuleConfig, .setModuleConfig): return { + guard case .setModuleConfig(let l) = lhs, case .setModuleConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setCannedMessageModuleMessages, .setCannedMessageModuleMessages): return { + guard case .setCannedMessageModuleMessages(let l) = lhs, case .setCannedMessageModuleMessages(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setRingtoneMessage, .setRingtoneMessage): return { + guard case .setRingtoneMessage(let l) = lhs, case .setRingtoneMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeByNodenum, .removeByNodenum): return { + guard case .removeByNodenum(let l) = lhs, case .removeByNodenum(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setFavoriteNode, .setFavoriteNode): return { + guard case .setFavoriteNode(let l) = lhs, case .setFavoriteNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeFavoriteNode, .removeFavoriteNode): return { + guard case .removeFavoriteNode(let l) = lhs, case .removeFavoriteNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setFixedPosition, .setFixedPosition): return { + guard case .setFixedPosition(let l) = lhs, case .setFixedPosition(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeFixedPosition, .removeFixedPosition): return { + guard case .removeFixedPosition(let l) = lhs, case .removeFixedPosition(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setTimeOnly, .setTimeOnly): return { + guard case .setTimeOnly(let l) = lhs, case .setTimeOnly(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getUiConfigRequest, .getUiConfigRequest): return { + guard case .getUiConfigRequest(let l) = lhs, case .getUiConfigRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.getUiConfigResponse, .getUiConfigResponse): return { + guard case .getUiConfigResponse(let l) = lhs, case .getUiConfigResponse(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.storeUiConfig, .storeUiConfig): return { + guard case .storeUiConfig(let l) = lhs, case .storeUiConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.setIgnoredNode, .setIgnoredNode): return { + guard case .setIgnoredNode(let l) = lhs, case .setIgnoredNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.removeIgnoredNode, .removeIgnoredNode): return { + guard case .removeIgnoredNode(let l) = lhs, case .removeIgnoredNode(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.beginEditSettings, .beginEditSettings): return { + guard case .beginEditSettings(let l) = lhs, case .beginEditSettings(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.commitEditSettings, .commitEditSettings): return { + guard case .commitEditSettings(let l) = lhs, case .commitEditSettings(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.factoryResetDevice, .factoryResetDevice): return { + guard case .factoryResetDevice(let l) = lhs, case .factoryResetDevice(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rebootOtaSeconds, .rebootOtaSeconds): return { + guard case .rebootOtaSeconds(let l) = lhs, case .rebootOtaSeconds(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.exitSimulator, .exitSimulator): return { + guard case .exitSimulator(let l) = lhs, case .exitSimulator(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rebootSeconds, .rebootSeconds): return { + guard case .rebootSeconds(let l) = lhs, case .rebootSeconds(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.shutdownSeconds, .shutdownSeconds): return { + guard case .shutdownSeconds(let l) = lhs, case .shutdownSeconds(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.factoryResetConfig, .factoryResetConfig): return { + guard case .factoryResetConfig(let l) = lhs, case .factoryResetConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodedbReset, .nodedbReset): return { + guard case .nodedbReset(let l) = lhs, case .nodedbReset(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// TODO: REPLACE - public enum ConfigType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ConfigType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -813,25 +1026,11 @@ public struct AdminMessage: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.ConfigType] = [ - .deviceConfig, - .positionConfig, - .powerConfig, - .networkConfig, - .displayConfig, - .loraConfig, - .bluetoothConfig, - .securityConfig, - .sessionkeyConfig, - .deviceuiConfig, - ] - } /// /// TODO: REPLACE - public enum ModuleConfigType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ModuleConfigType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -929,26 +1128,9 @@ public struct AdminMessage: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.ModuleConfigType] = [ - .mqttConfig, - .serialConfig, - .extnotifConfig, - .storeforwardConfig, - .rangetestConfig, - .telemetryConfig, - .cannedmsgConfig, - .audioConfig, - .remotehardwareConfig, - .neighborinfoConfig, - .ambientlightingConfig, - .detectionsensorConfig, - .paxcounterConfig, - ] - } - public enum BackupLocation: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum BackupLocation: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -980,20 +1162,61 @@ public struct AdminMessage: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [AdminMessage.BackupLocation] = [ - .flash, - .sd, - ] - } public init() {} } +#if swift(>=4.2) + +extension AdminMessage.ConfigType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.ConfigType] = [ + .deviceConfig, + .positionConfig, + .powerConfig, + .networkConfig, + .displayConfig, + .loraConfig, + .bluetoothConfig, + .securityConfig, + .sessionkeyConfig, + .deviceuiConfig, + ] +} + +extension AdminMessage.ModuleConfigType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.ModuleConfigType] = [ + .mqttConfig, + .serialConfig, + .extnotifConfig, + .storeforwardConfig, + .rangetestConfig, + .telemetryConfig, + .cannedmsgConfig, + .audioConfig, + .remotehardwareConfig, + .neighborinfoConfig, + .ambientlightingConfig, + .detectionsensorConfig, + .paxcounterConfig, + ] +} + +extension AdminMessage.BackupLocation: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [AdminMessage.BackupLocation] = [ + .flash, + .sd, + ] +} + +#endif // swift(>=4.2) + /// /// Parameters for setting up Meshtastic for ameteur radio usage -public struct HamParameters: Sendable { +public struct HamParameters { // 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. @@ -1023,7 +1246,7 @@ public struct HamParameters: Sendable { /// /// Response envelope for node_remote_hardware_pins -public struct NodeRemoteHardwarePinsResponse: Sendable { +public struct NodeRemoteHardwarePinsResponse { // 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. @@ -1037,6 +1260,16 @@ public struct NodeRemoteHardwarePinsResponse: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension AdminMessage: @unchecked Sendable {} +extension AdminMessage.OneOf_PayloadVariant: @unchecked Sendable {} +extension AdminMessage.ConfigType: @unchecked Sendable {} +extension AdminMessage.ModuleConfigType: @unchecked Sendable {} +extension AdminMessage.BackupLocation: @unchecked Sendable {} +extension HamParameters: @unchecked Sendable {} +extension NodeRemoteHardwarePinsResponse: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -1890,7 +2123,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa if self.txPower != 0 { try visitor.visitSingularInt32Field(value: self.txPower, fieldNumber: 2) } - if self.frequency.bitPattern != 0 { + if self.frequency != 0 { try visitor.visitSingularFloatField(value: self.frequency, fieldNumber: 3) } if !self.shortName.isEmpty { diff --git a/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift index 52dac5ca..0457077c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/apponly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/apponly.proto @@ -8,6 +7,7 @@ // 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 @@ -26,7 +26,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// any SECONDARY channels. /// No DISABLED channels are included. /// This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL -public struct ChannelSet: Sendable { +public struct ChannelSet { // 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. @@ -53,6 +53,10 @@ public struct ChannelSet: Sendable { fileprivate var _loraConfig: Config.LoRaConfig? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension ChannelSet: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift index 06d6af88..867648a9 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/atak.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/atak.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Team: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -131,6 +130,11 @@ public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension Team: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Team] = [ .unspecifedColor, @@ -149,12 +153,13 @@ public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable { .darkGreen, .brown, ] - } +#endif // swift(>=4.2) + /// /// Role of the group member -public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum MemberRole: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -228,6 +233,11 @@ public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension MemberRole: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [MemberRole] = [ .unspecifed, @@ -240,12 +250,13 @@ public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable { .rto, .k9, ] - } +#endif // swift(>=4.2) + /// /// Packets for the official ATAK Plugin -public struct TAKPacket: @unchecked Sendable { +public struct TAKPacket { // 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. @@ -326,7 +337,7 @@ public struct TAKPacket: @unchecked Sendable { /// /// The payload of the packet - public enum OneOf_PayloadVariant: Equatable, @unchecked Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// TAK position report case pli(PLI) @@ -338,6 +349,28 @@ public struct TAKPacket: @unchecked Sendable { /// May be compressed / truncated by the sender (EUD) case detail(Data) + #if !swift(>=4.1) + public static func ==(lhs: TAKPacket.OneOf_PayloadVariant, rhs: TAKPacket.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 (.pli, .pli): return { + guard case .pli(let l) = lhs, case .pli(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.chat, .chat): return { + guard case .chat(let l) = lhs, case .chat(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.detail, .detail): return { + guard case .detail(let l) = lhs, case .detail(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -349,7 +382,7 @@ public struct TAKPacket: @unchecked Sendable { /// /// ATAK GeoChat message -public struct GeoChat: Sendable { +public struct GeoChat { // 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. @@ -391,7 +424,7 @@ public struct GeoChat: Sendable { /// /// ATAK Group /// <__group role='Team Member' name='Cyan'/> -public struct Group: Sendable { +public struct Group { // 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. @@ -413,7 +446,7 @@ public struct Group: Sendable { /// /// ATAK EUD Status /// -public struct Status: Sendable { +public struct Status { // 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. @@ -430,7 +463,7 @@ public struct Status: Sendable { /// /// ATAK Contact /// -public struct Contact: Sendable { +public struct Contact { // 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. @@ -450,7 +483,7 @@ public struct Contact: Sendable { /// /// Position Location Information from ATAK -public struct PLI: Sendable { +public struct PLI { // 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. @@ -482,6 +515,18 @@ public struct PLI: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension Team: @unchecked Sendable {} +extension MemberRole: @unchecked Sendable {} +extension TAKPacket: @unchecked Sendable {} +extension TAKPacket.OneOf_PayloadVariant: @unchecked Sendable {} +extension GeoChat: @unchecked Sendable {} +extension Group: @unchecked Sendable {} +extension Status: @unchecked Sendable {} +extension Contact: @unchecked Sendable {} +extension PLI: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift index ce1f0503..1b8c84de 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/cannedmessages.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/cannedmessages.proto @@ -8,6 +7,7 @@ // 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 @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Canned message module configuration. -public struct CannedMessageModuleConfig: Sendable { +public struct CannedMessageModuleConfig { // 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. @@ -36,6 +36,10 @@ public struct CannedMessageModuleConfig: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension CannedMessageModuleConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift index 180cd698..5b9c7e49 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/channel.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/channel.proto @@ -37,15 +36,13 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// FIXME: Add description of multi-channel support and how primary vs secondary channels are used. /// FIXME: explain how apps use channels for security. /// explain how remote settings and remote gpio are managed as an example -public struct ChannelSettings: @unchecked Sendable { +public struct ChannelSettings { // 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. /// /// Deprecated in favor of LoraConfig.channel_num - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var channelNum: UInt32 = 0 /// @@ -114,7 +111,7 @@ public struct ChannelSettings: @unchecked Sendable { /// /// This message is specifically for modules to store per-channel configuration data. -public struct ModuleSettings: Sendable { +public struct ModuleSettings { // 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. @@ -135,7 +132,7 @@ public struct ModuleSettings: Sendable { /// /// A pair of a channel number, mode and the (sharable) settings for that channel -public struct Channel: Sendable { +public struct Channel { // 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. @@ -173,7 +170,7 @@ public struct Channel: Sendable { /// cross band routing as needed. /// If a device has only a single radio (the common case) only one channel can be PRIMARY at a time /// (but any number of SECONDARY channels can't be sent received on that common frequency) - public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Role: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -212,13 +209,6 @@ public struct Channel: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Channel.Role] = [ - .disabled, - .primary, - .secondary, - ] - } public init() {} @@ -226,6 +216,26 @@ public struct Channel: Sendable { fileprivate var _settings: ChannelSettings? = nil } +#if swift(>=4.2) + +extension Channel.Role: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Channel.Role] = [ + .disabled, + .primary, + .secondary, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension ChannelSettings: @unchecked Sendable {} +extension ModuleSettings: @unchecked Sendable {} +extension Channel: @unchecked Sendable {} +extension Channel.Role: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift index d72c0ae1..f89a8e3c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/clientonly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/clientonly.proto @@ -8,6 +7,7 @@ // 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 @@ -23,7 +23,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// This abstraction is used to contain any configuration for provisioning a node on any client. /// It is useful for importing and exporting configurations. -public struct DeviceProfile: Sendable { +public struct DeviceProfile { // 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. @@ -130,6 +130,10 @@ public struct DeviceProfile: Sendable { fileprivate var _cannedMessages: String? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension DeviceProfile: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift index b3988aaa..e0d45bcf 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/config.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/config.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct Config: Sendable { +public struct Config { // 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. @@ -114,7 +113,7 @@ public struct Config: Sendable { /// /// Payload Variant - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { case device(Config.DeviceConfig) case position(Config.PositionConfig) case power(Config.PowerConfig) @@ -126,11 +125,61 @@ public struct Config: Sendable { case sessionkey(Config.SessionkeyConfig) case deviceUi(DeviceUIConfig) + #if !swift(>=4.1) + public static func ==(lhs: Config.OneOf_PayloadVariant, rhs: Config.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 (.device, .device): return { + guard case .device(let l) = lhs, case .device(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.position, .position): return { + guard case .position(let l) = lhs, case .position(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.power, .power): return { + guard case .power(let l) = lhs, case .power(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.network, .network): return { + guard case .network(let l) = lhs, case .network(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.display, .display): return { + guard case .display(let l) = lhs, case .display(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.lora, .lora): return { + guard case .lora(let l) = lhs, case .lora(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.bluetooth, .bluetooth): return { + guard case .bluetooth(let l) = lhs, case .bluetooth(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.security, .security): return { + guard case .security(let l) = lhs, case .security(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.sessionkey, .sessionkey): return { + guard case .sessionkey(let l) = lhs, case .sessionkey(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.deviceUi, .deviceUi): return { + guard case .deviceUi(let l) = lhs, case .deviceUi(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// Configuration - public struct DeviceConfig: Sendable { + public struct DeviceConfig { // 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. @@ -142,8 +191,6 @@ public struct Config: Sendable { /// /// Disabling this will disable the SerialConsole by not initilizing the StreamAPI /// Moved to SecurityConfig - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var serialEnabled: Bool = false /// @@ -173,8 +220,6 @@ public struct Config: Sendable { /// If true, device is considered to be "managed" by a mesh administrator /// Clients should then limit available configuration and administrative options inside the user interface /// Moved to SecurityConfig - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var isManaged: Bool = false /// @@ -193,7 +238,7 @@ public struct Config: Sendable { /// /// Defines the device's role on the Mesh network - public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Role: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -211,8 +256,6 @@ public struct Config: Sendable { /// The wifi radio and the oled screen will be put to sleep. /// This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. case router // = 2 - - /// NOTE: This enum value was marked as deprecated in the .proto file case routerClient // = 3 /// @@ -313,27 +356,11 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DeviceConfig.Role] = [ - .client, - .clientMute, - .router, - .routerClient, - .repeater, - .tracker, - .sensor, - .tak, - .clientHidden, - .lostAndFound, - .takTracker, - .routerLate, - ] - } /// /// Defines the device's behavior for how messages are rebroadcast - public enum RebroadcastMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum RebroadcastMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -394,16 +421,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [ - .all, - .allSkipDecoding, - .localOnly, - .knownOnly, - .none, - .corePortnumsOnly, - ] - } public init() {} @@ -411,7 +428,7 @@ public struct Config: Sendable { /// /// Position Config - public struct PositionConfig: Sendable { + public struct PositionConfig { // 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. @@ -433,8 +450,6 @@ public struct Config: Sendable { /// /// Is GPS enabled for this node? - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var gpsEnabled: Bool = false /// @@ -445,8 +460,6 @@ public struct Config: Sendable { /// /// Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var gpsAttemptTime: UInt32 = 0 /// @@ -487,7 +500,7 @@ public struct Config: Sendable { /// are always included (also time if GPS-synced) /// NOTE: the more fields are included, the larger the message will be - /// leading to longer airtime and a higher risk of packet loss - public enum PositionFlags: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum PositionFlags: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -577,24 +590,9 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.PositionConfig.PositionFlags] = [ - .unset, - .altitude, - .altitudeMsl, - .geoidalSeparation, - .dop, - .hvdop, - .satinview, - .seqNo, - .timestamp, - .heading, - .speed, - ] - } - public enum GpsMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum GpsMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -632,13 +630,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.PositionConfig.GpsMode] = [ - .disabled, - .enabled, - .notPresent, - ] - } public init() {} @@ -647,7 +638,7 @@ public struct Config: Sendable { /// /// Power Config\ /// See [Power Config](/docs/settings/config/power) for additional power config details. - public struct PowerConfig: Sendable { + public struct PowerConfig { // 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. @@ -707,7 +698,7 @@ public struct Config: Sendable { /// /// Network Config - public struct NetworkConfig: Sendable { + public struct NetworkConfig { // 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. @@ -758,7 +749,7 @@ public struct Config: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum AddressMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum AddressMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -790,17 +781,11 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.NetworkConfig.AddressMode] = [ - .dhcp, - .static, - ] - } /// /// Available flags auxiliary network protocols - public enum ProtocolFlags: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ProtocolFlags: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -832,15 +817,9 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [ - .noBroadcast, - .udpBroadcast, - ] - } - public struct IpV4Config: Sendable { + public struct IpV4Config { // 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. @@ -873,7 +852,7 @@ public struct Config: Sendable { /// /// Display Config - public struct DisplayConfig: Sendable { + public struct DisplayConfig { // 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. @@ -934,7 +913,7 @@ public struct Config: Sendable { /// /// How the GPS coordinates are displayed on the OLED screen. - public enum GpsCoordinateFormat: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum GpsCoordinateFormat: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -997,21 +976,11 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.GpsCoordinateFormat] = [ - .dec, - .dms, - .utm, - .mgrs, - .olc, - .osgr, - ] - } /// /// Unit display preference - public enum DisplayUnits: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum DisplayUnits: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1043,34 +1012,32 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.DisplayUnits] = [ - .metric, - .imperial, - ] - } /// /// Override OLED outo detect with this if it fails. - public enum OledType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum OledType: SwiftProtobuf.Enum { public typealias RawValue = Int /// - /// Default / Auto + /// Default / Autodetect case oledAuto // = 0 /// - /// Default / Auto + /// Default / Autodetect case oledSsd1306 // = 1 /// - /// Default / Auto + /// Default / Autodetect case oledSh1106 // = 2 /// /// Can not be auto detected but set by proto. Used for 128x128 screens case oledSh1107 // = 3 + + /// + /// Can not be auto detected but set by proto. Used for 128x64 screens + case oledSh110712864 // = 4 case UNRECOGNIZED(Int) public init() { @@ -1083,6 +1050,7 @@ public struct Config: Sendable { case 1: self = .oledSsd1306 case 2: self = .oledSh1106 case 3: self = .oledSh1107 + case 4: self = .oledSh110712864 default: self = .UNRECOGNIZED(rawValue) } } @@ -1093,21 +1061,14 @@ public struct Config: Sendable { case .oledSsd1306: return 1 case .oledSh1106: return 2 case .oledSh1107: return 3 + case .oledSh110712864: return 4 case .UNRECOGNIZED(let i): return i } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.OledType] = [ - .oledAuto, - .oledSsd1306, - .oledSh1106, - .oledSh1107, - ] - } - public enum DisplayMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum DisplayMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1151,17 +1112,9 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.DisplayMode] = [ - .default, - .twocolor, - .inverted, - .color, - ] - } - public enum CompassOrientation: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum CompassOrientation: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1229,18 +1182,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.DisplayConfig.CompassOrientation] = [ - .degrees0, - .degrees90, - .degrees180, - .degrees270, - .degrees0Inverted, - .degrees90Inverted, - .degrees180Inverted, - .degrees270Inverted, - ] - } public init() {} @@ -1248,7 +1189,7 @@ public struct Config: Sendable { /// /// Lora Config - public struct LoRaConfig: @unchecked Sendable { + public struct LoRaConfig { // 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. @@ -1412,7 +1353,7 @@ public struct Config: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum RegionCode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum RegionCode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1564,38 +1505,12 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.LoRaConfig.RegionCode] = [ - .unset, - .us, - .eu433, - .eu868, - .cn, - .jp, - .anz, - .kr, - .tw, - .ru, - .in, - .nz865, - .th, - .lora24, - .ua433, - .ua868, - .my433, - .my919, - .sg923, - .ph433, - .ph868, - .ph915, - ] - } /// /// Standard predefined channel settings /// Note: these mappings must match ModemPreset Choice in the device code. - public enum ModemPreset: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum ModemPreset: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1609,8 +1524,6 @@ public struct Config: Sendable { /// /// Very Long Range - Slow /// Deprecated in 2.5: Works only with txco and is unusably slow - /// - /// NOTE: This enum value was marked as deprecated in the .proto file case veryLongSlow // = 2 /// @@ -1674,19 +1587,6 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.LoRaConfig.ModemPreset] = [ - .longFast, - .longSlow, - .veryLongSlow, - .mediumSlow, - .mediumFast, - .shortSlow, - .shortFast, - .longModerate, - .shortTurbo, - ] - } public init() {} @@ -1694,7 +1594,7 @@ public struct Config: Sendable { fileprivate var _storage = _StorageClass.defaultInstance } - public struct BluetoothConfig: Sendable { + public struct BluetoothConfig { // 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. @@ -1713,7 +1613,7 @@ public struct Config: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum PairingMode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum PairingMode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1751,19 +1651,12 @@ public struct Config: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Config.BluetoothConfig.PairingMode] = [ - .randomPin, - .fixedPin, - .noPin, - ] - } public init() {} } - public struct SecurityConfig: @unchecked Sendable { + public struct SecurityConfig { // 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. @@ -1807,7 +1700,7 @@ public struct Config: Sendable { /// /// Blank config request, strictly for getting the session key - public struct SessionkeyConfig: Sendable { + public struct SessionkeyConfig { // 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. @@ -1820,6 +1713,218 @@ public struct Config: Sendable { public init() {} } +#if swift(>=4.2) + +extension Config.DeviceConfig.Role: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DeviceConfig.Role] = [ + .client, + .clientMute, + .router, + .routerClient, + .repeater, + .tracker, + .sensor, + .tak, + .clientHidden, + .lostAndFound, + .takTracker, + .routerLate, + ] +} + +extension Config.DeviceConfig.RebroadcastMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [ + .all, + .allSkipDecoding, + .localOnly, + .knownOnly, + .none, + .corePortnumsOnly, + ] +} + +extension Config.PositionConfig.PositionFlags: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.PositionConfig.PositionFlags] = [ + .unset, + .altitude, + .altitudeMsl, + .geoidalSeparation, + .dop, + .hvdop, + .satinview, + .seqNo, + .timestamp, + .heading, + .speed, + ] +} + +extension Config.PositionConfig.GpsMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.PositionConfig.GpsMode] = [ + .disabled, + .enabled, + .notPresent, + ] +} + +extension Config.NetworkConfig.AddressMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.NetworkConfig.AddressMode] = [ + .dhcp, + .static, + ] +} + +extension Config.NetworkConfig.ProtocolFlags: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [ + .noBroadcast, + .udpBroadcast, + ] +} + +extension Config.DisplayConfig.GpsCoordinateFormat: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.GpsCoordinateFormat] = [ + .dec, + .dms, + .utm, + .mgrs, + .olc, + .osgr, + ] +} + +extension Config.DisplayConfig.DisplayUnits: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.DisplayUnits] = [ + .metric, + .imperial, + ] +} + +extension Config.DisplayConfig.OledType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.OledType] = [ + .oledAuto, + .oledSsd1306, + .oledSh1106, + .oledSh1107, + .oledSh110712864, + ] +} + +extension Config.DisplayConfig.DisplayMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.DisplayConfig.DisplayMode] = [ + .default, + .twocolor, + .inverted, + .color, + ] +} + +extension Config.DisplayConfig.CompassOrientation: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public 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. + public static let allCases: [Config.LoRaConfig.RegionCode] = [ + .unset, + .us, + .eu433, + .eu868, + .cn, + .jp, + .anz, + .kr, + .tw, + .ru, + .in, + .nz865, + .th, + .lora24, + .ua433, + .ua868, + .my433, + .my919, + .sg923, + .ph433, + .ph868, + .ph915, + ] +} + +extension Config.LoRaConfig.ModemPreset: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.LoRaConfig.ModemPreset] = [ + .longFast, + .longSlow, + .veryLongSlow, + .mediumSlow, + .mediumFast, + .shortSlow, + .shortFast, + .longModerate, + .shortTurbo, + ] +} + +extension Config.BluetoothConfig.PairingMode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Config.BluetoothConfig.PairingMode] = [ + .randomPin, + .fixedPin, + .noPin, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension Config: @unchecked Sendable {} +extension Config.OneOf_PayloadVariant: @unchecked Sendable {} +extension Config.DeviceConfig: @unchecked Sendable {} +extension Config.DeviceConfig.Role: @unchecked Sendable {} +extension Config.DeviceConfig.RebroadcastMode: @unchecked Sendable {} +extension Config.PositionConfig: @unchecked Sendable {} +extension Config.PositionConfig.PositionFlags: @unchecked Sendable {} +extension Config.PositionConfig.GpsMode: @unchecked Sendable {} +extension Config.PowerConfig: @unchecked Sendable {} +extension Config.NetworkConfig: @unchecked Sendable {} +extension Config.NetworkConfig.AddressMode: @unchecked Sendable {} +extension Config.NetworkConfig.ProtocolFlags: @unchecked Sendable {} +extension Config.NetworkConfig.IpV4Config: @unchecked Sendable {} +extension Config.DisplayConfig: @unchecked Sendable {} +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 {} +extension Config.BluetoothConfig: @unchecked Sendable {} +extension Config.BluetoothConfig.PairingMode: @unchecked Sendable {} +extension Config.SecurityConfig: @unchecked Sendable {} +extension Config.SessionkeyConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -2327,7 +2432,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.onBatteryShutdownAfterSecs != 0 { try visitor.visitSingularUInt32Field(value: self.onBatteryShutdownAfterSecs, fieldNumber: 2) } - if self.adcMultiplierOverride.bitPattern != 0 { + if self.adcMultiplierOverride != 0 { try visitor.visitSingularFloatField(value: self.adcMultiplierOverride, fieldNumber: 3) } if self.waitBluetoothSecs != 0 { @@ -2636,6 +2741,7 @@ extension Config.DisplayConfig.OledType: SwiftProtobuf._ProtoNameProviding { 1: .same(proto: "OLED_SSD1306"), 2: .same(proto: "OLED_SH1106"), 3: .same(proto: "OLED_SH1107"), + 4: .same(proto: "OLED_SH1107_128_64"), ] } @@ -2794,7 +2900,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if _storage._codingRate != 0 { try visitor.visitSingularUInt32Field(value: _storage._codingRate, fieldNumber: 5) } - if _storage._frequencyOffset.bitPattern != 0 { + if _storage._frequencyOffset != 0 { try visitor.visitSingularFloatField(value: _storage._frequencyOffset, fieldNumber: 6) } if _storage._region != .unset { @@ -2818,7 +2924,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem if _storage._sx126XRxBoostedGain != false { try visitor.visitSingularBoolField(value: _storage._sx126XRxBoostedGain, fieldNumber: 13) } - if _storage._overrideFrequency.bitPattern != 0 { + if _storage._overrideFrequency != 0 { try visitor.visitSingularFloatField(value: _storage._overrideFrequency, fieldNumber: 14) } if _storage._paFanDisabled != false { @@ -3035,8 +3141,8 @@ extension Config.SessionkeyConfig: SwiftProtobuf.Message, SwiftProtobuf._Message public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let _ = try decoder.nextFieldNumber() { + } } public func traverse(visitor: inout V) throws { diff --git a/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift index 6847c0e3..a2ec180e 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/connection_status.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/connection_status.proto @@ -8,6 +7,7 @@ // 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 @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct DeviceConnectionStatus: Sendable { +public struct DeviceConnectionStatus { // 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. @@ -81,7 +81,7 @@ public struct DeviceConnectionStatus: Sendable { /// /// WiFi connection status -public struct WifiConnectionStatus: Sendable { +public struct WifiConnectionStatus { // 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. @@ -114,7 +114,7 @@ public struct WifiConnectionStatus: Sendable { /// /// Ethernet connection status -public struct EthernetConnectionStatus: Sendable { +public struct EthernetConnectionStatus { // 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. @@ -139,7 +139,7 @@ public struct EthernetConnectionStatus: Sendable { /// /// Ethernet or WiFi connection status -public struct NetworkConnectionStatus: Sendable { +public struct NetworkConnectionStatus { // 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. @@ -167,7 +167,7 @@ public struct NetworkConnectionStatus: Sendable { /// /// Bluetooth connection status -public struct BluetoothConnectionStatus: Sendable { +public struct BluetoothConnectionStatus { // 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. @@ -191,7 +191,7 @@ public struct BluetoothConnectionStatus: Sendable { /// /// Serial connection status -public struct SerialConnectionStatus: Sendable { +public struct SerialConnectionStatus { // 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. @@ -209,6 +209,15 @@ public struct SerialConnectionStatus: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension DeviceConnectionStatus: @unchecked Sendable {} +extension WifiConnectionStatus: @unchecked Sendable {} +extension EthernetConnectionStatus: @unchecked Sendable {} +extension NetworkConnectionStatus: @unchecked Sendable {} +extension BluetoothConnectionStatus: @unchecked Sendable {} +extension SerialConnectionStatus: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift index 0281d6c1..c3835518 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/device_ui.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/device_ui.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum Theme: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Theme: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -59,18 +58,24 @@ public enum Theme: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension Theme: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Theme] = [ .dark, .light, .red, ] - } +#endif // swift(>=4.2) + /// /// Localization -public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Language: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -137,6 +142,10 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { /// Slovenian case slovenian // = 15 + /// + /// Ukrainian + case ukrainian // = 16 + /// /// Simplified Chinese (experimental) case simplifiedChinese // = 30 @@ -168,6 +177,7 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { case 13: self = .greek case 14: self = .norwegian case 15: self = .slovenian + case 16: self = .ukrainian case 30: self = .simplifiedChinese case 31: self = .traditionalChinese default: self = .UNRECOGNIZED(rawValue) @@ -192,12 +202,18 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { case .greek: return 13 case .norwegian: return 14 case .slovenian: return 15 + case .ukrainian: return 16 case .simplifiedChinese: return 30 case .traditionalChinese: return 31 case .UNRECOGNIZED(let i): return i } } +} + +#if swift(>=4.2) + +extension Language: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Language] = [ .english, @@ -216,13 +232,15 @@ public enum Language: SwiftProtobuf.Enum, Swift.CaseIterable { .greek, .norwegian, .slovenian, + .ukrainian, .simplifiedChinese, .traditionalChinese, ] - } -public struct DeviceUIConfig: @unchecked Sendable { +#endif // swift(>=4.2) + +public struct DeviceUIConfig { // 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. @@ -343,7 +361,7 @@ public struct DeviceUIConfig: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } -public struct NodeFilter: Sendable { +public struct NodeFilter { // 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. @@ -381,7 +399,7 @@ public struct NodeFilter: Sendable { public init() {} } -public struct NodeHighlight: Sendable { +public struct NodeHighlight { // 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. @@ -411,7 +429,7 @@ public struct NodeHighlight: Sendable { public init() {} } -public struct GeoPoint: Sendable { +public struct GeoPoint { // 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. @@ -433,7 +451,7 @@ public struct GeoPoint: Sendable { public init() {} } -public struct Map: Sendable { +public struct Map { // 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. @@ -464,6 +482,16 @@ public struct Map: Sendable { fileprivate var _home: GeoPoint? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension Theme: @unchecked Sendable {} +extension Language: @unchecked Sendable {} +extension DeviceUIConfig: @unchecked Sendable {} +extension NodeFilter: @unchecked Sendable {} +extension NodeHighlight: @unchecked Sendable {} +extension GeoPoint: @unchecked Sendable {} +extension Map: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -494,6 +522,7 @@ extension Language: SwiftProtobuf._ProtoNameProviding { 13: .same(proto: "GREEK"), 14: .same(proto: "NORWEGIAN"), 15: .same(proto: "SLOVENIAN"), + 16: .same(proto: "UKRAINIAN"), 30: .same(proto: "SIMPLIFIED_CHINESE"), 31: .same(proto: "TRADITIONAL_CHINESE"), ] diff --git a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift index 72248719..9a5dfe8f 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/deviceonly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/deviceonly.proto @@ -23,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Position with static location information only for NodeDBLite -public struct PositionLite: Sendable { +public struct PositionLite { // 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. @@ -58,15 +57,13 @@ public struct PositionLite: Sendable { public init() {} } -public struct UserLite: @unchecked Sendable { +public struct UserLite { // 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. /// /// This is the addr of the radio. - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var macaddr: Data = Data() /// @@ -105,7 +102,7 @@ public struct UserLite: @unchecked Sendable { public init() {} } -public struct NodeInfoLite: @unchecked Sendable { +public struct NodeInfoLite { // 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. @@ -227,7 +224,7 @@ public struct NodeInfoLite: @unchecked Sendable { /// FIXME, since we write this each time we enter deep sleep (and have infinite /// flash) it would be better to use some sort of append only data structure for /// the receive queue and use the preferences store for the other stuff -public struct DeviceState: @unchecked Sendable { +public struct DeviceState { // 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. @@ -287,8 +284,6 @@ public struct DeviceState: @unchecked Sendable { /// Used only during development. /// Indicates developer is testing and changes should never be saved to flash. /// Deprecated in 2.3.1 - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var noSave: Bool { get {return _storage._noSave} set {_uniqueStorage()._noSave = newValue} @@ -297,8 +292,6 @@ public struct DeviceState: @unchecked Sendable { /// /// Previously used to manage GPS factory resets. /// Deprecated in 2.5.23 - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var didGpsReset: Bool { get {return _storage._didGpsReset} set {_uniqueStorage()._didGpsReset = newValue} @@ -331,7 +324,7 @@ public struct DeviceState: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } -public struct NodeDatabase: Sendable { +public struct NodeDatabase { // 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. @@ -353,7 +346,7 @@ public struct NodeDatabase: Sendable { /// /// The on-disk saved channels -public struct ChannelFile: Sendable { +public struct ChannelFile { // 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. @@ -375,7 +368,7 @@ public struct ChannelFile: Sendable { /// /// The on-disk backup of the node's preferences -public struct BackupPreferences: Sendable { +public struct BackupPreferences { // 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. @@ -442,6 +435,16 @@ public struct BackupPreferences: Sendable { fileprivate var _owner: User? = nil } +#if swift(>=5.5) && canImport(_Concurrency) +extension PositionLite: @unchecked Sendable {} +extension UserLite: @unchecked Sendable {} +extension NodeInfoLite: @unchecked Sendable {} +extension DeviceState: @unchecked Sendable {} +extension NodeDatabase: @unchecked Sendable {} +extension ChannelFile: @unchecked Sendable {} +extension BackupPreferences: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -677,7 +680,7 @@ extension NodeInfoLite: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat try { if let v = _storage._position { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() - if _storage._snr.bitPattern != 0 { + if _storage._snr != 0 { try visitor.visitSingularFloatField(value: _storage._snr, fieldNumber: 4) } if _storage._lastHeard != 0 { diff --git a/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift index 165ed685..92b72c15 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/interdevice.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/interdevice.proto @@ -8,6 +7,7 @@ // 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 @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum MessageType: SwiftProtobuf.Enum { public typealias RawValue = Int case ack // = 0 @@ -82,6 +82,11 @@ public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension MessageType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [MessageType] = [ .ack, @@ -97,10 +102,11 @@ public enum MessageType: SwiftProtobuf.Enum, Swift.CaseIterable { .aht20Humidity, .tvocIndex, ] - } -public struct SensorData: Sendable { +#endif // swift(>=4.2) + +public struct SensorData { // 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. @@ -130,16 +136,34 @@ public struct SensorData: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() /// The sensor data, either as a float or an uint32 - public enum OneOf_Data: Equatable, Sendable { + public enum OneOf_Data: Equatable { case floatValue(Float) case uint32Value(UInt32) + #if !swift(>=4.1) + public static func ==(lhs: SensorData.OneOf_Data, rhs: SensorData.OneOf_Data) -> 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 (.floatValue, .floatValue): return { + guard case .floatValue(let l) = lhs, case .floatValue(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.uint32Value, .uint32Value): return { + guard case .uint32Value(let l) = lhs, case .uint32Value(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} } -public struct InterdeviceMessage: Sendable { +public struct InterdeviceMessage { // 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. @@ -166,15 +190,41 @@ public struct InterdeviceMessage: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() /// The message data - public enum OneOf_Data: Equatable, Sendable { + public enum OneOf_Data: Equatable { case nmea(String) case sensor(SensorData) + #if !swift(>=4.1) + public static func ==(lhs: InterdeviceMessage.OneOf_Data, rhs: InterdeviceMessage.OneOf_Data) -> 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 (.nmea, .nmea): return { + guard case .nmea(let l) = lhs, case .nmea(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.sensor, .sensor): return { + guard case .sensor(let l) = lhs, case .sensor(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension MessageType: @unchecked Sendable {} +extension SensorData: @unchecked Sendable {} +extension SensorData.OneOf_Data: @unchecked Sendable {} +extension InterdeviceMessage: @unchecked Sendable {} +extension InterdeviceMessage.OneOf_Data: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift index c3356286..0af27466 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/localonly.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/localonly.proto @@ -8,6 +7,7 @@ // 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 @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct LocalConfig: @unchecked Sendable { +public struct LocalConfig { // 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. @@ -129,7 +129,7 @@ public struct LocalConfig: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } -public struct LocalModuleConfig: @unchecked Sendable { +public struct LocalModuleConfig { // 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. @@ -293,6 +293,11 @@ public struct LocalModuleConfig: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } +#if swift(>=5.5) && canImport(_Concurrency) +extension LocalConfig: @unchecked Sendable {} +extension LocalModuleConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift index 8c869ba8..051f395f 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mesh.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/mesh.proto @@ -26,7 +25,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// bin/build-all.sh script. /// Because they will be used to find firmware filenames in the android app for OTA updates. /// To match the old style filenames, _ is converted to -, p is converted to . -public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum HardwareModel: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -407,6 +406,41 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { /// Seeed XIAO nRF52840 + Wio SX1262 kit case xiaoNrf52Kit // = 88 + /// + /// Elecrow ThinkNode M1 & M2 + /// https://www.elecrow.com/wiki/ThinkNode-M1_Transceiver_Device(Meshtastic)_Power_By_nRF52840.html + /// https://www.elecrow.com/wiki/ThinkNode-M2_Transceiver_Device(Meshtastic)_Power_By_NRF52840.html (this actually uses ESP32-S3) + case thinknodeM1 // = 89 + case thinknodeM2 // = 90 + + /// + /// Lilygo T-ETH-Elite + case tEthElite // = 91 + + /// + /// Heltec HRI-3621 industrial probe + case heltecSensorHub // = 92 + + /// + /// Reserved Fried Chicken ID for future use + case reservedFriedChicken // = 93 + + /// + /// Heltec Magnetic Power Bank with Meshtastic compatible + case heltecMeshPocket // = 94 + + /// + /// Seeed Solar Node + case seeedSolarNode // = 95 + + /// + /// NomadStar Meteor Pro https://nomadstar.ch/ + case nomadstarMeteorPro // = 96 + + /// + /// Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin + case crowpanel // = 97 + /// /// ------------------------------------------------------------------------------------------------------------------------------------------ /// 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. @@ -509,6 +543,15 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { case 86: self = .meshTab case 87: self = .meshlink case 88: self = .xiaoNrf52Kit + case 89: self = .thinknodeM1 + case 90: self = .thinknodeM2 + case 91: self = .tEthElite + case 92: self = .heltecSensorHub + case 93: self = .reservedFriedChicken + case 94: self = .heltecMeshPocket + case 95: self = .seeedSolarNode + case 96: self = .nomadstarMeteorPro + case 97: self = .crowpanel case 255: self = .privateHw default: self = .UNRECOGNIZED(rawValue) } @@ -605,11 +648,25 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { case .meshTab: return 86 case .meshlink: return 87 case .xiaoNrf52Kit: return 88 + case .thinknodeM1: return 89 + case .thinknodeM2: return 90 + case .tEthElite: return 91 + case .heltecSensorHub: return 92 + case .reservedFriedChicken: return 93 + case .heltecMeshPocket: return 94 + case .seeedSolarNode: return 95 + case .nomadstarMeteorPro: return 96 + case .crowpanel: return 97 case .privateHw: return 255 case .UNRECOGNIZED(let i): return i } } +} + +#if swift(>=4.2) + +extension HardwareModel: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [HardwareModel] = [ .unset, @@ -701,14 +758,24 @@ public enum HardwareModel: SwiftProtobuf.Enum, Swift.CaseIterable { .meshTab, .meshlink, .xiaoNrf52Kit, + .thinknodeM1, + .thinknodeM2, + .tEthElite, + .heltecSensorHub, + .reservedFriedChicken, + .heltecMeshPocket, + .seeedSolarNode, + .nomadstarMeteorPro, + .crowpanel, .privateHw, ] - } +#endif // swift(>=4.2) + /// /// Shared constants between device and phone -public enum Constants: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum Constants: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -743,20 +810,26 @@ public enum Constants: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension Constants: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [Constants] = [ .zero, .dataPayloadLen, ] - } +#endif // swift(>=4.2) + /// /// Error codes for critical errors /// The device might report these fault codes on the screen. /// If you encounter a fault code, please post on the meshtastic.discourse.group /// and we'll try to help. -public enum CriticalErrorCode: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum CriticalErrorCode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -865,6 +938,11 @@ public enum CriticalErrorCode: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension CriticalErrorCode: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [CriticalErrorCode] = [ .none, @@ -882,14 +960,15 @@ public enum CriticalErrorCode: SwiftProtobuf.Enum, Swift.CaseIterable { .flashCorruptionRecoverable, .flashCorruptionUnrecoverable, ] - } +#endif // swift(>=4.2) + /// /// Enum for modules excluded from a device's configuration. /// Each value represents a ModuleConfigType that can be toggled as excluded /// by setting its corresponding bit in the `excluded_modules` bitmask field. -public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum ExcludedModules: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -947,6 +1026,14 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { /// /// Paxcounter module case paxcounterConfig // = 4096 + + /// + /// Bluetooth config (not technically a module, but used to indicate bluetooth capabilities) + case bluetoothConfig // = 8192 + + /// + /// Network config (not technically a module, but used to indicate network capabilities) + case networkConfig // = 16384 case UNRECOGNIZED(Int) public init() { @@ -969,6 +1056,8 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { case 1024: self = .ambientlightingConfig case 2048: self = .detectionsensorConfig case 4096: self = .paxcounterConfig + case 8192: self = .bluetoothConfig + case 16384: self = .networkConfig default: self = .UNRECOGNIZED(rawValue) } } @@ -989,10 +1078,17 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { case .ambientlightingConfig: return 1024 case .detectionsensorConfig: return 2048 case .paxcounterConfig: return 4096 + case .bluetoothConfig: return 8192 + case .networkConfig: return 16384 case .UNRECOGNIZED(let i): return i } } +} + +#if swift(>=4.2) + +extension ExcludedModules: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [ExcludedModules] = [ .excludedNone, @@ -1009,13 +1105,16 @@ public enum ExcludedModules: SwiftProtobuf.Enum, Swift.CaseIterable { .ambientlightingConfig, .detectionsensorConfig, .paxcounterConfig, + .bluetoothConfig, + .networkConfig, ] - } +#endif // swift(>=4.2) + /// /// A GPS Position -public struct Position: @unchecked Sendable { +public struct Position { // 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. @@ -1232,7 +1331,7 @@ public struct Position: @unchecked Sendable { /// /// How the location was acquired: manual, onboard GPS, external (EUD) GPS - public enum LocSource: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum LocSource: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1276,20 +1375,12 @@ public struct Position: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Position.LocSource] = [ - .locUnset, - .locManual, - .locInternal, - .locExternal, - ] - } /// /// How the altitude was acquired: manual, GPS int/ext, etc /// Default: same as location_source if present - public enum AltSource: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum AltSource: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1339,15 +1430,6 @@ public struct Position: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Position.AltSource] = [ - .altUnset, - .altManual, - .altInternal, - .altExternal, - .altBarometric, - ] - } public init() {} @@ -1355,6 +1437,31 @@ public struct Position: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } +#if swift(>=4.2) + +extension Position.LocSource: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Position.LocSource] = [ + .locUnset, + .locManual, + .locInternal, + .locExternal, + ] +} + +extension Position.AltSource: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Position.AltSource] = [ + .altUnset, + .altManual, + .altInternal, + .altExternal, + .altBarometric, + ] +} + +#endif // swift(>=4.2) + /// /// Broadcast when a newly powered mesh node wants to find a node num it can use /// Sent from the phone over bluetooth to set the user id for the owner of this node. @@ -1376,7 +1483,7 @@ public struct Position: @unchecked Sendable { /// A few nodenums are reserved and will never be requested: /// 0xff - broadcast /// 0 through 3 - for future use -public struct User: @unchecked Sendable { +public struct User { // 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. @@ -1401,8 +1508,6 @@ public struct User: @unchecked Sendable { /// Deprecated in Meshtastic 2.1.x /// This is the addr of the radio. /// Not populated by the phone, but added by the esp32 when broadcasting - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var macaddr: Data = Data() /// @@ -1434,7 +1539,7 @@ public struct User: @unchecked Sendable { /// /// A message used in a traceroute -public struct RouteDiscovery: Sendable { +public struct RouteDiscovery { // 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. @@ -1462,7 +1567,7 @@ public struct RouteDiscovery: Sendable { /// /// A Routing control Data packet handled by the routing module -public struct Routing: Sendable { +public struct Routing { // 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. @@ -1502,7 +1607,7 @@ public struct Routing: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_Variant: Equatable, Sendable { + public enum OneOf_Variant: Equatable { /// /// A route request going from the requester case routeRequest(RouteDiscovery) @@ -1514,12 +1619,34 @@ public struct Routing: Sendable { /// in addition to ack.fail_id to provide details on the type of failure). case errorReason(Routing.Error) + #if !swift(>=4.1) + public static func ==(lhs: Routing.OneOf_Variant, rhs: Routing.OneOf_Variant) -> 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 (.routeRequest, .routeRequest): return { + guard case .routeRequest(let l) = lhs, case .routeRequest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.routeReply, .routeReply): return { + guard case .routeReply(let l) = lhs, case .routeReply(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.errorReason, .errorReason): return { + guard case .errorReason(let l) = lhs, case .errorReason(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// A failure in delivering a message (usually used for routing control messages, but might be provided in addition to ack.fail_id to provide /// details on the type of failure). - public enum Error: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Error: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1637,36 +1764,42 @@ public struct Routing: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [Routing.Error] = [ - .none, - .noRoute, - .gotNak, - .timeout, - .noInterface, - .maxRetransmit, - .noChannel, - .tooLarge, - .noResponse, - .dutyCycleLimit, - .badRequest, - .notAuthorized, - .pkiFailed, - .pkiUnknownPubkey, - .adminBadSessionKey, - .adminPublicKeyUnauthorized, - ] - } public init() {} } +#if swift(>=4.2) + +extension Routing.Error: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [Routing.Error] = [ + .none, + .noRoute, + .gotNak, + .timeout, + .noInterface, + .maxRetransmit, + .noChannel, + .tooLarge, + .noResponse, + .dutyCycleLimit, + .badRequest, + .notAuthorized, + .pkiFailed, + .pkiUnknownPubkey, + .adminBadSessionKey, + .adminPublicKeyUnauthorized, + ] +} + +#endif // swift(>=4.2) + /// /// (Formerly called SubPacket) /// The payload portion fo a packet, this is the actual bytes that are sent /// inside a radio packet (because from/to are broken out by the comms library) -public struct DataMessage: @unchecked Sendable { +public struct DataMessage { // 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. @@ -1733,7 +1866,7 @@ public struct DataMessage: @unchecked Sendable { /// /// Waypoint message, used to share arbitrary locations across the mesh -public struct Waypoint: Sendable { +public struct Waypoint { // 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. @@ -1795,7 +1928,7 @@ public struct Waypoint: Sendable { /// /// This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server -public struct MqttClientProxyMessage: @unchecked Sendable { +public struct MqttClientProxyMessage { // 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. @@ -1836,7 +1969,7 @@ public struct MqttClientProxyMessage: @unchecked Sendable { /// /// The actual service envelope payload or text for mqtt pub / sub - public enum OneOf_PayloadVariant: Equatable, @unchecked Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Bytes case data(Data) @@ -1844,6 +1977,24 @@ public struct MqttClientProxyMessage: @unchecked Sendable { /// Text case text(String) + #if !swift(>=4.1) + public static func ==(lhs: MqttClientProxyMessage.OneOf_PayloadVariant, rhs: MqttClientProxyMessage.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 (.data, .data): return { + guard case .data(let l) = lhs, case .data(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.text, .text): return { + guard case .text(let l) = lhs, case .text(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -1853,7 +2004,7 @@ public struct MqttClientProxyMessage: @unchecked Sendable { /// A packet envelope sent/received over the mesh /// only payload_variant is sent in the payload portion of the LORA packet. /// The other fields are either not sent at all, or sent in the special 16 byte LORA header. -public struct MeshPacket: @unchecked Sendable { +public struct MeshPacket { // 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. @@ -1987,8 +2138,6 @@ public struct MeshPacket: @unchecked Sendable { /// /// Describe if this message is delayed - /// - /// NOTE: This field was marked as deprecated in the .proto file. public var delayed: MeshPacket.Delayed { get {return _storage._delayed} set {_uniqueStorage()._delayed = newValue} @@ -2050,7 +2199,7 @@ public struct MeshPacket: @unchecked Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_PayloadVariant: Equatable, @unchecked Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// TODO: REPLACE case decoded(DataMessage) @@ -2058,6 +2207,24 @@ public struct MeshPacket: @unchecked Sendable { /// TODO: REPLACE case encrypted(Data) + #if !swift(>=4.1) + public static func ==(lhs: MeshPacket.OneOf_PayloadVariant, rhs: MeshPacket.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 (.decoded, .decoded): return { + guard case .decoded(let l) = lhs, case .decoded(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.encrypted, .encrypted): return { + guard case .encrypted(let l) = lhs, case .encrypted(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// @@ -2079,7 +2246,7 @@ public struct MeshPacket: @unchecked Sendable { /// So I bit the bullet and implemented a new (internal - not sent over the air) /// field in MeshPacket called 'priority'. /// And the transmission queue in the router object is now a priority queue. - public enum Priority: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Priority: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -2163,25 +2330,11 @@ public struct MeshPacket: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [MeshPacket.Priority] = [ - .unset, - .min, - .background, - .default, - .reliable, - .response, - .high, - .alert, - .ack, - .max, - ] - } /// /// Identify if this is a delayed packet - public enum Delayed: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Delayed: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -2219,13 +2372,6 @@ public struct MeshPacket: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [MeshPacket.Delayed] = [ - .noDelay, - .broadcast, - .direct, - ] - } public init() {} @@ -2233,6 +2379,35 @@ public struct MeshPacket: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } +#if swift(>=4.2) + +extension MeshPacket.Priority: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [MeshPacket.Priority] = [ + .unset, + .min, + .background, + .default, + .reliable, + .response, + .high, + .alert, + .ack, + .max, + ] +} + +extension MeshPacket.Delayed: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [MeshPacket.Delayed] = [ + .noDelay, + .broadcast, + .direct, + ] +} + +#endif // swift(>=4.2) + /// /// The bluetooth to device link: /// Old BTLE protocol docs from TODO, merge in above and make real docs... @@ -2250,7 +2425,7 @@ public struct MeshPacket: @unchecked Sendable { /// level etc) SET_CONFIG (switches device to a new set of radio params and /// preshared key, drops all existing nodes, force our node to rejoin this new group) /// Full information about a node on the mesh -public struct NodeInfo: @unchecked Sendable { +public struct NodeInfo { // 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. @@ -2363,7 +2538,7 @@ public struct NodeInfo: @unchecked Sendable { /// Unique local debugging info for this node /// Note: we don't include position or the user info, because that will come in the /// Sent to the phone in response to WantNodes. -public struct MyNodeInfo: @unchecked Sendable { +public struct MyNodeInfo { // 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. @@ -2402,7 +2577,7 @@ public struct MyNodeInfo: @unchecked Sendable { /// on the message it is assumed to be a continuation of the previously sent message. /// This allows the device code to use fixed maxlen 64 byte strings for messages, /// and then extend as needed by emitting multiple records. -public struct LogRecord: Sendable { +public struct LogRecord { // 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. @@ -2427,7 +2602,7 @@ public struct LogRecord: Sendable { /// /// Log levels, chosen to match python logging conventions. - public enum Level: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Level: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -2489,23 +2664,29 @@ public struct LogRecord: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [LogRecord.Level] = [ - .unset, - .critical, - .error, - .warning, - .info, - .debug, - .trace, - ] - } public init() {} } -public struct QueueStatus: Sendable { +#if swift(>=4.2) + +extension LogRecord.Level: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [LogRecord.Level] = [ + .unset, + .critical, + .error, + .warning, + .info, + .debug, + .trace, + ] +} + +#endif // swift(>=4.2) + +public struct QueueStatus { // 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. @@ -2532,7 +2713,7 @@ public struct QueueStatus: Sendable { /// It will support READ and NOTIFY. When a new packet arrives the device will BLE notify? /// It will sit in that descriptor until consumed by the phone, /// at which point the next item in the FIFO will be populated. -public struct FromRadio: Sendable { +public struct FromRadio { // 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. @@ -2718,7 +2899,7 @@ public struct FromRadio: Sendable { /// /// Log levels, chosen to match python logging conventions. - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Log levels, chosen to match python logging conventions. case packet(MeshPacket) @@ -2776,6 +2957,80 @@ public struct FromRadio: Sendable { /// Persistent data for device-ui case deviceuiConfig(DeviceUIConfig) + #if !swift(>=4.1) + public static func ==(lhs: FromRadio.OneOf_PayloadVariant, rhs: FromRadio.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 (.packet, .packet): return { + guard case .packet(let l) = lhs, case .packet(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.myInfo, .myInfo): return { + guard case .myInfo(let l) = lhs, case .myInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.nodeInfo, .nodeInfo): return { + guard case .nodeInfo(let l) = lhs, case .nodeInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.config, .config): return { + guard case .config(let l) = lhs, case .config(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.logRecord, .logRecord): return { + guard case .logRecord(let l) = lhs, case .logRecord(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.configCompleteID, .configCompleteID): return { + guard case .configCompleteID(let l) = lhs, case .configCompleteID(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rebooted, .rebooted): return { + guard case .rebooted(let l) = lhs, case .rebooted(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.moduleConfig, .moduleConfig): return { + guard case .moduleConfig(let l) = lhs, case .moduleConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.channel, .channel): return { + guard case .channel(let l) = lhs, case .channel(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.queueStatus, .queueStatus): return { + guard case .queueStatus(let l) = lhs, case .queueStatus(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.xmodemPacket, .xmodemPacket): return { + guard case .xmodemPacket(let l) = lhs, case .xmodemPacket(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.metadata, .metadata): return { + guard case .metadata(let l) = lhs, case .metadata(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.mqttClientProxyMessage, .mqttClientProxyMessage): return { + guard case .mqttClientProxyMessage(let l) = lhs, case .mqttClientProxyMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.fileInfo, .fileInfo): return { + guard case .fileInfo(let l) = lhs, case .fileInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.clientNotification, .clientNotification): return { + guard case .clientNotification(let l) = lhs, case .clientNotification(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.deviceuiConfig, .deviceuiConfig): return { + guard case .deviceuiConfig(let l) = lhs, case .deviceuiConfig(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -2786,7 +3041,7 @@ public struct FromRadio: Sendable { /// To be used for important messages that should to be displayed to the user /// in the form of push notifications or validation messages when saving /// invalid configuration. -public struct ClientNotification: Sendable { +public struct ClientNotification { // 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. @@ -2823,7 +3078,7 @@ public struct ClientNotification: Sendable { /// /// Individual File info for the device -public struct FileInfo: Sendable { +public struct FileInfo { // 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. @@ -2844,7 +3099,7 @@ public struct FileInfo: Sendable { /// /// Packets/commands to the radio will be written (reliably) to the toRadio characteristic. /// Once the write completes the phone can assume it is handled. -public struct ToRadio: Sendable { +public struct ToRadio { // 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. @@ -2924,7 +3179,7 @@ public struct ToRadio: Sendable { /// /// Log levels, chosen to match python logging conventions. - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Send this packet on the mesh case packet(MeshPacket) @@ -2951,6 +3206,40 @@ public struct ToRadio: Sendable { /// Heartbeat message (used to keep the device connection awake on serial) case heartbeat(Heartbeat) + #if !swift(>=4.1) + public static func ==(lhs: ToRadio.OneOf_PayloadVariant, rhs: ToRadio.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 (.packet, .packet): return { + guard case .packet(let l) = lhs, case .packet(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.wantConfigID, .wantConfigID): return { + guard case .wantConfigID(let l) = lhs, case .wantConfigID(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.disconnect, .disconnect): return { + guard case .disconnect(let l) = lhs, case .disconnect(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.xmodemPacket, .xmodemPacket): return { + guard case .xmodemPacket(let l) = lhs, case .xmodemPacket(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.mqttClientProxyMessage, .mqttClientProxyMessage): return { + guard case .mqttClientProxyMessage(let l) = lhs, case .mqttClientProxyMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.heartbeat, .heartbeat): return { + guard case .heartbeat(let l) = lhs, case .heartbeat(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -2958,7 +3247,7 @@ public struct ToRadio: Sendable { /// /// Compressed message payload -public struct Compressed: @unchecked Sendable { +public struct Compressed { // 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. @@ -2978,7 +3267,7 @@ public struct Compressed: @unchecked Sendable { /// /// Full info on edges for a single node -public struct NeighborInfo: Sendable { +public struct NeighborInfo { // 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. @@ -3006,7 +3295,7 @@ public struct NeighborInfo: Sendable { /// /// A single edge in the mesh -public struct Neighbor: Sendable { +public struct Neighbor { // 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. @@ -3036,7 +3325,7 @@ public struct Neighbor: Sendable { /// /// Device metadata response -public struct DeviceMetadata: Sendable { +public struct DeviceMetadata { // 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. @@ -3098,7 +3387,7 @@ public struct DeviceMetadata: Sendable { /// /// A heartbeat message is sent to the node from the client to keep the connection alive. /// This is currently only needed to keep serial connections alive, but can be used by any PhoneAPI. -public struct Heartbeat: Sendable { +public struct Heartbeat { // 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. @@ -3110,7 +3399,7 @@ public struct Heartbeat: Sendable { /// /// RemoteHardwarePins associated with a node -public struct NodeRemoteHardwarePin: Sendable { +public struct NodeRemoteHardwarePin { // 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. @@ -3137,7 +3426,7 @@ public struct NodeRemoteHardwarePin: Sendable { fileprivate var _pin: RemoteHardwarePin? = nil } -public struct ChunkedPayload: @unchecked Sendable { +public 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. @@ -3165,7 +3454,7 @@ public struct ChunkedPayload: @unchecked Sendable { /// /// Wrapper message for broken repeated oneof support -public struct resend_chunks: Sendable { +public 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. @@ -3179,7 +3468,7 @@ public struct resend_chunks: Sendable { /// /// Responses to a ChunkedPayload request -public struct ChunkedPayloadResponse: Sendable { +public 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. @@ -3222,7 +3511,7 @@ public struct ChunkedPayloadResponse: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// Request to transfer chunked payload case requestTransfer(Bool) @@ -3233,11 +3522,77 @@ public struct ChunkedPayloadResponse: Sendable { /// Request missing indexes in the chunked payload case resendChunks(resend_chunks) + #if !swift(>=4.1) + public 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 } public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension HardwareModel: @unchecked Sendable {} +extension Constants: @unchecked Sendable {} +extension CriticalErrorCode: @unchecked Sendable {} +extension ExcludedModules: @unchecked Sendable {} +extension Position: @unchecked Sendable {} +extension Position.LocSource: @unchecked Sendable {} +extension Position.AltSource: @unchecked Sendable {} +extension User: @unchecked Sendable {} +extension RouteDiscovery: @unchecked Sendable {} +extension Routing: @unchecked Sendable {} +extension Routing.OneOf_Variant: @unchecked Sendable {} +extension Routing.Error: @unchecked Sendable {} +extension DataMessage: @unchecked Sendable {} +extension Waypoint: @unchecked Sendable {} +extension MqttClientProxyMessage: @unchecked Sendable {} +extension MqttClientProxyMessage.OneOf_PayloadVariant: @unchecked Sendable {} +extension MeshPacket: @unchecked Sendable {} +extension MeshPacket.OneOf_PayloadVariant: @unchecked Sendable {} +extension MeshPacket.Priority: @unchecked Sendable {} +extension MeshPacket.Delayed: @unchecked Sendable {} +extension NodeInfo: @unchecked Sendable {} +extension MyNodeInfo: @unchecked Sendable {} +extension LogRecord: @unchecked Sendable {} +extension LogRecord.Level: @unchecked Sendable {} +extension QueueStatus: @unchecked Sendable {} +extension FromRadio: @unchecked Sendable {} +extension FromRadio.OneOf_PayloadVariant: @unchecked Sendable {} +extension ClientNotification: @unchecked Sendable {} +extension FileInfo: @unchecked Sendable {} +extension ToRadio: @unchecked Sendable {} +extension ToRadio.OneOf_PayloadVariant: @unchecked Sendable {} +extension Compressed: @unchecked Sendable {} +extension NeighborInfo: @unchecked Sendable {} +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. fileprivate let _protobuf_package = "meshtastic" @@ -3333,6 +3688,15 @@ extension HardwareModel: SwiftProtobuf._ProtoNameProviding { 86: .same(proto: "MESH_TAB"), 87: .same(proto: "MESHLINK"), 88: .same(proto: "XIAO_NRF52_KIT"), + 89: .same(proto: "THINKNODE_M1"), + 90: .same(proto: "THINKNODE_M2"), + 91: .same(proto: "T_ETH_ELITE"), + 92: .same(proto: "HELTEC_SENSOR_HUB"), + 93: .same(proto: "RESERVED_FRIED_CHICKEN"), + 94: .same(proto: "HELTEC_MESH_POCKET"), + 95: .same(proto: "SEEED_SOLAR_NODE"), + 96: .same(proto: "NOMADSTAR_METEOR_PRO"), + 97: .same(proto: "CROWPANEL"), 255: .same(proto: "PRIVATE_HW"), ] } @@ -3379,6 +3743,8 @@ extension ExcludedModules: SwiftProtobuf._ProtoNameProviding { 1024: .same(proto: "AMBIENTLIGHTING_CONFIG"), 2048: .same(proto: "DETECTIONSENSOR_CONFIG"), 4096: .same(proto: "PAXCOUNTER_CONFIG"), + 8192: .same(proto: "BLUETOOTH_CONFIG"), + 16384: .same(proto: "NETWORK_CONFIG"), ] } @@ -4288,7 +4654,7 @@ extension MeshPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if _storage._rxTime != 0 { try visitor.visitSingularFixed32Field(value: _storage._rxTime, fieldNumber: 7) } - if _storage._rxSnr.bitPattern != 0 { + if _storage._rxSnr != 0 { try visitor.visitSingularFloatField(value: _storage._rxSnr, fieldNumber: 8) } if _storage._hopLimit != 0 { @@ -4490,7 +4856,7 @@ extension NodeInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB try { if let v = _storage._position { try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() - if _storage._snr.bitPattern != 0 { + if _storage._snr != 0 { try visitor.visitSingularFloatField(value: _storage._snr, fieldNumber: 4) } if _storage._lastHeard != 0 { @@ -5369,7 +5735,7 @@ extension Neighbor: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB if self.nodeID != 0 { try visitor.visitSingularUInt32Field(value: self.nodeID, fieldNumber: 1) } - if self.snr.bitPattern != 0 { + if self.snr != 0 { try visitor.visitSingularFloatField(value: self.snr, fieldNumber: 2) } if self.lastRxTime != 0 { @@ -5494,8 +5860,8 @@ extension Heartbeat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementation public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let _ = try decoder.nextFieldNumber() { + } } public func traverse(visitor: inout V) throws { diff --git a/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift index 0138ccff..bcf4041c 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/module_config.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/module_config.proto @@ -8,6 +7,7 @@ // 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 @@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public enum RemoteHardwarePinType: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum RemoteHardwarePinType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -58,18 +58,24 @@ public enum RemoteHardwarePinType: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension RemoteHardwarePinType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [RemoteHardwarePinType] = [ .unknown, .digitalRead, .digitalWrite, ] - } +#endif // swift(>=4.2) + /// /// Module Config -public struct ModuleConfig: Sendable { +public struct ModuleConfig { // 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. @@ -212,7 +218,7 @@ public struct ModuleConfig: Sendable { /// /// TODO: REPLACE - public enum OneOf_PayloadVariant: Equatable, Sendable { + public enum OneOf_PayloadVariant: Equatable { /// /// TODO: REPLACE case mqtt(ModuleConfig.MQTTConfig) @@ -253,11 +259,73 @@ public struct ModuleConfig: Sendable { /// TODO: REPLACE case paxcounter(ModuleConfig.PaxcounterConfig) + #if !swift(>=4.1) + public static func ==(lhs: ModuleConfig.OneOf_PayloadVariant, rhs: ModuleConfig.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 (.mqtt, .mqtt): return { + guard case .mqtt(let l) = lhs, case .mqtt(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.serial, .serial): return { + guard case .serial(let l) = lhs, case .serial(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.externalNotification, .externalNotification): return { + guard case .externalNotification(let l) = lhs, case .externalNotification(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.storeForward, .storeForward): return { + guard case .storeForward(let l) = lhs, case .storeForward(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.rangeTest, .rangeTest): return { + guard case .rangeTest(let l) = lhs, case .rangeTest(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.telemetry, .telemetry): return { + guard case .telemetry(let l) = lhs, case .telemetry(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.cannedMessage, .cannedMessage): return { + guard case .cannedMessage(let l) = lhs, case .cannedMessage(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.audio, .audio): return { + guard case .audio(let l) = lhs, case .audio(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.remoteHardware, .remoteHardware): return { + guard case .remoteHardware(let l) = lhs, case .remoteHardware(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.neighborInfo, .neighborInfo): return { + guard case .neighborInfo(let l) = lhs, case .neighborInfo(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.ambientLighting, .ambientLighting): return { + guard case .ambientLighting(let l) = lhs, case .ambientLighting(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.detectionSensor, .detectionSensor): return { + guard case .detectionSensor(let l) = lhs, case .detectionSensor(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.paxcounter, .paxcounter): return { + guard case .paxcounter(let l) = lhs, case .paxcounter(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// MQTT Client Config - public struct MQTTConfig: Sendable { + public struct MQTTConfig { // 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. @@ -332,7 +400,7 @@ public struct ModuleConfig: Sendable { /// /// Settings for reporting unencrypted information about our node to a map via MQTT - public struct MapReportSettings: Sendable { + public struct MapReportSettings { // 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. @@ -352,7 +420,7 @@ public struct ModuleConfig: Sendable { /// /// RemoteHardwareModule Config - public struct RemoteHardwareConfig: Sendable { + public struct RemoteHardwareConfig { // 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. @@ -376,7 +444,7 @@ public struct ModuleConfig: Sendable { /// /// NeighborInfoModule Config - public struct NeighborInfoConfig: Sendable { + public struct NeighborInfoConfig { // 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. @@ -402,7 +470,7 @@ public struct ModuleConfig: Sendable { /// /// Detection Sensor Module Config - public struct DetectionSensorConfig: Sendable { + public struct DetectionSensorConfig { // 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. @@ -449,7 +517,7 @@ public struct ModuleConfig: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum TriggerType: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum TriggerType: SwiftProtobuf.Enum { public typealias RawValue = Int /// Event is triggered if pin is low @@ -501,16 +569,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.DetectionSensorConfig.TriggerType] = [ - .logicLow, - .logicHigh, - .fallingEdge, - .risingEdge, - .eitherEdgeActiveLow, - .eitherEdgeActiveHigh, - ] - } public init() {} @@ -518,7 +576,7 @@ public struct ModuleConfig: Sendable { /// /// Audio Config for codec2 voice - public struct AudioConfig: Sendable { + public struct AudioConfig { // 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. @@ -555,7 +613,7 @@ public struct ModuleConfig: Sendable { /// /// Baudrate for codec2 voice - public enum Audio_Baud: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Audio_Baud: SwiftProtobuf.Enum { public typealias RawValue = Int case codec2Default // = 0 case codec23200 // = 1 @@ -602,19 +660,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.AudioConfig.Audio_Baud] = [ - .codec2Default, - .codec23200, - .codec22400, - .codec21600, - .codec21400, - .codec21300, - .codec21200, - .codec2700, - .codec2700B, - ] - } public init() {} @@ -622,7 +667,7 @@ public struct ModuleConfig: Sendable { /// /// Config for the Paxcounter Module - public struct PaxcounterConfig: Sendable { + public struct PaxcounterConfig { // 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. @@ -648,7 +693,7 @@ public struct ModuleConfig: Sendable { /// /// Serial Config - public struct SerialConfig: Sendable { + public struct SerialConfig { // 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. @@ -691,7 +736,7 @@ public struct ModuleConfig: Sendable { /// /// TODO: REPLACE - public enum Serial_Baud: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Serial_Baud: SwiftProtobuf.Enum { public typealias RawValue = Int case baudDefault // = 0 case baud110 // = 1 @@ -759,31 +804,11 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.SerialConfig.Serial_Baud] = [ - .baudDefault, - .baud110, - .baud300, - .baud600, - .baud1200, - .baud2400, - .baud4800, - .baud9600, - .baud19200, - .baud38400, - .baud57600, - .baud115200, - .baud230400, - .baud460800, - .baud576000, - .baud921600, - ] - } /// /// TODO: REPLACE - public enum Serial_Mode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Serial_Mode: SwiftProtobuf.Enum { public typealias RawValue = Int case `default` // = 0 case simple // = 1 @@ -828,17 +853,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [ - .default, - .simple, - .proto, - .textmsg, - .nmea, - .caltopo, - .ws85, - ] - } public init() {} @@ -846,7 +860,7 @@ public struct ModuleConfig: Sendable { /// /// External Notifications Config - public struct ExternalNotificationConfig: Sendable { + public struct ExternalNotificationConfig { // 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. @@ -929,7 +943,7 @@ public struct ModuleConfig: Sendable { /// /// Store and Forward Module Config - public struct StoreForwardConfig: Sendable { + public struct StoreForwardConfig { // 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. @@ -965,7 +979,7 @@ public struct ModuleConfig: Sendable { /// /// Preferences for the RangeTestModule - public struct RangeTestConfig: Sendable { + public struct RangeTestConfig { // 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. @@ -990,7 +1004,7 @@ public struct ModuleConfig: Sendable { /// /// Configuration for both device and environment metrics - public struct TelemetryConfig: Sendable { + public struct TelemetryConfig { // 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. @@ -1059,7 +1073,7 @@ public struct ModuleConfig: Sendable { /// /// Canned Messages Module Config - public struct CannedMessageConfig: Sendable { + public struct CannedMessageConfig { // 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. @@ -1114,7 +1128,7 @@ public struct ModuleConfig: Sendable { /// /// TODO: REPLACE - public enum InputEventChar: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum InputEventChar: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -1182,18 +1196,6 @@ public struct ModuleConfig: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [ - .none, - .up, - .down, - .left, - .right, - .select, - .back, - .cancel, - ] - } public init() {} @@ -1202,7 +1204,7 @@ public struct ModuleConfig: Sendable { /// ///Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels. ///Initially created for the RAK14001 RGB LED module. - public struct AmbientLightingConfig: Sendable { + public struct AmbientLightingConfig { // 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. @@ -1235,9 +1237,89 @@ public struct ModuleConfig: Sendable { public init() {} } +#if swift(>=4.2) + +extension ModuleConfig.DetectionSensorConfig.TriggerType: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.DetectionSensorConfig.TriggerType] = [ + .logicLow, + .logicHigh, + .fallingEdge, + .risingEdge, + .eitherEdgeActiveLow, + .eitherEdgeActiveHigh, + ] +} + +extension ModuleConfig.AudioConfig.Audio_Baud: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.AudioConfig.Audio_Baud] = [ + .codec2Default, + .codec23200, + .codec22400, + .codec21600, + .codec21400, + .codec21300, + .codec21200, + .codec2700, + .codec2700B, + ] +} + +extension ModuleConfig.SerialConfig.Serial_Baud: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.SerialConfig.Serial_Baud] = [ + .baudDefault, + .baud110, + .baud300, + .baud600, + .baud1200, + .baud2400, + .baud4800, + .baud9600, + .baud19200, + .baud38400, + .baud57600, + .baud115200, + .baud230400, + .baud460800, + .baud576000, + .baud921600, + ] +} + +extension ModuleConfig.SerialConfig.Serial_Mode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [ + .default, + .simple, + .proto, + .textmsg, + .nmea, + .caltopo, + .ws85, + ] +} + +extension ModuleConfig.CannedMessageConfig.InputEventChar: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [ + .none, + .up, + .down, + .left, + .right, + .select, + .back, + .cancel, + ] +} + +#endif // swift(>=4.2) + /// /// A GPIO pin definition for remote hardware module -public struct RemoteHardwarePin: Sendable { +public struct RemoteHardwarePin { // 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. @@ -1259,6 +1341,32 @@ public struct RemoteHardwarePin: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension RemoteHardwarePinType: @unchecked Sendable {} +extension ModuleConfig: @unchecked Sendable {} +extension ModuleConfig.OneOf_PayloadVariant: @unchecked Sendable {} +extension ModuleConfig.MQTTConfig: @unchecked Sendable {} +extension ModuleConfig.MapReportSettings: @unchecked Sendable {} +extension ModuleConfig.RemoteHardwareConfig: @unchecked Sendable {} +extension ModuleConfig.NeighborInfoConfig: @unchecked Sendable {} +extension ModuleConfig.DetectionSensorConfig: @unchecked Sendable {} +extension ModuleConfig.DetectionSensorConfig.TriggerType: @unchecked Sendable {} +extension ModuleConfig.AudioConfig: @unchecked Sendable {} +extension ModuleConfig.AudioConfig.Audio_Baud: @unchecked Sendable {} +extension ModuleConfig.PaxcounterConfig: @unchecked Sendable {} +extension ModuleConfig.SerialConfig: @unchecked Sendable {} +extension ModuleConfig.SerialConfig.Serial_Baud: @unchecked Sendable {} +extension ModuleConfig.SerialConfig.Serial_Mode: @unchecked Sendable {} +extension ModuleConfig.ExternalNotificationConfig: @unchecked Sendable {} +extension ModuleConfig.StoreForwardConfig: @unchecked Sendable {} +extension ModuleConfig.RangeTestConfig: @unchecked Sendable {} +extension ModuleConfig.TelemetryConfig: @unchecked Sendable {} +extension ModuleConfig.CannedMessageConfig: @unchecked Sendable {} +extension ModuleConfig.CannedMessageConfig.InputEventChar: @unchecked Sendable {} +extension ModuleConfig.AmbientLightingConfig: @unchecked Sendable {} +extension RemoteHardwarePin: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift index 006fd9c8..efe6cdd5 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/mqtt.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/mqtt.proto @@ -8,6 +7,7 @@ // 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 @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// This message wraps a MeshPacket with extra metadata about the sender and how it arrived. -public struct ServiceEnvelope: Sendable { +public struct ServiceEnvelope { // 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. @@ -57,7 +57,7 @@ public struct ServiceEnvelope: Sendable { /// /// Information about a node intended to be reported unencrypted to a map using MQTT. -public struct MapReport: Sendable { +public struct MapReport { // 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. @@ -121,6 +121,11 @@ public struct MapReport: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension ServiceEnvelope: @unchecked Sendable {} +extension MapReport: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift index e24ed371..cf8aa463 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/paxcount.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/paxcount.proto @@ -8,6 +7,7 @@ // 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 @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// TODO: REPLACE -public struct Paxcount: Sendable { +public struct Paxcount { // 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. @@ -44,6 +44,10 @@ public struct Paxcount: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension Paxcount: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift index cac96bc4..3b0efa08 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/portnums.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/portnums.proto @@ -8,6 +7,7 @@ // 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 @@ -33,7 +33,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// Note: This was formerly a Type enum named 'typ' with the same id # /// We have change to this 'portnum' based scheme for specifying app handlers for particular payloads. /// This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically. -public enum PortNum: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum PortNum: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -290,6 +290,11 @@ public enum PortNum: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension PortNum: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [PortNum] = [ .unknownApp, @@ -323,9 +328,14 @@ public enum PortNum: SwiftProtobuf.Enum, Swift.CaseIterable { .atakForwarder, .max, ] - } +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension PortNum: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. extension PortNum: SwiftProtobuf._ProtoNameProviding { diff --git a/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift index 58c21701..5f51e948 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/powermon.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/powermon.proto @@ -8,6 +7,7 @@ // 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 @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// 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) -public struct PowerMon: Sendable { +public 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. @@ -31,7 +31,7 @@ public struct PowerMon: Sendable { /// 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. - public enum State: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum State: SwiftProtobuf.Enum { public typealias RawValue = Int case none // = 0 case cpuDeepSleep // = 1 @@ -104,31 +104,37 @@ public struct PowerMon: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [PowerMon.State] = [ - .none, - .cpuDeepSleep, - .cpuLightSleep, - .vext1On, - .loraRxon, - .loraTxon, - .loraRxactive, - .btOn, - .ledOn, - .screenOn, - .screenDrawing, - .wifiOn, - .gpsActive, - ] - } public init() {} } +#if swift(>=4.2) + +extension PowerMon.State: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [PowerMon.State] = [ + .none, + .cpuDeepSleep, + .cpuLightSleep, + .vext1On, + .loraRxon, + .loraTxon, + .loraRxactive, + .btOn, + .ledOn, + .screenOn, + .screenDrawing, + .wifiOn, + .gpsActive, + ] +} + +#endif // swift(>=4.2) + /// /// PowerStress testing support via the C++ PowerStress module -public struct PowerStressMessage: Sendable { +public struct PowerStressMessage { // 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. @@ -145,7 +151,7 @@ public struct PowerStressMessage: Sendable { /// What operation would we like the UUT to perform. ///note: senders should probably set want_response in their request packets, so that they can know when the state ///machine has started processing their request - public enum Opcode: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Opcode: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -266,35 +272,48 @@ public struct PowerStressMessage: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [PowerStressMessage.Opcode] = [ - .unset, - .printInfo, - .forceQuiet, - .endQuiet, - .screenOn, - .screenOff, - .cpuIdle, - .cpuDeepsleep, - .cpuFullon, - .ledOn, - .ledOff, - .loraOff, - .loraTx, - .loraRx, - .btOff, - .btOn, - .wifiOff, - .wifiOn, - .gpsOff, - .gpsOn, - ] - } public init() {} } +#if swift(>=4.2) + +extension PowerStressMessage.Opcode: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [PowerStressMessage.Opcode] = [ + .unset, + .printInfo, + .forceQuiet, + .endQuiet, + .screenOn, + .screenOff, + .cpuIdle, + .cpuDeepsleep, + .cpuFullon, + .ledOn, + .ledOff, + .loraOff, + .loraTx, + .loraRx, + .btOff, + .btOn, + .wifiOff, + .wifiOn, + .gpsOff, + .gpsOn, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension PowerMon: @unchecked Sendable {} +extension PowerMon.State: @unchecked Sendable {} +extension PowerStressMessage: @unchecked Sendable {} +extension PowerStressMessage.Opcode: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" @@ -304,8 +323,8 @@ extension PowerMon: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB public static let _protobuf_nameMap = SwiftProtobuf._NameMap() public mutating func decodeMessage(decoder: inout D) throws { - // Load everything into unknown fields - while try decoder.nextFieldNumber() != nil {} + while let _ = try decoder.nextFieldNumber() { + } } public func traverse(visitor: inout V) throws { @@ -360,7 +379,7 @@ extension PowerStressMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.cmd != .unset { try visitor.visitSingularEnumField(value: self.cmd, fieldNumber: 1) } - if self.numSeconds.bitPattern != 0 { + if self.numSeconds != 0 { try visitor.visitSingularFloatField(value: self.numSeconds, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) diff --git a/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift index d23dc07b..ac6eeb26 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/remote_hardware.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/remote_hardware.proto @@ -8,6 +7,7 @@ // 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 @@ -30,7 +30,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// because no security yet (beyond the channel mechanism). /// It should be off by default and then protected based on some TBD mechanism /// (a special channel once multichannel support is included?) -public struct HardwareMessage: Sendable { +public struct HardwareMessage { // 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. @@ -52,7 +52,7 @@ public struct HardwareMessage: Sendable { /// /// TODO: REPLACE - public enum TypeEnum: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum TypeEnum: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -110,21 +110,32 @@ public struct HardwareMessage: Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [HardwareMessage.TypeEnum] = [ - .unset, - .writeGpios, - .watchGpios, - .gpiosChanged, - .readGpios, - .readGpiosReply, - ] - } public init() {} } +#if swift(>=4.2) + +extension HardwareMessage.TypeEnum: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [HardwareMessage.TypeEnum] = [ + .unset, + .writeGpios, + .watchGpios, + .gpiosChanged, + .readGpios, + .readGpiosReply, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension HardwareMessage: @unchecked Sendable {} +extension HardwareMessage.TypeEnum: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift index 38d0c880..6fdf3208 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/rtttl.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/rtttl.proto @@ -8,6 +7,7 @@ // 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 @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Canned message module configuration. -public struct RTTTLConfig: Sendable { +public struct RTTTLConfig { // 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. @@ -36,6 +36,10 @@ public struct RTTTLConfig: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension RTTTLConfig: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift index deb96569..54efa77b 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/storeforward.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/storeforward.proto @@ -23,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// TODO: REPLACE -public struct StoreAndForward: @unchecked Sendable { +public struct StoreAndForward { // 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. @@ -80,7 +79,7 @@ public struct StoreAndForward: @unchecked Sendable { /// /// TODO: REPLACE - public enum OneOf_Variant: Equatable, @unchecked Sendable { + public enum OneOf_Variant: Equatable { /// /// TODO: REPLACE case stats(StoreAndForward.Statistics) @@ -94,12 +93,38 @@ public struct StoreAndForward: @unchecked Sendable { /// Text from history message. case text(Data) + #if !swift(>=4.1) + public static func ==(lhs: StoreAndForward.OneOf_Variant, rhs: StoreAndForward.OneOf_Variant) -> 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 (.stats, .stats): return { + guard case .stats(let l) = lhs, case .stats(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.history, .history): return { + guard case .history(let l) = lhs, case .history(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.heartbeat, .heartbeat): return { + guard case .heartbeat(let l) = lhs, case .heartbeat(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.text, .text): return { + guard case .text(let l) = lhs, case .text(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } /// /// 001 - 063 = From Router /// 064 - 127 = From Client - public enum RequestResponse: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum RequestResponse: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -217,31 +242,11 @@ public struct StoreAndForward: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [StoreAndForward.RequestResponse] = [ - .unset, - .routerError, - .routerHeartbeat, - .routerPing, - .routerPong, - .routerBusy, - .routerHistory, - .routerStats, - .routerTextDirect, - .routerTextBroadcast, - .clientError, - .clientHistory, - .clientStats, - .clientPing, - .clientPong, - .clientAbort, - ] - } /// /// TODO: REPLACE - public struct Statistics: Sendable { + public struct Statistics { // 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. @@ -289,7 +294,7 @@ public struct StoreAndForward: @unchecked Sendable { /// /// TODO: REPLACE - public struct History: Sendable { + public struct History { // 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. @@ -314,7 +319,7 @@ public struct StoreAndForward: @unchecked Sendable { /// /// TODO: REPLACE - public struct Heartbeat: Sendable { + public struct Heartbeat { // 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. @@ -335,6 +340,41 @@ public struct StoreAndForward: @unchecked Sendable { public init() {} } +#if swift(>=4.2) + +extension StoreAndForward.RequestResponse: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [StoreAndForward.RequestResponse] = [ + .unset, + .routerError, + .routerHeartbeat, + .routerPing, + .routerPong, + .routerBusy, + .routerHistory, + .routerStats, + .routerTextDirect, + .routerTextBroadcast, + .clientError, + .clientHistory, + .clientStats, + .clientPing, + .clientPong, + .clientAbort, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension StoreAndForward: @unchecked Sendable {} +extension StoreAndForward.OneOf_Variant: @unchecked Sendable {} +extension StoreAndForward.RequestResponse: @unchecked Sendable {} +extension StoreAndForward.Statistics: @unchecked Sendable {} +extension StoreAndForward.History: @unchecked Sendable {} +extension StoreAndForward.Heartbeat: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift index 4cd8e939..da282fe2 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/telemetry.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/telemetry.proto @@ -8,6 +7,7 @@ // 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 @@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP /// /// Supported I2C Sensors for telemetry in Meshtastic -public enum TelemetrySensorType: SwiftProtobuf.Enum, Swift.CaseIterable { +public enum TelemetrySensorType: SwiftProtobuf.Enum { public typealias RawValue = Int /// @@ -270,6 +270,11 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum, Swift.CaseIterable { } } +} + +#if swift(>=4.2) + +extension TelemetrySensorType: CaseIterable { // The compiler won't synthesize support with the UNRECOGNIZED case. public static let allCases: [TelemetrySensorType] = [ .sensorUnset, @@ -311,12 +316,13 @@ public enum TelemetrySensorType: SwiftProtobuf.Enum, Swift.CaseIterable { .dps310, .rak12035, ] - } +#endif // swift(>=4.2) + /// /// Key native device metrics such as battery level -public struct DeviceMetrics: Sendable { +public struct DeviceMetrics { // 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. @@ -389,7 +395,7 @@ public struct DeviceMetrics: Sendable { /// /// Weather station or other environmental metrics -public struct EnvironmentMetrics: @unchecked Sendable { +public struct EnvironmentMetrics { // 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. @@ -647,7 +653,7 @@ public struct EnvironmentMetrics: @unchecked Sendable { /// /// Power Metrics (voltage / current / etc) -public struct PowerMetrics: Sendable { +public struct PowerMetrics { // 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. @@ -732,7 +738,7 @@ public struct PowerMetrics: Sendable { /// /// Air quality metrics -public struct AirQualityMetrics: Sendable { +public struct AirQualityMetrics { // 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. @@ -870,7 +876,7 @@ public struct AirQualityMetrics: Sendable { public mutating func clearParticles100Um() {self._particles100Um = nil} /// - /// 10.0um Particle Count + /// CO2 concentration in ppm public var co2: UInt32 { get {return _co2 ?? 0} set {_co2 = newValue} @@ -901,7 +907,7 @@ public struct AirQualityMetrics: Sendable { /// /// Local device mesh statistics -public struct LocalStats: Sendable { +public struct LocalStats { // 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. @@ -959,7 +965,7 @@ public struct LocalStats: Sendable { /// /// Health telemetry metrics -public struct HealthMetrics: Sendable { +public struct HealthMetrics { // 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. @@ -1008,7 +1014,7 @@ public struct HealthMetrics: Sendable { /// /// Types of Measurements the telemetry module is equipped to handle -public struct Telemetry: Sendable { +public struct Telemetry { // 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. @@ -1081,7 +1087,7 @@ public struct Telemetry: Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum OneOf_Variant: Equatable, Sendable { + public enum OneOf_Variant: Equatable { /// /// Key native device metrics such as battery level case deviceMetrics(DeviceMetrics) @@ -1101,6 +1107,40 @@ public struct Telemetry: Sendable { /// Health telemetry metrics case healthMetrics(HealthMetrics) + #if !swift(>=4.1) + public static func ==(lhs: Telemetry.OneOf_Variant, rhs: Telemetry.OneOf_Variant) -> 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 (.deviceMetrics, .deviceMetrics): return { + guard case .deviceMetrics(let l) = lhs, case .deviceMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.environmentMetrics, .environmentMetrics): return { + guard case .environmentMetrics(let l) = lhs, case .environmentMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.airQualityMetrics, .airQualityMetrics): return { + guard case .airQualityMetrics(let l) = lhs, case .airQualityMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.powerMetrics, .powerMetrics): return { + guard case .powerMetrics(let l) = lhs, case .powerMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.localStats, .localStats): return { + guard case .localStats(let l) = lhs, case .localStats(let r) = rhs else { preconditionFailure() } + return l == r + }() + case (.healthMetrics, .healthMetrics): return { + guard case .healthMetrics(let l) = lhs, case .healthMetrics(let r) = rhs else { preconditionFailure() } + return l == r + }() + default: return false + } + } + #endif } public init() {} @@ -1108,7 +1148,7 @@ public struct Telemetry: Sendable { /// /// NAU7802 Telemetry configuration, for saving to flash -public struct Nau7802Config: Sendable { +public 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. @@ -1126,6 +1166,19 @@ public struct Nau7802Config: Sendable { public init() {} } +#if swift(>=5.5) && canImport(_Concurrency) +extension TelemetrySensorType: @unchecked Sendable {} +extension DeviceMetrics: @unchecked Sendable {} +extension EnvironmentMetrics: @unchecked Sendable {} +extension PowerMetrics: @unchecked Sendable {} +extension AirQualityMetrics: @unchecked Sendable {} +extension LocalStats: @unchecked Sendable {} +extension HealthMetrics: @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. fileprivate let _protobuf_package = "meshtastic" @@ -1693,10 +1746,10 @@ extension LocalStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio if self.uptimeSeconds != 0 { try visitor.visitSingularUInt32Field(value: self.uptimeSeconds, fieldNumber: 1) } - if self.channelUtilization.bitPattern != 0 { + if self.channelUtilization != 0 { try visitor.visitSingularFloatField(value: self.channelUtilization, fieldNumber: 2) } - if self.airUtilTx.bitPattern != 0 { + if self.airUtilTx != 0 { try visitor.visitSingularFloatField(value: self.airUtilTx, fieldNumber: 3) } if self.numPacketsTx != 0 { @@ -1963,7 +2016,7 @@ extension Nau7802Config: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa if self.zeroOffset != 0 { try visitor.visitSingularInt32Field(value: self.zeroOffset, fieldNumber: 1) } - if self.calibrationFactor.bitPattern != 0 { + if self.calibrationFactor != 0 { try visitor.visitSingularFloatField(value: self.calibrationFactor, fieldNumber: 2) } try unknownFields.traverse(visitor: &visitor) diff --git a/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift b/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift index 46907a58..1f41fe0b 100644 --- a/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift +++ b/MeshtasticProtobufs/Sources/meshtastic/xmodem.pb.swift @@ -1,6 +1,5 @@ // DO NOT EDIT. // swift-format-ignore-file -// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: meshtastic/xmodem.proto @@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -public struct XModem: @unchecked Sendable { +public struct XModem { // 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. @@ -36,7 +35,7 @@ public struct XModem: @unchecked Sendable { public var unknownFields = SwiftProtobuf.UnknownStorage() - public enum Control: SwiftProtobuf.Enum, Swift.CaseIterable { + public enum Control: SwiftProtobuf.Enum { public typealias RawValue = Int case nul // = 0 case soh // = 1 @@ -80,23 +79,34 @@ public struct XModem: @unchecked Sendable { } } - // The compiler won't synthesize support with the UNRECOGNIZED case. - public static let allCases: [XModem.Control] = [ - .nul, - .soh, - .stx, - .eot, - .ack, - .nak, - .can, - .ctrlz, - ] - } public init() {} } +#if swift(>=4.2) + +extension XModem.Control: CaseIterable { + // The compiler won't synthesize support with the UNRECOGNIZED case. + public static let allCases: [XModem.Control] = [ + .nul, + .soh, + .stx, + .eot, + .ack, + .nak, + .can, + .ctrlz, + ] +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension XModem: @unchecked Sendable {} +extension XModem.Control: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "meshtastic" diff --git a/Widgets/WidgetsLiveActivity.swift b/Widgets/WidgetsLiveActivity.swift index 3923fee7..656cc8a1 100644 --- a/Widgets/WidgetsLiveActivity.swift +++ b/Widgets/WidgetsLiveActivity.swift @@ -224,7 +224,7 @@ struct NodeInfoView: View { .foregroundStyle(.secondary) .opacity(isLuminanceReduced ? 0.8 : 1.0) .fixedSize() - + let now = Date() Text("Last Heard: \(now.formatted())") .font(.caption) diff --git a/protobufs b/protobufs index 06864665..27fac391 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 068646653e8375fc145988026ad242a3cf70f7ab +Subproject commit 27fac39141d99fe727a0a1824c5397409b1aea75