Merge branch 'main' into configurable_columns
|
|
@ -222,6 +222,7 @@
|
|||
DDDE5A1129AFE69700490C6C /* MeshActivityAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDE5A0F29AFE69700490C6C /* MeshActivityAttributes.swift */; };
|
||||
DDDE5A1329AFEAB900490C6C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDDE5A1229AFEAB900490C6C /* Assets.xcassets */; };
|
||||
DDDE5A1429AFEAB900490C6C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDDE5A1229AFEAB900490C6C /* Assets.xcassets */; };
|
||||
DDDFE73F2D0D48FF0044463C /* IgnoreNodeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDFE73E2D0D48FF0044463C /* IgnoreNodeButton.swift */; };
|
||||
DDE0F7C5295F77B700B8AAB3 /* AppSettingsEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE0F7C4295F77B700B8AAB3 /* AppSettingsEnums.swift */; };
|
||||
DDE5B4042B2279A700FCDD05 /* TraceRouteLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE5B4032B2279A700FCDD05 /* TraceRouteLog.swift */; };
|
||||
DDE9659C2B1C3B6A00531070 /* RouteRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDE9659B2B1C3B6A00531070 /* RouteRecorder.swift */; };
|
||||
|
|
@ -520,6 +521,8 @@
|
|||
DDDE5A0F29AFE69700490C6C /* MeshActivityAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshActivityAttributes.swift; sourceTree = "<group>"; };
|
||||
DDDE5A1229AFEAB900490C6C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
DDDEE5E229DBE43E00A8E078 /* MeshtasticDataModelV11.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV11.xcdatamodel; sourceTree = "<group>"; };
|
||||
DDDFE73E2D0D48FF0044463C /* IgnoreNodeButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IgnoreNodeButton.swift; sourceTree = "<group>"; };
|
||||
DDDFE7402D0D4A070044463C /* MeshtasticDataModelV 47.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 47.xcdatamodel"; sourceTree = "<group>"; };
|
||||
DDE0F7C4295F77B700B8AAB3 /* AppSettingsEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettingsEnums.swift; sourceTree = "<group>"; };
|
||||
DDE5B4032B2279A700FCDD05 /* TraceRouteLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraceRouteLog.swift; sourceTree = "<group>"; };
|
||||
DDE5B4052B227E3200FCDD05 /* TraceRouteEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraceRouteEntityExtension.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -590,6 +593,7 @@
|
|||
251926882C3BAF2E00249DF5 /* Actions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DDDFE73E2D0D48FF0044463C /* IgnoreNodeButton.swift */,
|
||||
251926842C3BA97800249DF5 /* FavoriteNodeButton.swift */,
|
||||
251926892C3BB1B200249DF5 /* ExchangePositionsButton.swift */,
|
||||
251926862C3BAE2200249DF5 /* NodeAlertsButton.swift */,
|
||||
|
|
@ -1236,6 +1240,7 @@
|
|||
"zh-Hant-TW",
|
||||
se,
|
||||
"pt-PT",
|
||||
sr,
|
||||
);
|
||||
mainGroup = DDC2E14B26CE248E0042C5E4;
|
||||
packageReferences = (
|
||||
|
|
@ -1349,6 +1354,7 @@
|
|||
6D825E622C34786C008DBEE4 /* CommonRegex.swift in Sources */,
|
||||
DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */,
|
||||
DDDB444C29F8AAA600EE2349 /* Color.swift in Sources */,
|
||||
DDDFE73F2D0D48FF0044463C /* IgnoreNodeButton.swift in Sources */,
|
||||
DDB8F4122A9EE5DD00230ECE /* UserList.swift in Sources */,
|
||||
DDB75A0F2A05920E006ED576 /* FileManager.swift in Sources */,
|
||||
DD3D17E02C3FB67200561584 /* LocalWeatherConditions.swift in Sources */,
|
||||
|
|
@ -1568,7 +1574,7 @@
|
|||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.MeshtasticTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
@ -1591,7 +1597,7 @@
|
|||
DEVELOPMENT_TEAM = GCH7VS5Y9R;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.5;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.MeshtasticTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
|
@ -1748,7 +1754,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5.10;
|
||||
MARKETING_VERSION = 2.5.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -1782,7 +1788,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5.10;
|
||||
MARKETING_VERSION = 2.5.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -1808,13 +1814,13 @@
|
|||
INFOPLIST_FILE = Widgets/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Widgets;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5.10;
|
||||
MARKETING_VERSION = 2.5.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
@ -1841,13 +1847,13 @@
|
|||
INFOPLIST_FILE = Widgets/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = Widgets;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.6;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5.10;
|
||||
MARKETING_VERSION = 2.5.13;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
@ -1959,6 +1965,7 @@
|
|||
DD3CC6BA28E366DF00FA9159 /* Meshtastic.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
DDDFE7402D0D4A070044463C /* MeshtasticDataModelV 47.xcdatamodel */,
|
||||
DD0BE30C2CB785D8000BA445 /* MeshtasticDataModelV 46.xcdatamodel */,
|
||||
DD6D5A342CA13BA600ED3032 /* MeshtasticDataModelV 45.xcdatamodel */,
|
||||
DD7CF8DA2C93663C008BD10E /* MeshtasticDataModelV 44.xcdatamodel */,
|
||||
|
|
@ -2006,7 +2013,7 @@
|
|||
DD5D0A9A2931AD6B00F7EA61 /* MeshtasticDataModelV2.xcdatamodel */,
|
||||
DD3CC6BB28E366DF00FA9159 /* MeshtasticDataModel.xcdatamodel */,
|
||||
);
|
||||
currentVersion = DD0BE30C2CB785D8000BA445 /* MeshtasticDataModelV 46.xcdatamodel */;
|
||||
currentVersion = DDDFE7402D0D4A070044463C /* MeshtasticDataModelV 47.xcdatamodel */;
|
||||
name = Meshtastic.xcdatamodeld;
|
||||
path = Meshtastic/Meshtastic.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "LILYGO-TTGO-LoRa32-V2-1-1-6-Version-433-868-915Mhz-ESP32-LoRa-OLED-0-96.jpg_Q90.jpg_.webp.png",
|
||||
"filename" : "heltec-ht62-esp32c3-sx1262.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
1
Meshtastic/Assets.xcassets/HELTECHT62.imageset/heltec-ht62-esp32c3-sx1262.svg
vendored
Normal file
|
After Width: | Height: | Size: 62 KiB |
12
Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "heltec-mesh-node-t114-case.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/HELTECMESHNODET114.imageset/heltec-mesh-node-t114-case.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="795.27 277.13 409.46 1319.35"><defs><style>.cls-1{fill:#353535;}.cls-2{fill:#1e1e1d;}.cls-3{fill:#b1a368;}.cls-10,.cls-11,.cls-4,.cls-6,.cls-8,.cls-9{fill:none;}.cls-4,.cls-6{stroke:#050606;}.cls-10,.cls-11,.cls-4,.cls-6,.cls-8{stroke-miterlimit:10;}.cls-4{stroke-width:2.41px;}.cls-5{fill:#30c2db;}.cls-6{stroke-width:3.91px;}.cls-7{fill:#dcf0f2;}.cls-10,.cls-11,.cls-8{stroke:#dcf0f2;}.cls-8{stroke-width:1.81px;}.cls-9{stroke:#17afbf;stroke-linecap:round;stroke-linejoin:round;stroke-width:7.23px;}.cls-10{stroke-width:1.78px;}.cls-11{stroke-width:1.81px;}</style></defs><g id="Layer_7" data-name="Layer 7"><path class="cls-1" d="M915.62,278.34h22.61a35,35,0,0,1,35,35V715.74a0,0,0,0,1,0,0H880.6a0,0,0,0,1,0,0V313.36A35,35,0,0,1,915.62,278.34Z"></path><rect class="cls-2" x="880.6" y="340.15" width="92.65" height="7.54"></rect><rect class="cls-2" x="880.6" y="356.68" width="92.65" height="7.54"></rect><rect class="cls-3" x="885.8" y="844.3" width="84.14" height="19.02"></rect><rect class="cls-3" x="880.6" y="819.07" width="92.65" height="25.23"></rect><rect class="cls-3" x="885.8" y="790.65" width="84.14" height="28.41"></rect><rect class="cls-3" x="880.6" y="723.02" width="92.65" height="67.63"></rect><rect class="cls-3" x="885.8" y="715.74" width="84.14" height="7.28"></rect><rect class="cls-4" x="885.8" y="844.3" width="84.14" height="19.02"></rect><rect class="cls-4" x="880.6" y="819.07" width="92.65" height="25.23"></rect><rect class="cls-4" x="885.8" y="790.65" width="84.14" height="28.41"></rect><rect class="cls-4" x="880.6" y="723.02" width="92.65" height="67.63"></rect><rect class="cls-4" x="885.8" y="715.74" width="84.14" height="7.28"></rect><path class="cls-4" d="M915.62,278.34h22.61a35,35,0,0,1,35,35V715.74a0,0,0,0,1,0,0H880.6a0,0,0,0,1,0,0V313.36A35,35,0,0,1,915.62,278.34Z"></path><rect class="cls-4" x="880.6" y="340.15" width="92.65" height="7.54"></rect><rect class="cls-4" x="880.6" y="356.68" width="92.65" height="7.54"></rect><rect class="cls-5" x="796.48" y="856.3" width="407.05" height="738.98" rx="47.74"></rect><rect class="cls-1" x="900.05" y="973.19" width="202.03" height="354.65" rx="16.4"></rect><rect class="cls-6" x="900.05" y="973.19" width="202.03" height="354.65" rx="16.4"></rect><rect class="cls-7" x="871.51" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><rect class="cls-7" x="1070.16" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><rect class="cls-4" x="871.51" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><rect class="cls-4" x="1070.16" y="890.41" width="55.42" height="31.12" rx="15.56"></rect><circle class="cls-8" cx="841.7" cy="1537.01" r="16.25"></circle><circle class="cls-8" cx="841.7" cy="913.26" r="16.25"></circle><circle class="cls-8" cx="1157.32" cy="913.26" r="16.25"></circle><circle class="cls-8" cx="1157.32" cy="1504.51" r="16.25"></circle><line class="cls-9" x1="942.51" y1="1592.42" x2="942.51" y2="1381.55"></line><line class="cls-9" x1="966.52" y1="1592.42" x2="966.52" y2="1381.55"></line><line class="cls-9" x1="990.57" y1="1592.42" x2="990.57" y2="1381.55"></line><line class="cls-9" x1="1014.59" y1="1592.42" x2="1014.59" y2="1381.55"></line><line class="cls-9" x1="1038.63" y1="1592.42" x2="1038.63" y2="1381.55"></line><line class="cls-9" x1="1062.65" y1="1592.42" x2="1062.65" y2="1381.55"></line><rect class="cls-4" x="796.48" y="856.3" width="407.05" height="738.98" rx="47.74"></rect><path class="cls-10" d="M1040.1,947.74H960.65A13.93,13.93,0,0,1,947,936.64l-10.23-49.2a13.93,13.93,0,0,1,13.64-16.77h97.72a13.93,13.93,0,0,1,13.75,16.18l-8,49.2A13.94,13.94,0,0,1,1040.1,947.74Z"></path><rect class="cls-11" x="816.35" y="870.67" width="365.51" height="703.12" rx="32.37"></rect><rect class="cls-11" x="888.77" y="963.84" width="223.2" height="374.66" rx="25.21"></rect></g></svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Heltec_turq.png",
|
||||
"filename" : "heltec-v3-case.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 4.2 MiB |
1
Meshtastic/Assets.xcassets/HELTECV3.imageset/heltec-v3-case.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="404.68 390.65 1217.15 959.26"><defs><style>.cls-1{fill:#dfeaf7;}.cls-2{fill:#17907f;}.cls-3{fill:#2b2b2b;}.cls-4,.cls-5{fill:none;stroke:#050606;stroke-miterlimit:10;}.cls-4{stroke-width:2.25px;}.cls-5{stroke-width:4px;}.cls-6{fill:#050606;}</style></defs><g id="Layer_5" data-name="Layer 5"><path class="cls-1" d="M1517.73,392.65h0a102.1,102.1,0,0,0-102.1,102.1V770.37A40.62,40.62,0,0,1,1375,811H455.16a48.49,48.49,0,0,0-48.48,48.48v126a11.85,11.85,0,0,0,3.46,8.37l15.34,15.34a11.81,11.81,0,0,1,3.47,8.37v137.16a11.81,11.81,0,0,1-3.47,8.37l-15.34,15.34a11.85,11.85,0,0,0-3.46,8.37v112.67a48.49,48.49,0,0,0,48.48,48.49H1571.34a48.51,48.51,0,0,0,48.49-48.5V494.75A102.1,102.1,0,0,0,1517.73,392.65Zm-110.61,815V954a33.14,33.14,0,0,1,66.27,0v253.65a33.14,33.14,0,0,1-66.27,0Z"></path><path class="cls-2" d="M1516,439.16c-30.23.91-53.92,26.54-53.92,56.79V770.37A87.11,87.11,0,0,1,1375,857.48H732.31A27.51,27.51,0,0,0,704.8,885v388.93a27.51,27.51,0,0,0,27.51,27.51h828.38a12.7,12.7,0,0,0,12.65-12.65v-794A55.69,55.69,0,0,0,1516,439.16Zm-108.9,768.47V954a33.14,33.14,0,0,1,66.27,0v253.65a33.14,33.14,0,0,1-66.27,0Z"></path><rect class="cls-3" x="787.14" y="943.38" width="429.45" height="224.42"></rect><path class="cls-1" d="M1478.6,915.35A54.23,54.23,0,0,0,1386,953.69v254.23a54.23,54.23,0,1,0,108.45,0V953.69A54,54,0,0,0,1478.6,915.35Zm-5.21,292.28a33.14,33.14,0,0,1-66.27,0V954a33.14,33.14,0,0,1,66.27,0Z"></path></g><g id="Layer_2" data-name="Layer 2"><path class="cls-4" d="M1573.34,494.75v794a12.68,12.68,0,0,1-12.65,12.65H732.31a27.51,27.51,0,0,1-27.51-27.51V885a27.51,27.51,0,0,1,27.51-27.51H1375a87.11,87.11,0,0,0,87.11-87.11V496c0-30.25,23.69-55.88,53.92-56.79A55.69,55.69,0,0,1,1573.34,494.75Z"></path><path class="cls-5" d="M410.14,1178.39,425.49,1163a11.78,11.78,0,0,0,3.46-8.35V1017.5a11.8,11.8,0,0,0-3.46-8.35l-15.35-15.36a11.77,11.77,0,0,1-3.46-8.35v-126A48.47,48.47,0,0,1,455.16,811H1375a40.63,40.63,0,0,0,40.63-40.63V494.75a102.1,102.1,0,0,1,102.1-102.1h0a102.1,102.1,0,0,1,102.1,102.1v804.66a48.51,48.51,0,0,1-48.49,48.5H455.16a48.48,48.48,0,0,1-48.48-48.49V1186.74A11.78,11.78,0,0,1,410.14,1178.39Z"></path><rect class="cls-4" x="1407.12" y="920.85" width="66.26" height="319.9" rx="33.13"></rect><rect class="cls-4" x="1386.03" y="899.46" width="108.46" height="362.69" rx="54.23"></rect><path class="cls-6" d="M639.76,1070.55a2.91,2.91,0,0,1-2.91-2.91v-30.53a5.42,5.42,0,0,0-1.6-3.86l-32.44-32.44a11.86,11.86,0,0,1-3.5-8.44V901a12.52,12.52,0,0,0-12.51-12.51H483.92a12.7,12.7,0,0,0-12.68,12.69v76.78a24.13,24.13,0,0,0,7.11,17.18l14.33,14.33a24.13,24.13,0,0,0,17.18,7.11h50.75a11.86,11.86,0,0,1,8.44,3.5l24.26,24.26a12.47,12.47,0,0,1,3.68,8.88v14.46a2.91,2.91,0,1,1-5.81,0v-14.46a6.72,6.72,0,0,0-2-4.77l-24.26-24.26a6.09,6.09,0,0,0-4.33-1.8H509.86a29.91,29.91,0,0,1-21.29-8.81l-14.33-14.33a29.87,29.87,0,0,1-8.81-21.29V901.14a18.51,18.51,0,0,1,18.49-18.5H586.8A18.34,18.34,0,0,1,605.12,901v91.41a6.09,6.09,0,0,0,1.8,4.33l32.44,32.44a11.19,11.19,0,0,1,3.3,8v30.53A2.9,2.9,0,0,1,639.76,1070.55Z"></path><path class="cls-6" d="M586.8,1289.46H483.92a18.51,18.51,0,0,1-18.49-18.5v-76.78a29.87,29.87,0,0,1,8.81-21.29l14.33-14.34a29.91,29.91,0,0,1,21.29-8.81h50.75a6.09,6.09,0,0,0,4.33-1.8l24.26-24.25a6.74,6.74,0,0,0,2-4.78v-14.46a2.91,2.91,0,0,1,5.81,0v14.46a12.51,12.51,0,0,1-3.68,8.89l-24.26,24.25a11.86,11.86,0,0,1-8.44,3.5H509.86a24.17,24.17,0,0,0-17.18,7.11L478.35,1177a24.09,24.09,0,0,0-7.11,17.18V1271a12.71,12.71,0,0,0,12.68,12.69H586.8a12.53,12.53,0,0,0,12.51-12.52v-91.4a11.83,11.83,0,0,1,3.5-8.44l32.44-32.44a5.46,5.46,0,0,0,1.6-3.87v-30.53a2.91,2.91,0,0,1,5.81,0V1135a11.19,11.19,0,0,1-3.3,8l-32.44,32.45a6.06,6.06,0,0,0-1.8,4.33v91.4A18.35,18.35,0,0,1,586.8,1289.46Z"></path><rect class="cls-4" x="787.14" y="943.38" width="429.45" height="224.42"></rect></g></svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
12
Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "heltec-vision-master-e213.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/HELTECVISIONMASTERE213.imageset/heltec-vision-master-e213.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="528.89 806.04 942.22 446.84"><defs><style>.cls-1{fill:#e8eae8;}.cls-2{fill:#dbdddb;}.cls-3{fill:#c6842a;}.cls-4,.cls-5,.cls-7,.cls-9{fill:none;stroke-miterlimit:10;}.cls-4,.cls-5{stroke:#050606;}.cls-4,.cls-9{stroke-width:2.44px;}.cls-5,.cls-7{stroke-width:1.22px;}.cls-6{fill:#b7b7b7;}.cls-7,.cls-9{stroke:#b7b7b7;}.cls-8{fill:#cbcccb;}.cls-10{fill:#434543;}</style></defs><g id="Layer_4" data-name="Layer 4"><path class="cls-1" d="M1469.9,826.68v390.94a19.43,19.43,0,0,1-19.43,19.43H549.53a19.43,19.43,0,0,1-19.43-19.43V826.68a19.42,19.42,0,0,1,19.43-19.42h900.94A19.42,19.42,0,0,1,1469.9,826.68Z"></path><path class="cls-2" d="M574.23,807.26v429.79h-24.7a19.43,19.43,0,0,1-19.43-19.43V826.68a19.42,19.42,0,0,1,19.43-19.42Z"></path><path class="cls-2" d="M1469.9,826.68v390.94a19.43,19.43,0,0,1-19.43,19.43h-37.56V807.26h37.56A19.42,19.42,0,0,1,1469.9,826.68Z"></path><path class="cls-3" d="M574.23,1129.8h-7.47a4.55,4.55,0,0,1-4.55-4.54V919.05a4.55,4.55,0,0,1,4.55-4.55h7.47"></path><rect class="cls-4" x="530.11" y="807.26" width="939.78" height="429.79" rx="19.42"></rect><line class="cls-5" x1="574.23" y1="807.26" x2="574.23" y2="1237.05"></line><path class="cls-5" d="M574.23,1129.8h-7.47a4.55,4.55,0,0,1-4.55-4.54V919.05a4.55,4.55,0,0,1,4.55-4.55h7.47"></path><rect class="cls-6" x="599.01" y="970.1" width="11.52" height="104.11"></rect><rect class="cls-5" x="599.01" y="970.1" width="11.52" height="104.11"></rect><path class="cls-2" d="M610.53,816.78V935.32l38.37,11.55a7.85,7.85,0,0,1,5.6,7.53V1107a7.87,7.87,0,0,1-7.87,7.87h-36.1v110.58H1406V816.78Zm775.41,384.75H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66h754.51Z"></path><path class="cls-1" d="M1385.94,840.45v361.08H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66Z"></path><path class="cls-7" d="M610.53,816.78V935.32l38.37,11.55a7.85,7.85,0,0,1,5.6,7.53V1107a7.87,7.87,0,0,1-7.87,7.87h-36.1v110.58H1406V816.78Zm775.41,384.75H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66h754.51Z"></path><path class="cls-7" d="M1385.94,840.45v361.08H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66Z"></path><path class="cls-7" d="M1385.94,840.45v361.08H631.43a3.66,3.66,0,0,1-3.66-3.66V1138a3.65,3.65,0,0,1,3.66-3.65h28.3a14.7,14.7,0,0,0,14.71-14.71V931a14.7,14.7,0,0,0-14.71-14.71h-28.3a3.65,3.65,0,0,1-3.66-3.66V844.11a3.66,3.66,0,0,1,3.66-3.66Z"></path><line class="cls-7" x1="666.4" y1="1132.79" x2="666.4" y2="1201.53"></line><line class="cls-7" x1="663.66" y1="916.86" x2="663.66" y2="840.45"></line><circle class="cls-8" cx="644.99" cy="878.66" r="10.7"></circle><circle class="cls-8" cx="644.99" cy="1171.55" r="10.7"></circle><circle class="cls-9" cx="644.99" cy="878.66" r="10.7"></circle><circle class="cls-9" cx="644.99" cy="1171.55" r="10.7"></circle><path class="cls-10" d="M1225,1237.05l2.23,11.19a4.25,4.25,0,0,0,4.17,3.42H1249a4.26,4.26,0,0,0,4.18-3.42l2.22-11.19"></path><path class="cls-10" d="M1306.87,1237.05l2.22,11.19a4.26,4.26,0,0,0,4.18,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.22-11.19"></path><path class="cls-10" d="M1388.77,1237.05l2.23,11.19a4.24,4.24,0,0,0,4.17,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.23-11.19"></path><path class="cls-4" d="M1225,1237.05l2.23,11.19a4.25,4.25,0,0,0,4.17,3.42H1249a4.26,4.26,0,0,0,4.18-3.42l2.22-11.19"></path><path class="cls-4" d="M1306.87,1237.05l2.22,11.19a4.26,4.26,0,0,0,4.18,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.22-11.19"></path><path class="cls-4" d="M1388.77,1237.05l2.23,11.19a4.24,4.24,0,0,0,4.17,3.42h17.62a4.25,4.25,0,0,0,4.17-3.42l2.23-11.19"></path><line class="cls-4" x1="1412.9" y1="807.26" x2="1412.9" y2="1237.05"></line></g></svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
12
Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "heltec-vision-master-e290.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/HELTECVISIONMASTERE290.imageset/heltec-vision-master-e290.svg
vendored
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Paper-Meshtastic-2 copy.jpg",
|
||||
"filename" : "heltec-wireless-paper.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 66 KiB |
1
Meshtastic/Assets.xcassets/HELTECWIRELESSPAPER.imageset/heltec-wireless-paper.svg
vendored
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "images.png",
|
||||
"filename" : "heltec-wireless-tracker.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
1
Meshtastic/Assets.xcassets/HELTECWIRELESSTRACKER.imageset/heltec-wireless-tracker.svg
vendored
Normal file
|
After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "heltecwsl.png",
|
||||
"filename" : "heltec-wsl-v3.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
1
Meshtastic/Assets.xcassets/HELTECWSLV3.imageset/heltec-wsl-v3.svg
vendored
Normal file
|
After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 209 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tbeam_supreme.png",
|
||||
"filename" : "tbeam-s3-core.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
1
Meshtastic/Assets.xcassets/LILYGOTBEAMS3CORE.imageset/tbeam-s3-core.svg
vendored
Normal file
|
After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 4.1 MiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "nano_g2_ultra_product_image.jpg",
|
||||
"filename" : "nano-g2-ultra.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
1
Meshtastic/Assets.xcassets/NANOG2ULTRA.imageset/nano-g2-ultra.svg
vendored
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 484 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "RAK_DEV_KIT-2.jpg",
|
||||
"filename" : "promicro.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
1
Meshtastic/Assets.xcassets/PROMICRO.imageset/promicro.svg
vendored
Normal file
|
After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "TLORA_olive 1.png",
|
||||
"filename" : "rak11310.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
1
Meshtastic/Assets.xcassets/RAK11310.imageset/rak11310.svg
vendored
Normal file
|
After Width: | Height: | Size: 58 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "RAK 4.png",
|
||||
"filename" : "rak4631_case.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 2.6 MiB |
1
Meshtastic/Assets.xcassets/RAK4631.imageset/rak4631_case.svg
vendored
Normal file
|
After Width: | Height: | Size: 9 KiB |
12
Meshtastic/Assets.xcassets/RPIPICO.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "pico.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
2956
Meshtastic/Assets.xcassets/RPIPICO.imageset/pico.svg
vendored
Normal file
|
After Width: | Height: | Size: 102 KiB |
12
Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "seeed-xiao-s3.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/SEEEDXIAOS3.imageset/seeed-xiao-s3.svg
vendored
Normal file
|
After Width: | Height: | Size: 28 KiB |
12
Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "seeed-sensecap-indicator.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/SENSECAPINDICATOR.imageset/seeed-sensecap-indicator.svg
vendored
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
12
Meshtastic/Assets.xcassets/STATIONG2.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "station-g2.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/STATIONG2.imageset/station-g2.svg
vendored
Normal file
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tbeam.png",
|
||||
"filename" : "tbeam.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
BIN
Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.png
vendored
|
Before Width: | Height: | Size: 1.7 MiB |
1
Meshtastic/Assets.xcassets/TBEAM.imageset/tbeam.svg
vendored
Normal file
|
After Width: | Height: | Size: 112 KiB |
12
Meshtastic/Assets.xcassets/TDECK.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "t-deck.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TDECK.imageset/t-deck.svg
vendored
Normal file
|
After Width: | Height: | Size: 23 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "LILYGO-TTGO-SoftRF-T-Echo-NRF52840-LoRa-SX1262-433-868-915MHz-Wireless-Module-L76K-GPS-1.png",
|
||||
"filename" : "t-echo.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 430 KiB |
1
Meshtastic/Assets.xcassets/TECHO.imageset/t-echo.svg
vendored
Normal file
|
After Width: | Height: | Size: 8 KiB |
|
Before Width: | Height: | Size: 457 KiB |
12
Meshtastic/Assets.xcassets/TLORAC6.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tlora-c6.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TLORAC6.imageset/tlora-c6.svg
vendored
Normal file
|
After Width: | Height: | Size: 30 KiB |
12
Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tlora-t3s3-epaper.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TLORAT3S3EPAPER.imageset/tlora-t3s3-epaper.svg
vendored
Normal file
|
After Width: | Height: | Size: 6 KiB |
12
Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tlora-t3s3-v1.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TLORAT3S3V1.imageset/tlora-t3s3-v1.svg
vendored
Normal file
|
After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 4 MiB |
12
Meshtastic/Assets.xcassets/TLORAV2116.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tlora-v2-1-1_6.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TLORAV2116.imageset/tlora-v2-1-1_6.svg
vendored
Normal file
|
After Width: | Height: | Size: 26 KiB |
12
Meshtastic/Assets.xcassets/TLORAV2118.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tlora-v2-1-1_8.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TLORAV2118.imageset/tlora-v2-1-1_8.svg
vendored
Normal file
|
After Width: | Height: | Size: 26 KiB |
12
Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "tracker-t1000-e.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TRACKERT1000E.imageset/tracker-t1000-e.svg
vendored
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
12
Meshtastic/Assets.xcassets/TWATCHS3.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "t-watch-s3.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/TWATCHS3.imageset/t-watch-s3.svg
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="733.42 451.82 573.87 931.48"><defs><style>.cls-1{fill:#8e8d8e;}.cls-2{fill:#383839;}.cls-3{fill:#cccccb;}.cls-4{fill:#222226;}.cls-5,.cls-6{fill:none;stroke:#050606;stroke-miterlimit:10;}.cls-5{stroke-width:1.87px;}.cls-6{stroke-width:3.77px;}.cls-7{fill:#4c4c4d;}</style></defs><g id="Layer_4" data-name="Layer 4"><path class="cls-1" d="M1277.27,847.59h4.35a8.09,8.09,0,0,1,8.09,8.08v138a8.09,8.09,0,0,1-8.09,8.09h-4.35"></path><path class="cls-1" d="M1277.27,732.73h18a10.14,10.14,0,0,1,10.14,10.14v43A10.14,10.14,0,0,1,1295.26,796h-18a0,0,0,0,1,0,0V732.73A0,0,0,0,1,1277.27,732.73Z"></path><path class="cls-2" d="M1256.49,1200.6h0a14.19,14.19,0,0,1-2.83,12.5c-8.13,9.86-19.94,18.58-46,30.75-19.15,9-28.65,16-38.35,29.6a93.15,93.15,0,0,0-8.7,14.61c-6.95,15.17-11.77,44.44-11.77,65.66v3.61a24.09,24.09,0,0,1-24.1,24.09H887.83a24.09,24.09,0,0,1-24.1-24.09v-3.61c0-21.22-4.82-50.49-11.77-65.66a93.15,93.15,0,0,0-8.7-14.61c-9.7-13.63-19.2-20.65-38.35-29.6-26.06-12.17-37.87-20.89-46-30.75a14.22,14.22,0,0,1-2.82-12.5h0"></path><path class="cls-2" d="M756.09,634.53h0a14.19,14.19,0,0,1,2.83-12.5c8.12-9.86,19.93-18.58,46-30.75,19.15-8.95,28.65-16,38.35-29.6a93.15,93.15,0,0,0,8.7-14.61c6.95-15.17,11.77-44.44,11.77-65.66V477.8a24.09,24.09,0,0,1,24.1-24.09h236.92a24.09,24.09,0,0,1,24.1,24.09v3.61c0,21.22,4.82,50.49,11.77,65.66a93.15,93.15,0,0,0,8.7,14.61c9.7,13.63,19.2,20.65,38.35,29.6,26,12.17,37.86,20.89,46,30.75a14.19,14.19,0,0,1,2.83,12.5h0"></path><rect class="cls-3" x="735.31" y="598.25" width="541.96" height="638.99" rx="96.44"></rect><path class="cls-2" d="M1247.38,694.68v446.11a66.63,66.63,0,0,1-66.54,66.56H831.75a66.62,66.62,0,0,1-66.56-66.56V694.68a66.63,66.63,0,0,1,66.56-66.55h349.09A66.64,66.64,0,0,1,1247.38,694.68Z"></path><rect class="cls-4" x="817.71" y="721.76" width="379.03" height="388.6"></rect><path class="cls-5" d="M1247.38,694.68v446.11a66.63,66.63,0,0,1-66.54,66.56H831.75a66.62,66.62,0,0,1-66.56-66.56V694.68a66.63,66.63,0,0,1,66.56-66.55h349.09A66.64,66.64,0,0,1,1247.38,694.68Z"></path><rect class="cls-6" x="735.31" y="598.25" width="541.96" height="638.99" rx="96.44"></rect><path class="cls-6" d="M1256.49,1200.6h0a14.19,14.19,0,0,1-2.83,12.5c-8.13,9.86-19.94,18.58-46,30.75-19.15,9-28.65,16-38.35,29.6a93.15,93.15,0,0,0-8.7,14.61c-6.95,15.17-11.77,44.44-11.77,65.66v3.61a24.09,24.09,0,0,1-24.1,24.09H887.83a24.09,24.09,0,0,1-24.1-24.09v-3.61c0-21.22-4.82-50.49-11.77-65.66a93.15,93.15,0,0,0-8.7-14.61c-9.7-13.63-19.2-20.65-38.35-29.6-26.06-12.17-37.87-20.89-46-30.75a14.22,14.22,0,0,1-2.82-12.5h0"></path><path class="cls-6" d="M756.09,634.53h0a14.19,14.19,0,0,1,2.83-12.5c8.12-9.86,19.93-18.58,46-30.75,19.15-8.95,28.65-16,38.35-29.6a93.15,93.15,0,0,0,8.7-14.61c6.95-15.17,11.77-44.44,11.77-65.66V477.8a24.09,24.09,0,0,1,24.1-24.09h236.92a24.09,24.09,0,0,1,24.1,24.09v3.61c0,21.22,4.82,50.49,11.77,65.66a93.15,93.15,0,0,0,8.7,14.61c9.7,13.63,19.2,20.65,38.35,29.6,26,12.17,37.86,20.89,46,30.75a14.19,14.19,0,0,1,2.83,12.5h0"></path><rect class="cls-5" x="817.71" y="721.76" width="379.03" height="388.6"></rect><path class="cls-6" d="M1277.27,847.59h4.35a8.09,8.09,0,0,1,8.09,8.08v138a8.09,8.09,0,0,1-8.09,8.09h-4.35"></path><path class="cls-6" d="M1277.27,732.73h18a10.14,10.14,0,0,1,10.14,10.14v43A10.14,10.14,0,0,1,1295.26,796h-18a0,0,0,0,1,0,0V732.73A0,0,0,0,1,1277.27,732.73Z"></path><circle class="cls-7" cx="1083.08" cy="1177.35" r="16.6"></circle><rect class="cls-2" x="1280.24" y="739.77" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="750.91" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="762.06" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="773.2" width="16.77" height="4.59" rx="2.29"></rect><rect class="cls-2" x="1280.24" y="784.34" width="16.77" height="4.59" rx="2.29"></rect></g></svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "play_store_icon_114px-2.png",
|
||||
"filename" : "unknown.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 12 KiB |
129
Meshtastic/Assets.xcassets/UNSET.imageset/unknown.svg
vendored
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
class="svg-icon"
|
||||
style="overflow:hidden;fill:currentColor"
|
||||
viewBox="0 0 909.87988 546.85529"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xml:space="preserve"
|
||||
width="909.87988"
|
||||
height="546.85529"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs3"><style
|
||||
id="style1">.cls-1{fill:#383838;}.cls-2{fill:#9f9f9e;}.cls-3{fill:#cbcccb;}.cls-4{fill:#b7b7b7;}.cls-5{fill:#353535;}.cls-6{fill:#b1a368;}.cls-7{fill:#2c2d2d;}.cls-10,.cls-11,.cls-8,.cls-9{fill:none;stroke:#050606;}.cls-10,.cls-11,.cls-8{stroke-miterlimit:10;}.cls-8,.cls-9{stroke-width:2px;}.cls-9{stroke-linecap:round;stroke-linejoin:round;}.cls-10{stroke-width:2.04px;}.cls-11{stroke-width:1.99px;}.cls-12{fill:#c08c2d;}.cls-13{fill:#af7a2b;}</style></defs><g
|
||||
id="Layer_7"
|
||||
data-name="Layer 7"
|
||||
transform="translate(-646.6554,-758.05941)"><path
|
||||
class="cls-2"
|
||||
d="m 1545.1753,893.49468 h 4.69 a 5.67,5.67 0 0 1 5.67,5.67 v 84.64998 a 5.67,5.67 0 0 1 -5.67,5.67 h -4.69"
|
||||
id="path1-4" /><rect
|
||||
class="cls-3"
|
||||
x="647.6554"
|
||||
y="862.80469"
|
||||
width="897.52002"
|
||||
height="441.10999"
|
||||
rx="11.7"
|
||||
id="rect2" /><path
|
||||
class="cls-2"
|
||||
d="m 681.12532,862.80468 v 113.47998 a 3.67,3.67 0 0 0 3.67,3.67 h 41 a 2.35,2.35 0 0 1 2.35,2.35 V 1303.9147 H 1517.6053 V 862.80468 Z M 1492.6453,1278.9147 H 753.18532 V 972.01466 a 17.06,17.06 0 0 0 -17.06,-17.06 h -27.5 a 2.5,2.5 0 0 1 -2.5,-2.5 v -62.14998 a 2.5,2.5 0 0 1 2.5,-2.5 h 783.99998 z"
|
||||
id="path2-7" /><path
|
||||
class="cls-3"
|
||||
d="M 1492.6453,887.80468 V 1278.9147 H 753.18532 V 972.01466 a 17,17 0 0 0 -7.2,-13.92 v -70.28998 z"
|
||||
id="path3-7" /><path
|
||||
class="cls-4"
|
||||
d="m 745.98532,887.80468 v 70.28998 a 17,17 0 0 0 -9.86,-3.14 h -27.5 a 2.5,2.5 0 0 1 -2.5,-2.5 v -62.14998 a 2.5,2.5 0 0 1 2.5,-2.5 z"
|
||||
id="path4" /><rect
|
||||
class="cls-2"
|
||||
x="672.10535"
|
||||
y="1011.4448"
|
||||
width="13.53"
|
||||
height="148.39999"
|
||||
id="rect4" /><path
|
||||
class="cls-6"
|
||||
d="m 1077.2923,853.76468 h 71.71 a 2.55,2.55 0 0 1 2.55,2.55 v 6.48 h -76.8 v -6.48 a 2.55,2.55 0 0 1 2.54,-2.55 z"
|
||||
id="path7" /><path
|
||||
class="cls-8"
|
||||
d="m 1082.9205,761.22647 h 60.8838 a 6.1958134,4.8451518 0 0 1 6.1958,4.84516 v 77.32638 h -73.2754 v -77.32638 a 6.1958134,4.8451518 0 0 1 6.1958,-4.84516 z"
|
||||
id="path39"
|
||||
style="fill:#b1a368" /><rect
|
||||
class="cls-8"
|
||||
x="1066.9833"
|
||||
y="778.19855"
|
||||
width="91.504646"
|
||||
height="55.957298"
|
||||
rx="5.5511622"
|
||||
id="rect39"
|
||||
style="fill:#b1a368" /><path
|
||||
class="cls-2"
|
||||
d="m 1158.4522,782.53954 v 47.24724 a 5.5153484,4.3130254 0 0 1 -5.5512,4.34102 h -80.3665 a 5.5511623,4.341032 0 0 1 -5.587,-4.34102 v -47.24724 a 5.5511623,4.341032 0 0 1 5.587,-4.34103 h 80.5098 a 5.5153484,4.3130254 0 0 1 5.4079,4.34103 z"
|
||||
id="path41-4"
|
||||
style="fill:none;stroke:#050606;stroke-width:3.16706;stroke-miterlimit:10" /><rect
|
||||
class="cls-6"
|
||||
x="1079.9424"
|
||||
y="843.73468"
|
||||
width="65.989998"
|
||||
height="10.03"
|
||||
id="rect8" /><path
|
||||
class="cls-8"
|
||||
d="M 1492.6453,887.80468 V 1278.9147 H 753.18532 V 972.01466 a 17.06,17.06 0 0 0 -17.06,-17.06 h -27.5 a 2.5,2.5 0 0 1 -2.5,-2.5 v -62.14998 a 2.5,2.5 0 0 1 2.5,-2.5 h 783.99998 m 25,-25 H 681.12532 v 113.47998 a 3.68,3.68 0 0 0 3.67,3.67 h 41 a 2.35,2.35 0 0 1 2.35,2.35 V 1303.9147 H 1517.6053 V 862.80468 Z"
|
||||
id="path10" /><line
|
||||
class="cls-8"
|
||||
x1="745.99536"
|
||||
y1="958.09467"
|
||||
x2="745.99536"
|
||||
y2="887.80469"
|
||||
id="line10" /><rect
|
||||
class="cls-8"
|
||||
x="672.10535"
|
||||
y="1011.4448"
|
||||
width="13.53"
|
||||
height="148.39999"
|
||||
id="rect11" /><path
|
||||
class="cls-8"
|
||||
d="m 1545.1753,893.49468 h 4.69 a 5.67,5.67 0 0 1 5.67,5.67 v 84.64998 a 5.67,5.67 0 0 1 -5.67,5.67 h -4.69"
|
||||
id="path14" /><path
|
||||
class="cls-10"
|
||||
d="m 1077.2923,853.76468 h 71.71 a 2.55,2.55 0 0 1 2.55,2.55 v 6.48 h -76.8 v -6.48 a 2.55,2.55 0 0 1 2.54,-2.55 z"
|
||||
id="path16" /><rect
|
||||
class="cls-11"
|
||||
x="1079.9424"
|
||||
y="843.73468"
|
||||
width="65.989998"
|
||||
height="10.03"
|
||||
id="rect17" /><path
|
||||
class="cls-2"
|
||||
d="m 725.27532,910.38466 a 14,14 0 1 0 14,14 13.95,13.95 0 0 0 -14,-14 z m 0,21.5 a 7.55,7.55 0 1 1 7.54,-7.55 7.55,7.55 0 0 1 -7.54,7.55 z"
|
||||
id="path19" /><circle
|
||||
class="cls-8"
|
||||
cx="725.27539"
|
||||
cy="924.33466"
|
||||
r="7.5500002"
|
||||
id="circle19" /><circle
|
||||
class="cls-8"
|
||||
cx="725.27539"
|
||||
cy="924.33466"
|
||||
r="13.95"
|
||||
id="circle20" /><path
|
||||
d="m 445.36309,440.05365 c 0,11.52004 10.38375,20.85861 23.19309,20.85861 12.80937,0 23.19311,-9.33857 23.19311,-20.85861 0,-11.52005 -10.38374,-20.85861 -23.19311,-20.85861 -12.80934,0 -23.19309,9.33856 -23.19309,20.85861 z"
|
||||
fill="#ccc"
|
||||
id="path1"
|
||||
style="overflow:hidden;fill:#4d4d4d;stroke-width:0.458227"
|
||||
transform="translate(646.6554,758.05941)" /><path
|
||||
d="m 469.40305,538.40107 c -119.83415,0 -217.31582,-93.40624 -217.31582,-208.23067 0,-114.82425 97.48167,-208.23058 217.31582,-208.23058 119.83417,0 217.31585,93.40633 217.31585,208.23058 0,114.82443 -97.48168,208.23067 -217.31585,208.23067 z m 0,-386.58065 c -102.63515,0 -186.13149,80.00572 -186.13149,178.34998 0,98.32948 83.49634,178.34997 186.13149,178.34997 102.61966,0 186.13151,-80.01997 186.13151,-178.34997 0,-98.34426 -83.51185,-178.34998 -186.13151,-178.34998 z"
|
||||
fill="#ccc"
|
||||
id="path2"
|
||||
style="overflow:hidden;fill:#4d4d4d;stroke-width:0.474832"
|
||||
transform="translate(646.6554,758.05941)" /><path
|
||||
d="m 468.55618,391.96713 c -8.53552,0 -15.46205,-6.22977 -15.46205,-13.90533 v -23.51468 c 0,-22.75028 19.32709,-40.13201 36.39722,-55.47009 12.50833,-11.26363 25.45056,-22.88885 25.45056,-32.16398 0,-23.18095 -20.81195,-42.03718 -46.38573,-42.03718 -26.0067,0 -46.38619,18.0497 -46.38619,41.09158 0,7.67594 -6.92654,13.90533 -15.46208,13.90533 -8.53554,0 -15.46207,-6.22977 -15.46207,-13.9058 0,-37.99002 34.68046,-68.90262 77.31034,-68.90262 42.62989,0 77.31034,31.32967 77.31034,69.84869 0,20.81694 -17.54944,36.5856 -34.51132,51.84064 -13.452,12.07016 -27.33645,24.55758 -27.33645,35.77907 v 23.51468 c 0,7.6764 -6.92702,13.91969 -15.46257,13.91969 z"
|
||||
fill="#ccc"
|
||||
id="path3"
|
||||
style="overflow:hidden;fill:#4d4d4d;stroke-width:0.458227;stroke:#000000;stroke-opacity:1"
|
||||
transform="translate(646.6554,758.05941)" /><rect
|
||||
class="cls-8"
|
||||
x="647.6554"
|
||||
y="862.80469"
|
||||
width="897.52002"
|
||||
height="441.10999"
|
||||
rx="11.7"
|
||||
id="rect28" /></g></svg>
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
12
Meshtastic/Assets.xcassets/WIOWM1110.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "wio-tracker-wm1110.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/WIOWM1110.imageset/wio-tracker-wm1110.svg
vendored
Normal file
|
After Width: | Height: | Size: 91 KiB |
12
Meshtastic/Assets.xcassets/WISMESHTAP.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "rak-wismeshtap.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
1
Meshtastic/Assets.xcassets/WISMESHTAP.imageset/rak-wismeshtap.svg
vendored
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
|
|
@ -27,27 +27,27 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
|
|||
var name: String {
|
||||
switch self {
|
||||
case .client:
|
||||
return "Client"
|
||||
return "device.role.name.client".localized
|
||||
case .clientMute:
|
||||
return "Client Mute"
|
||||
return "device.role.name.clientMute".localized
|
||||
case .router:
|
||||
return "Router"
|
||||
return "device.role.name.router".localized
|
||||
case .routerClient:
|
||||
return "Router & Client"
|
||||
return "device.role.name.routerClient".localized
|
||||
case .repeater:
|
||||
return "Repeater"
|
||||
return "device.role.name.repeater".localized
|
||||
case .tracker:
|
||||
return "Tracker"
|
||||
return "device.role.name.tracker".localized
|
||||
case .sensor:
|
||||
return "Sensor"
|
||||
return "device.role.name.sensor".localized
|
||||
case .tak:
|
||||
return "TAK"
|
||||
return "device.role.name.tak".localized
|
||||
case .takTracker:
|
||||
return "TAK Tracker"
|
||||
return "device.role.name.takTracker".localized
|
||||
case .clientHidden:
|
||||
return "Client Hidden"
|
||||
return "device.role.name.clientHidden".localized
|
||||
case .lostAndFound:
|
||||
return "Lost and Found"
|
||||
return "device.role.name.lostAndFound".localized
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,13 +149,13 @@ enum DisplayModes: Int, CaseIterable, Identifiable {
|
|||
var description: String {
|
||||
switch self {
|
||||
case .defaultMode:
|
||||
return "Default 128x64 screen layout"
|
||||
return "default.128x64.screen.layout".localized
|
||||
case .twoColor:
|
||||
return "Optimized for 2 color displays"
|
||||
return "optimized.for.2.color.displays".localized
|
||||
case .inverted:
|
||||
return "Inverted top bar for 2 Color display"
|
||||
return "inverted.top.bar.for.2.color.display".localized
|
||||
case .color:
|
||||
return "TFT Full Color Displays"
|
||||
return "tft.full.color.displays".localized
|
||||
}
|
||||
}
|
||||
func protoEnumValue() -> Config.DisplayConfig.DisplayMode {
|
||||
|
|
|
|||
|
|
@ -176,6 +176,54 @@ enum RegionCodes: Int, CaseIterable, Identifiable {
|
|||
return 100
|
||||
}
|
||||
}
|
||||
var isCountry: Bool {
|
||||
switch self {
|
||||
case .unset:
|
||||
return false
|
||||
case .us:
|
||||
return true
|
||||
case .eu433:
|
||||
return false
|
||||
case .eu868:
|
||||
return false
|
||||
case .cn:
|
||||
return true
|
||||
case .jp:
|
||||
return true
|
||||
case .anz:
|
||||
return false
|
||||
case .kr:
|
||||
return true
|
||||
case .tw:
|
||||
return true
|
||||
case .ru:
|
||||
return true
|
||||
case .in:
|
||||
return true
|
||||
case .nz865:
|
||||
return true
|
||||
case .th:
|
||||
return true
|
||||
case .ua433:
|
||||
return true
|
||||
case .ua868:
|
||||
return true
|
||||
case .lora24:
|
||||
return false
|
||||
case .my433:
|
||||
return true
|
||||
case .my919:
|
||||
return true
|
||||
case .sg923:
|
||||
return true
|
||||
case .ph433:
|
||||
return true
|
||||
case .ph868:
|
||||
return true
|
||||
case .ph915:
|
||||
return true
|
||||
}
|
||||
}
|
||||
func protoEnumValue() -> Config.LoRaConfig.RegionCode {
|
||||
|
||||
switch self {
|
||||
|
|
|
|||
|
|
@ -20,17 +20,17 @@ enum Aqi: Int, CaseIterable, Identifiable {
|
|||
var description: String {
|
||||
switch self {
|
||||
case .good:
|
||||
return "Good"
|
||||
return "telemetry.good".localized
|
||||
case .moderate:
|
||||
return "Moderate"
|
||||
return "telemetry.moderate".localized
|
||||
case .sensitive:
|
||||
return "Unhealthy for Sensitive Groups"
|
||||
return "telemetry.sensitive".localized
|
||||
case .unhealthy:
|
||||
return "Unhealthy"
|
||||
return "telementry.unhealthy".localized
|
||||
case .veryUnhealthy:
|
||||
return "Very Unhealthy"
|
||||
return "telementry.veryUnhealthy".localized
|
||||
case .hazardous:
|
||||
return "Hazardous"
|
||||
return "telementry.hazardous".localized
|
||||
}
|
||||
}
|
||||
var color: Color {
|
||||
|
|
|
|||
|
|
@ -33,48 +33,79 @@ extension UserEntity {
|
|||
let unreadMessages = messageList.filter { ($0 as AnyObject).read == false }
|
||||
return unreadMessages.count
|
||||
}
|
||||
|
||||
/// SVG Images for Vendors who are signed project backers
|
||||
var hardwareImage: String? {
|
||||
guard let hwModel else { return nil }
|
||||
switch hwModel {
|
||||
case "HELTECV1", "HELTECV3", "HELTECV20", "HELTECV21":
|
||||
/// Heltec
|
||||
case "HELTECHT62":
|
||||
return "HELTECHT62"
|
||||
case "HELTECMESHNODET114":
|
||||
return "HELTECMESHNODET114"
|
||||
case "HELTECV3":
|
||||
return "HELTECV3"
|
||||
case "HELTECVISIONMASTERE213":
|
||||
return "HELTECVISIONMASTERE213"
|
||||
case "HELTECVISIONMASTERE290":
|
||||
return "HELTECVISIONMASTERE290"
|
||||
case "HELTECWIRELESSPAPER", "HELTECWIRELESSPAPERV10":
|
||||
return "HELTECWIRELESSPAPER"
|
||||
case "HELTECWIRELESSTRACKER", "HELTECWIRELESSTRACKERV10":
|
||||
return "HELTECWIRELESSTRACKER"
|
||||
case "HELTECWSLV3":
|
||||
return "HELTECWSLV3"
|
||||
case "LILYGOTBEAMSCORE":
|
||||
/// LilyGO
|
||||
case "TDECK":
|
||||
return "TDECK"
|
||||
case "TECHO":
|
||||
return "TECHO"
|
||||
case "TWATCHS3":
|
||||
return "TWATCHS3"
|
||||
case "LILYGOTBEAMS3CORE":
|
||||
return "LILYGOTBEAMS3CORE"
|
||||
case "TBEAM", "TBEAM_V0P7":
|
||||
return "TBEAM"
|
||||
case "TLORAC6":
|
||||
return "TLORAC6"
|
||||
case "TLORAT3S3EPAPER":
|
||||
return "TLORAT3S3EPAPER"
|
||||
case "TLORAT3S3V1":
|
||||
return "TLORAT3S3V1"
|
||||
case "TLORAV2116":
|
||||
return "TLORAV2116"
|
||||
case "TLORAV2118":
|
||||
return "TLORAV2118"
|
||||
/// Seeed Studio
|
||||
case "SENSECAPINDICATOR":
|
||||
return "SENSECAPINDICATOR"
|
||||
case "TRACKERT1000E":
|
||||
return "TRACKERT1000E"
|
||||
case "SEEEDXIAOS3":
|
||||
return "SEEEDXIAOS3"
|
||||
case "WIOWM1110":
|
||||
return "WIOWM1110"
|
||||
/// RAK Wireless
|
||||
case "RAK4631":
|
||||
return "RAK4631"
|
||||
case "RAK11310":
|
||||
return "RAK11310"
|
||||
case "WISMESHTAP":
|
||||
return "WISMESHTAP"
|
||||
/// B&Q Consulting
|
||||
case "NANOG1", "NANOG1EXPLORER":
|
||||
return "NANOG1"
|
||||
case "NANOG2ULTRA":
|
||||
return "NANOG2ULTRA"
|
||||
case "RAK4631":
|
||||
return "RAK4631"
|
||||
case "RAK11200":
|
||||
return "RAK11200"
|
||||
case "SOLAR_NODE":
|
||||
return "SOLAR_NODE"
|
||||
case "STATIONG1":
|
||||
return "STATIONG1"
|
||||
case "ТВЕАМ", "TBEAMVOP7":
|
||||
return "ТВЕАМ"
|
||||
case "TECHO":
|
||||
return "TECHO"
|
||||
case "TLORAV1", "TLORAV11P3":
|
||||
return "TLORAV1"
|
||||
case "TLORAV2", "TLORAT3S3", "TLORAV211P6", "TLORAV211P8":
|
||||
return "TLORABOARD"
|
||||
case "UNPHONE":
|
||||
return "UNPHONE"
|
||||
case "STATIONG2":
|
||||
return "STATIONG2"
|
||||
/// DIY Devices
|
||||
case "RPIPICO":
|
||||
return "RPIPICO"
|
||||
default:
|
||||
return "UNSET"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func createUser(num: Int64, context: NSManagedObjectContext) -> UserEntity {
|
||||
let newUser = UserEntity(context: context)
|
||||
newUser.num = Int64(num)
|
||||
|
|
|
|||
|
|
@ -61,11 +61,10 @@ extension String {
|
|||
}
|
||||
|
||||
func camelCaseToWords() -> String {
|
||||
return unicodeScalars.dropFirst().reduce(String(prefix(1))) {
|
||||
return CharacterSet.uppercaseLetters.contains($1)
|
||||
? $0 + " " + String($1)
|
||||
: $0 + String($1)
|
||||
}
|
||||
return self
|
||||
.replacingOccurrences(of: "([a-z])([A-Z](?=[A-Z])[a-z]*)", with: "$1 $2", options: .regularExpression)
|
||||
.replacingOccurrences(of: "([A-Z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression)
|
||||
.replacingOccurrences(of: "([a-z])([A-Z][a-z])", with: "$1 $2", options: .regularExpression)
|
||||
}
|
||||
|
||||
var length: Int {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
@Published var automaticallyReconnect: Bool = true
|
||||
@Published var mqttProxyConnected: Bool = false
|
||||
@Published var mqttError: String = ""
|
||||
public var minimumVersion = "2.0.0"
|
||||
public var minimumVersion = "2.3.2"
|
||||
public var connectedVersion: String
|
||||
public var isConnecting: Bool = false
|
||||
public var isConnected: Bool = false
|
||||
|
|
@ -242,14 +242,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
if errorCode == 6 { // CBError.Code.connectionTimeout The connection has timed out unexpectedly.
|
||||
// Happens when device is manually reset / powered off
|
||||
lastConnectionError = "🚨" + String.localizedStringWithFormat("ble.errorcode.6 %@".localized, e.localizedDescription)
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
} else if errorCode == 7 { // CBError.Code.peripheralDisconnected The specified device has disconnected from us.
|
||||
// Seems to be what is received when a tbeam sleeps, immediately recconnecting does not work.
|
||||
if UserDefaults.preferredPeripheralId == peripheral.identifier.uuidString {
|
||||
manager.notifications = [
|
||||
Notification(
|
||||
id: (peripheral.identifier.uuidString),
|
||||
title: "Radio Disconnected",
|
||||
title: "Radio Disconnected".localized,
|
||||
subtitle: "\(peripheral.name ?? "unknown".localized)",
|
||||
content: e.localizedDescription,
|
||||
target: "bluetooth",
|
||||
|
|
@ -258,18 +258,18 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
]
|
||||
manager.schedule()
|
||||
}
|
||||
lastConnectionError = "🚨 \(e.localizedDescription)"
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
lastConnectionError = "🚨 \("The specified device has disconnected from us".localized)"
|
||||
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("ble.errorcode.14 %@".localized, e.localizedDescription)
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown") Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)")
|
||||
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 {
|
||||
manager.notifications = [
|
||||
Notification(
|
||||
id: (peripheral.identifier.uuidString),
|
||||
title: "Radio Disconnected",
|
||||
title: "Radio Disconnected".localized,
|
||||
subtitle: "\(peripheral.name ?? "unknown".localized)",
|
||||
content: e.localizedDescription,
|
||||
target: "bluetooth",
|
||||
|
|
@ -279,12 +279,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
manager.schedule()
|
||||
}
|
||||
lastConnectionError = "🚨 \(e.localizedDescription)"
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
|
||||
}
|
||||
} else {
|
||||
// Disconnected without error which indicates user intent to disconnect
|
||||
// Happens when swiping to disconnect
|
||||
Logger.services.info("ℹ️ [BLE] Disconnected: \(peripheral.name ?? "Unknown", privacy: .public): User Initiated Disconnect")
|
||||
Logger.services.info("ℹ️ [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public): \(String(describing: "User Initiated Disconnect".localized))")
|
||||
}
|
||||
// Start a scan so the disconnected peripheral is moved to the peripherals[] if it is awake
|
||||
self.startScanning()
|
||||
|
|
@ -988,6 +988,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
MeshLogger.log("🕸️ MESH PACKET received for ATAK Plugin App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
|
||||
case .powerstressApp:
|
||||
MeshLogger.log("🕸️ MESH PACKET received for Power Stress App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
|
||||
case .alertApp:
|
||||
MeshLogger.log("🕸️ MESH PACKET received for Alert App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
|
||||
}
|
||||
|
||||
if decodedInfo.configCompleteID != 0 && decodedInfo.configCompleteID == configNonce {
|
||||
|
|
@ -1895,6 +1897,64 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
|
|||
return false
|
||||
}
|
||||
|
||||
public func setIgnoredNode(node: NodeInfoEntity, connectedNodeNum: Int64) -> Bool {
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setIgnoredNode = UInt32(node.num)
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedNodeNum)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
var dataMessage = DataMessage()
|
||||
guard let adminData: Data = try? adminPacket.serializedData() else {
|
||||
return false
|
||||
}
|
||||
dataMessage.payload = adminData
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
guard let binaryData: Data = try? toRadio.serializedData() else {
|
||||
return false
|
||||
}
|
||||
|
||||
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func removeIgnoredNode(node: NodeInfoEntity, connectedNodeNum: Int64) -> Bool {
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.removeIgnoredNode = UInt32(node.num)
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedNodeNum)
|
||||
meshPacket.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
|
||||
meshPacket.priority = MeshPacket.Priority.reliable
|
||||
meshPacket.wantAck = true
|
||||
var dataMessage = DataMessage()
|
||||
guard let adminData: Data = try? adminPacket.serializedData() else {
|
||||
return false
|
||||
}
|
||||
dataMessage.payload = adminData
|
||||
dataMessage.portnum = PortNum.adminApp
|
||||
meshPacket.decoded = dataMessage
|
||||
var toRadio: ToRadio!
|
||||
toRadio = ToRadio()
|
||||
toRadio.packet = meshPacket
|
||||
guard let binaryData: Data = try? toRadio.serializedData() else {
|
||||
return false
|
||||
}
|
||||
|
||||
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func saveLicensedUser(ham: HamParameters, fromUser: UserEntity, toUser: UserEntity, adminIndex: Int32) -> Int64 {
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.setHamMode = ham
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
|
|||
newNode.num = Int64(nodeInfo.num)
|
||||
newNode.channel = Int32(nodeInfo.channel)
|
||||
newNode.favorite = nodeInfo.isFavorite
|
||||
newNode.ignored = nodeInfo.isIgnored
|
||||
newNode.hopsAway = Int32(nodeInfo.hopsAway)
|
||||
|
||||
if nodeInfo.hasDeviceMetrics {
|
||||
|
|
@ -358,6 +359,7 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
|
|||
fetchedNode[0].snr = nodeInfo.snr
|
||||
fetchedNode[0].channel = Int32(nodeInfo.channel)
|
||||
fetchedNode[0].favorite = nodeInfo.isFavorite
|
||||
fetchedNode[0].ignored = nodeInfo.isIgnored
|
||||
fetchedNode[0].hopsAway = Int32(nodeInfo.hopsAway)
|
||||
|
||||
if nodeInfo.hasUser {
|
||||
|
|
@ -772,7 +774,8 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
|
|||
}
|
||||
}
|
||||
} else if telemetry.metricsType == 4 {
|
||||
// Update our live activity if there is one running, not available on mac iOS >= 16.2
|
||||
// Update our live activity if there is one running, not available on mac
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
#if canImport(ActivityKit)
|
||||
|
||||
let fifteenMinutesLater = Calendar.current.date(byAdding: .minute, value: (Int(15) ), to: Date())!
|
||||
|
|
@ -801,6 +804,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
|
|||
Logger.services.debug("Updated live activity.")
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
} catch {
|
||||
|
|
@ -876,6 +880,9 @@ func textMessageAppPacket(
|
|||
if fetchedUsers.first(where: { $0.num == packet.to }) != nil && packet.to != Constants.maximumNodeNum {
|
||||
if !storeForwardBroadcast {
|
||||
newMessage.toUser = fetchedUsers.first(where: { $0.num == packet.to })
|
||||
} else {
|
||||
/// Make a new to user if they are unknown
|
||||
newMessage.toUser = createUser(num: Int64(truncatingIfNeeded: packet.to), context: context)
|
||||
}
|
||||
}
|
||||
if fetchedUsers.first(where: { $0.num == packet.from }) != nil {
|
||||
|
|
@ -903,11 +910,14 @@ func textMessageAppPacket(
|
|||
newMessage.fromUser?.publicKey = packet.publicKey
|
||||
}
|
||||
}
|
||||
if packet.rxTime > 0 {
|
||||
newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
|
||||
} else {
|
||||
newMessage.fromUser?.userNode?.lastHeard = Date()
|
||||
}
|
||||
} else {
|
||||
/// Make a new from user if they are unknown
|
||||
newMessage.fromUser = createUser(num: Int64(truncatingIfNeeded: packet.from), context: context)
|
||||
}
|
||||
if packet.rxTime > 0 {
|
||||
newMessage.fromUser?.userNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(packet.rxTime)))
|
||||
} else {
|
||||
newMessage.fromUser?.userNode?.lastHeard = Date()
|
||||
}
|
||||
newMessage.messagePayload = messageText
|
||||
newMessage.messagePayloadMarkdown = generateMessageMarkdown(message: messageText!)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>_XCCurrentVersionName</key>
|
||||
<string>MeshtasticDataModelV 46.xcdatamodel</string>
|
||||
<string>MeshtasticDataModelV 47.xcdatamodel</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,485 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23507" systemVersion="24B91" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AmbientLightingConfigEntity" representedClassName="AmbientLightingConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="blue" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="current" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="green" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ledState" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="red" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="ambientLightingConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="ambientLightingConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="BluetoothConfigEntity" representedClassName="BluetoothConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="deviceLoggingEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="fixedPin" optional="YES" attributeType="Integer 32" defaultValueString="123456" usesScalarValueType="YES"/>
|
||||
<attribute name="mode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="bluetoothConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="bluetoothConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="CannedMessageConfigEntity" representedClassName="CannedMessageConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventCcw" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventCw" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerEventPress" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinA" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinB" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="inputbrokerPinPress" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="messages" optional="YES" attributeType="String" minValueString="0" maxValueString="198"/>
|
||||
<attribute name="rotary1Enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="sendBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="updown1Enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="cannedMessagesConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="cannedMessageConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="ChannelEntity" representedClassName="ChannelEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="downlinkEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="index" attributeType="Integer 32" minValueString="0" maxValueString="13" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="mute" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="positionPrecision" optional="YES" attributeType="Integer 32" defaultValueString="32" usesScalarValueType="YES"/>
|
||||
<attribute name="psk" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="role" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="uplinkEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="myInfoChannel" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="channels" inverseEntity="MyInfoEntity"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="index"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="DetectionSensorConfigEntity" representedClassName="DetectionSensorConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="minimumBroadcastSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="monitorPin" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="sendBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="stateBroadcastSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="triggerType" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="usePullup" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<relationship name="detectionSensorConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="detectionSensorConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DeviceConfigEntity" representedClassName="DeviceConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="buttonGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="buzzerGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="debugLogEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="disableTripleClick" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="doubleTapAsButtonPress" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="isManaged" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="ledHeartbeatEnabled" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="nodeInfoBroadcastSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rebroadcastMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="role" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="serialEnabled" optional="YES" attributeType="Boolean" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="tripleClickAsAdHocPing" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="tzdef" optional="YES" attributeType="String"/>
|
||||
<relationship name="deviceConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="deviceConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DeviceMetadataEntity" representedClassName="DeviceMetadataEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="canShutdown" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceStateVersion" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="firmwareVersion" optional="YES" attributeType="String"/>
|
||||
<attribute name="hasBluetooth" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="hasEthernet" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="hasWifi" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="hwModel" optional="YES" attributeType="String"/>
|
||||
<attribute name="positionFlags" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="role" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="metadataNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="metadata" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="DisplayConfigEntity" representedClassName="DisplayConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="compassNorthTop" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="displayMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="flipScreen" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsFormat" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="headingBold" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="oledType" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="screenCarouselInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="screenOnSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="units" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wakeOnTapOrMotion" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="displayConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="displayConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="ExternalNotificationConfigEntity" representedClassName="ExternalNotificationConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="active" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertBell" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertBellBuzzer" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertBellVibra" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertMessage" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertMessageBuzzer" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="alertMessageVibra" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="nagTimeout" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="output" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="outputBuzzer" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="outputMilliseconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="outputVibra" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="useI2SAsBuzzer" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="usePWM" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<relationship name="externalNotificationConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="externalNotificationConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="LocationEntity" representedClassName="LocationEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="heading" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="longitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="speed" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="routeLocation" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="RouteEntity" inverseName="locations" inverseEntity="RouteEntity"/>
|
||||
</entity>
|
||||
<entity name="LoRaConfigEntity" representedClassName="LoRaConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="bandwidth" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="channelNum" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="codingRate" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="frequencyOffset" optional="YES" attributeType="Float" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hopLimit" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ignoreMqtt" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="modemPreset" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="okToMqtt" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="overrideDutyCycle" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="overrideFrequency" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="regionCode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="spreadFactor" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sx126xRxBoostedGain" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="txEnabled" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="txPower" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="usePreset" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<relationship name="loRaConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="loRaConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="MessageEntity" representedClassName="MessageEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ackError" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ackSNR" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="ackTimestamp" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="admin" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="adminDescription" optional="YES" attributeType="String"/>
|
||||
<attribute name="channel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="isEmoji" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="messageId" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="messagePayload" optional="YES" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="messagePayloadMarkdown" optional="YES" attributeType="String"/>
|
||||
<attribute name="messageTimestamp" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="pkiEncrypted" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="portNum" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="publicKey" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="read" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="realACK" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="receivedACK" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="replyID" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rssi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<relationship name="fromUser" optional="YES" maxCount="1" deletionRule="Nullify" ordered="YES" destinationEntity="UserEntity" inverseName="sentMessages" inverseEntity="UserEntity"/>
|
||||
<relationship name="toUser" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="receivedMessages" inverseEntity="UserEntity"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="messageId"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="MQTTConfigEntity" representedClassName="MQTTConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="address" optional="YES" attributeType="String"/>
|
||||
<attribute name="enabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="encryptionEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="jsonEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="mapPositionPrecision" optional="YES" attributeType="Integer 32" defaultValueString="13" usesScalarValueType="YES"/>
|
||||
<attribute name="mapPublishIntervalSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="mapReportingEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="password" optional="YES" attributeType="String" maxValueString="30"/>
|
||||
<attribute name="proxyToClientEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="root" optional="YES" attributeType="String" defaultValueString="msh"/>
|
||||
<attribute name="tlsEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="username" optional="YES" attributeType="String" maxValueString="30"/>
|
||||
<relationship name="mqttConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="mqttConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="MyInfoEntity" representedClassName="MyInfoEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="adminIndex" optional="YES" attributeType="Integer 32" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="bleName" optional="YES" attributeType="String"/>
|
||||
<attribute name="minAppVersion" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="myNodeNum" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="peripheralId" optional="YES" attributeType="String"/>
|
||||
<attribute name="rebootCount" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="channels" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="ChannelEntity" inverseName="myInfoChannel" inverseEntity="ChannelEntity"/>
|
||||
<relationship name="myInfoNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="myInfo" inverseEntity="NodeInfoEntity"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="myNodeNum"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="NetworkConfigEntity" representedClassName="NetworkConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="dns" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ethEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="gateway" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ip" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ntpServer" optional="YES" attributeType="String"/>
|
||||
<attribute name="subnet" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiMode" optional="YES" attributeType="Integer 32" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiPsk" optional="YES" attributeType="String" minValueString="0" maxValueString="60"/>
|
||||
<attribute name="wifiSsid" optional="YES" attributeType="String" minValueString="0" maxValueString="30"/>
|
||||
<relationship name="networkConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="networkConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="NodeInfoEntity" representedClassName="NodeInfoEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="bleName" optional="YES" attributeType="String"/>
|
||||
<attribute name="channel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="favorite" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="firstHeard" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="hopsAway" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="ignored" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="lastHeard" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="peripheralId" optional="YES" attributeType="String"/>
|
||||
<attribute name="rssi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="sessionExpiration" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="sessionPasskey" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="viaMqtt" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="ambientLightingConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="AmbientLightingConfigEntity" inverseName="ambientLightingConfigNode" inverseEntity="AmbientLightingConfigEntity"/>
|
||||
<relationship name="bluetoothConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="BluetoothConfigEntity" inverseName="bluetoothConfigNode" inverseEntity="BluetoothConfigEntity"/>
|
||||
<relationship name="cannedMessageConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="CannedMessageConfigEntity" inverseName="cannedMessagesConfigNode" inverseEntity="CannedMessageConfigEntity"/>
|
||||
<relationship name="detectionSensorConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="DetectionSensorConfigEntity" inverseName="detectionSensorConfigNode" inverseEntity="DetectionSensorConfigEntity"/>
|
||||
<relationship name="deviceConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="DeviceConfigEntity" inverseName="deviceConfigNode" inverseEntity="DeviceConfigEntity"/>
|
||||
<relationship name="displayConfig" optional="YES" maxCount="1" deletionRule="Cascade" destinationEntity="DisplayConfigEntity" inverseName="displayConfigNode" inverseEntity="DisplayConfigEntity"/>
|
||||
<relationship name="externalNotificationConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="ExternalNotificationConfigEntity" inverseName="externalNotificationConfigNode" inverseEntity="ExternalNotificationConfigEntity"/>
|
||||
<relationship name="loRaConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="LoRaConfigEntity" inverseName="loRaConfigNode" inverseEntity="LoRaConfigEntity"/>
|
||||
<relationship name="metadata" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DeviceMetadataEntity" inverseName="metadataNode" inverseEntity="DeviceMetadataEntity"/>
|
||||
<relationship name="mqttConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MQTTConfigEntity" inverseName="mqttConfigNode" inverseEntity="MQTTConfigEntity"/>
|
||||
<relationship name="myInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="myInfoNode" inverseEntity="MyInfoEntity"/>
|
||||
<relationship name="networkConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NetworkConfigEntity" inverseName="networkConfigNode" inverseEntity="NetworkConfigEntity"/>
|
||||
<relationship name="pax" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PaxCounterEntity" inverseName="paxNode" inverseEntity="PaxCounterEntity"/>
|
||||
<relationship name="paxCounterConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PaxCounterConfigEntity" inverseName="paxCounterConfigNode" inverseEntity="PaxCounterConfigEntity"/>
|
||||
<relationship name="positionConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PositionConfigEntity" inverseName="positionConfigNode" inverseEntity="PositionConfigEntity"/>
|
||||
<relationship name="positions" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PositionEntity" inverseName="nodePosition" inverseEntity="PositionEntity"/>
|
||||
<relationship name="powerConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="PowerConfigEntity" inverseName="powerConfigNode" inverseEntity="PowerConfigEntity"/>
|
||||
<relationship name="rangeTestConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="RangeTestConfigEntity" inverseName="rangeTestConfigNode" inverseEntity="RangeTestConfigEntity"/>
|
||||
<relationship name="rtttlConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="RTTTLConfigEntity" inverseName="rtttlConfigNode" inverseEntity="RTTTLConfigEntity"/>
|
||||
<relationship name="securityConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="SecurityConfigEntity" inverseName="securityConfigNode" inverseEntity="SecurityConfigEntity"/>
|
||||
<relationship name="serialConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="SerialConfigEntity" inverseName="serialConfigNode" inverseEntity="SerialConfigEntity"/>
|
||||
<relationship name="storeForwardConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="StoreForwardConfigEntity" inverseName="storeForwardConfigNode" inverseEntity="StoreForwardConfigEntity"/>
|
||||
<relationship name="telemetries" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TelemetryEntity" inverseName="nodeTelemetry" inverseEntity="TelemetryEntity"/>
|
||||
<relationship name="telemetryConfig" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TelemetryConfigEntity" inverseName="telemetryConfigNode" inverseEntity="TelemetryConfigEntity"/>
|
||||
<relationship name="traceRoutes" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TraceRouteEntity" inverseName="node" inverseEntity="TraceRouteEntity"/>
|
||||
<relationship name="user" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="UserEntity" inverseName="userNode" inverseEntity="UserEntity"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="num"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="PaxCounterConfigEntity" representedClassName="PaxCounterConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="bleThreshold" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="updateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wifiThreshold" optional="YES" attributeType="Integer 32" defaultValueString="-80" usesScalarValueType="YES"/>
|
||||
<relationship name="paxCounterConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="paxCounterConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PaxCounterEntity" representedClassName="PaxCounterEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ble" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="uptime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="wifi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="paxNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="pax" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PositionConfigEntity" representedClassName="PositionConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="broadcastSmartMinimumDistance" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="broadcastSmartMinimumIntervalSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceGpsEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="fixedPosition" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsAttemptTime" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsEnGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="gpsUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="positionBroadcastSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="positionFlags" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rxGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="smartPositionEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="txGpio" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="positionConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="positionConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PositionEntity" representedClassName="PositionEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="heading" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="latest" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="longitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="precisionBits" optional="YES" attributeType="Integer 32" defaultValueString="32" usesScalarValueType="YES"/>
|
||||
<attribute name="rssi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="satsInView" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="seqNo" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="speed" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="nodePosition" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="positions" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="PowerConfigEntity" representedClassName="PowerConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="adcMultiplierOverride" optional="YES" attributeType="Float" usesScalarValueType="YES"/>
|
||||
<attribute name="deviceBatteryInaAddress" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="isPowerSaving" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="lsSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="minWakeSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="onBatteryShutdownAfterSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="waitBluetoothSecs" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="powerConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="powerConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="RangeTestConfigEntity" representedClassName="RangeTestConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="save" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="sender" optional="YES" attributeType="Integer 32" usesScalarValueType="YES"/>
|
||||
<relationship name="rangeTestConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="rangeTestConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="RouteEntity" representedClassName="RouteEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="color" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="distance" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="elevationGain" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="endDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="notes" optional="YES" attributeType="String"/>
|
||||
<relationship name="locations" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="LocationEntity" inverseName="routeLocation" inverseEntity="LocationEntity"/>
|
||||
</entity>
|
||||
<entity name="RTTTLConfigEntity" representedClassName="RTTTLConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="ringtone" optional="YES" attributeType="String" maxValueString="228" defaultValueString=""/>
|
||||
<relationship name="rtttlConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="rtttlConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="SecurityConfigEntity" representedClassName="SecurityConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="adminChannelEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="adminKey" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="adminKey2" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="adminKey3" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="bluetoothLoggingEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="debugLogApiEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="isManaged" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="privateKey" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="publicKey" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="serialEnabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<relationship name="securityConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="securityConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="SerialConfigEntity" representedClassName="SerialConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="baudRate" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="echo" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="enabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="mode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="overrideConsoleSerialPort" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="rxd" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="timeout" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="txd" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="serialConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="serialConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="StoreForwardConfigEntity" representedClassName="StoreForwardConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="enabled" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="heartbeat" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="historyReturnMax" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="historyReturnWindow" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="isRouter" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="lastHeartbeat" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="lastRequest" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="records" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="storeForwardConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="storeForwardConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TelemetryConfigEntity" representedClassName="TelemetryConfigEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="deviceUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentDisplayFahrenheit" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentMeasurementEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentScreenEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="environmentUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="powerMeasurementEnabled" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="powerScreenEnabled" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="powerUpdateInterval" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="telemetryConfigNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="telemetryConfig" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TelemetryEntity" representedClassName="TelemetryEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="airUtilTx" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="barometricPressure" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="batteryLevel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="channelUtilization" optional="YES" attributeType="Float" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="current" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="gasResistance" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="iaq" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="metricsType" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numOnlineNodes" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numPacketsRx" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numPacketsRxBad" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numPacketsTx" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numRxDupe" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numTotalNodes" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numTxRelay" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numTxRelayCanceled" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="relativeHumidity" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="rssi" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="temperature" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="uptimeSeconds" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="voltage" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="weight" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="windDirection" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="windGust" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="windLull" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="windSpeed" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<relationship name="nodeTelemetry" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="telemetries" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TraceRouteEntity" representedClassName="TraceRouteEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="hasPositions" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="hopsBack" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="hopsTowards" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="response" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="routeBackText" optional="YES" attributeType="String"/>
|
||||
<attribute name="routeText" optional="YES" attributeType="String"/>
|
||||
<attribute name="sent" optional="YES" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="hops" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="TraceRouteHopEntity" inverseName="traceRoute" inverseEntity="TraceRouteHopEntity"/>
|
||||
<relationship name="node" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="traceRoutes" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TraceRouteHopEntity" representedClassName="TraceRouteHopEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="altitude" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="back" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="latitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="longitudeI" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String"/>
|
||||
<attribute name="num" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<relationship name="traceRoute" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TraceRouteEntity" inverseName="hops" inverseEntity="TraceRouteEntity"/>
|
||||
</entity>
|
||||
<entity name="UserEntity" representedClassName="UserEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="hwDisplayName" optional="YES" attributeType="String"/>
|
||||
<attribute name="hwModel" attributeType="String"/>
|
||||
<attribute name="hwModelId" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="isLicensed" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="keyMatch" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
|
||||
<attribute name="lastMessage" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="longName" attributeType="String"/>
|
||||
<attribute name="mute" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="newPublicKey" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="numString" optional="YES" attributeType="String"/>
|
||||
<attribute name="pkiEncrypted" optional="YES" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="publicKey" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="role" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="shortName" attributeType="String"/>
|
||||
<attribute name="userId" attributeType="String"/>
|
||||
<relationship name="receivedMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="toUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="userNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="user" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="WaypointEntity" representedClassName="WaypointEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="created" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="expire" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="icon" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="lastUpdated" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="latitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="locked" attributeType="Integer 64" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="longDescription" optional="YES" attributeType="String" maxValueString="100"/>
|
||||
<attribute name="longitudeI" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="name" attributeType="String" minValueString="1" maxValueString="30"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
<constraint value="id"/>
|
||||
</uniquenessConstraint>
|
||||
</uniquenessConstraints>
|
||||
</entity>
|
||||
</model>
|
||||
|
|
@ -199,9 +199,9 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
|
|||
manager.notifications = [
|
||||
Notification(
|
||||
id: (UUID().uuidString),
|
||||
title: "New Node",
|
||||
title: "New Node".localized,
|
||||
subtitle: "\(newUser.longName ?? "unknown".localized)",
|
||||
content: "New Node has been discovered",
|
||||
content: "New Node has been discovered".localized,
|
||||
target: "nodes",
|
||||
path: "meshtastic:///nodes?nodenum=\(newUser.num)"
|
||||
)
|
||||
|
|
@ -832,9 +832,9 @@ func upsertSecurityConfigPacket(config: Config.SecurityConfig, nodeNum: Int64, s
|
|||
if config.adminKey.count > 0 {
|
||||
fetchedNode[0].securityConfig?.adminKey = config.adminKey[0]
|
||||
if config.adminKey.count > 1 {
|
||||
fetchedNode[0].securityConfig?.adminKey = config.adminKey[1]
|
||||
fetchedNode[0].securityConfig?.adminKey2 = config.adminKey[1]
|
||||
} else if config.adminKey.count > 2 {
|
||||
fetchedNode[0].securityConfig?.adminKey = config.adminKey[2]
|
||||
fetchedNode[0].securityConfig?.adminKey3 = config.adminKey[2]
|
||||
}
|
||||
}
|
||||
fetchedNode[0].securityConfig?.isManaged = config.isManaged
|
||||
|
|
|
|||
|
|
@ -86,7 +86,8 @@
|
|||
],
|
||||
"images": [
|
||||
"t-echo.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 8,
|
||||
|
|
@ -113,7 +114,8 @@
|
|||
"images": [
|
||||
"rak4631.svg",
|
||||
"rak4631_case.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 10,
|
||||
|
|
@ -139,7 +141,7 @@
|
|||
},
|
||||
{
|
||||
"hwModel": 12,
|
||||
"hwModelSlug": "TBEAM_S3_CORE",
|
||||
"hwModelSlug": "LILYGO_TBEAM_S3_CORE",
|
||||
"platformioTarget": "tbeam-s3-core",
|
||||
"architecture": "esp32-s3",
|
||||
"activelySupported": true,
|
||||
|
|
@ -150,7 +152,8 @@
|
|||
],
|
||||
"images": [
|
||||
"tbeam-s3-core.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 13,
|
||||
|
|
@ -204,7 +207,8 @@
|
|||
],
|
||||
"images": [
|
||||
"tlora-t3s3-v1.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 16,
|
||||
|
|
@ -219,7 +223,8 @@
|
|||
],
|
||||
"images": [
|
||||
"tlora-t3s3-epaper.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 17,
|
||||
|
|
@ -243,6 +248,10 @@
|
|||
"displayName": "Nano G2 Ultra",
|
||||
"tags": [
|
||||
"B&Q"
|
||||
],
|
||||
"requiresDfu": true,
|
||||
"images": [
|
||||
"nano-g2-ultra.svg"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -258,7 +267,8 @@
|
|||
],
|
||||
"images": [
|
||||
"wio-tracker-wm1110.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 25,
|
||||
|
|
@ -282,7 +292,11 @@
|
|||
"displayName": "RAK WisBlock 11310",
|
||||
"tags": [
|
||||
"RAK"
|
||||
]
|
||||
],
|
||||
"images": [
|
||||
"rak11310.svg"
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 29,
|
||||
|
|
@ -294,7 +308,8 @@
|
|||
"displayName": "Canary One",
|
||||
"tags": [
|
||||
"Canary"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 30,
|
||||
|
|
@ -306,7 +321,8 @@
|
|||
"displayName": "RP2040 LoRa",
|
||||
"tags": [
|
||||
"Waveshare"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 31,
|
||||
|
|
@ -318,6 +334,10 @@
|
|||
"displayName": "Station G2",
|
||||
"tags": [
|
||||
"B&Q"
|
||||
],
|
||||
"requiresDfu": true,
|
||||
"images": [
|
||||
"station-g2.svg"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -330,6 +350,9 @@
|
|||
"displayName": "DIY V1",
|
||||
"tags": [
|
||||
"DIY"
|
||||
],
|
||||
"images": [
|
||||
"diy.svg"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -407,8 +430,12 @@
|
|||
"supportLevel": 3,
|
||||
"displayName": "Raspberry Pi Pico",
|
||||
"tags": [
|
||||
"Raspberry Pi",
|
||||
"RPi",
|
||||
"DIY"
|
||||
],
|
||||
"requiresDfu": true,
|
||||
"images": [
|
||||
"pico.svg"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -420,8 +447,12 @@
|
|||
"supportLevel": 3,
|
||||
"displayName": "Raspberry Pi Pico W",
|
||||
"tags": [
|
||||
"Raspberry Pi",
|
||||
"RPi",
|
||||
"DIY"
|
||||
],
|
||||
"requiresDfu": true,
|
||||
"images": [
|
||||
"rpipicow.svg"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -437,19 +468,21 @@
|
|||
],
|
||||
"images": [
|
||||
"heltec-wireless-tracker.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 58,
|
||||
"hwModelSlug": "HELTEC_WIRELESS_TRACKER_V1_0",
|
||||
"platformioTarget": "heltec-wireless-tracker-V1-0",
|
||||
"architecture": "esp32-s3",
|
||||
"activelySupported": true,
|
||||
"activelySupported": false,
|
||||
"supportLevel": 3,
|
||||
"displayName": "Heltec Wireless Tracker V1.0",
|
||||
"images": [
|
||||
"heltec-wireless-tracker.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 49,
|
||||
|
|
@ -479,7 +512,8 @@
|
|||
],
|
||||
"images": [
|
||||
"t-deck.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 51,
|
||||
|
|
@ -525,7 +559,7 @@
|
|||
"hwModelSlug": "HELTEC_WIRELESS_PAPER_V1_0",
|
||||
"platformioTarget": "heltec-wireless-paper-v1_0",
|
||||
"architecture": "esp32-s3",
|
||||
"activelySupported": true,
|
||||
"activelySupported": false,
|
||||
"supportLevel": 3,
|
||||
"tags": [
|
||||
"Heltec"
|
||||
|
|
@ -542,7 +576,8 @@
|
|||
"architecture": "esp32-s3",
|
||||
"activelySupported": true,
|
||||
"supportLevel": 3,
|
||||
"displayName": "unPhone"
|
||||
"displayName": "unPhone",
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 48,
|
||||
|
|
@ -551,7 +586,8 @@
|
|||
"architecture": "esp32-s3",
|
||||
"activelySupported": true,
|
||||
"supportLevel": 3,
|
||||
"displayName": "TrackSenger (small TFT)"
|
||||
"displayName": "TrackSenger (small TFT)",
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 48,
|
||||
|
|
@ -560,7 +596,8 @@
|
|||
"architecture": "esp32-s3",
|
||||
"activelySupported": true,
|
||||
"supportLevel": 3,
|
||||
"displayName": "TrackSenger (big TFT)"
|
||||
"displayName": "TrackSenger (big TFT)",
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 48,
|
||||
|
|
@ -581,7 +618,8 @@
|
|||
"displayName": "EBYTE EoRa-S3",
|
||||
"tags": [
|
||||
"EByte"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 64,
|
||||
|
|
@ -608,7 +646,8 @@
|
|||
],
|
||||
"images": [
|
||||
"heltec-vision-master-t190.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 67,
|
||||
|
|
@ -623,7 +662,8 @@
|
|||
],
|
||||
"images": [
|
||||
"heltec-vision-master-e213.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 68,
|
||||
|
|
@ -638,7 +678,8 @@
|
|||
],
|
||||
"images": [
|
||||
"heltec-vision-master-e290.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 69,
|
||||
|
|
@ -654,7 +695,8 @@
|
|||
"images": [
|
||||
"heltec-mesh-node-t114.svg",
|
||||
"heltec-mesh-node-t114-case.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 70,
|
||||
|
|
@ -684,7 +726,8 @@
|
|||
],
|
||||
"images": [
|
||||
"tracker-t1000-e.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 72,
|
||||
|
|
@ -699,6 +742,23 @@
|
|||
],
|
||||
"images": [
|
||||
"seeed-xiao-s3.svg"
|
||||
]
|
||||
],
|
||||
"requiresDfu": true
|
||||
},
|
||||
{
|
||||
"hwModel": 84,
|
||||
"hwModelSlug": "WISMESH_TAP",
|
||||
"platformioTarget": "rak_wismeshtap",
|
||||
"architecture": "nrf52840",
|
||||
"activelySupported": false,
|
||||
"supportLevel": 1,
|
||||
"displayName": "RAK WisMesh Tap",
|
||||
"tags": [
|
||||
"RAK"
|
||||
],
|
||||
"images": [
|
||||
"rak-wismeshtap.svg"
|
||||
],
|
||||
"requiresDfu": true
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -324,7 +324,8 @@ struct Connect: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
#if canImport(ActivityKit)
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
#if canImport(ActivityKit)
|
||||
func startNodeActivity() {
|
||||
liveActivityStarted = true
|
||||
// 15 Minutes Local Stats Interval
|
||||
|
|
@ -367,8 +368,8 @@ struct Connect: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
func didDismissSheet() {
|
||||
bleManager.disconnectPeripheral(reconnect: false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,11 +41,9 @@ struct InvalidVersion: View {
|
|||
.font(.title3)
|
||||
.foregroundColor(.orange)
|
||||
.padding(.bottom)
|
||||
Text("Version \(minimumVersion) includes breaking changes to devices and the client apps. Only nodes version \(minimumVersion) and above are supported.")
|
||||
Text("Version \(minimumVersion) includes substantial network optimizations and extensive changes to devices and client apps. Only nodes version \(minimumVersion) and above are supported.")
|
||||
.font(.callout)
|
||||
.padding([.leading, .trailing, .bottom])
|
||||
Link("Version 1.2 End of life (EOL) Info", destination: URL(string: "https://meshtastic.org/docs/1.2-End-of-life/")!)
|
||||
.font(.callout)
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
Button {
|
||||
|
|
|
|||
|
|
@ -47,13 +47,13 @@ enum LoRaSignalStrength: Int {
|
|||
var description: String {
|
||||
switch self {
|
||||
case .none:
|
||||
return "None"
|
||||
return "lora.signal.strength.none".localized
|
||||
case .bad:
|
||||
return "Bad"
|
||||
return "lora.signal.strength.bad".localized
|
||||
case .fair:
|
||||
return "Fair"
|
||||
return "lora.signal.strength.fair".localized
|
||||
case .good:
|
||||
return "Good"
|
||||
return "lora.signal.strength.good".localized
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ struct MQTTIcon: View {
|
|||
.symbolRenderingMode(.hierarchical)
|
||||
}.popover(isPresented: self.$isPopoverOpen, arrowEdge: .bottom, content: {
|
||||
VStack(spacing: 0.5) {
|
||||
Text("Topic: " + topic)
|
||||
Text("Topic: \(topic)".localized)
|
||||
.padding(20)
|
||||
Button("close", action: { self.isPopoverOpen = false }).padding([.bottom], 20)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct UserList: View {
|
|||
@State private var isOnline = false
|
||||
@State private var isPkiEncrypted = false
|
||||
@State private var isFavorite = false
|
||||
@State private var isIgnored = false
|
||||
@State private var isEnvironment = false
|
||||
@State private var distanceFilter = false
|
||||
@State private var maxDistance: Double = 800000
|
||||
|
|
@ -44,7 +45,7 @@ struct UserList: View {
|
|||
NSSortDescriptor(key: "pkiEncrypted", ascending: false),
|
||||
NSSortDescriptor(key: "userNode.lastHeard", ascending: false),
|
||||
NSSortDescriptor(key: "longName", ascending: true)],
|
||||
predicate: NSPredicate(format: "longName != ''"),
|
||||
predicate: NSPredicate(format: "userNode.ignored == false && longName != ''"),
|
||||
animation: .default
|
||||
)
|
||||
var users: FetchedResults<UserEntity>
|
||||
|
|
@ -194,7 +195,7 @@ struct UserList: View {
|
|||
.listStyle(.plain)
|
||||
.navigationTitle(String.localizedStringWithFormat("contacts %@".localized, String(users.count == 0 ? 0 : users.count)))
|
||||
.sheet(isPresented: $editingFilters) {
|
||||
NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles)
|
||||
NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, isIgnored: $isIgnored, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles)
|
||||
}
|
||||
.sheet(isPresented: $showingHelp) {
|
||||
DirectMessagesHelp()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import CoreData
|
||||
import OSLog
|
||||
import SwiftUI
|
||||
|
||||
struct IgnoreNodeButton: View {
|
||||
var bleManager: BLEManager
|
||||
var context: NSManagedObjectContext
|
||||
|
||||
@ObservedObject
|
||||
var node: NodeInfoEntity
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
guard let connectedNodeNum = bleManager.connectedPeripheral?.num else { return }
|
||||
let success = if node.ignored {
|
||||
bleManager.removeIgnoredNode(
|
||||
node: node,
|
||||
connectedNodeNum: Int64(connectedNodeNum)
|
||||
)
|
||||
} else {
|
||||
bleManager.setIgnoredNode(
|
||||
node: node,
|
||||
connectedNodeNum: Int64(connectedNodeNum)
|
||||
)
|
||||
}
|
||||
if success {
|
||||
node.ignored = !node.ignored
|
||||
do {
|
||||
try context.save()
|
||||
} catch {
|
||||
context.rollback()
|
||||
Logger.data.error("Save Ignored Node Error")
|
||||
}
|
||||
Logger.data.debug("Ignored a node")
|
||||
}
|
||||
} label: {
|
||||
Label {
|
||||
Text(node.ignored ? "Remove from ignored" : "Ignore Node")
|
||||
} icon: {
|
||||
Image(systemName: node.ignored ? "minus.circle.fill" : "minus.circle")
|
||||
.symbolRenderingMode(.multicolor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,9 @@ struct NodeDetail: View {
|
|||
formatter.unitsStyle = .full
|
||||
return formatter
|
||||
}()
|
||||
var modemPreset: ModemPresets = ModemPresets(
|
||||
rawValue: UserDefaults.modemPreset
|
||||
) ?? ModemPresets.longFast
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
|
@ -44,6 +47,34 @@ struct NodeDetail: View {
|
|||
NodeInfoItem(node: node)
|
||||
}
|
||||
Section("Node") {
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
CircleText(
|
||||
text: node.user?.shortName ?? "?",
|
||||
color: Color(UIColor(hex: UInt32(node.num))),
|
||||
circleSize: 75
|
||||
)
|
||||
if node.snr != 0 && !node.viaMqtt && node.hopsAway == 0 {
|
||||
Spacer()
|
||||
VStack {
|
||||
let signalStrength = getLoRaSignalStrength(snr: node.snr, rssi: node.rssi, preset: modemPreset)
|
||||
LoRaSignalStrengthIndicator(signalStrength: signalStrength)
|
||||
Text("Signal \(signalStrength.description)").font(.footnote)
|
||||
Text("SNR \(String(format: "%.2f", node.snr))dB")
|
||||
.foregroundColor(getSnrColor(snr: node.snr, preset: modemPreset))
|
||||
.font(.caption)
|
||||
Text("RSSI \(node.rssi)dB")
|
||||
.foregroundColor(getRssiColor(rssi: node.rssi))
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
if node.telemetries?.count ?? 0 > 0 {
|
||||
Spacer()
|
||||
BatteryGauge(node: node)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.listRowSeparator(.hidden)
|
||||
if let user = node.user {
|
||||
if !user.keyMatch {
|
||||
Label {
|
||||
|
|
|
|||
|
|
@ -12,61 +12,71 @@ import MapKit
|
|||
struct NodeInfoItem: View {
|
||||
|
||||
@ObservedObject var node: NodeInfoEntity
|
||||
|
||||
var modemPreset: ModemPresets = ModemPresets(
|
||||
rawValue: UserDefaults.modemPreset
|
||||
) ?? ModemPresets.longFast
|
||||
@State private var currentDevice: DeviceHardware?
|
||||
|
||||
var body: some View {
|
||||
if let user = node.user {
|
||||
ViewThatFits(in: .horizontal) {
|
||||
VStack {
|
||||
if let user = node.user {
|
||||
HStack(alignment: .center) {
|
||||
if user.hwModel != "UNSET" {
|
||||
Image(user.hardwareImage ?? "UNSET")
|
||||
HStack {
|
||||
Spacer()
|
||||
if user.hwModel != "UNSET" {
|
||||
VStack(alignment: .center) {
|
||||
Spacer()
|
||||
Image(systemName: currentDevice?.activelySupported ?? false ? "checkmark.seal.fill" : "x.circle")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 65, height: 65)
|
||||
.cornerRadius(5)
|
||||
Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized)))
|
||||
.font(.callout)
|
||||
} else {
|
||||
Image(systemName: "person.crop.circle.badge.questionmark")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 65, height: 65)
|
||||
.cornerRadius(5)
|
||||
Text(String("incomplete".localized))
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 75, height: 75)
|
||||
.foregroundStyle(currentDevice?.activelySupported ?? false ? .green : .red)
|
||||
Text( currentDevice?.activelySupported ?? false ? "Supported" : "Unsupported")
|
||||
.foregroundStyle(.gray)
|
||||
.font(.callout)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
VStack(alignment: .center) {
|
||||
HStack {
|
||||
if user.hardwareImage != "UNSET" {
|
||||
Image(user.hardwareImage ?? "UNSET")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(maxHeight: 150)
|
||||
.cornerRadius(5)
|
||||
} else {
|
||||
Image(systemName: "person.crop.circle.badge.questionmark")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 75, height: 75)
|
||||
.cornerRadius(5)
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.onAppear {
|
||||
Api().loadDeviceHardwareData { (hw) in
|
||||
for device in hw {
|
||||
let currentHardware = node.user?.hwModel ?? "UNSET"
|
||||
let deviceString = device.hwModelSlug.replacingOccurrences(of: "_", with: "").uppercased()
|
||||
if deviceString == currentHardware {
|
||||
currentDevice = device
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
CircleText(
|
||||
text: node.user?.shortName ?? "?",
|
||||
color: Color(UIColor(hex: UInt32(node.num))),
|
||||
circleSize: 75
|
||||
)
|
||||
if node.snr != 0 && !node.viaMqtt && node.hopsAway == 0 {
|
||||
Spacer()
|
||||
VStack {
|
||||
let signalStrength = getLoRaSignalStrength(snr: node.snr, rssi: node.rssi, preset: modemPreset)
|
||||
LoRaSignalStrengthIndicator(signalStrength: signalStrength)
|
||||
Text("Signal \(signalStrength.description)").font(.footnote)
|
||||
Text("SNR \(String(format: "%.2f", node.snr))dB")
|
||||
.foregroundColor(getSnrColor(snr: node.snr, preset: modemPreset))
|
||||
.font(.caption)
|
||||
Text("RSSI \(node.rssi)dB")
|
||||
.foregroundColor(getRssiColor(rssi: node.rssi))
|
||||
.font(.caption)
|
||||
}
|
||||
}
|
||||
if node.telemetries?.count ?? 0 > 0 {
|
||||
Spacer()
|
||||
BatteryGauge(node: node)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.listRowSeparator(.hidden)
|
||||
HStack {
|
||||
Label {
|
||||
Text("Model")
|
||||
} icon: {
|
||||
Image(systemName: "flipphone")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
}
|
||||
Spacer()
|
||||
if user.hwModel != "UNSET" {
|
||||
Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized)))
|
||||
} else {
|
||||
Text(String("incomplete".localized))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ struct NodeListFilter: View {
|
|||
@Binding var isOnline: Bool
|
||||
@Binding var isPkiEncrypted: Bool
|
||||
@Binding var isFavorite: Bool
|
||||
@Binding var isIgnored: Bool
|
||||
@Binding var isEnvironment: Bool
|
||||
@Binding var distanceFilter: Bool
|
||||
@Binding var maximumDistance: Double
|
||||
|
|
@ -90,6 +91,18 @@ struct NodeListFilter: View {
|
|||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
.listRowSeparator(.visible)
|
||||
Toggle(isOn: $isIgnored) {
|
||||
|
||||
Label {
|
||||
Text("Ignored")
|
||||
} icon: {
|
||||
|
||||
Image(systemName: "minus.circle.fill")
|
||||
.symbolRenderingMode(.multicolor)
|
||||
}
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
.listRowSeparator(.visible)
|
||||
|
||||
if filterTitle == "Node Filters" {
|
||||
Toggle(isOn: $isEnvironment) {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ struct MeshMap: View {
|
|||
@State private var isOnline = false
|
||||
@State private var isPkiEncrypted = false
|
||||
@State private var isFavorite = false
|
||||
@State private var isIgnored = false
|
||||
@State private var isEnvironment = false
|
||||
@State private var distanceFilter = false
|
||||
@State private var maxDistance: Double = 800000
|
||||
|
|
@ -161,6 +162,7 @@ struct MeshMap: View {
|
|||
isOnline: $isOnline,
|
||||
isPkiEncrypted: $isPkiEncrypted,
|
||||
isFavorite: $isFavorite,
|
||||
isIgnored: $isIgnored,
|
||||
isEnvironment: $isEnvironment,
|
||||
distanceFilter: $distanceFilter,
|
||||
maximumDistance: $maxDistance,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ struct NodeList: View {
|
|||
@State private var isOnline = false
|
||||
@State private var isPkiEncrypted = false
|
||||
@State private var isFavorite = false
|
||||
@State private var isIgnored = false
|
||||
@State private var isEnvironment = false
|
||||
@State private var distanceFilter = false
|
||||
@State private var maxDistance: Double = 800000
|
||||
|
|
@ -40,6 +41,7 @@ struct NodeList: View {
|
|||
|
||||
var boolFilters: [Bool] {[
|
||||
isFavorite,
|
||||
isIgnored,
|
||||
isOnline,
|
||||
isPkiEncrypted,
|
||||
isEnvironment,
|
||||
|
|
@ -53,6 +55,7 @@ struct NodeList: View {
|
|||
|
||||
@FetchRequest(
|
||||
sortDescriptors: [
|
||||
NSSortDescriptor(key: "ignored", ascending: true),
|
||||
NSSortDescriptor(key: "favorite", ascending: false),
|
||||
NSSortDescriptor(key: "lastHeard", ascending: false),
|
||||
NSSortDescriptor(key: "user.longName", ascending: true)
|
||||
|
|
@ -132,6 +135,11 @@ struct NodeList: View {
|
|||
} label: {
|
||||
Label("Exchange Positions", systemImage: "arrow.triangle.2.circlepath")
|
||||
}
|
||||
IgnoreNodeButton(
|
||||
bleManager: bleManager,
|
||||
context: context,
|
||||
node: node
|
||||
)
|
||||
Button(role: .destructive) {
|
||||
deleteNodeId = node.num
|
||||
isPresentingDeleteNodeAlert = true
|
||||
|
|
@ -164,6 +172,7 @@ struct NodeList: View {
|
|||
isOnline: $isOnline,
|
||||
isPkiEncrypted: $isPkiEncrypted,
|
||||
isFavorite: $isFavorite,
|
||||
isIgnored: $isIgnored,
|
||||
isEnvironment: $isEnvironment,
|
||||
distanceFilter: $distanceFilter,
|
||||
maximumDistance: $maxDistance,
|
||||
|
|
@ -392,6 +401,14 @@ struct NodeList: View {
|
|||
let isFavoritePredicate = NSPredicate(format: "favorite == YES")
|
||||
predicates.append(isFavoritePredicate)
|
||||
}
|
||||
/// Ignored
|
||||
if isIgnored {
|
||||
let isIgnoredPredicate = NSPredicate(format: "ignored == YES")
|
||||
predicates.append(isIgnoredPredicate)
|
||||
} else if !isIgnored {
|
||||
let isIgnoredPredicate = NSPredicate(format: "ignored == NO")
|
||||
predicates.append(isIgnoredPredicate)
|
||||
}
|
||||
/// Environment
|
||||
if isEnvironment {
|
||||
let environmentPredicate = NSPredicate(format: "SUBQUERY(telemetries, $tel, $tel.metricsType == 1).@count > 0")
|
||||
|
|
|
|||
|
|
@ -37,20 +37,21 @@ struct TraceRouteLog: View {
|
|||
VStack {
|
||||
List(node.traceRoutes?.reversed() as? [TraceRouteEntity] ?? [], id: \.self, selection: $selectedRoute) { route in
|
||||
Label {
|
||||
if route.response && route.hopsTowards == 0 {
|
||||
Text("\(route.time?.formatted() ?? "unknown".localized) - Direct")
|
||||
.font(.caption)
|
||||
} else if route.response && route.hopsTowards == 1 {
|
||||
Text("\(route.time?.formatted() ?? "unknown".localized) - 1 Hop")
|
||||
let routeTime = route.time?.formatted() ?? "unknown".localized
|
||||
if route.response && route.hopsTowards == route.hopsBack {
|
||||
let hopString = String(localized: "\(route.hopsTowards) Hops")
|
||||
Text("\(routeTime) - \(hopString)")
|
||||
.font(.caption)
|
||||
} else if route.response {
|
||||
Text("\(route.time?.formatted() ?? "unknown".localized) - \(route.hopsTowards) Hops Towards \(route.hopsBack) Hops Back")
|
||||
let hopTowardsString = String(localized: "\(route.hopsTowards) Hops")
|
||||
let hopBackString = String(localized: "\(route.hopsBack) Hops")
|
||||
Text("\(routeTime) - \(hopTowardsString) Towards \(hopBackString) Back")
|
||||
.font(.caption)
|
||||
} else if route.sent {
|
||||
Text("\(route.time?.formatted() ?? "unknown".localized) - No Response")
|
||||
Text("\(routeTime) - No Response")
|
||||
.font(.caption)
|
||||
} else {
|
||||
Text("\(route.time?.formatted() ?? "unknown".localized) - Not Sent")
|
||||
Text("\(routeTime) - Not Sent")
|
||||
.font(.caption)
|
||||
}
|
||||
} icon: {
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ struct BluetoothConfig: View {
|
|||
.onFirstAppear {
|
||||
// Need to request a BluetoothConfig from the remote node before allowing changes
|
||||
if let connectedPeripheral = bleManager.connectedPeripheral, let node {
|
||||
Logger.mesh.info("empty bluetooth config")
|
||||
|
||||
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
|
||||
if let connectedNode {
|
||||
if node.num != connectedNode.num {
|
||||
|
|
@ -111,10 +111,12 @@ struct BluetoothConfig: View {
|
|||
/// 2.5 Administration with session passkey
|
||||
let expiration = node.sessionExpiration ?? Date()
|
||||
if expiration < Date() || node.bluetoothConfig == nil {
|
||||
Logger.mesh.info("⚙️ Empty or expired bluetooth config requesting via PKI admin")
|
||||
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
} else {
|
||||
/// Legacy Administration
|
||||
Logger.mesh.info("☠️ Using insecure legacy admin, empty bluetooth config")
|
||||
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||