mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
new: sensors view (#285)
This commit is contained in:
@@ -1294,6 +1294,12 @@ abstract class S {
|
||||
/// **'s'**
|
||||
String get second;
|
||||
|
||||
/// No description provided for @sensors.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Sensor'**
|
||||
String get sensors;
|
||||
|
||||
/// No description provided for @sequence.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -627,6 +627,9 @@ class SDe extends S {
|
||||
@override
|
||||
String get second => 's';
|
||||
|
||||
@override
|
||||
String get sensors => 'Sensor';
|
||||
|
||||
@override
|
||||
String get sequence => 'Sequenz';
|
||||
|
||||
|
||||
@@ -627,6 +627,9 @@ class SEn extends S {
|
||||
@override
|
||||
String get second => 's';
|
||||
|
||||
@override
|
||||
String get sensors => 'Sensor';
|
||||
|
||||
@override
|
||||
String get sequence => 'Sequence';
|
||||
|
||||
|
||||
@@ -627,6 +627,9 @@ class SFr extends S {
|
||||
@override
|
||||
String get second => 's';
|
||||
|
||||
@override
|
||||
String get sensors => 'Capteur';
|
||||
|
||||
@override
|
||||
String get sequence => 'Séquence';
|
||||
|
||||
|
||||
@@ -627,6 +627,9 @@ class SId extends S {
|
||||
@override
|
||||
String get second => 'S';
|
||||
|
||||
@override
|
||||
String get sensors => 'Sensor';
|
||||
|
||||
@override
|
||||
String get sequence => 'Urutan';
|
||||
|
||||
|
||||
@@ -627,6 +627,9 @@ class SZh extends S {
|
||||
@override
|
||||
String get second => '秒';
|
||||
|
||||
@override
|
||||
String get sensors => '传感器';
|
||||
|
||||
@override
|
||||
String get sequence => '顺序';
|
||||
|
||||
@@ -1505,6 +1508,9 @@ class SZhTw extends SZh {
|
||||
@override
|
||||
String get second => '秒';
|
||||
|
||||
@override
|
||||
String get sensors => '传感器';
|
||||
|
||||
@override
|
||||
String get sequence => '順序';
|
||||
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
@@ -596,7 +596,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -720,7 +720,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
@@ -730,7 +730,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -748,7 +748,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
@@ -758,7 +758,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -779,7 +779,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -792,7 +792,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||
@@ -818,7 +818,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -831,7 +831,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -854,7 +854,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -867,7 +867,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -890,7 +890,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -902,7 +902,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||
@@ -931,7 +931,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -943,7 +943,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||
PRODUCT_NAME = ServerBox;
|
||||
@@ -969,7 +969,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -981,7 +981,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||
PRODUCT_NAME = ServerBox;
|
||||
|
||||
@@ -258,5 +258,11 @@ class PropertyListenable<T> extends ValueListenable<T> {
|
||||
}
|
||||
|
||||
@override
|
||||
T get value => box.get(key, defaultValue: defaultValue);
|
||||
T get value {
|
||||
final val = box.get(key, defaultValue: defaultValue);
|
||||
if (val == null || val is! T) {
|
||||
return defaultValue!;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,6 +200,7 @@ enum StatusCmdType {
|
||||
diskio,
|
||||
battery,
|
||||
nvidia,
|
||||
sensors,
|
||||
;
|
||||
}
|
||||
|
||||
@@ -220,6 +221,7 @@ const _statusCmds = [
|
||||
'cat /proc/diskstats',
|
||||
'for f in /sys/class/power_supply/*/uevent; do cat "\$f"; echo; done',
|
||||
'nvidia-smi -q -x',
|
||||
'sensors -j',
|
||||
];
|
||||
|
||||
enum BSDStatusCmdType {
|
||||
|
||||
175
lib/data/model/server/sensors.dart
Normal file
175
lib/data/model/server/sensors.dart
Normal file
@@ -0,0 +1,175 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:toolbox/core/extension/listx.dart';
|
||||
import 'package:toolbox/data/res/logger.dart';
|
||||
|
||||
final class SensorAdaptor {
|
||||
final String raw;
|
||||
|
||||
const SensorAdaptor(this.raw);
|
||||
|
||||
static const acpiRaw = 'ACPI interface';
|
||||
static const pciRaw = 'PCI adapter';
|
||||
static const virtualRaw = 'Virtual device';
|
||||
static const isaRaw = 'ISA adapter';
|
||||
static const acpi = SensorAdaptor(acpiRaw);
|
||||
static const pci = SensorAdaptor(pciRaw);
|
||||
static const virtual = SensorAdaptor(virtualRaw);
|
||||
static const isa = SensorAdaptor(isaRaw);
|
||||
|
||||
static SensorAdaptor parse(String raw) => switch (raw) {
|
||||
acpiRaw => acpi,
|
||||
pciRaw => pci,
|
||||
virtualRaw => virtual,
|
||||
isaRaw => isa,
|
||||
_ => SensorAdaptor(raw),
|
||||
};
|
||||
}
|
||||
|
||||
final class SensorTemp {
|
||||
final double? current;
|
||||
final double? max;
|
||||
final double? min;
|
||||
|
||||
const SensorTemp({this.current, this.max, this.min});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SensorTemp{current: $current, max: $max, min: $min}';
|
||||
}
|
||||
|
||||
@override
|
||||
operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is SensorTemp &&
|
||||
other.current == current &&
|
||||
other.max == max &&
|
||||
other.min == min;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => current.hashCode ^ max.hashCode ^ min.hashCode;
|
||||
}
|
||||
|
||||
final class SensorItem {
|
||||
final String device;
|
||||
final SensorAdaptor adapter;
|
||||
final Map<String, SensorTemp> props;
|
||||
|
||||
const SensorItem({
|
||||
required this.device,
|
||||
required this.adapter,
|
||||
required this.props,
|
||||
});
|
||||
|
||||
static List<SensorItem> parse(String raw) {
|
||||
final rmErrRaw = raw.split('\n')
|
||||
..removeWhere((element) => element.contains('ERROR:'));
|
||||
final map = json.decode(rmErrRaw.join('\n')) as Map<String, dynamic>;
|
||||
final items = <SensorItem>[];
|
||||
for (final key in map.keys) {
|
||||
try {
|
||||
final adapter = SensorAdaptor.parse(map[key]['Adapter'] as String);
|
||||
final props = <String, SensorTemp>{};
|
||||
for (final subKey in map[key].keys) {
|
||||
if (subKey == 'Adapter') {
|
||||
continue;
|
||||
}
|
||||
final subMap = map[key][subKey] as Map<String, dynamic>;
|
||||
final currentKey =
|
||||
subMap.keys.toList().firstWhereOrNull((e) => e.endsWith('input'));
|
||||
final current = subMap[currentKey] as double?;
|
||||
final maxKey = subMap.keys
|
||||
.toList()
|
||||
.firstWhereOrNull((e) => e.endsWith('max') || e.endsWith('crit'));
|
||||
final max = subMap[maxKey] as double?;
|
||||
final minKey =
|
||||
subMap.keys.toList().firstWhereOrNull((e) => e.endsWith('min'));
|
||||
final min = subMap[minKey] as double?;
|
||||
if (current == null && max == null && min == null) {
|
||||
continue;
|
||||
}
|
||||
props[subKey] = SensorTemp(current: current, max: max, min: min);
|
||||
}
|
||||
items.add(SensorItem(device: key, adapter: adapter, props: props));
|
||||
} catch (e, s) {
|
||||
Loggers.parse.warning(e, s);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
static const sensorsRaw = '''
|
||||
{
|
||||
"coretemp-isa-0000":{
|
||||
"Adapter": "ISA adapter",
|
||||
"Package id 0":{
|
||||
"temp1_input": 51.000,
|
||||
"temp1_max": 105.000,
|
||||
"temp1_crit": 105.000,
|
||||
"temp1_crit_alarm": 0.000
|
||||
},
|
||||
"Core 0":{
|
||||
"temp2_input": 40.000,
|
||||
"temp2_max": 105.000,
|
||||
"temp2_crit": 105.000,
|
||||
"temp2_crit_alarm": 0.000
|
||||
},
|
||||
"Core 1":{
|
||||
"temp3_input": 40.000,
|
||||
"temp3_max": 105.000,
|
||||
"temp3_crit": 105.000,
|
||||
"temp3_crit_alarm": 0.000
|
||||
},
|
||||
"Core 2":{
|
||||
"temp4_input": 40.000,
|
||||
"temp4_max": 105.000,
|
||||
"temp4_crit": 105.000,
|
||||
"temp4_crit_alarm": 0.000
|
||||
},
|
||||
"Core 3":{
|
||||
"temp5_input": 40.000,
|
||||
"temp5_max": 105.000,
|
||||
"temp5_crit": 105.000,
|
||||
"temp5_crit_alarm": 0.000
|
||||
}
|
||||
},
|
||||
"acpitz-acpi-0":{
|
||||
"Adapter": "ACPI interface",
|
||||
"temp1":{
|
||||
"temp1_input": 27.800,
|
||||
"temp1_crit": 119.000
|
||||
}
|
||||
},
|
||||
"iwlwifi_1-virtual-0":{
|
||||
"Adapter": "Virtual device",
|
||||
"temp1":{
|
||||
ERROR: Can't get value of subfeature temp1_input: Can't read
|
||||
|
||||
}
|
||||
},
|
||||
"nvme-pci-0400":{
|
||||
"Adapter": "PCI adapter",
|
||||
"Composite":{
|
||||
"temp1_input": 35.850,
|
||||
"temp1_max": 83.850,
|
||||
"temp1_min": -273.150,
|
||||
"temp1_crit": 84.850,
|
||||
"temp1_alarm": 0.000
|
||||
},
|
||||
"Sensor 1":{
|
||||
"temp2_input": 35.850,
|
||||
"temp2_max": 65261.850,
|
||||
"temp2_min": -273.150
|
||||
},
|
||||
"Sensor 2":{
|
||||
"temp3_input": 37.850,
|
||||
"temp3_max": 65261.850,
|
||||
"temp3_min": -273.150
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import 'package:toolbox/data/model/server/disk.dart';
|
||||
import 'package:toolbox/data/model/server/memory.dart';
|
||||
import 'package:toolbox/data/model/server/net_speed.dart';
|
||||
import 'package:toolbox/data/model/server/nvdia.dart';
|
||||
import 'package:toolbox/data/model/server/sensors.dart';
|
||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||
import 'package:toolbox/data/model/server/system.dart';
|
||||
import 'package:toolbox/data/model/server/temp.dart';
|
||||
@@ -55,6 +56,7 @@ class ServerStatus {
|
||||
List<NvidiaSmiItem>? nvidia;
|
||||
final List<Battery> batteries = [];
|
||||
final Map<StatusCmdType, String> more = {};
|
||||
final List<SensorItem> sensors = [];
|
||||
|
||||
ServerStatus({
|
||||
required this.cpu,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:toolbox/data/model/server/battery.dart';
|
||||
import 'package:toolbox/data/model/server/nvdia.dart';
|
||||
import 'package:toolbox/data/model/server/sensors.dart';
|
||||
import 'package:toolbox/data/model/server/server.dart';
|
||||
import 'package:toolbox/data/model/server/system.dart';
|
||||
import 'package:toolbox/data/res/logger.dart';
|
||||
@@ -143,6 +144,16 @@ Future<ServerStatus> _getLinuxStatus(ServerStatusUpdateReq req) async {
|
||||
Loggers.parse.warning(e, s);
|
||||
}
|
||||
|
||||
try {
|
||||
final sensors = SensorItem.parse(StatusCmdType.sensors.find(segments));
|
||||
if (sensors.isNotEmpty) {
|
||||
req.ss.sensors.clear();
|
||||
req.ss.sensors.addAll(sensors);
|
||||
}
|
||||
} catch (e, s) {
|
||||
Loggers.parse.warning(e, s);
|
||||
}
|
||||
|
||||
return req.ss;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 773;
|
||||
static const String engine = "3.19.1";
|
||||
static const String buildAt = "2024-02-22 11:55:07";
|
||||
static const int modifications = 8;
|
||||
static const int build = 775;
|
||||
static const String engine = "3.19.0";
|
||||
static const String buildAt = "2024-02-23 09:28:28";
|
||||
static const int modifications = 2;
|
||||
static const int script = 38;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ abstract final class Defaults {
|
||||
'gpu',
|
||||
'disk',
|
||||
'net',
|
||||
'sensor',
|
||||
'temp',
|
||||
'battery'
|
||||
];
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
"save": "Speichern",
|
||||
"saved": "Gerettet",
|
||||
"second": "s",
|
||||
"sensors": "Sensor",
|
||||
"sequence": "Sequenz",
|
||||
"server": "Server",
|
||||
"serverDetailOrder": "Reihenfolge der Widgets auf der Detailseite",
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
"save": "Save",
|
||||
"saved": "Saved",
|
||||
"second": "s",
|
||||
"sensors": "Sensor",
|
||||
"sequence": "Sequence",
|
||||
"server": "Server",
|
||||
"serverDetailOrder": "Detail page widget order",
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
"save": "Enregistrer",
|
||||
"saved": "Enregistré",
|
||||
"second": "s",
|
||||
"sensors": "Capteur",
|
||||
"sequence": "Séquence",
|
||||
"server": "Serveur",
|
||||
"serverDetailOrder": "Ordre des widgets de la page de détails",
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
"save": "Menyimpan",
|
||||
"saved": "Diselamatkan",
|
||||
"second": "S",
|
||||
"sensors": "Sensor",
|
||||
"sequence": "Urutan",
|
||||
"server": "Server",
|
||||
"serverDetailOrder": "Detail pesanan widget halaman",
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
"save": "保存",
|
||||
"saved": "已保存",
|
||||
"second": "秒",
|
||||
"sensors": "传感器",
|
||||
"sequence": "顺序",
|
||||
"server": "服务器",
|
||||
"serverDetailOrder": "详情页部件顺序",
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
"save": "保存",
|
||||
"saved": "已保存",
|
||||
"second": "秒",
|
||||
"sensors": "传感器",
|
||||
"sequence": "順序",
|
||||
"server": "服務器",
|
||||
"serverDetailOrder": "詳情頁部件順序",
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:toolbox/data/model/server/cpu.dart';
|
||||
import 'package:toolbox/data/model/server/disk.dart';
|
||||
import 'package:toolbox/data/model/server/net_speed.dart';
|
||||
import 'package:toolbox/data/model/server/nvdia.dart';
|
||||
import 'package:toolbox/data/model/server/sensors.dart';
|
||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||
import 'package:toolbox/data/model/server/system.dart';
|
||||
import 'package:toolbox/data/res/store.dart';
|
||||
@@ -47,6 +48,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
_buildGpuView,
|
||||
_buildDiskView,
|
||||
_buildNetView,
|
||||
_buildSensors,
|
||||
_buildTemperature,
|
||||
_buildBatteries,
|
||||
],
|
||||
@@ -316,7 +318,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
}
|
||||
|
||||
Widget _buildGpuView(ServerStatus ss) {
|
||||
if (ss.nvidia == null) return UIs.placeholder;
|
||||
if (ss.nvidia == null || ss.nvidia?.isEmpty == true) return UIs.placeholder;
|
||||
final children = ss.nvidia?.map((e) => _buildGpuItem(e)).toList() ?? [];
|
||||
return CardX(
|
||||
child: ExpandTile(
|
||||
@@ -331,10 +333,6 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
Widget _buildGpuItem(NvidiaSmiItem item) {
|
||||
final mem = item.memory;
|
||||
final processes = mem.processes;
|
||||
final children = <Widget>[];
|
||||
if (processes.isNotEmpty) {
|
||||
children.addAll(processes.map((e) => _buildGpuProcessItem(e)));
|
||||
}
|
||||
return ListTile(
|
||||
title: Text(item.name, style: UIs.text13),
|
||||
leading: Text(
|
||||
@@ -664,6 +662,51 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSensors(ServerStatus ss) {
|
||||
if (ss.sensors.isEmpty) return UIs.placeholder;
|
||||
return CardX(
|
||||
child: ExpandTile(
|
||||
title: Text(l10n.sensors),
|
||||
leading: const Icon(Icons.thermostat, size: 17),
|
||||
childrenPadding: const EdgeInsets.only(bottom: 7),
|
||||
initiallyExpanded: _getInitExpand(ss.sensors.length, 3),
|
||||
children: ss.sensors.map(_buildSensorItem).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSensorItem(SensorItem si) {
|
||||
if (si.props.isEmpty) return UIs.placeholder;
|
||||
return ListTile(
|
||||
title: Text(si.device, style: UIs.text15),
|
||||
subtitle: Column(
|
||||
children: si.props.keys
|
||||
.map((e) => _buildSensorDetailItem(e, si.props[e]))
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSensorDetailItem(String key, SensorTemp? st) {
|
||||
if (st == null) return UIs.placeholder;
|
||||
final text = () {
|
||||
final current = st.current?.toStringAsFixed(1);
|
||||
final max = st.max?.toStringAsFixed(1);
|
||||
final min = st.min?.toStringAsFixed(1);
|
||||
final currentText = current == null ? '' : '$current°C';
|
||||
final maxText = max == null ? '' : ' | ${l10n.max}:$max';
|
||||
final minText = min == null ? '' : ' | ${l10n.min}:$min';
|
||||
return '$currentText$maxText$minText';
|
||||
}();
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(key, style: UIs.text13),
|
||||
Text(text, style: UIs.text13Grey),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAnimatedText(Key key, String text, TextStyle style) {
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 277),
|
||||
|
||||
@@ -439,7 +439,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
||||
@@ -449,7 +449,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "Server Box";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -574,7 +574,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
||||
@@ -584,7 +584,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "Server Box";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -604,7 +604,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 771;
|
||||
CURRENT_PROJECT_VERSION = 775;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -615,7 +615,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 1.0.771;
|
||||
MARKETING_VERSION = 1.0.775;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "Server Box";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
||||
44
test/sensors_test.dart
Normal file
44
test/sensors_test.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:toolbox/data/model/server/sensors.dart';
|
||||
|
||||
void main() {
|
||||
test('parse sensors', () {
|
||||
final sensors = SensorItem.parse(SensorItem.sensorsRaw);
|
||||
expect(sensors.map((e) => e.device), [
|
||||
'coretemp-isa-0000',
|
||||
'acpitz-acpi-0',
|
||||
'iwlwifi_1-virtual-0',
|
||||
'nvme-pci-0400',
|
||||
]);
|
||||
expect(sensors.map((e) => e.adapter), [
|
||||
SensorAdaptor.isa,
|
||||
SensorAdaptor.acpi,
|
||||
SensorAdaptor.virtual,
|
||||
SensorAdaptor.pci,
|
||||
]);
|
||||
expect(
|
||||
sensors.map((e) => e.props),
|
||||
[
|
||||
{
|
||||
'Package id 0': const SensorTemp(current: 51, max: 105),
|
||||
'Core 0': const SensorTemp(current: 40, max: 105),
|
||||
'Core 1': const SensorTemp(current: 40, max: 105),
|
||||
'Core 2': const SensorTemp(current: 40, max: 105),
|
||||
'Core 3': const SensorTemp(current: 40, max: 105),
|
||||
},
|
||||
{
|
||||
'temp1': const SensorTemp(current: 27.8, max: 119),
|
||||
},
|
||||
{},
|
||||
{
|
||||
'Composite':
|
||||
const SensorTemp(current: 35.85, max: 83.85, min: -273.15),
|
||||
'Sensor 1':
|
||||
const SensorTemp(current: 35.85, max: 65261.85, min: -273.15),
|
||||
'Sensor 2':
|
||||
const SensorTemp(current: 37.85, max: 65261.85, min: -273.15),
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user