Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
laki_icu_app
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张宏
laki_icu_app
Commits
5dc83081
Commit
5dc83081
authored
Jun 27, 2026
by
akari
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 修复部分蓝牙逻辑
parent
6d1704c6
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
485 additions
and
238 deletions
+485
-238
device_control_bloc.dart
lib/blocs/device_control/device_control_bloc.dart
+301
-89
device_control_state.dart
lib/blocs/device_control/device_control_state.dart
+3
-3
device_control_bo.dart
lib/models/bo/device_control_bo.dart
+61
-34
bluetooth_manager.dart
lib/utils/bluetooth/bluetooth_manager.dart
+4
-1
device_control_index_view.dart
.../monitoring/device_control/device_control_index_view.dart
+3
-9
device_control_care_panel.dart
...ing/device_control/widgets/device_control_care_panel.dart
+8
-19
device_control_common.dart
...itoring/device_control/widgets/device_control_common.dart
+17
-17
device_control_confirm_dialog.dart
...device_control/widgets/device_control_confirm_dialog.dart
+10
-6
device_control_metric_card.dart
...ng/device_control/widgets/device_control_metric_card.dart
+50
-11
device_control_mode_panel.dart
...ing/device_control/widgets/device_control_mode_panel.dart
+3
-9
device_control_time_panel.dart
...ing/device_control/widgets/device_control_time_panel.dart
+1
-5
device_control_wind_panel.dart
...ing/device_control/widgets/device_control_wind_panel.dart
+15
-31
monitoring_index_cubit.dart
lib/views/monitoring/index/cubit/monitoring_index_cubit.dart
+9
-4
No files found.
lib/blocs/device_control/device_control_bloc.dart
View file @
5dc83081
...
...
@@ -15,6 +15,8 @@ import 'package:laki_icu_app/utils/logger.dart';
import
'package:laki_icu_app/utils/mqtt/index.dart'
;
import
'package:laki_icu_app/utils/storage/storage_service.dart'
;
enum
_LightTarget
{
check
,
illumination
,
blue
,
red
}
/// 用途:设备控制Bloc
/// 涉及页面:设备控制页面
/// 说明:提供各个子模块的获取和设置方法,方便MCU单元调用
...
...
@@ -228,24 +230,30 @@ class DeviceControlBloc
sn:
report
.
sn
.
isEmpty
?
state
.
data
.
sn
:
report
.
sn
,
cabinTemp:
state
.
data
.
cabinTemp
.
copyWith
(
currentValue:
_formatTemperature
(
report
.
mainTemperature
),
setValue:
_formatTemperatureOrKeep
(
report
.
temperatureSetting
,
state
.
data
.
cabinTemp
.
setValue
,
),
setValue:
state
.
data
.
cabinTemp
.
isOn
?
_formatTemperatureOrKeep
(
report
.
temperatureSetting
,
state
.
data
.
cabinTemp
.
setValue
,
)
:
_preservedCabinTempSetValue
,
),
cabinHumidity:
state
.
data
.
cabinHumidity
.
copyWith
(
currentValue:
_formatInt
(
report
.
humidity
),
setValue:
_formatIntOrKeep
(
report
.
humiditySetting
,
state
.
data
.
cabinHumidity
.
setValue
,
),
setValue:
state
.
data
.
cabinHumidity
.
isOn
?
_formatIntOrKeep
(
report
.
humiditySetting
,
state
.
data
.
cabinHumidity
.
setValue
,
)
:
_preservedCabinHumiditySetValue
,
),
oxygenConcentration:
state
.
data
.
oxygenConcentration
.
copyWith
(
currentValue:
_formatInt
(
report
.
oxygenConcentration
),
setValue:
_formatIntOrKeep
(
report
.
oxygenSetting
,
state
.
data
.
oxygenConcentration
.
setValue
,
),
setValue:
state
.
data
.
oxygenConcentration
.
isOn
?
_formatIntOrKeep
(
report
.
oxygenSetting
,
state
.
data
.
oxygenConcentration
.
setValue
,
)
:
_preservedOxygenConcentrationSetValue
,
),
co2Concentration:
state
.
data
.
co2Concentration
.
copyWith
(
currentValue:
_formatInt
(
report
.
co2Measurement
),
...
...
@@ -302,8 +310,12 @@ class DeviceControlBloc
final
humiLower
=
humidity
!=
null
&&
humidity
<
config
.
humidityMin
;
final
oxyUpper
=
oxygen
!=
null
&&
oxygen
>
config
.
oxygenMax
;
final
oxyLower
=
oxygen
!=
null
&&
oxygen
<
config
.
oxygenMin
;
final
hasAnyAlarm
=
tempUpper
||
tempLower
||
humiUpper
||
humiLower
||
oxyUpper
||
oxyLower
;
final
hasAnyAlarm
=
tempUpper
||
tempLower
||
humiUpper
||
humiLower
||
oxyUpper
||
oxyLower
;
// MQTT 上行(仅存在告警时才发送)
final
mqttClient
=
globalMqttClient
;
...
...
@@ -439,10 +451,10 @@ class DeviceControlBloc
}
/// [用户操作] 设置舱内温度开关(发送给MCU)—— 持久化
void
_onCabinTempSwitchChanged
(
Future
<
void
>
_onCabinTempSwitchChanged
(
DeviceControlCabinTempSwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
{
)
async
{
final
newData
=
state
.
data
.
copyWith
(
cabinTemp:
state
.
data
.
cabinTemp
.
copyWith
(
isOn:
event
.
isOn
,
...
...
@@ -453,7 +465,13 @@ class DeviceControlBloc
userSettings:
state
.
userSettings
.
copyWith
(
cabinTempIsOn:
event
.
isOn
),
clearError:
true
,
));
// TODO: 发送设置到MCU
await
_writeControlValueToBluetooth
(
identifier:
0x02
,
setValue:
event
.
isOn
?
_preservedCabinTempSetValue
:
'10'
,
errorPrefix:
'舱内温度
${event.isOn ? '开启' : '关闭'}
'
,
emit:
emit
,
scale:
event
.
isOn
?
10
:
1
,
);
}
// ==================== 舱内湿度控制事件处理 ====================
...
...
@@ -520,10 +538,10 @@ class DeviceControlBloc
}
/// [用户操作] 设置舱内湿度开关(发送给MCU)—— 持久化
void
_onCabinHumiditySwitchChanged
(
Future
<
void
>
_onCabinHumiditySwitchChanged
(
DeviceControlCabinHumiditySwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
{
)
async
{
final
newData
=
state
.
data
.
copyWith
(
cabinHumidity:
state
.
data
.
cabinHumidity
.
copyWith
(
isOn:
event
.
isOn
,
...
...
@@ -534,7 +552,12 @@ class DeviceControlBloc
userSettings:
state
.
userSettings
.
copyWith
(
cabinHumidityIsOn:
event
.
isOn
),
clearError:
true
,
));
// TODO: 发送设置到MCU
await
_writeControlValueToBluetooth
(
identifier:
0x04
,
setValue:
event
.
isOn
?
_preservedCabinHumiditySetValue
:
'100'
,
errorPrefix:
'舱内湿度
${event.isOn ? '开启' : '关闭'}
'
,
emit:
emit
,
);
}
// ==================== 氧气浓度控制事件处理 ====================
...
...
@@ -567,7 +590,7 @@ class DeviceControlBloc
)
async
{
final
currentValue
=
int
.
tryParse
(
state
.
data
.
oxygenConcentration
.
setValue
)
??
0
;
final
nextValue
=
(
currentValue
+
event
.
step
).
clamp
(
0
,
100
);
final
nextValue
=
(
currentValue
+
event
.
step
).
clamp
(
0
,
_oxygenSetValueMax
);
Log
.
warn
(
'🔥🔥🔥 BLE_WRITE_DEBUG oxygen_concentration_adjust '
'current=
$currentValue
step=
${event.step}
next=
$nextValue
'
,
...
...
@@ -579,45 +602,55 @@ class DeviceControlBloc
String
setValue
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
final
safeSetValue
=
_clampIntString
(
setValue
,
0
,
_oxygenSetValueMax
);
final
newData
=
state
.
data
.
copyWith
(
oxygenConcentration:
state
.
data
.
oxygenConcentration
.
copyWith
(
setValue:
setValue
,
setValue:
s
afeS
etValue
,
),
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
oxygenConcentrationSetValue:
s
etValue
),
userSettings:
state
.
userSettings
.
copyWith
(
oxygenConcentrationSetValue:
safeS
etValue
),
clearError:
true
,
));
Log
.
warn
(
'🔥🔥🔥 BLE_WRITE_DEBUG oxygen_concentration_set_value value=
$setValue
'
,
'🔥🔥🔥 BLE_WRITE_DEBUG oxygen_concentration_set_value value=
$s
afeS
etValue
'
,
);
await
_writeControlValueToBluetooth
(
identifier:
0x05
,
setValue:
setValue
,
setValue:
s
afeS
etValue
,
errorPrefix:
'氧气浓度设定'
,
emit:
emit
,
);
}
/// [用户操作] 设置氧气浓度开关(发送给MCU)—— 持久化
void
_onOxygenConcentrationSwitchChanged
(
Future
<
void
>
_onOxygenConcentrationSwitchChanged
(
DeviceControlOxygenConcentrationSwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
{
)
async
{
final
safeSetValue
=
_preservedOxygenConcentrationSetValue
;
final
newData
=
state
.
data
.
copyWith
(
oxygenConcentration:
state
.
data
.
oxygenConcentration
.
copyWith
(
isOn:
event
.
isOn
,
setValue:
safeSetValue
,
),
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
oxygenConcentrationIsOn:
event
.
isOn
),
userSettings:
state
.
userSettings
.
copyWith
(
oxygenConcentrationIsOn:
event
.
isOn
,
oxygenConcentrationSetValue:
safeSetValue
,
),
clearError:
true
,
));
// TODO: 发送设置到MCU
await
_writeControlValueToBluetooth
(
identifier:
0x05
,
setValue:
event
.
isOn
?
_preservedOxygenConcentrationSetValue
:
'20'
,
errorPrefix:
'氧气浓度
${event.isOn ? '开启' : '关闭'}
'
,
emit:
emit
,
);
}
// ==================== 二氧化碳浓度控制事件处理 ====================
...
...
@@ -650,7 +683,7 @@ class DeviceControlBloc
)
async
{
final
currentValue
=
int
.
tryParse
(
state
.
data
.
co2Concentration
.
alarmThreshold
)
??
0
;
final
nextValue
=
(
currentValue
+
event
.
step
).
clamp
(
0
,
9999
);
final
nextValue
=
(
currentValue
+
event
.
step
).
clamp
(
4000
,
5000
);
Log
.
warn
(
'🔥🔥🔥 BLE_WRITE_DEBUG co2_alarm_threshold_adjust '
'current=
$currentValue
step=
${event.step}
next=
$nextValue
'
,
...
...
@@ -662,24 +695,25 @@ class DeviceControlBloc
String
alarmThreshold
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
final
safeAlarmThreshold
=
_clampIntString
(
alarmThreshold
,
4000
,
5000
);
final
newData
=
state
.
data
.
copyWith
(
co2Concentration:
state
.
data
.
co2Concentration
.
copyWith
(
alarmThreshold:
a
larmThreshold
,
alarmThreshold:
safeA
larmThreshold
,
),
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
co2AlarmThreshold:
a
larmThreshold
),
state
.
userSettings
.
copyWith
(
co2AlarmThreshold:
safeA
larmThreshold
),
clearError:
true
,
));
Log
.
warn
(
'🔥🔥🔥 BLE_WRITE_DEBUG co2_alarm_threshold_set_value '
'value=
$
a
larmThreshold
'
,
'value=
$
safeA
larmThreshold
'
,
);
await
_writeControlValueToBluetooth
(
identifier:
0x31
,
setValue:
a
larmThreshold
,
setValue:
safeA
larmThreshold
,
errorPrefix:
'二氧化碳浓度设定'
,
emit:
emit
,
);
...
...
@@ -740,6 +774,10 @@ class DeviceControlBloc
DeviceControlWindSpeedModeChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
if
(
event
.
mode
==
WindSpeedMode
.
off
&&
state
.
data
.
cabinTemp
.
isOn
)
{
emit
(
state
.
copyWith
(
error:
'舱内温度开启时风速不能关闭'
));
return
;
}
final
newData
=
state
.
data
.
copyWith
(
windSpeed:
state
.
data
.
windSpeed
.
copyWith
(
currentMode:
event
.
mode
,
...
...
@@ -817,14 +855,37 @@ class DeviceControlBloc
DeviceControlOpenOxygenSwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
final
oxygenSetValue
=
event
.
isOn
?
state
.
data
.
oxygenConcentration
.
setValue
:
_clampIntString
(
state
.
data
.
oxygenConcentration
.
setValue
,
0
,
60
);
final
newData
=
state
.
data
.
copyWith
(
openOxygen:
state
.
data
.
openOxygen
.
copyWith
(
isOn:
event
.
isOn
,
),
oxygenConcentration:
state
.
data
.
oxygenConcentration
.
copyWith
(
setValue:
oxygenSetValue
,
),
circulationMode:
event
.
isOn
?
state
.
data
.
circulationMode
.
copyWith
(
currentMode:
CirculationMode
.
external
,
)
:
null
,
windSpeed:
event
.
isOn
?
state
.
data
.
windSpeed
.
copyWith
(
currentMode:
WindSpeedMode
.
off
)
:
null
,
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
openOxygenIsOn:
event
.
isOn
),
userSettings:
state
.
userSettings
.
copyWith
(
openOxygenIsOn:
event
.
isOn
,
oxygenConcentrationSetValue:
oxygenSetValue
,
circulationModeValue:
event
.
isOn
?
CirculationMode
.
external
:
state
.
userSettings
.
circulationModeValue
,
windSpeedModeValue:
event
.
isOn
?
WindSpeedMode
.
off
:
state
.
userSettings
.
windSpeedModeValue
,
),
clearError:
true
,
));
await
_writeSwitchValueToBluetooth
(
...
...
@@ -906,20 +967,9 @@ class DeviceControlBloc
DeviceControlCheckLightSwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
final
newData
=
state
.
data
.
copyWith
(
lightControl:
state
.
data
.
lightControl
.
copyWith
(
checkLightOn:
event
.
isOn
,
),
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
checkLightOn:
event
.
isOn
),
clearError:
true
,
));
await
_writeSwitchValueToBluetooth
(
identifier:
0x0A
,
await
_setExclusiveLight
(
target:
_LightTarget
.
check
,
isOn:
event
.
isOn
,
errorPrefix:
'检查灯'
,
emit:
emit
,
);
}
...
...
@@ -929,20 +979,9 @@ class DeviceControlBloc
DeviceControlIlluminationLightSwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
final
newData
=
state
.
data
.
copyWith
(
lightControl:
state
.
data
.
lightControl
.
copyWith
(
illuminationOn:
event
.
isOn
,
),
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
illuminationOn:
event
.
isOn
),
clearError:
true
,
));
await
_writeSwitchValueToBluetooth
(
identifier:
0x09
,
await
_setExclusiveLight
(
target:
_LightTarget
.
illumination
,
isOn:
event
.
isOn
,
errorPrefix:
'照明灯'
,
emit:
emit
,
);
}
...
...
@@ -952,20 +991,9 @@ class DeviceControlBloc
DeviceControlBlueLightSwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
final
newData
=
state
.
data
.
copyWith
(
lightControl:
state
.
data
.
lightControl
.
copyWith
(
blueLightOn:
event
.
isOn
,
),
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
blueLightOn:
event
.
isOn
),
clearError:
true
,
));
await
_writeSwitchValueToBluetooth
(
identifier:
0x1E
,
await
_setExclusiveLight
(
target:
_LightTarget
.
blue
,
isOn:
event
.
isOn
,
errorPrefix:
'蓝光'
,
emit:
emit
,
);
}
...
...
@@ -975,20 +1003,9 @@ class DeviceControlBloc
DeviceControlRedLightSwitchChanged
event
,
Emitter
<
DeviceControlState
>
emit
,
)
async
{
final
newData
=
state
.
data
.
copyWith
(
lightControl:
state
.
data
.
lightControl
.
copyWith
(
redLightOn:
event
.
isOn
,
),
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
redLightOn:
event
.
isOn
),
clearError:
true
,
));
await
_writeSwitchValueToBluetooth
(
identifier:
0x1F
,
await
_setExclusiveLight
(
target:
_LightTarget
.
red
,
isOn:
event
.
isOn
,
errorPrefix:
'红光'
,
emit:
emit
,
);
}
...
...
@@ -1037,6 +1054,199 @@ class DeviceControlBloc
// TODO: 发送重置指令到MCU
}
int
get
_oxygenSetValueMax
=>
state
.
data
.
openOxygen
.
isOn
?
80
:
60
;
String
get
_preservedCabinTempSetValue
{
final
savedValue
=
state
.
userSettings
.
cabinTempSetValue
;
if
(
savedValue
!=
null
)
return
savedValue
;
final
value
=
state
.
data
.
cabinTemp
.
setValue
;
if
(!
state
.
data
.
cabinTemp
.
isOn
&&
value
==
'1'
)
{
return
'24'
;
}
return
value
;
}
String
get
_preservedCabinHumiditySetValue
{
final
savedValue
=
state
.
userSettings
.
cabinHumiditySetValue
;
if
(
savedValue
!=
null
)
return
savedValue
;
final
value
=
state
.
data
.
cabinHumidity
.
setValue
;
if
(!
state
.
data
.
cabinHumidity
.
isOn
&&
value
==
'100'
)
{
return
'50'
;
}
return
value
;
}
String
get
_preservedOxygenConcentrationSetValue
{
final
savedValue
=
state
.
userSettings
.
oxygenConcentrationSetValue
;
final
value
=
savedValue
??
state
.
data
.
oxygenConcentration
.
setValue
;
if
(
savedValue
==
null
&&
!
state
.
data
.
oxygenConcentration
.
isOn
&&
value
==
'20'
)
{
return
'60'
;
}
return
_clampIntString
(
value
,
0
,
_oxygenSetValueMax
,
);
}
String
_clampIntString
(
String
value
,
int
min
,
int
max
)
{
final
parsed
=
int
.
tryParse
(
value
);
if
(
parsed
==
null
)
return
'
$min
'
;
return
'
${parsed.clamp(min, max)}
'
;
}
Future
<
void
>
_setExclusiveLight
({
required
_LightTarget
target
,
required
bool
isOn
,
required
Emitter
<
DeviceControlState
>
emit
,
})
async
{
final
current
=
state
.
data
.
lightControl
;
final
nextLightControl
=
isOn
?
_lightControlForTurnOn
(
current
,
target
)
:
current
.
copyWith
(
checkLightOn:
target
==
_LightTarget
.
check
?
false
:
null
,
illuminationOn:
target
==
_LightTarget
.
illumination
?
false
:
null
,
blueLightOn:
target
==
_LightTarget
.
blue
?
false
:
null
,
redLightOn:
target
==
_LightTarget
.
red
?
false
:
null
,
);
final
newData
=
state
.
data
.
copyWith
(
lightControl:
nextLightControl
);
emit
(
state
.
copyWith
(
data:
newData
,
userSettings:
state
.
userSettings
.
copyWith
(
checkLightOn:
nextLightControl
.
checkLightOn
,
illuminationOn:
nextLightControl
.
illuminationOn
,
blueLightOn:
nextLightControl
.
blueLightOn
,
redLightOn:
nextLightControl
.
redLightOn
,
),
clearError:
true
,
));
final
List
<
_LightTarget
>
lightsToClose
=
[];
if
(
isOn
)
{
for
(
final
light
in
_lightsToCloseBeforeTurnOn
(
target
))
{
if
(
_isLightOn
(
current
,
light
))
lightsToClose
.
add
(
light
);
}
}
for
(
final
light
in
lightsToClose
)
{
await
_writeLightToBluetooth
(
light
,
false
,
emit
);
await
Future
<
void
>.
delayed
(
const
Duration
(
milliseconds:
300
));
}
await
_writeLightToBluetooth
(
target
,
isOn
,
emit
);
}
LightControlBO
_lightControlForTurnOn
(
LightControlBO
current
,
_LightTarget
target
,
)
{
switch
(
target
)
{
case
_LightTarget
.
check
:
return
current
.
copyWith
(
checkLightOn:
true
,
blueLightOn:
false
,
redLightOn:
false
,
);
case
_LightTarget
.
illumination
:
return
current
.
copyWith
(
illuminationOn:
true
,
blueLightOn:
false
,
redLightOn:
false
,
);
case
_LightTarget
.
blue
:
return
const
LightControlBO
(
checkLightOn:
false
,
illuminationOn:
false
,
blueLightOn:
true
,
redLightOn:
false
,
);
case
_LightTarget
.
red
:
return
const
LightControlBO
(
checkLightOn:
false
,
illuminationOn:
false
,
blueLightOn:
false
,
redLightOn:
true
,
);
}
}
List
<
_LightTarget
>
_lightsToCloseBeforeTurnOn
(
_LightTarget
target
)
{
switch
(
target
)
{
case
_LightTarget
.
check
:
case
_LightTarget
.
illumination
:
return
const
[
_LightTarget
.
blue
,
_LightTarget
.
red
];
case
_LightTarget
.
blue
:
return
const
[
_LightTarget
.
check
,
_LightTarget
.
illumination
,
_LightTarget
.
red
,
];
case
_LightTarget
.
red
:
return
const
[
_LightTarget
.
check
,
_LightTarget
.
illumination
,
_LightTarget
.
blue
,
];
}
}
bool
_isLightOn
(
LightControlBO
lightControl
,
_LightTarget
target
)
{
switch
(
target
)
{
case
_LightTarget
.
check
:
return
lightControl
.
checkLightOn
;
case
_LightTarget
.
illumination
:
return
lightControl
.
illuminationOn
;
case
_LightTarget
.
blue
:
return
lightControl
.
blueLightOn
;
case
_LightTarget
.
red
:
return
lightControl
.
redLightOn
;
}
}
Future
<
void
>
_writeLightToBluetooth
(
_LightTarget
target
,
bool
isOn
,
Emitter
<
DeviceControlState
>
emit
,
)
{
return
_writeSwitchValueToBluetooth
(
identifier:
_lightIdentifier
(
target
),
isOn:
isOn
,
errorPrefix:
_lightName
(
target
),
emit:
emit
,
);
}
int
_lightIdentifier
(
_LightTarget
target
)
{
switch
(
target
)
{
case
_LightTarget
.
check
:
return
0x0A
;
case
_LightTarget
.
illumination
:
return
0x09
;
case
_LightTarget
.
blue
:
return
0x1E
;
case
_LightTarget
.
red
:
return
0x1F
;
}
}
String
_lightName
(
_LightTarget
target
)
{
switch
(
target
)
{
case
_LightTarget
.
check
:
return
'检查灯'
;
case
_LightTarget
.
illumination
:
return
'照明灯'
;
case
_LightTarget
.
blue
:
return
'蓝光'
;
case
_LightTarget
.
red
:
return
'红光'
;
}
}
Future
<
void
>
_writeControlValueToBluetooth
({
required
int
identifier
,
required
String
setValue
,
...
...
@@ -1098,6 +1308,8 @@ class DeviceControlBloc
int
_windSpeedProtocolValue
(
WindSpeedMode
mode
)
{
switch
(
mode
)
{
case
WindSpeedMode
.
off
:
return
3
;
case
WindSpeedMode
.
comfort
:
return
0
;
case
WindSpeedMode
.
strong
:
...
...
lib/blocs/device_control/device_control_state.dart
View file @
5dc83081
...
...
@@ -21,7 +21,7 @@ const DeviceControlBO _defaultDeviceControlBO = DeviceControlBO(
),
oxygenConcentration:
OxygenConcentrationBO
(
currentValue:
'--'
,
setValue:
'
9
0'
,
setValue:
'
6
0'
,
unit:
'%'
,
isOn:
true
,
),
...
...
@@ -41,10 +41,10 @@ const DeviceControlBO _defaultDeviceControlBO = DeviceControlBO(
currentMode:
WindSpeedMode
.
sleep
,
),
nebulizationTime:
NebulizationTimeBO
(
setMinutes:
'
0
0'
,
setMinutes:
'
3
0'
,
),
disinfectionTime:
DisinfectionTimeBO
(
setMinutes:
'
14
'
,
setMinutes:
'
30
'
,
),
openOxygen:
OpenOxygenControlBO
(
isOn:
false
,
...
...
lib/models/bo/device_control_bo.dart
View file @
5dc83081
...
...
@@ -121,7 +121,8 @@ class DeviceControlBO extends Equatable {
environmentTemp:
json
[
'environmentTemp'
]
as
String
?
??
'25.0℃'
,
totalOxygenTime:
json
[
'totalOxygenTime'
]
as
String
?
??
'0h'
,
cabinTemp:
json
[
'cabinTemp'
]
!=
null
?
TemperatureControlBO
.
fromJson
(
json
[
'cabinTemp'
]
as
Map
<
String
,
dynamic
>)
?
TemperatureControlBO
.
fromJson
(
json
[
'cabinTemp'
]
as
Map
<
String
,
dynamic
>)
:
const
TemperatureControlBO
(
currentValue:
'24'
,
setValue:
'24'
,
...
...
@@ -129,7 +130,8 @@ class DeviceControlBO extends Equatable {
isOn:
false
,
),
cabinHumidity:
json
[
'cabinHumidity'
]
!=
null
?
HumidityControlBO
.
fromJson
(
json
[
'cabinHumidity'
]
as
Map
<
String
,
dynamic
>)
?
HumidityControlBO
.
fromJson
(
json
[
'cabinHumidity'
]
as
Map
<
String
,
dynamic
>)
:
const
HumidityControlBO
(
currentValue:
'24'
,
setValue:
'50'
,
...
...
@@ -137,22 +139,25 @@ class DeviceControlBO extends Equatable {
isOn:
false
,
),
oxygenConcentration:
json
[
'oxygenConcentration'
]
!=
null
?
OxygenConcentrationBO
.
fromJson
(
json
[
'oxygenConcentration'
]
as
Map
<
String
,
dynamic
>)
?
OxygenConcentrationBO
.
fromJson
(
json
[
'oxygenConcentration'
]
as
Map
<
String
,
dynamic
>)
:
const
OxygenConcentrationBO
(
currentValue:
'24'
,
setValue:
'
9
0'
,
setValue:
'
6
0'
,
unit:
'%'
,
isOn:
true
,
),
co2Concentration:
json
[
'co2Concentration'
]
!=
null
?
CO2ConcentrationBO
.
fromJson
(
json
[
'co2Concentration'
]
as
Map
<
String
,
dynamic
>)
?
CO2ConcentrationBO
.
fromJson
(
json
[
'co2Concentration'
]
as
Map
<
String
,
dynamic
>)
:
const
CO2ConcentrationBO
(
currentValue:
'2400'
,
alarmThreshold:
'4000'
,
unit:
'PPM'
,
),
careLevel:
json
[
'careLevel'
]
!=
null
?
CareLevelControlBO
.
fromJson
(
json
[
'careLevel'
]
as
Map
<
String
,
dynamic
>)
?
CareLevelControlBO
.
fromJson
(
json
[
'careLevel'
]
as
Map
<
String
,
dynamic
>)
:
const
CareLevelControlBO
(
currentLevel:
CareLevel
.
special
,
),
...
...
@@ -163,22 +168,26 @@ class DeviceControlBO extends Equatable {
description:
'CO₂超设定值时自动启动外循环净化,当降至2000ppm后,本功能自动关闭'
,
),
windSpeed:
json
[
'windSpeed'
]
!=
null
?
WindSpeedControlBO
.
fromJson
(
json
[
'windSpeed'
]
as
Map
<
String
,
dynamic
>)
?
WindSpeedControlBO
.
fromJson
(
json
[
'windSpeed'
]
as
Map
<
String
,
dynamic
>)
:
const
WindSpeedControlBO
(
currentMode:
WindSpeedMode
.
sleep
,
),
nebulizationTime:
json
[
'nebulizationTime'
]
!=
null
?
NebulizationTimeBO
.
fromJson
(
json
[
'nebulizationTime'
]
as
Map
<
String
,
dynamic
>)
?
NebulizationTimeBO
.
fromJson
(
json
[
'nebulizationTime'
]
as
Map
<
String
,
dynamic
>)
:
const
NebulizationTimeBO
(
setMinutes:
'
0
0'
,
setMinutes:
'
3
0'
,
),
disinfectionTime:
json
[
'disinfectionTime'
]
!=
null
?
DisinfectionTimeBO
.
fromJson
(
json
[
'disinfectionTime'
]
as
Map
<
String
,
dynamic
>)
?
DisinfectionTimeBO
.
fromJson
(
json
[
'disinfectionTime'
]
as
Map
<
String
,
dynamic
>)
:
const
DisinfectionTimeBO
(
setMinutes:
'
14
'
,
setMinutes:
'
30
'
,
),
openOxygen:
json
[
'openOxygen'
]
!=
null
?
OpenOxygenControlBO
.
fromJson
(
json
[
'openOxygen'
]
as
Map
<
String
,
dynamic
>)
?
OpenOxygenControlBO
.
fromJson
(
json
[
'openOxygen'
]
as
Map
<
String
,
dynamic
>)
:
const
OpenOxygenControlBO
(
isOn:
false
,
description:
'开启后风扇打开,制冷、加热和循环等设备暂停。
\n
*保持设备周围空气相对禁止,严禁烟火'
,
...
...
@@ -191,12 +200,14 @@ class DeviceControlBO extends Equatable {
seconds:
'00'
,
),
circulationMode:
json
[
'circulationMode'
]
!=
null
?
CirculationModeBO
.
fromJson
(
json
[
'circulationMode'
]
as
Map
<
String
,
dynamic
>)
?
CirculationModeBO
.
fromJson
(
json
[
'circulationMode'
]
as
Map
<
String
,
dynamic
>)
:
const
CirculationModeBO
(
currentMode:
CirculationMode
.
external
,
),
lightControl:
json
[
'lightControl'
]
!=
null
?
LightControlBO
.
fromJson
(
json
[
'lightControl'
]
as
Map
<
String
,
dynamic
>)
?
LightControlBO
.
fromJson
(
json
[
'lightControl'
]
as
Map
<
String
,
dynamic
>)
:
const
LightControlBO
(
checkLightOn:
false
,
illuminationOn:
false
,
...
...
@@ -365,7 +376,7 @@ class OxygenConcentrationBO extends Equatable {
factory
OxygenConcentrationBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
OxygenConcentrationBO
(
currentValue:
json
[
'currentValue'
]
as
String
?
??
'24'
,
setValue:
json
[
'setValue'
]
as
String
?
??
'
9
0'
,
setValue:
json
[
'setValue'
]
as
String
?
??
'
6
0'
,
unit:
json
[
'unit'
]
as
String
?
??
'%'
,
isOn:
json
[
'isOn'
]
as
bool
?
??
true
,
);
...
...
@@ -495,7 +506,7 @@ class FreshAirControlBO extends Equatable {
}
/// 风速模式枚举
enum
WindSpeedMode
{
sleep
,
comfort
,
strong
}
enum
WindSpeedMode
{
off
,
sleep
,
comfort
,
strong
}
/// 用途:风速调节控制数据
/// 涉及页面:设备控制页面
...
...
@@ -548,7 +559,7 @@ class NebulizationTimeBO extends Equatable {
factory
NebulizationTimeBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
NebulizationTimeBO
(
setMinutes:
json
[
'setMinutes'
]
as
String
?
??
'
0
0'
,
setMinutes:
json
[
'setMinutes'
]
as
String
?
??
'
3
0'
,
);
}
...
...
@@ -576,7 +587,7 @@ class DisinfectionTimeBO extends Equatable {
factory
DisinfectionTimeBO
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
return
DisinfectionTimeBO
(
setMinutes:
json
[
'setMinutes'
]
as
String
?
??
'
14
'
,
setMinutes:
json
[
'setMinutes'
]
as
String
?
??
'
30
'
,
);
}
...
...
@@ -741,7 +752,8 @@ class LightControlBO extends Equatable {
}
@override
List
<
Object
?>
get
props
=>
[
checkLightOn
,
illuminationOn
,
blueLightOn
,
redLightOn
];
List
<
Object
?>
get
props
=>
[
checkLightOn
,
illuminationOn
,
blueLightOn
,
redLightOn
];
}
/// 用途:设备控制用户设置数据(仅包含用户可配置的字段,不包含MCU获取的值)
...
...
@@ -851,16 +863,21 @@ class DeviceControlUserSettings extends Equatable {
sn:
sn
??
this
.
sn
,
cabinTempSetValue:
cabinTempSetValue
??
this
.
cabinTempSetValue
,
cabinTempIsOn:
cabinTempIsOn
??
this
.
cabinTempIsOn
,
cabinHumiditySetValue:
cabinHumiditySetValue
??
this
.
cabinHumiditySetValue
,
cabinHumiditySetValue:
cabinHumiditySetValue
??
this
.
cabinHumiditySetValue
,
cabinHumidityIsOn:
cabinHumidityIsOn
??
this
.
cabinHumidityIsOn
,
oxygenConcentrationSetValue:
oxygenConcentrationSetValue
??
this
.
oxygenConcentrationSetValue
,
oxygenConcentrationIsOn:
oxygenConcentrationIsOn
??
this
.
oxygenConcentrationIsOn
,
oxygenConcentrationSetValue:
oxygenConcentrationSetValue
??
this
.
oxygenConcentrationSetValue
,
oxygenConcentrationIsOn:
oxygenConcentrationIsOn
??
this
.
oxygenConcentrationIsOn
,
co2AlarmThreshold:
co2AlarmThreshold
??
this
.
co2AlarmThreshold
,
careLevelValue:
careLevelValue
??
this
.
careLevelValue
,
freshAirModeValue:
freshAirModeValue
??
this
.
freshAirModeValue
,
windSpeedModeValue:
windSpeedModeValue
??
this
.
windSpeedModeValue
,
nebulizationTimeMinutes:
nebulizationTimeMinutes
??
this
.
nebulizationTimeMinutes
,
disinfectionTimeMinutes:
disinfectionTimeMinutes
??
this
.
disinfectionTimeMinutes
,
nebulizationTimeMinutes:
nebulizationTimeMinutes
??
this
.
nebulizationTimeMinutes
,
disinfectionTimeMinutes:
disinfectionTimeMinutes
??
this
.
disinfectionTimeMinutes
,
openOxygenIsOn:
openOxygenIsOn
??
this
.
openOxygenIsOn
,
circulationModeValue:
circulationModeValue
??
this
.
circulationModeValue
,
checkLightOn:
checkLightOn
??
this
.
checkLightOn
,
...
...
@@ -884,7 +901,8 @@ class DeviceControlUserSettings extends Equatable {
isOn:
cabinHumidityIsOn
??
bo
.
cabinHumidity
.
isOn
,
),
oxygenConcentration:
bo
.
oxygenConcentration
.
copyWith
(
setValue:
oxygenConcentrationSetValue
??
bo
.
oxygenConcentration
.
setValue
,
setValue:
oxygenConcentrationSetValue
??
bo
.
oxygenConcentration
.
setValue
,
isOn:
oxygenConcentrationIsOn
??
bo
.
oxygenConcentration
.
isOn
,
),
co2Concentration:
bo
.
co2Concentration
.
copyWith
(
...
...
@@ -927,7 +945,8 @@ class DeviceControlUserSettings extends Equatable {
cabinTempIsOn:
json
[
'cabinTempIsOn'
]
as
bool
?,
cabinHumiditySetValue:
json
[
'cabinHumiditySetValue'
]
as
String
?,
cabinHumidityIsOn:
json
[
'cabinHumidityIsOn'
]
as
bool
?,
oxygenConcentrationSetValue:
json
[
'oxygenConcentrationSetValue'
]
as
String
?,
oxygenConcentrationSetValue:
json
[
'oxygenConcentrationSetValue'
]
as
String
?,
oxygenConcentrationIsOn:
json
[
'oxygenConcentrationIsOn'
]
as
bool
?,
co2AlarmThreshold:
json
[
'co2AlarmThreshold'
]
as
String
?,
careLevelValue:
json
[
'careLevelValue'
]
!=
null
...
...
@@ -969,18 +988,26 @@ class DeviceControlUserSettings extends Equatable {
if
(
sn
!=
null
)
'sn'
:
sn
,
if
(
cabinTempSetValue
!=
null
)
'cabinTempSetValue'
:
cabinTempSetValue
,
if
(
cabinTempIsOn
!=
null
)
'cabinTempIsOn'
:
cabinTempIsOn
,
if
(
cabinHumiditySetValue
!=
null
)
'cabinHumiditySetValue'
:
cabinHumiditySetValue
,
if
(
cabinHumiditySetValue
!=
null
)
'cabinHumiditySetValue'
:
cabinHumiditySetValue
,
if
(
cabinHumidityIsOn
!=
null
)
'cabinHumidityIsOn'
:
cabinHumidityIsOn
,
if
(
oxygenConcentrationSetValue
!=
null
)
'oxygenConcentrationSetValue'
:
oxygenConcentrationSetValue
,
if
(
oxygenConcentrationIsOn
!=
null
)
'oxygenConcentrationIsOn'
:
oxygenConcentrationIsOn
,
if
(
oxygenConcentrationSetValue
!=
null
)
'oxygenConcentrationSetValue'
:
oxygenConcentrationSetValue
,
if
(
oxygenConcentrationIsOn
!=
null
)
'oxygenConcentrationIsOn'
:
oxygenConcentrationIsOn
,
if
(
co2AlarmThreshold
!=
null
)
'co2AlarmThreshold'
:
co2AlarmThreshold
,
if
(
careLevelValue
!=
null
)
'careLevelValue'
:
careLevelValue
!.
name
,
if
(
freshAirModeValue
!=
null
)
'freshAirModeValue'
:
freshAirModeValue
!.
name
,
if
(
windSpeedModeValue
!=
null
)
'windSpeedModeValue'
:
windSpeedModeValue
!.
name
,
if
(
nebulizationTimeMinutes
!=
null
)
'nebulizationTimeMinutes'
:
nebulizationTimeMinutes
,
if
(
disinfectionTimeMinutes
!=
null
)
'disinfectionTimeMinutes'
:
disinfectionTimeMinutes
,
if
(
freshAirModeValue
!=
null
)
'freshAirModeValue'
:
freshAirModeValue
!.
name
,
if
(
windSpeedModeValue
!=
null
)
'windSpeedModeValue'
:
windSpeedModeValue
!.
name
,
if
(
nebulizationTimeMinutes
!=
null
)
'nebulizationTimeMinutes'
:
nebulizationTimeMinutes
,
if
(
disinfectionTimeMinutes
!=
null
)
'disinfectionTimeMinutes'
:
disinfectionTimeMinutes
,
if
(
openOxygenIsOn
!=
null
)
'openOxygenIsOn'
:
openOxygenIsOn
,
if
(
circulationModeValue
!=
null
)
'circulationModeValue'
:
circulationModeValue
!.
name
,
if
(
circulationModeValue
!=
null
)
'circulationModeValue'
:
circulationModeValue
!.
name
,
if
(
checkLightOn
!=
null
)
'checkLightOn'
:
checkLightOn
,
if
(
illuminationOn
!=
null
)
'illuminationOn'
:
illuminationOn
,
if
(
blueLightOn
!=
null
)
'blueLightOn'
:
blueLightOn
,
...
...
lib/utils/bluetooth/bluetooth_manager.dart
View file @
5dc83081
...
...
@@ -747,7 +747,10 @@ class BleBluetoothManager<T> {
}
static
bool
_startsWithAny
(
String
value
,
List
<
String
>
prefixes
)
{
return
prefixes
.
any
(
value
.
startsWith
);
final
normalizedValue
=
value
.
trim
().
toUpperCase
();
return
prefixes
.
any
(
(
prefix
)
=>
normalizedValue
.
startsWith
(
prefix
.
trim
().
toUpperCase
()),
);
}
static
String
_normalizeRemoteIdForSort
(
String
remoteId
)
{
...
...
lib/views/monitoring/device_control/device_control_index_view.dart
View file @
5dc83081
...
...
@@ -10,7 +10,6 @@ import 'package:laki_icu_app/models/bo/monitoring_bo.dart';
import
'cubit/device_control_index_cubit.dart'
;
import
'cubit/device_control_index_state.dart'
;
import
'widgets/device_control_care_panel.dart'
;
import
'widgets/device_control_confirm_dialog.dart'
;
import
'widgets/device_control_info_panel.dart'
;
import
'widgets/device_control_metric_card.dart'
;
import
'widgets/device_control_mode_panel.dart'
;
...
...
@@ -163,14 +162,9 @@ class _DeviceControlLayout extends StatelessWidget {
icon:
Icons
.
air
,
body:
'开启后风扇打开、制冷、加热和
\n
循环等设备暂停。'
,
warning:
'*保持设备周围空气相对禁止,严禁烟火'
,
onTap:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
DeviceControlOpenOxygenSwitchChanged
(!
isOn
),
),
);
},
onTap:
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
DeviceControlOpenOxygenSwitchChanged
(!
isOn
),
),
);
},
),
...
...
lib/views/monitoring/device_control/widgets/device_control_care_panel.dart
View file @
5dc83081
...
...
@@ -7,7 +7,6 @@ import 'package:laki_icu_app/blocs/device_control/device_control_state.dart';
import
'package:laki_icu_app/models/bo/device_control_bo.dart'
;
import
'device_control_common.dart'
;
import
'device_control_confirm_dialog.dart'
;
/// 护理等级面板
class
DeviceControlCarePanel
extends
StatelessWidget
{
...
...
@@ -37,14 +36,9 @@ class DeviceControlCarePanel extends StatelessWidget {
Expanded
(
child:
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
DeviceControlCareLevelChanged
(
item
.
level
),
),
);
},
onTap:
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
DeviceControlCareLevelChanged
(
item
.
level
),
),
child:
Text
(
item
.
label
,
textAlign:
TextAlign
.
center
,
...
...
@@ -107,16 +101,11 @@ class _CareLevelBar extends StatelessWidget {
Expanded
(
child:
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
DeviceControlCareLevelChanged
(
_careLevelItems
[
index
].
level
,
),
),
);
},
onTap:
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
DeviceControlCareLevelChanged
(
_careLevelItems
[
index
].
level
,
),
),
child:
Container
(
height:
20
.
h
,
decoration:
BoxDecoration
(
...
...
lib/views/monitoring/device_control/widgets/device_control_common.dart
View file @
5dc83081
...
...
@@ -94,31 +94,31 @@ class DeviceControlPill extends StatelessWidget {
super
.
key
,
required
this
.
text
,
this
.
active
=
false
,
this
.
onTap
,
});
final
String
text
;
final
bool
active
;
final
VoidCallback
?
onTap
;
@override
Widget
build
(
BuildContext
context
)
{
return
Container
(
height:
40
.
h
,
constraints:
BoxConstraints
(
minWidth:
90
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
18
.
w
),
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
Colors
.
white
.
withValues
(
alpha:
active
?
0.14
:
0.06
),
border:
Border
.
all
(
color:
active
?
const
Color
(
0xFF52FFBB
)
:
const
Color
(
0xFF75C1DD
),
width:
1
.
w
,
return
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
onTap
,
child:
Container
(
height:
40
.
h
,
constraints:
BoxConstraints
(
minWidth:
90
.
w
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
18
.
w
),
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
Colors
.
white
.
withValues
(
alpha:
active
?
0.14
:
0.06
),
border:
Border
.
all
(
color:
active
?
const
Color
(
0xFF52FFBB
)
:
const
Color
(
0xFF75C1DD
),
width:
1
.
w
,
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
),
borderRadius:
BorderRadius
.
circular
(
20
.
r
),
),
child:
GestureDetector
(
onTap:
()
{
var
key
=
super
.
key
;
debugPrint
(
"test
$key
"
);
},
child:
Text
(
text
,
style:
TextStyle
(
...
...
lib/views/monitoring/device_control/widgets/device_control_confirm_dialog.dart
View file @
5dc83081
...
...
@@ -13,8 +13,9 @@ class DeviceControlConfirmConfig {
Future
<
void
>
confirmDeviceControlChange
(
BuildContext
context
,
VoidCallback
onConfirmed
,
)
async
{
VoidCallback
onConfirmed
,
{
String
message
=
'确认设置当前修改参数'
,
})
async
{
if
(!
DeviceControlConfirmConfig
.
enabled
)
{
onConfirmed
();
return
;
...
...
@@ -23,7 +24,7 @@ Future<void> confirmDeviceControlChange(
final
confirmed
=
await
showDialog
<
bool
>(
context:
context
,
barrierColor:
Colors
.
black
.
withValues
(
alpha:
0.44
),
builder:
(
_
)
=>
const
_DeviceControlConfirmDialog
(
),
builder:
(
_
)
=>
_DeviceControlConfirmDialog
(
message:
message
),
);
if
(!
context
.
mounted
||
confirmed
!=
true
)
return
;
...
...
@@ -31,7 +32,9 @@ Future<void> confirmDeviceControlChange(
}
class
_DeviceControlConfirmDialog
extends
StatelessWidget
{
const
_DeviceControlConfirmDialog
();
const
_DeviceControlConfirmDialog
({
required
this
.
message
});
final
String
message
;
@override
Widget
build
(
BuildContext
context
)
{
...
...
@@ -83,8 +86,9 @@ class _DeviceControlConfirmDialog extends StatelessWidget {
),
const
Spacer
(),
Text
(
'确认设置当前修改参数'
,
maxLines:
1
,
message
,
maxLines:
3
,
textAlign:
TextAlign
.
center
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
color:
Colors
.
white
,
...
...
lib/views/monitoring/device_control/widgets/device_control_metric_card.dart
View file @
5dc83081
...
...
@@ -40,7 +40,12 @@ class DeviceControlMetricCard extends StatelessWidget {
previous
.
data
.
oxygenConcentration
.
currentValue
!=
current
.
data
.
oxygenConcentration
.
currentValue
||
previous
.
data
.
co2Concentration
.
currentValue
!=
current
.
data
.
co2Concentration
.
currentValue
,
current
.
data
.
co2Concentration
.
currentValue
||
previous
.
data
.
cabinTemp
.
isOn
!=
current
.
data
.
cabinTemp
.
isOn
||
previous
.
data
.
cabinHumidity
.
isOn
!=
current
.
data
.
cabinHumidity
.
isOn
||
previous
.
data
.
oxygenConcentration
.
isOn
!=
current
.
data
.
oxygenConcentration
.
isOn
||
previous
.
data
.
openOxygen
.
isOn
!=
current
.
data
.
openOxygen
.
isOn
,
builder:
(
context
,
state
)
{
final
currentValue
=
isTemperature
?
state
.
data
.
cabinTemp
.
currentValue
...
...
@@ -72,6 +77,19 @@ class DeviceControlMetricCard extends StatelessWidget {
isOxygen:
isOxygen
,
isCo2:
isCo2
,
);
final
isSwitchOn
=
isTemperature
?
state
.
data
.
cabinTemp
.
isOn
:
isHumidity
?
state
.
data
.
cabinHumidity
.
isOn
:
isOxygen
?
state
.
data
.
oxygenConcentration
.
isOn
:
false
;
final
switchEventBuilder
=
_switchEventBuilder
(
isTemperature:
isTemperature
,
isHumidity:
isHumidity
,
isOxygen:
isOxygen
,
);
final
displaySetValue
=
!
isCo2
&&
!
isSwitchOn
?
'--'
:
setValue
;
return
DeviceControlPanelFrame
(
active:
isOxygen
,
...
...
@@ -86,12 +104,18 @@ class DeviceControlMetricCard extends StatelessWidget {
child:
DeviceControlPanelTitle
(
_title
(
metric
.
label
)),
),
DeviceControlPill
(
text:
isOxygen
?
'ON'
:
isCo2
?
'PPM'
:
'Off'
,
active:
isOxygen
,
text:
isCo2
?
'PPM'
:
(
isSwitchOn
?
'ON'
:
'Off'
),
active:
!
isCo2
&&
isSwitchOn
,
onTap:
switchEventBuilder
==
null
?
null
:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
switchEventBuilder
(!
isSwitchOn
),
),
);
},
),
],
),
...
...
@@ -166,7 +190,6 @@ class DeviceControlMetricCard extends StatelessWidget {
?
null
:
()
=>
_showSetValueKeyboard
(
context
,
initialValue:
setValue
,
decimalEnabled:
isTemperature
,
eventBuilder:
setValueEventBuilder
,
),
...
...
@@ -174,7 +197,7 @@ class DeviceControlMetricCard extends StatelessWidget {
padding:
EdgeInsets
.
symmetric
(
horizontal:
18
.
w
,
vertical:
8
.
h
),
child:
Text
(
s
etValue
,
displayS
etValue
,
style:
TextStyle
(
color:
isCo2
?
const
Color
(
0xFFFFC400
)
...
...
@@ -262,15 +285,31 @@ class DeviceControlMetricCard extends StatelessWidget {
return
null
;
}
static
DeviceControlEvent
Function
(
bool
isOn
)?
_switchEventBuilder
({
required
bool
isTemperature
,
required
bool
isHumidity
,
required
bool
isOxygen
,
})
{
if
(
isTemperature
)
{
return
(
isOn
)
=>
DeviceControlCabinTempSwitchChanged
(
isOn
);
}
if
(
isHumidity
)
{
return
(
isOn
)
=>
DeviceControlCabinHumiditySwitchChanged
(
isOn
);
}
if
(
isOxygen
)
{
return
(
isOn
)
=>
DeviceControlOxygenConcentrationSwitchChanged
(
isOn
);
}
return
null
;
}
static
Future
<
void
>
_showSetValueKeyboard
(
BuildContext
context
,
{
required
String
initialValue
,
required
bool
decimalEnabled
,
required
DeviceControlEvent
Function
(
String
value
)
eventBuilder
,
})
async
{
final
result
=
await
NumericKeyboard
.
show
(
context
,
initialValue:
initialValue
==
'--'
?
''
:
initialValue
,
initialValue:
''
,
decimalEnabled:
decimalEnabled
,
);
if
(!
context
.
mounted
||
result
==
null
)
return
;
...
...
lib/views/monitoring/device_control/widgets/device_control_mode_panel.dart
View file @
5dc83081
...
...
@@ -7,7 +7,6 @@ import 'package:laki_icu_app/blocs/device_control/device_control_state.dart';
import
'package:laki_icu_app/models/bo/device_control_bo.dart'
;
import
'device_control_common.dart'
;
import
'device_control_confirm_dialog.dart'
;
/// 模式切换面板(外循环/检查灯/照明灯/内循环/蓝光/红光)
class
DeviceControlModePanel
extends
StatelessWidget
{
...
...
@@ -95,14 +94,9 @@ class DeviceControlModePanel extends StatelessWidget {
label:
item
.
label
,
icon:
item
.
icon
,
active:
item
.
active
,
onTap:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
item
.
event
,
),
);
},
onTap:
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
item
.
event
,
),
),
),
],
...
...
lib/views/monitoring/device_control/widgets/device_control_time_panel.dart
View file @
5dc83081
...
...
@@ -7,7 +7,6 @@ import 'package:laki_icu_app/blocs/device_control/device_control_state.dart';
import
'package:laki_icu_app/utils/numeric_keyboard.dart'
;
import
'device_control_common.dart'
;
import
'device_control_confirm_dialog.dart'
;
/// 设置雾化/消毒时间面板
class
DeviceControlTimePanel
extends
StatelessWidget
{
...
...
@@ -82,10 +81,7 @@ class DeviceControlTimePanel extends StatelessWidget {
final
value
=
result
.
trim
();
if
(
value
.
isEmpty
)
return
;
await
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
eventBuilder
(
value
)),
);
context
.
read
<
DeviceControlBloc
>().
add
(
eventBuilder
(
value
));
}
}
...
...
lib/views/monitoring/device_control/widgets/device_control_wind_panel.dart
View file @
5dc83081
...
...
@@ -7,7 +7,6 @@ import 'package:laki_icu_app/blocs/device_control/device_control_state.dart';
import
'package:laki_icu_app/models/bo/device_control_bo.dart'
;
import
'device_control_common.dart'
;
import
'device_control_confirm_dialog.dart'
;
/// 风速调节面板
class
DeviceControlWindPanel
extends
StatelessWidget
{
...
...
@@ -34,16 +33,11 @@ class DeviceControlWindPanel extends StatelessWidget {
label:
'睡眠模式'
,
icon:
Icons
.
nightlight_round
,
active:
currentMode
==
WindSpeedMode
.
sleep
,
onTap:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
const
DeviceControlWindSpeedModeChanged
(
WindSpeedMode
.
sleep
,
),
),
);
},
onTap:
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
const
DeviceControlWindSpeedModeChanged
(
WindSpeedMode
.
sleep
,
),
),
),
),
SizedBox
(
height:
18
.
h
),
...
...
@@ -52,16 +46,11 @@ class DeviceControlWindPanel extends StatelessWidget {
label:
'舒适模式'
,
icon:
Icons
.
favorite_border
,
active:
currentMode
==
WindSpeedMode
.
comfort
,
onTap:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
const
DeviceControlWindSpeedModeChanged
(
WindSpeedMode
.
comfort
,
),
),
);
},
onTap:
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
const
DeviceControlWindSpeedModeChanged
(
WindSpeedMode
.
comfort
,
),
),
),
),
SizedBox
(
height:
18
.
h
),
...
...
@@ -70,16 +59,11 @@ class DeviceControlWindPanel extends StatelessWidget {
label:
'强劲模式'
,
icon:
Icons
.
air
,
active:
currentMode
==
WindSpeedMode
.
strong
,
onTap:
()
{
confirmDeviceControlChange
(
context
,
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
const
DeviceControlWindSpeedModeChanged
(
WindSpeedMode
.
strong
,
),
),
);
},
onTap:
()
=>
context
.
read
<
DeviceControlBloc
>().
add
(
const
DeviceControlWindSpeedModeChanged
(
WindSpeedMode
.
strong
,
),
),
),
),
],
...
...
lib/views/monitoring/index/cubit/monitoring_index_cubit.dart
View file @
5dc83081
...
...
@@ -612,7 +612,7 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
try
{
await
_bluetoothManager
.
scanForDevices
(
namePrefixes:
const
[],
namePrefixes:
const
[
'CNA'
],
timeout:
const
Duration
(
seconds:
10
),
);
}
catch
(
e
)
{
...
...
@@ -916,7 +916,8 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
);
// 按告警标题去重:相同标题 → 原地覆盖;不同标题 → 插入头部
final
existingIndex
=
state
.
cameraAlerts
.
indexWhere
((
a
)
=>
a
.
title
==
title
);
final
existingIndex
=
state
.
cameraAlerts
.
indexWhere
((
a
)
=>
a
.
title
==
title
);
if
(
existingIndex
>=
0
)
{
// 已存在相同标题 → 原地替换
final
updatedAlerts
=
List
<
AlertInfoBO
>.
from
(
state
.
cameraAlerts
);
...
...
@@ -1361,8 +1362,12 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
if
(
client
==
null
||
!
client
.
isConnected
||
deviceSn
==
null
||
deviceSn
.
isEmpty
)
return
;
if
(
alert
.
alarmId
==
null
)
return
;
deviceSn
.
isEmpty
)
{
return
;
}
if
(
alert
.
alarmId
==
null
)
{
return
;
}
try
{
client
.
publishCameraAlarmResult
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment