Indoor air quality

Add Compact signal strength back to the node list
This commit is contained in:
Garth Vander Houwen 2024-04-10 16:41:15 -07:00
parent 9d4a864ee3
commit fc1cdc4d88
6 changed files with 250 additions and 146 deletions

View file

@ -86,7 +86,6 @@
DD5E5211298EE33B00D21B61 /* remote_hardware.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E51FF298EE33B00D21B61 /* remote_hardware.pb.swift */; };
DD5E5212298EE33B00D21B61 /* apponly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E5200298EE33B00D21B61 /* apponly.pb.swift */; };
DD5E5213298EE33B00D21B61 /* deviceonly.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E5201298EE33B00D21B61 /* deviceonly.pb.swift */; };
DD5E523A298EFA5300D21B61 /* TelemetryWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E5239298EFA5300D21B61 /* TelemetryWeather.swift */; };
DD5E523F298F5A9E00D21B61 /* AirQualityIndexCompact.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5E523E298F5A9E00D21B61 /* AirQualityIndexCompact.swift */; };
DD6193752862F6E600E59241 /* ExternalNotificationConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6193742862F6E600E59241 /* ExternalNotificationConfig.swift */; };
DD6193772862F90F00E59241 /* CannedMessagesConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6193762862F90F00E59241 /* CannedMessagesConfig.swift */; };
@ -124,6 +123,9 @@
DDA0B6B2294CDC55001356EC /* Channels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDA0B6B1294CDC55001356EC /* Channels.swift */; };
DDA1C48E28DB49D3009933EC /* ChannelRoles.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDA1C48D28DB49D3009933EC /* ChannelRoles.swift */; };
DDA6B2E928419CF2003E8C16 /* MeshPackets.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDA6B2E828419CF2003E8C16 /* MeshPackets.swift */; };
DDA9515A2BC6624100CEA535 /* TelemetryWeather.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDA951592BC6624100CEA535 /* TelemetryWeather.swift */; };
DDA9515C2BC6631200CEA535 /* TelemetryEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDA9515B2BC6631200CEA535 /* TelemetryEnums.swift */; };
DDA9515E2BC6F56F00CEA535 /* IndoorAirQuality.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDA9515D2BC6F56F00CEA535 /* IndoorAirQuality.swift */; };
DDAB580D2B0DAA9E00147258 /* Routes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAB580C2B0DAA9E00147258 /* Routes.swift */; };
DDAB580F2B0DAFBC00147258 /* LocationEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAB580E2B0DAFBC00147258 /* LocationEntityExtension.swift */; };
DDAD49ED2AFB39DC00B4425D /* MeshMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAD49EC2AFB39DC00B4425D /* MeshMap.swift */; };
@ -162,7 +164,6 @@
DDC94FCE29CF55310082EA6E /* RtttlConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC94FCD29CF55310082EA6E /* RtttlConfig.swift */; };
DDCDC6CB29481FCC004C1DDA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DDCDC6CD29481FCC004C1DDA /* Localizable.strings */; };
DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */; };
DDD3BBD5292D763200D609B3 /* MeshtasticTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD3BBD4292D763200D609B3 /* MeshtasticTests.swift */; };
DDD43FE32A78C8900083A3E9 /* MqttClientProxyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD43FE22A78C8900083A3E9 /* MqttClientProxyManager.swift */; };
DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD6EEAE29BC024700383354 /* Firmware.swift */; };
DDD94A502845C8F5004A87A0 /* DateTimeText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD94A4F2845C8F5004A87A0 /* DateTimeText.swift */; };
@ -188,7 +189,6 @@
DDDBC87B2BC62E4E001E8DF7 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DDDBC87A2BC62E4E001E8DF7 /* Settings.bundle */; };
DDDC22382BA92344002C44F1 /* MeshMapContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDC22372BA92344002C44F1 /* MeshMapContent.swift */; };
DDDCD5702BB26F5C00BE6B60 /* NodeListFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDCD56F2BB26F5C00BE6B60 /* NodeListFilter.swift */; };
DDDCD5722BB3E46400BE6B60 /* BLEManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C5226EB1DF10058C060 /* BLEManager.swift */; };
DDDE59F529AF163D00490C6C /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41A61C29AE7E8E003C5A37 /* WidgetKit.framework */; };
DDDE59F629AF163D00490C6C /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41A61E29AE7E8F003C5A37 /* SwiftUI.framework */; };
DDDE59F929AF163D00490C6C /* WidgetsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDE59F829AF163D00490C6C /* WidgetsBundle.swift */; };
@ -211,13 +211,6 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
DDC2E16B26CE248F0042C5E4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DDC2E14C26CE248E0042C5E4 /* Project object */;
proxyType = 1;
remoteGlobalIDString = DDC2E15326CE248E0042C5E4;
remoteInfo = MeshtasticClient;
};
DDC2E17626CE248F0042C5E4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DDC2E14C26CE248E0042C5E4 /* Project object */;
@ -343,7 +336,6 @@
DD5E51FF298EE33B00D21B61 /* remote_hardware.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = remote_hardware.pb.swift; sourceTree = "<group>"; };
DD5E5200298EE33B00D21B61 /* apponly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = apponly.pb.swift; sourceTree = "<group>"; };
DD5E5201298EE33B00D21B61 /* deviceonly.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = deviceonly.pb.swift; sourceTree = "<group>"; };
DD5E5239298EFA5300D21B61 /* TelemetryWeather.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryWeather.swift; sourceTree = "<group>"; };
DD5E523E298F5A9E00D21B61 /* AirQualityIndexCompact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirQualityIndexCompact.swift; sourceTree = "<group>"; };
DD6193742862F6E600E59241 /* ExternalNotificationConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalNotificationConfig.swift; sourceTree = "<group>"; };
DD6193762862F90F00E59241 /* CannedMessagesConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CannedMessagesConfig.swift; sourceTree = "<group>"; };
@ -385,6 +377,9 @@
DDA0B6B1294CDC55001356EC /* Channels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channels.swift; sourceTree = "<group>"; };
DDA1C48D28DB49D3009933EC /* ChannelRoles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelRoles.swift; sourceTree = "<group>"; };
DDA6B2E828419CF2003E8C16 /* MeshPackets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshPackets.swift; sourceTree = "<group>"; };
DDA951592BC6624100CEA535 /* TelemetryWeather.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TelemetryWeather.swift; sourceTree = "<group>"; };
DDA9515B2BC6631200CEA535 /* TelemetryEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryEnums.swift; sourceTree = "<group>"; };
DDA9515D2BC6F56F00CEA535 /* IndoorAirQuality.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndoorAirQuality.swift; sourceTree = "<group>"; };
DDAB580B2B0D913500147258 /* MeshtasticDataModelV20.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV20.xcdatamodel; sourceTree = "<group>"; };
DDAB580C2B0DAA9E00147258 /* Routes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Routes.swift; sourceTree = "<group>"; };
DDAB580E2B0DAFBC00147258 /* LocationEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationEntityExtension.swift; sourceTree = "<group>"; };
@ -419,7 +414,6 @@
DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Assets.xcassets; sourceTree = "<group>"; };
DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
DDC2E16526CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DDC2E16A26CE248F0042C5E4 /* MeshtasticTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeshtasticTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
DDC2E17026CE248F0042C5E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DDC2E17526CE248F0042C5E4 /* MeshtasticUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MeshtasticUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
DDC2E17926CE248F0042C5E4 /* MeshtasticUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticUITests.swift; sourceTree = "<group>"; };
@ -505,13 +499,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DDC2E16726CE248F0042C5E4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DDC2E17226CE248F0042C5E4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -724,6 +711,7 @@
DD8ED9C6289CE4A100B3B0AB /* Enums */ = {
isa = PBXGroup;
children = (
DDA951592BC6624100CEA535 /* TelemetryWeather.swift */,
DDE0F7C4295F77B700B8AAB3 /* AppSettingsEnums.swift */,
DDB6ABD828B0A4BA00384BA1 /* BluetoothModes.swift */,
DD1925B628CDA5A400720036 /* CannedMessagesConfigEnums.swift */,
@ -737,8 +725,8 @@
DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */,
DD1925B828CDA93900720036 /* SerialConfigEnums.swift */,
DD994B68295F88B60013760A /* IntervalEnums.swift */,
DD5E5239298EFA5300D21B61 /* TelemetryWeather.swift */,
D93068D42B812B700066FBC8 /* MessageDestination.swift */,
DDA9515B2BC6631200CEA535 /* TelemetryEnums.swift */,
);
path = Enums;
sourceTree = "<group>";
@ -810,7 +798,6 @@
isa = PBXGroup;
children = (
DDC2E15426CE248E0042C5E4 /* Meshtastic.app */,
DDC2E16A26CE248F0042C5E4 /* MeshtasticTests.xctest */,
DDC2E17526CE248F0042C5E4 /* MeshtasticUITests.xctest */,
DDDE59F429AF163D00490C6C /* WidgetsExtension.appex */,
);
@ -930,6 +917,7 @@
DDB75A1D2A0B0CD0006ED576 /* LoRaSignalStrengthIndicator.swift */,
DDB75A202A12B954006ED576 /* LoRaSignalStrength.swift */,
DDB75A222A13CDA9006ED576 /* BatteryLevelCompact.swift */,
DDA9515D2BC6F56F00CEA535 /* IndoorAirQuality.swift */,
);
path = Helpers;
sourceTree = "<group>";
@ -1057,24 +1045,6 @@
productReference = DDC2E15426CE248E0042C5E4 /* Meshtastic.app */;
productType = "com.apple.product-type.application";
};
DDC2E16926CE248F0042C5E4 /* MeshtasticTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = DDC2E18126CE248F0042C5E4 /* Build configuration list for PBXNativeTarget "MeshtasticTests" */;
buildPhases = (
DDC2E16626CE248F0042C5E4 /* Sources */,
DDC2E16726CE248F0042C5E4 /* Frameworks */,
DDC2E16826CE248F0042C5E4 /* Resources */,
);
buildRules = (
);
dependencies = (
DDC2E16C26CE248F0042C5E4 /* PBXTargetDependency */,
);
name = MeshtasticTests;
productName = MeshtasticClientTests;
productReference = DDC2E16A26CE248F0042C5E4 /* MeshtasticTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
DDC2E17426CE248F0042C5E4 /* MeshtasticUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = DDC2E18426CE248F0042C5E4 /* Build configuration list for PBXNativeTarget "MeshtasticUITests" */;
@ -1123,11 +1093,6 @@
CreatedOnToolsVersion = 12.5.1;
LastSwiftMigration = 1340;
};
DDC2E16926CE248F0042C5E4 = {
CreatedOnToolsVersion = 12.5.1;
LastSwiftMigration = 1410;
TestTargetID = DDC2E15326CE248E0042C5E4;
};
DDC2E17426CE248F0042C5E4 = {
CreatedOnToolsVersion = 12.5.1;
TestTargetID = DDC2E15326CE248E0042C5E4;
@ -1163,7 +1128,6 @@
projectRoot = "";
targets = (
DDC2E15326CE248E0042C5E4 /* Meshtastic */,
DDC2E16926CE248F0042C5E4 /* MeshtasticTests */,
DDC2E17426CE248F0042C5E4 /* MeshtasticUITests */,
DDDE59F329AF163D00490C6C /* WidgetsExtension */,
);
@ -1185,13 +1149,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DDC2E16826CE248F0042C5E4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DDC2E17326CE248F0042C5E4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -1238,6 +1195,7 @@
DDFFA7472B3A7F3C004730DB /* Bundle.swift in Sources */,
DD5E520C298EE33B00D21B61 /* portnums.pb.swift in Sources */,
DD457188293C7E63000C49FB /* BLESignalStrengthIndicator.swift in Sources */,
DDA9515C2BC6631200CEA535 /* TelemetryEnums.swift in Sources */,
DDFEB3BB29900C1200EE7472 /* CurrentConditionsCompact.swift in Sources */,
DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */,
DD0E20FD2B87090400F2D100 /* clientonly.pb.swift in Sources */,
@ -1298,6 +1256,7 @@
DDDB444229F8A88700EE2349 /* Double.swift in Sources */,
DD5E520F298EE33B00D21B61 /* cannedmessages.pb.swift in Sources */,
DDF45C342BC1A48E005ED5F2 /* MQTTIcon.swift in Sources */,
DDA9515A2BC6624100CEA535 /* TelemetryWeather.swift in Sources */,
DDB75A232A13CDA9006ED576 /* BatteryLevelCompact.swift in Sources */,
DDB75A162A0594AD006ED576 /* TileOverlay.swift in Sources */,
DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */,
@ -1387,11 +1346,11 @@
DD15E4F52B8BFC8E00654F61 /* PaxCounterLog.swift in Sources */,
DD3CC6C028E7A60700FA9159 /* MessagingEnums.swift in Sources */,
DD97E96628EFD9820056DDA4 /* MeshtasticLogo.swift in Sources */,
DD5E523A298EFA5300D21B61 /* TelemetryWeather.swift in Sources */,
DDAB580D2B0DAA9E00147258 /* Routes.swift in Sources */,
C9697F9D279336B700250207 /* LocalMBTileOverlay.swift in Sources */,
D93068D52B812B700066FBC8 /* MessageDestination.swift in Sources */,
DD58C5F22919AD3C00D5BEFB /* ChannelEntityExtension.swift in Sources */,
DDA9515E2BC6F56F00CEA535 /* IndoorAirQuality.swift in Sources */,
DDDB444E29F8AB0E00EE2349 /* Int.swift in Sources */,
DD0F791B28713C8A00A6FDAD /* AdminMessageList.swift in Sources */,
DD3CC6BC28E366DF00FA9159 /* Meshtastic.xcdatamodeld in Sources */,
@ -1417,15 +1376,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DDC2E16626CE248F0042C5E4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DDD3BBD5292D763200D609B3 /* MeshtasticTests.swift in Sources */,
DDDCD5722BB3E46400BE6B60 /* BLEManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DDC2E17126CE248F0042C5E4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -1448,11 +1398,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
DDC2E16C26CE248F0042C5E4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DDC2E15326CE248E0042C5E4 /* Meshtastic */;
targetProxy = DDC2E16B26CE248F0042C5E4 /* PBXContainerItemProxy */;
};
DDC2E17726CE248F0042C5E4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DDC2E15326CE248E0042C5E4 /* Meshtastic */;
@ -1672,55 +1617,6 @@
};
name = Release;
};
DDC2E18226CE248F0042C5E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = GCH7VS5Y9R;
INFOPLIST_FILE = MeshtasticTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Meshtastic.app/Meshtastic";
};
name = Debug;
};
DDC2E18326CE248F0042C5E4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = GCH7VS5Y9R;
INFOPLIST_FILE = MeshtasticTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Meshtastic.app/Meshtastic";
};
name = Release;
};
DDC2E18526CE248F0042C5E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -1850,15 +1746,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DDC2E18126CE248F0042C5E4 /* Build configuration list for PBXNativeTarget "MeshtasticTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DDC2E18226CE248F0042C5E4 /* Debug */,
DDC2E18326CE248F0042C5E4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DDC2E18426CE248F0042C5E4 /* Build configuration list for PBXNativeTarget "MeshtasticUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View file

@ -0,0 +1,79 @@
//
// TelemetryEnums.swift
// Meshtastic
//
// Created by Garth Vander Houwen on 4/9/24.
//
import Foundation
import SwiftUI
enum Iaq: Int, CaseIterable, Identifiable {
case excellent = 0
case good = 1
case lightlyPolluted = 2
case moderatelyPolluted = 3
case heavilyPolluted = 4
case severelyPolluted = 5
case extremelyPolluted = 6
var id: Int { self.rawValue }
var description: String {
switch self {
case .excellent:
return "Excellent"
case .good:
return "Good"
case .lightlyPolluted:
return "Lightly Polluted"
case .moderatelyPolluted:
return "Lightly Polluted"
case .heavilyPolluted:
return "Heavily Polluted"
case .severelyPolluted:
return "Severely Polluted"
case .extremelyPolluted:
return "Extremely Polluted"
}
}
var color: Color {
switch self {
case .excellent:
return .green
case .good:
return .mint
case .lightlyPolluted:
return .yellow
case .moderatelyPolluted:
return .orange
case .heavilyPolluted:
return .red
case .severelyPolluted:
return .purple
case .extremelyPolluted:
return .brown
}
}
static func getIaq(for value: Int) -> Iaq {
let iaq: Iaq
switch value {
case 0...50:
iaq = .excellent
case 51...100:
iaq = .good
case 101...150:
iaq = .lightlyPolluted
case 151...200:
iaq = .moderatelyPolluted
case 201...250:
iaq = .heavilyPolluted
case 251...350:
iaq = .severelyPolluted
case 351...:
iaq = .extremelyPolluted
default:
fatalError("Invalid int value")
}
return iaq
}
}

View file

@ -0,0 +1,125 @@
//
// IndoorAirQuality.swift
// Meshtastic
//
// Copyright(c) by Garth Vander Houwen on 4/10/24.
//
import Foundation
import SwiftUI
enum IaqDisplayMode: Int, CaseIterable, Identifiable {
case pill = 0
case dot = 1
case text = 2
case gauge = 3
var id: Int { self.rawValue }
}
struct IndoorAirQuality: View {
var iaq: Int = 0
var displayMode: IaqDisplayMode = .pill
let gradient = Gradient(colors: [.green, .mint, .yellow, .orange, .red, .purple, .purple, .brown, .brown, .brown, .brown])
var body: some View {
let iaqEnum = Iaq.getIaq(for: iaq)
switch displayMode {
case .pill:
ZStack (alignment: .leading) {
RoundedRectangle(cornerRadius: 10)
.fill(iaqEnum.color)
.frame(width: 125, height: 30)
Label("IAQ \(iaq)", systemImage: iaq < 100 ? "aqi.low" : ((iaq > 100 && iaq < 201) ? "aqi.medium" : "aqi.high"))
.padding(.leading, 4)
}
case .dot:
VStack {
HStack {
Text("\(iaq)")
Circle()
.fill(iaqEnum.color)
.frame(width: 10, height: 10)
}
}
case .text:
Text(iaqEnum.description)
.font(.caption)
case .gauge:
Gauge(value: Double(iaq), in: 0...500) {
Text("IAQ")
.foregroundColor(iaqEnum.color)
} currentValueLabel: {
Text("\(Int(iaq))")
}
.tint(gradient)
.gaugeStyle(.accessoryCircular)
}
}
}
struct IndoorAirQuality_Previews: PreviewProvider {
static var previews: some View {
VStack {
Text(".pill")
.font(.title)
HStack {
VStack{
IndoorAirQuality(iaq: 6)
IndoorAirQuality(iaq: 51)
IndoorAirQuality(iaq: 101)
}
VStack {
IndoorAirQuality(iaq: 201)
IndoorAirQuality(iaq: 350)
IndoorAirQuality(iaq: 351)
}
}
Text(".dot")
.font(.title)
HStack {
VStack (alignment: .leading) {
IndoorAirQuality(iaq: 6, displayMode: .dot)
IndoorAirQuality(iaq: 51, displayMode: .dot)
IndoorAirQuality(iaq: 101, displayMode: .dot)
}
VStack (alignment: .leading) {
IndoorAirQuality(iaq: 201, displayMode: .dot)
IndoorAirQuality(iaq: 350, displayMode: .dot)
IndoorAirQuality(iaq: 351, displayMode: .dot)
}
}
Text(".text")
.font(.title)
IndoorAirQuality(iaq: 6, displayMode: .text)
IndoorAirQuality(iaq: 51, displayMode: .text)
IndoorAirQuality(iaq: 101, displayMode: .text)
IndoorAirQuality(iaq: 201, displayMode: .text)
IndoorAirQuality(iaq: 350, displayMode: .text)
IndoorAirQuality(iaq: 351, displayMode: .text)
Text(".gauge")
.font(.title)
HStack (alignment: .top) {
VStack{
IndoorAirQuality(iaq: 6, displayMode: .gauge)
IndoorAirQuality(iaq: 51, displayMode: .gauge)
IndoorAirQuality(iaq: 101, displayMode: .gauge)
IndoorAirQuality(iaq: 151, displayMode: .gauge)
}
VStack{
IndoorAirQuality(iaq: 201, displayMode: .gauge)
IndoorAirQuality(iaq: 251, displayMode: .gauge)
IndoorAirQuality(iaq: 301, displayMode: .gauge)
IndoorAirQuality(iaq: 350, displayMode: .gauge)
}
VStack{
IndoorAirQuality(iaq: 351, displayMode: .gauge)
IndoorAirQuality(iaq: 401, displayMode: .gauge)
IndoorAirQuality(iaq: 500, displayMode: .gauge)
}
}
}.previewLayout(.fixed(width: 300, height: 800))
}
}

View file

@ -35,14 +35,13 @@ struct LoRaSignalStrengthMeter: View {
.font(.callout)
.frame(width: 30)
Text("Signal \(signalStrength.description)")
.font(.callout)
.font(UIDevice.current.userInterfaceIdiom == .phone ? .callout : .caption)
.foregroundColor(.gray)
.fixedSize()
}
.gaugeStyle(.accessoryLinear)
.tint(gradient)
.font(.caption)
}
}
}
@ -54,20 +53,22 @@ struct LoRaSignalStrengthMeter_Previews: PreviewProvider {
VStack {
HStack {
// Good
LoRaSignalStrengthMeter(snr: -1, rssi: -114, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -5, rssi: -100, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -10, rssi: -100, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -17, rssi: -100, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -17, rssi: -114, preset: ModemPresets.longFast, compact: false)
}
HStack {
// Fair
LoRaSignalStrengthMeter(snr: -9.5, rssi: -119, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -15.0, rssi: -115, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -17.5, rssi: -100, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -22.5, rssi: -100, preset: ModemPresets.longFast, compact: false)
}
HStack {
// Bad
LoRaSignalStrengthMeter(snr: -11.25, rssi: -120, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -12.75, rssi: -139, preset: ModemPresets.longFast, compact: false)
}
HStack {
LoRaSignalStrengthMeter(snr: -20.25, rssi: -128, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -30, rssi: -120, preset: ModemPresets.longFast, compact: false)
}
@ -75,12 +76,14 @@ struct LoRaSignalStrengthMeter_Previews: PreviewProvider {
LoRaSignalStrengthMeter(snr: -15, rssi: -124, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -17.25, rssi: -126, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -19.5, rssi: -128, preset: ModemPresets.longFast, compact: false)
LoRaSignalStrengthMeter(snr: -20, rssi: -150, preset: ModemPresets.longFast, compact: false)
}
HStack {
// None
LoRaSignalStrengthMeter(snr: -26.0, rssi: -129, preset: ModemPresets.longFast, compact: false)
}
}
.padding(.top)
}
VStack {

View file

@ -87,7 +87,10 @@ struct EnvironmentMetricsLog: View {
Text("\(String(format: "%.1f", em.barometricPressure)) hPa")
}
TableColumn("Indoor Air Quality") { em in
Text("\(String(format: "%.1f", em.gasResistance)) ohms")
HStack {
Text("IAQ")
IndoorAirQuality(iaq: Int(em.iaq), displayMode: IaqDisplayMode.dot )
}
}
TableColumn("current") { em in
Text("\(String(format: "%.1f", em.current))")
@ -106,7 +109,7 @@ struct EnvironmentMetricsLog: View {
GridItem(.flexible(minimum: 30, maximum: 50), spacing: 0.1),
GridItem(.flexible(minimum: 30, maximum: 60), spacing: 0.1),
GridItem(.flexible(minimum: 30, maximum: 60), spacing: 0.1),
GridItem(.flexible(minimum: 30, maximum: 50), spacing: 0.1),
GridItem(.flexible(minimum: 30, maximum: 70), spacing: 0.1),
GridItem(spacing: 0)
]
LazyVGrid(columns: columns, alignment: .leading, spacing: 1, pinnedViews: [.sectionHeaders]) {
@ -138,7 +141,7 @@ struct EnvironmentMetricsLog: View {
.font(.caption)
Text("\(String(format: "%.1f", em.barometricPressure))")
.font(.caption)
Text("\(String(format: "%.1f", em.gasResistance))")
IndoorAirQuality(iaq: Int(em.iaq), displayMode: .dot)
.font(.caption)
Text(em.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
.font(.caption)

View file

@ -13,6 +13,7 @@ struct NodeListItem: View {
@ObservedObject var node: NodeInfoEntity
var connected: Bool
var connectedNode: Int64
var modemPreset: ModemPresets = ModemPresets(rawValue: UserDefaults.modemPreset) ?? ModemPresets.longFast
var body: some View {
@ -141,19 +142,6 @@ struct NodeListItem: View {
.font(UIDevice.current.userInterfaceIdiom == .phone ? .callout : .caption)
}
}
if node.hopsAway > 0 {
HStack {
Image(systemName: "hare")
.font(.callout)
.symbolRenderingMode(.hierarchical)
Text("Hops Away:")
.foregroundColor(.gray)
.font(UIDevice.current.userInterfaceIdiom == .phone ? .callout : .caption)
Image(systemName: "\(node.hopsAway).square")
.font(.title2)
.symbolRenderingMode(.hierarchical)
}
}
if node.hasPositions || node.hasEnvironmentMetrics || node.hasDetectionSensorMetrics || node.hasTraceRoutes {
HStack {
Image(systemName: "scroll")
@ -197,6 +185,25 @@ struct NodeListItem: View {
}
}
}
if node.hopsAway > 0 {
HStack {
Image(systemName: "hare")
.font(.callout)
.symbolRenderingMode(.hierarchical)
Text("Hops Away:")
.foregroundColor(.gray)
.font(UIDevice.current.userInterfaceIdiom == .phone ? .callout : .caption)
Image(systemName: "\(node.hopsAway).square")
.font(.title2)
.symbolRenderingMode(.hierarchical)
}
} else {
if node.snr != 0 && !node.viaMqtt {
VStack(alignment: .center) {
LoRaSignalStrengthMeter(snr: node.snr, rssi: node.rssi, preset: modemPreset, compact: true)
}
}
}
}
.frame(maxWidth: .infinity, alignment: .leading)
}