mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 23:34:24 +01:00
new: more battery data & fix: auto reload
This commit is contained in:
@@ -220,7 +220,7 @@ const _statusCmds = [
|
||||
'cat /sys/class/thermal/thermal_zone*/temp',
|
||||
'hostname',
|
||||
'cat /proc/diskstats',
|
||||
'cat /sys/class/power_supply/*/capacity',
|
||||
'cat /sys/class/power_supply/*/uevent',
|
||||
'nvidia-smi -q -x',
|
||||
];
|
||||
|
||||
|
||||
93
lib/data/model/server/battery.dart
Normal file
93
lib/data/model/server/battery.dart
Normal file
@@ -0,0 +1,93 @@
|
||||
import 'package:toolbox/data/res/logger.dart';
|
||||
|
||||
/// raw dat from server:
|
||||
/// ```text
|
||||
/// POWER_SUPPLY_NAME=hidpp_battery_0
|
||||
/// POWER_SUPPLY_TYPE=Battery
|
||||
/// POWER_SUPPLY_ONLINE=1
|
||||
/// POWER_SUPPLY_STATUS=Discharging
|
||||
/// POWER_SUPPLY_SCOPE=Device
|
||||
/// POWER_SUPPLY_MODEL_NAME=MX Anywhere 3
|
||||
/// POWER_SUPPLY_MANUFACTURER=Logitech
|
||||
/// POWER_SUPPLY_SERIAL_NUMBER=0f-fc-43-f8
|
||||
/// POWER_SUPPLY_CAPACITY=35
|
||||
/// ```
|
||||
class Battery {
|
||||
final int? percent;
|
||||
final BatteryStatus status;
|
||||
final String? name;
|
||||
final int? cycle;
|
||||
final int? powerNow;
|
||||
|
||||
const Battery({
|
||||
required this.status,
|
||||
this.percent,
|
||||
this.name,
|
||||
this.cycle,
|
||||
this.powerNow,
|
||||
});
|
||||
|
||||
factory Battery.fromRaw(String raw) {
|
||||
final lines = raw.split('\n');
|
||||
final map = <String, String>{};
|
||||
for (final line in lines) {
|
||||
final parts = line.split('=');
|
||||
if (parts.length != 2) continue;
|
||||
map[parts[0]] = parts[1];
|
||||
}
|
||||
|
||||
final capacity = map['POWER_SUPPLY_CAPACITY']; // 30%
|
||||
final cycle = map['POWER_SUPPLY_CYCLE_COUNT']; // 30
|
||||
final powerNow = map['POWER_SUPPLY_POWER_NOW']; // 30W
|
||||
|
||||
return Battery(
|
||||
percent: capacity == null ? null : int.tryParse(capacity),
|
||||
status: BatteryStatus.parse(map['POWER_SUPPLY_STATUS']),
|
||||
name: map['POWER_SUPPLY_MODEL_NAME'],
|
||||
cycle: cycle == null ? null : int.tryParse(cycle),
|
||||
powerNow: powerNow == null ? null : int.tryParse(powerNow),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum BatteryStatus {
|
||||
charging,
|
||||
discharging,
|
||||
full,
|
||||
unknown,
|
||||
;
|
||||
|
||||
static BatteryStatus parse(String? status) {
|
||||
switch (status) {
|
||||
case 'Charging':
|
||||
return BatteryStatus.charging;
|
||||
case 'Discharging':
|
||||
return BatteryStatus.discharging;
|
||||
case 'Full':
|
||||
return BatteryStatus.full;
|
||||
default:
|
||||
return BatteryStatus.unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract final class Batteries {
|
||||
static List<Battery> parse(String raw) {
|
||||
final lines = raw.split('\n');
|
||||
final batteries = <Battery>[];
|
||||
final oneBatLines = <String>[];
|
||||
for (final line in lines) {
|
||||
if (line.isEmpty) {
|
||||
try {
|
||||
batteries.add(Battery.fromRaw(oneBatLines.join('\n')));
|
||||
} catch (e, s) {
|
||||
Loggers.parse.warning(e, s);
|
||||
}
|
||||
oneBatLines.clear();
|
||||
} else {
|
||||
oneBatLines.add(line);
|
||||
}
|
||||
}
|
||||
return batteries;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:toolbox/data/model/app/shell_func.dart';
|
||||
import 'package:toolbox/data/model/server/battery.dart';
|
||||
import 'package:toolbox/data/model/server/conn.dart';
|
||||
import 'package:toolbox/data/model/server/cpu.dart';
|
||||
import 'package:toolbox/data/model/server/disk.dart';
|
||||
@@ -38,10 +39,6 @@ class Server implements TagPickable {
|
||||
bool get canViewDetails => state == ServerState.finished;
|
||||
|
||||
String get id => spi.id;
|
||||
|
||||
bool get isBusy => status._isBusy;
|
||||
|
||||
set isBusy(bool value) => status._isBusy = value;
|
||||
}
|
||||
|
||||
class ServerStatus {
|
||||
@@ -56,11 +53,9 @@ class ServerStatus {
|
||||
String? err;
|
||||
DiskIO diskIO;
|
||||
List<NvidiaSmiItem>? nvidia;
|
||||
final List<Battery> batteries = [];
|
||||
final Map<StatusCmdType, String> more = {};
|
||||
|
||||
/// Whether is connectting, parsing and etc.
|
||||
bool _isBusy = false;
|
||||
|
||||
ServerStatus({
|
||||
required this.cpu,
|
||||
required this.mem,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:toolbox/data/model/server/battery.dart';
|
||||
import 'package:toolbox/data/model/server/nvdia.dart';
|
||||
import 'package:toolbox/data/model/server/server.dart';
|
||||
import 'package:toolbox/data/model/server/system.dart';
|
||||
@@ -129,8 +130,10 @@ Future<ServerStatus> _getLinuxStatus(ServerStatusUpdateReq req) async {
|
||||
|
||||
try {
|
||||
final battery = StatusCmdType.battery.find(segments);
|
||||
if (battery.isNotEmpty && !battery.contains('/sys/class/power_supply')) {
|
||||
req.ss.more[StatusCmdType.battery] = battery;
|
||||
final batteries = Batteries.parse(battery);
|
||||
req.ss.batteries.clear();
|
||||
if (batteries.isNotEmpty) {
|
||||
req.ss.batteries.addAll(batteries);
|
||||
}
|
||||
} catch (e, s) {
|
||||
Loggers.parse.warning(e, s);
|
||||
|
||||
@@ -155,16 +155,6 @@ class ServerProvider extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void setNotBusy([String? id]) {
|
||||
if (id == null) {
|
||||
for (final s in _servers.values) {
|
||||
s.isBusy = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
_servers[id]?.isBusy = false;
|
||||
}
|
||||
|
||||
bool get isAutoRefreshOn => _timer != null;
|
||||
|
||||
void setDisconnected() {
|
||||
@@ -248,15 +238,6 @@ class ServerProvider extends ChangeNotifier {
|
||||
|
||||
void _setServerState(Server s, ServerState ss) {
|
||||
s.state = ss;
|
||||
|
||||
/// Only set [Sever.isBusy] to false when err occurs or finished.
|
||||
switch (ss) {
|
||||
case ServerState.failed || ServerState.finished:
|
||||
s.isBusy = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -275,11 +256,6 @@ class ServerProvider extends ChangeNotifier {
|
||||
|
||||
s.status.err = null;
|
||||
|
||||
/// If busy, it may be because of network reasons that the last request
|
||||
/// has not been completed, and the request should not be made again at this time.
|
||||
if (s.isBusy) return;
|
||||
s.isBusy = true;
|
||||
|
||||
if (s.needGenClient || (s.client?.isClosed ?? true)) {
|
||||
_setServerState(s, ServerState.connecting);
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 683;
|
||||
static const int build = 685;
|
||||
static const String engine = "3.16.4";
|
||||
static const String buildAt = "2023-12-19 15:25:07";
|
||||
static const int modifications = 1;
|
||||
static const String buildAt = "2023-12-20 14:09:17";
|
||||
static const int modifications = 4;
|
||||
static const int script = 32;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,15 @@ import 'package:toolbox/data/model/ssh/virtual_key.dart';
|
||||
abstract final class Defaults {
|
||||
// default server details page cards order
|
||||
static const detailCardOrder = [
|
||||
'uptime',
|
||||
'sys',
|
||||
'cpu',
|
||||
'mem',
|
||||
'swap',
|
||||
'gpu',
|
||||
'disk',
|
||||
'net',
|
||||
'temp'
|
||||
'temp',
|
||||
'battery'
|
||||
];
|
||||
|
||||
static const diskIgnorePath = [
|
||||
|
||||
@@ -3,28 +3,27 @@ import 'package:flutter/material.dart';
|
||||
abstract final class UIs {
|
||||
/// Font style
|
||||
|
||||
static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);
|
||||
static const textSize11 = TextStyle(fontSize: 11);
|
||||
static const textSize11Bold = TextStyle(
|
||||
static const text11 = TextStyle(fontSize: 11);
|
||||
static const text11Bold = TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
);
|
||||
static const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11);
|
||||
static const text11Grey = TextStyle(color: Colors.grey, fontSize: 11);
|
||||
static const text12 = TextStyle(fontSize: 12);
|
||||
static const text12Bold = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
static const text12Grey = TextStyle(color: Colors.grey, fontSize: 12);
|
||||
static const textSize13 = TextStyle(fontSize: 13);
|
||||
static const textSize13Bold = TextStyle(
|
||||
static const text13 = TextStyle(fontSize: 13);
|
||||
static const text13Bold = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
static const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13);
|
||||
static const textSize15 = TextStyle(fontSize: 15);
|
||||
static const textSize18 = TextStyle(fontSize: 18);
|
||||
static const textSize27 = TextStyle(fontSize: 27);
|
||||
static const text13Grey = TextStyle(color: Colors.grey, fontSize: 13);
|
||||
static const text15 = TextStyle(fontSize: 15);
|
||||
static const text18 = TextStyle(fontSize: 18);
|
||||
static const text27 = TextStyle(fontSize: 27);
|
||||
static const textGrey = TextStyle(color: Colors.grey);
|
||||
static const textRed = TextStyle(color: Colors.red);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user