“虞渠成” 9728ded717 debug
2026-06-17 17:46:30 +08:00

1760 lines
65 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using Kill.Managers;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading.Tasks;
using Kill.Network;
using Kill.UI.Components;
using Kill.Bluetooth;
using Kill.Bluetooth.Protocol;
using Kill.Core;
using Unity.VisualScripting;
namespace Kill.UI.Pages
{
public class HomePageCtrl : MonoBehaviour
{
public static HomePageCtrl Instance { get; private set; }
public GameObject noDevicePage;
public GameObject normalPage;
// 存储待执行的UI更新操作
private List<Action> pendingUIUpdates = new List<Action>();
public Button selectDeviceButton;
public GameObject selectDevicePage;
// 设备列表数据 (使用 Kill.Managers.DeviceInfo)
public List<Kill.Managers.DeviceInfo> OwnedDevices { get; private set; } = new List<Kill.Managers.DeviceInfo>();
public List<Kill.Managers.DeviceInfo> SharedDevices { get; private set; } = new List<Kill.Managers.DeviceInfo>();
public Kill.Managers.DeviceInfo selectedDevice;
bool hasBluetooth = false;
bool hasWifi = false;
bool isPollingOnline = false;
bool stopPolling = false;
// UI 组件引用
public HomePageDeviceState deviceState;
public HomePageDeviceCtrl deviceCtrl;
public HomePageSchedule deviceSchedule;
public Button scheduleSettingButton;
public GameObject scheduleSettingPrefab;
/// <summary>
/// 触发密码验证按钮
/// </summary>
public GameObject LockButtonPlane;
// 状态初始化相关
private bool isDeviceStateInitializing = false; // 是否正在初始化设备状态
private int pendingStatusCount = 0; // 待接收的状态数量
private int TOTAL_STATUS_COUNT = 8; // 总共需要查询的状态数量
private float statusQueryTimeout = 15f; // 状态查询超时时间(秒)
private Coroutine statusQueryTimeoutCoroutine; // 超时协程
// 串行查询相关
private Queue<Action> statusQueryQueue = new Queue<Action>(); // 状态查询队列
private bool isQueryingStatus = false; // 是否正在查询状态
// 工作模式设置后查询相关
private bool isWaitingForWorkModeQuery = false; // 是否正在等待工作模式查询响应
void Awake()
{
Instance = this;
}
async Task Start()
{
// 订阅蓝牙事件
SubscribeBluetoothEvents();
// 获取设备列表
await FetchDeviceList();
Init();
}
float waitLockTime=0;
void FixedUpdate()
{
if(!LockButtonPlane.activeSelf)
{
waitLockTime+=Time.deltaTime;
}
else
{
waitLockTime=0;
}
if(waitLockTime>=60)
LockButtonPlane.SetActive(true);
}
void OnApplicationPause(bool pause)
{
LockButtonPlane.SetActive(true);
}
void OnDestroy()
{
StopDeviceOnlineStatusPolling();
UnsubscribeBluetoothEvents();
StopAllCoroutines();
}
#region
private void SubscribeBluetoothEvents()
{
if (BluetoothManager.Instance != null)
{
BluetoothManager.Instance.OnConnectedSuccess += OnBluetoothConnected;
BluetoothManager.Instance.OnDisconnected += OnBluetoothDisconnected;
BluetoothManager.Instance.OnError += OnBluetoothError;
BluetoothManager.Instance.OnStopScan+=deviceState.StopScan;
BluetoothManager.Instance.OnStartScan+=deviceState.OnStartScan;
}
if (BLECommunicationManager.Instance != null)
{
// 订阅用户登录结果事件
BLECommunicationManager.Instance.OnUserLoginResult += OnUserLoginResult;
// 订阅设备状态事件
BLECommunicationManager.Instance.OnWorkModeSettingReceived += OnWorkModeReceived;
BLECommunicationManager.Instance.OnDeviceLockControlReceived += OnLockReceived;
BLECommunicationManager.Instance.OnScheduleTaskListReceived += OnScheduleTaskListReceived;
BLECommunicationManager.Instance.OnAngleControlReceived += OnAngleControlReceived;
BLECommunicationManager.Instance.OnDistanceControlReceived += OnDistanceControlReceived;
BLECommunicationManager.Instance.OnFillLightControlReceived += OnFillLightControlReceived;
//BLECommunicationManager.Instance.OnMillimeterWaveSettingReceived += OnMillimeterWaveReceived;
BLECommunicationManager.Instance.OnVisualDetectionSettingReceived += OnVisualDetectionReceived;
// 订阅蚊虫数据事件
BLECommunicationManager.Instance.OnMosquitoDataReceived += OnMosquitoDataReceived;
}
}
private void UnsubscribeBluetoothEvents()
{
if (BluetoothManager.Instance != null)
{
BluetoothManager.Instance.OnConnectedSuccess -= OnBluetoothConnected;
BluetoothManager.Instance.OnDisconnected -= OnBluetoothDisconnected;
BluetoothManager.Instance.OnError -= OnBluetoothError;
BluetoothManager.Instance.OnStopScan-=deviceState.StopScan;
BluetoothManager.Instance.OnStartScan-=deviceState.OnStartScan;
}
if (BLECommunicationManager.Instance != null)
{
// 取消订阅用户登录结果事件
BLECommunicationManager.Instance.OnUserLoginResult -= OnUserLoginResult;
BLECommunicationManager.Instance.OnDeviceLockControlReceived -= OnLockReceived;
BLECommunicationManager.Instance.OnWorkModeSettingReceived -= OnWorkModeReceived;
BLECommunicationManager.Instance.OnScheduleTaskListReceived -= OnScheduleTaskListReceived;
BLECommunicationManager.Instance.OnAngleControlReceived -= OnAngleControlReceived;
BLECommunicationManager.Instance.OnDistanceControlReceived -= OnDistanceControlReceived;
BLECommunicationManager.Instance.OnFillLightControlReceived -= OnFillLightControlReceived;
// BLECommunicationManager.Instance.OnMillimeterWaveSettingReceived -= OnMillimeterWaveReceived;
BLECommunicationManager.Instance.OnVisualDetectionSettingReceived -= OnVisualDetectionReceived;
// 取消订阅蚊虫数据事件
BLECommunicationManager.Instance.OnMosquitoDataReceived -= OnMosquitoDataReceived;
}
}
#endregion
#region
// 标记是否已完成蓝牙用户登录
private bool isBluetoothUserLoggedIn = false;
private void OnBluetoothConnected()
{
Debug.Log("[HomePageCtrl] 蓝牙连接成功");
hasBluetooth = true;
DataManager.Instance.hasBluetooth = true;
// 更新连接状态UI
pendingUIUpdates.Add(() =>
{
deviceState?.UpdateDeviceState(hasBluetooth, hasWifi);
// 先进行蓝牙用户登录,登录成功后再获取设备状态
StartCoroutine(BluetoothUserLoginThenQueryStatus());
});
}
/// <summary>
/// 蓝牙用户登录,登录成功后查询设备状态
/// </summary>
private IEnumerator BluetoothUserLoginThenQueryStatus()
{
LoadingUI.Show();
yield return new WaitForSeconds(0.5f);
// 获取用户ID
string username = DataManager.Instance?.userInfo?.id;
if (string.IsNullOrEmpty(username))
{
Debug.LogError("[HomePageCtrl] 蓝牙用户登录失败:用户未登录");
yield break;
}
Debug.Log($"[HomePageCtrl] 开始进行蓝牙用户登录,用户名: {username}");
isBluetoothUserLoggedIn = false;
// 调用蓝牙用户登录
BLECommunicationManager.Instance?.UserLogin(username, (response) =>
{
if (response.IsSuccess)
{
Debug.Log("[HomePageCtrl] 蓝牙用户登录成功");
isBluetoothUserLoggedIn = true;
}
else
{
Debug.LogError($"[HomePageCtrl] 蓝牙用户登录失败: {response.Status}");
}
});
// 等待登录结果最多3秒
float timeout = 3f;
float elapsed = 0f;
while (!isBluetoothUserLoggedIn && elapsed < timeout)
{
yield return new WaitForSeconds(0.1f);
elapsed += 0.1f;
}
if (isBluetoothUserLoggedIn)
{
Debug.Log("[HomePageCtrl] 蓝牙用户登录成功,获取锁定状态");
BLECommunicationManager.Instance.ReadDeviceLockControl();
}
else
{
Debug.LogWarning("[HomePageCtrl] 蓝牙用户登录超时3s重试");
yield return new WaitForSeconds(3);
StartCoroutine(BluetoothUserLoginThenQueryStatus());
}
}
/// <summary>
/// 用户登录结果回调
/// </summary>
private void OnUserLoginResult(UserLoginResponse response)
{
Debug.Log($"[HomePageCtrl] 收到用户登录结果: {response.Status}");
// 登录结果在 UserLogin 回调中处理,这里仅作日志记录
}
/// <summary>
/// 开始设备状态初始化
/// </summary>
private void StartDeviceStateInitialization()
{
isDeviceStateInitializing = true;
pendingStatusCount = TOTAL_STATUS_COUNT;
// 显示Loading阻止操作
LoadingUI.Show();
// 启动超时检测
if (statusQueryTimeoutCoroutine != null)
{
StopCoroutine(statusQueryTimeoutCoroutine);
}
statusQueryTimeoutCoroutine = StartCoroutine(StatusQueryTimeoutCoroutine());
Debug.Log($"[HomePageCtrl] 开始设备状态初始化,待接收状态数: {pendingStatusCount}");
}
/// <summary>
/// 状态查询超时协程
/// </summary>
private IEnumerator StatusQueryTimeoutCoroutine()
{
yield return new WaitForSeconds(statusQueryTimeout);
if (isDeviceStateInitializing)
{
Debug.LogWarning($"[HomePageCtrl] 设备状态查询超时,已接收 {TOTAL_STATUS_COUNT - pendingStatusCount}/{TOTAL_STATUS_COUNT} 个状态");
FinishDeviceStateInitialization();
}
}
Coroutine bluetoothDeviceInfoCoroutine = null;
/// <summary>
/// 完成设备状态初始化
/// </summary>
private void FinishDeviceStateInitialization()
{
isDeviceStateInitializing = false;
pendingStatusCount = 0;
// 隐藏Loading
LoadingUI.Hide();
// 停止超时协程
if (statusQueryTimeoutCoroutine != null)
{
StopCoroutine(statusQueryTimeoutCoroutine);
statusQueryTimeoutCoroutine = null;
}
bluetoothDeviceInfoCoroutine=StartCoroutine(CheckDeviceError());
Debug.Log("[HomePageCtrl] 设备状态初始化完成");
}
/// <summary>
/// 接收一个状态,减少待接收计数
/// </summary>
private void ReceiveStatus()
{
if (!isDeviceStateInitializing) return;
pendingStatusCount--;
Debug.Log($"[HomePageCtrl] 接收到状态,剩余: {pendingStatusCount}/{TOTAL_STATUS_COUNT}");
// 所有状态都接收完成
if (pendingStatusCount <= 0)
{
FinishDeviceStateInitialization();
}
}
private void OnBluetoothDisconnected(string address)
{
Debug.Log("[HomePageCtrl] 蓝牙断开连接");
hasBluetooth = false;
DataManager.Instance.hasBluetooth = false;
isBluetoothUserLoggedIn = false;
isQueryingStatus = false;
statusQueryQueue?.Clear();
UIManager.Instance?.ClearBackAction();
UIManager.Instance.OpenPage(UIManager.PageName.homePage, null, true);
if(bluetoothDeviceInfoCoroutine!=null)
{
StopCoroutine(bluetoothDeviceInfoCoroutine);
}
}
private void OnBluetoothError(string error)
{
Debug.LogError($"[HomePageCtrl] 蓝牙错误: {error}");
}
/// <summary>
/// 延迟查询设备状态
/// </summary>
private IEnumerator QueryDeviceStatusDelayed()
{
// 等待 500ms 确保连接稳定
yield return new WaitForSeconds(0.1f);
// 开始设备状态初始化显示Loading
StartDeviceStateInitialization();
// 串行查询设备状态
StartCoroutine(QueryAllDeviceStatusSequential());
}
/// <summary>
/// 串行查询所有设备状态(收到返回后再发送下一个)
/// </summary>
private IEnumerator QueryAllDeviceStatusSequential()
{
Debug.Log("[HomePageCtrl] 开始串行查询设备状态...");
// 清空队列
statusQueryQueue.Clear();
isQueryingStatus = true;
// 将查询请求加入队列
statusQueryQueue.Enqueue(() => { Debug.Log("[HomePageCtrl] 查询: 工作模式"); BLECommunicationManager.Instance?.ReadWorkMode(); });
statusQueryQueue.Enqueue(() => { Debug.Log("[HomePageCtrl] 查询: 定时任务"); BLECommunicationManager.Instance?.ReadScheduleTasks(); });
statusQueryQueue.Enqueue(() => { Debug.Log("[HomePageCtrl] 查询: 角度控制"); BLECommunicationManager.Instance?.ReadAngleControl(); });
statusQueryQueue.Enqueue(() => { Debug.Log("[HomePageCtrl] 查询: 距离控制"); BLECommunicationManager.Instance?.ReadDistanceControl(); });
statusQueryQueue.Enqueue(() => { Debug.Log("[HomePageCtrl] 查询: 补光灯控制"); BLECommunicationManager.Instance?.ReadFillLightControl(); });
statusQueryQueue.Enqueue(() => { Debug.Log("[HomePageCtrl] 查询: 视觉检测"); BLECommunicationManager.Instance?.ReadVisualDetectionSetting(); });
statusQueryQueue.Enqueue(OnWriteLanguageClick);
statusQueryQueue.Enqueue(OnWriteTimeClick);
// 依次执行查询
while (statusQueryQueue.Count > 0 && isQueryingStatus)
{
int pendingCountBefore = pendingStatusCount;
var query = statusQueryQueue.Dequeue();
query?.Invoke();
// 等待 200ms 确保请求发送完成
yield return new WaitForSeconds(0.2f);
// 等待响应最多2秒
float waitTime = 0f;
float maxWaitTime = 2f;
while (waitTime < maxWaitTime)
{
// 检查是否已接收到状态(通过 pendingStatusCount 减少来判断)
if (pendingStatusCount < pendingCountBefore)
{
Debug.Log($"[HomePageCtrl] 收到响应,继续下一个查询");
break;
}
yield return new WaitForSeconds(0.05f);
waitTime += 0.05f;
}
}
isQueryingStatus = false;
Debug.Log("[HomePageCtrl] 串行查询设备状态完成");
OnGetAllMosquitoDataClick();
}
/// <summary>
/// 查询所有设备状态(旧方法,已废弃)
/// </summary>
private void QueryAllDeviceStatus()
{
Debug.Log("[HomePageCtrl] 开始查询设备状态...");
// 查询工作模式
BLECommunicationManager.Instance?.ReadWorkMode();
// 查询硬件状态
BLECommunicationManager.Instance?.ReadHardwareStatus();
// 查询定时任务
BLECommunicationManager.Instance?.ReadScheduleTasks();
// 查询角度控制
BLECommunicationManager.Instance?.ReadAngleControl();
// 查询距离控制
BLECommunicationManager.Instance?.ReadDistanceControl();
// 查询补光灯控制
BLECommunicationManager.Instance?.ReadFillLightControl();
// 查询毫米波雷达设置
BLECommunicationManager.Instance?.ReadMillimeterWaveSetting();
// 查询视觉检测设置
BLECommunicationManager.Instance?.ReadVisualDetectionSetting();
}
#endregion
#region
// 当前工作模式
private WorkMode currentWorkMode = WorkMode.Standby;
/// <summary>
/// 设置工作模式
/// </summary>
/// <param name="mode">0:待机 1:扫描 2:消杀</param>
public async void SetWorkMode(int mode)
{
waitLockTime=0;
// 检查是否与当前模式相同
if ((int)currentWorkMode == mode)
{
Debug.Log($"[HomePageCtrl] 目标模式 {mode} 与当前模式相同,不执行切换");
return;
}
// WiFi模式
if (hasWifi && !hasBluetooth)
{
LoadingUI.Show();
bool success = await SetWorkModeByWifiAsync(mode);
LoadingUI.Hide();
if (success)
{
currentWorkMode = (WorkMode)mode;
deviceCtrl?.InitWrokMode(mode);
}
return;
}
// 检查蓝牙连接
if (!BluetoothManager.Instance.IsConnected)
{
Debug.LogWarning("[HomePageCtrl] 蓝牙未连接,无法切换工作模式");
LoadingUI.Hide();
return;
}
// 显示 Loading
LoadingUI.Show();
// 构建工作模式设置
WorkModeSetting setting = new WorkModeSetting
{
Mode = (WorkMode)mode
};
Debug.Log($"[HomePageCtrl] 正在设置工作模式: {setting.Mode}");
// 发送设置命令
BLECommunicationManager.Instance?.WriteWorkMode(setting, (success) =>
{
Loom.QueueOnMainThread(() =>
{
if (success)
{
Debug.Log($"[HomePageCtrl] 工作模式设置成功: {setting.Mode}");
// 更新当前模式
currentWorkMode = setting.Mode;
// 更新 UI
pendingUIUpdates.Add(() =>
{
deviceCtrl?.InitWrokMode(mode);
});
}
else
{
Debug.LogError("[HomePageCtrl] 工作模式设置失败");
LoadingUI.Hide();
}
});
});
}
public async Task<bool> SetWorkModeByWifiAsync(int mode)
{
var setting = new WorkModeSetting { Mode = (WorkMode)mode };
bool success = await SendBleCommandByWifiAsync(
BLEConstants.CMD_WORK_MODE_SETTING, setting.ToBytes());
if (success)
{
Debug.Log($"[HomePageCtrl] WiFi工作模式设置成功: {(WorkMode)mode}");
}
return success;
}
private void OnLockReceived(DeviceLockControl setting)
{
Debug.Log($"[HomePageCtrl] 锁定状态: {setting.IsLocked}");
pendingUIUpdates.Add(() =>
{
LoadingUI.Hide();
if (setting.IsLocked)
{
deviceCtrl.InitDeviceControl(false);
BLECommunicationManager.Instance.ReadScheduleTasks();
}
else
{
deviceCtrl.InitDeviceControl(true);
StartCoroutine(QueryDeviceStatusDelayed());
}
});
}
private void OnWorkModeReceived(WorkModeSetting setting)
{
Debug.Log($"[HomePageCtrl] 收到工作模式: {setting.Mode}");
ReceiveStatus();
// 更新当前工作模式
currentWorkMode = setting.Mode;
// 如果是工作模式设置后的查询响应,重置等待标志
if (isWaitingForWorkModeQuery)
{
isWaitingForWorkModeQuery = false;
Debug.Log("[HomePageCtrl] 工作模式查询响应已处理");
}
pendingUIUpdates.Add(() =>
{
deviceCtrl?.InitWrokMode((int)setting.Mode);
});
}
private void OnScheduleTaskListReceived(ScheduleTaskListResponse response)
{
// 如果设置页面正在处理,跳过主页处理
if (ScheduleSettingPage.IsSettingPageActive())
{
Debug.Log("[HomePageCtrl] 设置页面正在处理定时任务列表,跳过主页更新");
return;
}
if (response.IsSuccess)
{
Debug.Log($"[HomePageCtrl] 收到定时任务列表: {response.Tasks.Length} 个任务");
ReceiveStatus();
pendingUIUpdates.Add(() =>
{
deviceSchedule?.Init(response.Tasks);
});
}
else
{
ReceiveStatus();
}
scheduleSettingButton.interactable = true;
}
private void OnAngleControlReceived(AngleControl control)
{
// 如果设置页面正在处理,跳过主页处理
if (FovSettingPage.IsSettingPageActive())
{
Debug.Log("[HomePageCtrl] 设置页面正在处理角度控制,跳过主页更新");
return;
}
Debug.Log($"[HomePageCtrl] 收到角度控制: {control.ActualAngle}°");
ReceiveStatus();
pendingUIUpdates.Add(() =>
{
// 使用实际角度值
int fov = (int)control.ActualAngle;
deviceCtrl?.InitFovText(fov);
});
}
/// <summary>
/// 刷新角度控制设置供FovSettingPage调用
/// </summary>
public void RefreshAngleControl()
{
Debug.Log("[HomePageCtrl] 刷新角度控制设置");
if (hasWifi && !hasBluetooth)
{
var config = DataManager.Instance.deviceConfig;
float fov = (config?.fov_angle ?? 0) * 0.1f;
pendingUIUpdates.Add(() => deviceCtrl?.InitFovText((int)fov));
return;
}
BLECommunicationManager.Instance?.ReadAngleControl();
}
private void OnDistanceControlReceived(DistanceControl control)
{
// 如果设置页面正在处理,跳过主页处理
if (LensSettingPage.IsSettingPageActive())
{
Debug.Log("[HomePageCtrl] 设置页面正在处理距离控制,跳过主页更新");
return;
}
// 单位是 0.1m,需要除以 10 转换为实际米数
float detectionDistance = control.DetectionDistance / 10f;
float aimDistance = control.AimDistance / 10f;
Debug.Log($"[HomePageCtrl] 收到距离控制: 检测={detectionDistance}m, 瞄准={aimDistance}m");
ReceiveStatus();
pendingUIUpdates.Add(() =>
{
// 使用检测距离,单位 0.1m 转实际米数保留1位小数
deviceCtrl?.InitLensText(detectionDistance, DataManager.Instance.userInfo.unit_system); // 0 = 米
});
}
/// <summary>
/// 刷新lens设置
/// </summary>
public void RefreshLensControl()
{
Debug.Log("[HomePageCtrl] 刷新距离控制设置");
if (hasWifi && !hasBluetooth)
{
var config = DataManager.Instance.deviceConfig;
float distance = (config?.detection_distance ?? 0) * 0.1f;
pendingUIUpdates.Add(() => deviceCtrl?.InitLensText(distance, DataManager.Instance.userInfo.unit_system));
return;
}
BLECommunicationManager.Instance?.ReadDistanceControl();
}
private void OnFillLightControlReceived(FillLightControl control)
{
// 如果设置页面正在处理,跳过主页处理
if (LightSettingPage.IsSettingPageActive())
{
Debug.Log("[HomePageCtrl] 设置页面正在处理补光灯控制,跳过主页更新");
return;
}
Debug.Log($"[HomePageCtrl] 收到补光灯控制: {control.Enable}");
ReceiveStatus();
pendingUIUpdates.Add(() =>
{
deviceCtrl?.InitLightText(control.Enable);
});
}
public void RefreshLightControl()
{
Debug.Log("[HomePageCtrl] 刷新补光灯控制设置");
if (hasWifi && !hasBluetooth)
{
var config = DataManager.Instance.deviceConfig;
pendingUIUpdates.Add(() => deviceCtrl?.InitLightText(config?.fill_light_enable ?? false));
return;
}
BLECommunicationManager.Instance?.ReadFillLightControl();
}
// private void OnMillimeterWaveReceived(MillimeterWaveSetting setting)
// {
// Debug.Log($"[HomePageCtrl] 收到毫米波设置: {setting.Enable}");
// ReceiveStatus();
// pendingUIUpdates.Add(() =>
// {
// // 更新安全状态 - 毫米波
// // 注意:需要结合 VisualDetectionSetting 一起判断
// });
// }
private void OnVisualDetectionReceived(VisualDetectionSetting setting)
{
// 如果设置页面正在处理,跳过主页处理
if (SafetySettingPage.IsSettingPageActive())
{
Debug.Log("[HomePageCtrl] 设置页面正在处理视觉检测设置,跳过主页更新");
return;
}
Debug.Log($"[HomePageCtrl] 收到视觉检测设置: {setting.Enable}");
ReceiveStatus();
pendingUIUpdates.Add(() =>
{
deviceCtrl?.InitSafeText(setting.Enable);
});
}
#endregion
/// <summary>
/// WiFi模式下从设备配置初始化首页UI
/// </summary>
private void InitDeviceUIFromConfig()
{
var config = DataManager.Instance.deviceConfig;
if (config == null) return;
bool isLocked = config.is_locked ?? false;
Debug.Log($"[HomePageCtrl] WiFi初始化设备锁定状态={isLocked}");
if (isLocked)
{
deviceCtrl?.InitDeviceControl(false);
}
else
{
deviceCtrl?.InitDeviceControl(true);
// 初始化工作模式
WorkMode workMode = DeviceConfig.ParseServerEnum(config.work_mode, WorkMode.Standby);
currentWorkMode = workMode;
deviceCtrl?.InitWrokMode((int)workMode);
// 初始化FOV
float fov = (config.fov_angle ?? 0) * 0.1f;
deviceCtrl?.InitFovText((int)fov);
// 初始化距离
float distance = (config.detection_distance ?? 0) * 0.1f;
deviceCtrl?.InitLensText(distance, DataManager.Instance.userInfo.unit_system);
// 初始化补光灯
deviceCtrl?.InitLightText(config.fill_light_enable ?? false);
// 初始化安全设置
deviceCtrl?.InitSafeText(config.visual_detect_enable ?? false);
}
// 初始化定时任务
var scheduleTasks = new List<ScheduleTask>();
foreach (var d in DataManager.Instance.scheduleTaskDatas)
{
// 过滤开始时间和结束时间都为0的无效任务
bool isInvalid = d.start_hour == 0 && d.start_minute == 0 &&
d.end_hour == 0 && d.end_minute == 0;
if (isInvalid) continue;
scheduleTasks.Add(new ScheduleTask
{
TaskId = d.task_id,
Enabled = d.enabled,
StartHour = d.start_hour,
StartMinute = d.start_minute,
EndHour = d.end_hour,
EndMinute = d.end_minute,
Mode = (ScheduleTaskMode)System.Enum.Parse(typeof(ScheduleTaskMode), d.mode, true),
Repeat = d.repeat_mask
});
}
if (scheduleTasks.Count > 0)
{
deviceSchedule?.Init(scheduleTasks.ToArray());
}
else
{
deviceSchedule?.DisplayNoSchedule();
}
}
public async Task Init()
{
if (DataManager.Instance.userInfo.device_count == 0)
{
noDevicePage.SetActive(true);
normalPage.SetActive(false);
selectedDevice = null;
selectDeviceButton.gameObject.SetActive(false);
return;
}
else
{
if (DataManager.Instance.userInfo.exam_completed == false)
{
UIManager.Instance.OpenMainPage(UIManager.PageName.safetylearningPage);
}
noDevicePage.SetActive(false);
normalPage.SetActive(true);
}
if (DataManager.Instance.selectedDeviceMac == "")
{
if(OwnedDevices.Count>0)
{
selectedDevice = OwnedDevices[0];
}
else
{
selectedDevice=SharedDevices[0];
}
DataManager.Instance.selectedDeviceMac = selectedDevice.ble_mac;
DataManager.Instance.SavaSelectedDeviceMac(selectedDevice.ble_mac);
}
else
{
selectedDevice = OwnedDevices.Find(x => x.ble_mac == DataManager.Instance.selectedDeviceMac);
if (selectedDevice == null)
{
selectedDevice = SharedDevices.Find(x => x.ble_mac == DataManager.Instance.selectedDeviceMac);
if (selectedDevice == null)
{
if (OwnedDevices.Count > 0)
{
selectedDevice = OwnedDevices[0];
}
else
{
selectedDevice = SharedDevices[0];
}
DataManager.Instance.selectedDeviceMac = selectedDevice.ble_mac;
DataManager.Instance.SavaSelectedDeviceMac(selectedDevice.ble_mac);
}
Debug.Log("当前选中设备:" + DataManager.Instance.selectedDeviceMac);
}
}
hasWifi=await GetDeviceOnlineStatus();
hasBluetooth = BluetoothManager.Instance.ChangeAimMac(selectedDevice.ble_mac);
selectDeviceButton.GetComponentInChildren<Text>().text = selectedDevice.device_name;
selectDeviceButton.gameObject.SetActive(true);
// 先初始化所有 UI 为未连接状态
ResetAllDeviceUI();
InitDeviceState();
deviceState?.UpdateDeviceState(hasBluetooth, hasWifi);
// 始终启动WiFi在线状态轮询
StartDeviceOnlineStatusPolling();
// 如果蓝牙已连接,立即查询状态
if (hasBluetooth)
{
deviceCtrl?.InitDeviceControl(false);
BLECommunicationManager.Instance.ReadDeviceLockControl();
scheduleSettingButton.interactable = true;
moreSettingButton.interactable = true;
}
else if(hasWifi)
{
deviceCtrl?.InitDeviceControl(false);
await DataManager.Instance.GetDeviceConfig(selectedDevice.ble_mac);
await DataManager.Instance.GetScheduleTasks(selectedDevice.device_sn);
scheduleSettingButton.interactable = true;
moreSettingButton.interactable = true;
InitDeviceUIFromConfig();
}
else
{
deviceCtrl?.InitDeviceControl(false);
scheduleSettingButton.interactable = false;
moreSettingButton.interactable = false;
}
GetLastRecords();
ShowCharts();
GetMessageTypeList();
// StartCoroutine(GetLastMosquitoData());
DataManager.Instance.selectedDevice = selectedDevice;
DataManager.Instance.OwnedDevices=OwnedDevices;
DataManager.Instance.SharedDevices=SharedDevices;
}
/// <summary>
/// 重置所有设备 UI 为未连接状态
/// </summary>
private void ResetAllDeviceUI()
{
Debug.Log("[HomePageCtrl] 重置所有 UI 为未连接状态");
// 重置工作模式为未连接
deviceCtrl?.InitWrokMode(-1);
// 重置 FOV
deviceCtrl?.InitFovText(0);
// 重置距离
deviceCtrl?.InitLensText(0f, 0);
// 重置补光灯
deviceCtrl?.InitLightText(false);
// 重置安全状态
deviceCtrl?.InitSafeText(false);
// 重置定时任务显示
deviceSchedule?.DisplayNoSchedule();
scheduleSettingButton.onClick.RemoveAllListeners();
scheduleSettingButton.onClick.AddListener(() =>
{
ShowScheduleSettingPage();
});
scheduleSettingButton.interactable = false;
}
/// <summary>
/// 获取用户设备列表
/// </summary>
public async Task FetchDeviceList()
{
LoadingUI.Show();
try
{
Debug.Log("[HomePageCtrl] 开始获取设备列表...");
// 构建带 user_id 参数的 URL
string userId = DataManager.Instance?.userInfo?.id;
if (string.IsNullOrEmpty(userId))
{
Debug.LogError("[HomePageCtrl] 获取设备列表失败: 用户未登录");
LoadingUI.Hide();
return;
}
string url = $"/api/v1/device/user/list?user_id={userId}";
var response = await NetworkCtrl.Instance.Get<DeviceListResponse>(url);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
// 更新设备列表
OwnedDevices = data.data.owned_devices ?? new List<Kill.Managers.DeviceInfo>();
foreach (var device in OwnedDevices)
{
device.owner_id = DataManager.Instance.userInfo.id;
if(string.IsNullOrEmpty(device.ble_mac))
{
device.ble_mac = device.device_sn;
}
}
SharedDevices = data.data.shared_devices ?? new List<Kill.Managers.DeviceInfo>();
foreach (var device in SharedDevices)
{
if(string.IsNullOrEmpty(device.ble_mac))
{
device.ble_mac = device.device_sn;
}
}
Debug.Log($"[HomePageCtrl] 获取设备列表成功: 自有设备={OwnedDevices.Count}, 共享设备={SharedDevices.Count}");
DataManager.Instance.userInfo.device_count = OwnedDevices.Count + SharedDevices.Count;
},
onError: null
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError($"[HomePageCtrl] 获取设备列表异常: {ex.Message}");
}
}
void Update()
{
// 执行所有挂起的UI更新
if (pendingUIUpdates.Count > 0)
{
foreach (var update in pendingUIUpdates)
{
update?.Invoke();
}
pendingUIUpdates.Clear();
}
}
public void ConnectDevice()
{
if (!CheckSafetylearning())
{
UIManager.Instance.OpenPage(UIManager.PageName.safetylearningPage);
return;
}
UIManager.Instance.OpenPage(UIManager.PageName.connectDevicePage);
}
public bool CheckSafetylearning()
{
bool isPassed = false;
isPassed = DataManager.Instance.userInfo.exam_completed;
return isPassed;
}
public void InitDeviceState()
{
// 初始化设备状态UI
deviceState?.UpdateDeviceState(hasBluetooth, hasWifi);
}
public void ShowDeviceList()
{
selectDevicePage.SetActive(true);
selectDevicePage.GetComponent<HomePageDevicePage>().InitDeviceList(OwnedDevices, SharedDevices, selectedDevice);
UIManager.Instance.RegisterBackAction(() =>
{
selectDevicePage.GetComponent<HomePageDevicePage>().ClosePage();
});
}
public GameObject fovSettingPagePrefab;
public void ShowFovSettingPage()
{
waitLockTime=0;
if (fovSettingPagePrefab == null)
{
Debug.LogError("[HomePageCtrl] 未设置FOV设置页面预制体");
return;
}
GameObject fovSettingPage = Instantiate(fovSettingPagePrefab, transform);
fovSettingPage.SetActive(true);
UIManager.Instance.RegisterBackAction(() =>
{
fovSettingPage.GetComponent<FovSettingPage>().OnCancelButtonClick();
});
}
public GameObject lensSettingPagePrefab;
public void ShowLensSettingPage()
{
waitLockTime=0;
if (lensSettingPagePrefab == null)
{
Debug.LogError("[HomePageCtrl] 未设置lens设置页面预制体");
return;
}
GameObject lensSettingPage = Instantiate(lensSettingPagePrefab, transform);
lensSettingPage.SetActive(true);
UIManager.Instance.RegisterBackAction(() =>
{
lensSettingPage.GetComponent<LensSettingPage>().OnCancelButtonClick();
});
}
public GameObject lightSettingPagePrefab;
public void ShowLightSettingPage()
{
waitLockTime=0;
if (lightSettingPagePrefab == null)
{
Debug.LogError("[HomePageCtrl] 未设置light设置页面预制体");
return;
}
GameObject lightSettingPage = Instantiate(lightSettingPagePrefab, transform);
lightSettingPage.SetActive(true);
UIManager.Instance.RegisterBackAction(() =>
{
lightSettingPage.GetComponent<LightSettingPage>().ClosePage();
});
}
public GameObject safetySettingPagePrefab;
public void ShowSafetySettingPage()
{
waitLockTime=0;
if (safetySettingPagePrefab == null)
{
Debug.LogError("[HomePageCtrl] 未设置safetySettingPage预制体");
return;
}
GameObject safetySettingPage = Instantiate(safetySettingPagePrefab, transform);
safetySettingPage.SetActive(true);
UIManager.Instance.RegisterBackAction(() =>
{
safetySettingPage.GetComponent<SafetySettingPage>().ClosePage();
});
}
public void ShowScheduleSettingPage()
{
waitLockTime=0;
if (scheduleSettingPrefab == null)
{
Debug.LogError("[HomePageCtrl] 未设置scheduleSettingPage预制体");
return;
}
GameObject scheduleSettingPage = Instantiate(scheduleSettingPrefab, transform);
scheduleSettingPage.SetActive(true);
// 注册页面关闭回调,更新主页定时任务显示
var schedulePage = scheduleSettingPage.GetComponent<ScheduleSettingPage>();
if (schedulePage != null)
{
schedulePage.OnPageClosed = () =>
{
// 重新读取定时任务更新主页显示
if (hasWifi && !hasBluetooth)
{
_ = RefreshHomeScheduleFromWifi();
}
else
{
BLECommunicationManager.Instance?.ReadScheduleTasks();
}
};
}
UIManager.Instance.RegisterBackAction(() =>
{
scheduleSettingPage.GetComponent<ScheduleSettingPage>().ClosePage();
});
}
public Button moreSettingButton;
public void EnterMoreSettingPage()
{
waitLockTime=0;
DataManager.Instance.selectedDevice = selectedDevice;
UIManager.Instance.OpenPage(UIManager.PageName.deviceInfoPage);
}
public void EnterRankingPage()
{
UIManager.Instance.OpenPage(UIManager.PageName.rankPage);
}
public void EnterSelfPage()
{
UIManager.Instance.OpenPage(UIManager.PageName.selfPage);
}
public MessageTypeListPage messagePagePrefab;
public void EnterMessagePage()
{
waitLockTime=0;
Instantiate(messagePagePrefab,transform);
}
public void EnterVideoPage()
{
waitLockTime=0;
UIManager.Instance.OpenPage(UIManager.PageName.videoPage);
}
public async void SetLock(bool ison)
{
waitLockTime=0;
if (hasBluetooth)
{
BLECommunicationManager.Instance.WriteDeviceLockControl(!ison, (success) =>
{
Loom.QueueOnMainThread(() =>
{
if (ison)
{
DeviceLockControl deviceLockControl = new DeviceLockControl();
deviceLockControl.IsLocked = false;
OnLockReceived(deviceLockControl);
LoadingUI.Hide();
}
else
{
deviceCtrl.InitDeviceControl(false);
LoadingUI.Hide();
}
});
});
}
else if (hasWifi)
{
// WiFi模式下锁定/解锁设备
try
{
var lockControl = new DeviceLockControl { IsLocked = !ison };
byte[] lockBytes = lockControl.ToBytes();
bool success = await SendBleCommandByWifiAsync(BLEConstants.CMD_DEVICE_LOCK, lockBytes);
if (success)
{
Debug.Log($"[HomePageCtrl] WiFi锁定设置成功: {(lockControl.IsLocked ? "" : "")}");
if (lockControl.IsLocked)
{
deviceCtrl?.InitDeviceControl(false);
}
else
{
deviceCtrl?.InitDeviceControl(true);
InitDeviceUIFromConfig();
}
}
}
finally
{
LoadingUI.Hide();
}
}
else
{
LoadingUI.Hide();
ToastUI.Show("100081");
}
}
IEnumerator CheckDeviceError()
{
while(hasBluetooth)
{
GetDeviceStatus();
yield return new WaitForSeconds(30);
}
}
int waitTime = 0;
IEnumerator GetLastMosquitoData()
{
while (true)
{
yield return new WaitForSeconds(1);
waitTime++;
if (waitTime==50)
{
OnGetAllMosquitoDataClick();
}
if(waitTime==100)
{
waitTime=0;
GetLastRecords();
ShowCharts();
GetMessageTypeList();
}
}
}
public Button errorTipButton;
public GameObject deiviceErrorTip;
public void GetDeviceStatus()
{
List<string> errorlist = new List<string>();
BLECommunicationManager.Instance.ReadHardwareStatus((status) =>
{
Loom.QueueOnMainThread(() =>
{
bool hasError = false;
if (status.TemperatureError != 0)
{
hasError = true;
string error = LanguageManager.Instance.GetLanguage("100228");
if (status.TemperatureError == 1)
{
error += LanguageManager.Instance.GetLanguage("100229");
}
else
{
error += LanguageManager.Instance.GetLanguage("100230");
}
}
if (status.MotorError != 0)
{
hasError = true;
string error = LanguageManager.Instance.GetLanguage("100231");
if (status.MotorError == 1)
{
error += LanguageManager.Instance.GetLanguage("100232");
}
else
{
error += LanguageManager.Instance.GetLanguage("100233");
}
errorlist.Add(error);
}
if (status.LaserError != 0)
{
hasError = true;
string error = LanguageManager.Instance.GetLanguage("100234");
if (status.LaserError == 1)
{
error += LanguageManager.Instance.GetLanguage("100232");
}
else if (status.LaserError == 2)
{
error += LanguageManager.Instance.GetLanguage("100236");
}
else
{
error += LanguageManager.Instance.GetLanguage("100235");
}
errorlist.Add(error);
}
if (status.VisionError != 0)
{
hasError = true;
string error = LanguageManager.Instance.GetLanguage("100237");
error += LanguageManager.Instance.GetLanguage("100232");
errorlist.Add(error);
}
if (status.AccelerometerError != 0)
{
hasError = true;
string error = LanguageManager.Instance.GetLanguage("100239");
error += LanguageManager.Instance.GetLanguage("100232");
errorlist.Add(error);
}
if (status.MillimeterWaveError != 0)
{
hasError = true;
string error = LanguageManager.Instance.GetLanguage("100240");
error += LanguageManager.Instance.GetLanguage("100232");
errorlist.Add(error);
}
if (status.LidarError != 0)
{
hasError = true;
string error = LanguageManager.Instance.GetLanguage("100241");
error += LanguageManager.Instance.GetLanguage("100232");
errorlist.Add(error);
}
errorTipButton.gameObject.SetActive(hasError);
string fullerror = "";
int index = 1;
foreach (string e in errorlist)
{
fullerror += $"{index}.{e}/n";
}
deiviceErrorTip.GetComponentInChildren<Text>().text=fullerror;
});
});
}
public Text lastRecordTimeTexts;
public async void GetLastRecords()
{
waitTime=0;
LoadingUI.Show();
string url = $"/api/v1/stats/device/records?device_sn={selectedDevice.ble_mac}&type=1&page=1&page_size=1";
var response = await NetworkCtrl.Instance.Get<RecordDataListResponse>(url);
LoadingUI.Hide();
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
if (data.data.records != null && data.data.records.Count > 0)
{
RecordData record = data.data.records[0];
lastRecordTimeTexts.text=$"<b>{record.time:HH:mm}</b> <size=30>{record.time:yyyy/MM/dd}</size>";
}
else
{
lastRecordTimeTexts.text = "--";
}
},
onError: null
);
}
public HomePageChartsCtrl homePageChartsCtrl;
public void ShowCharts()
{
waitTime = 0;
homePageChartsCtrl.Init();
}
List<MosquitoData> mosquitoDatas;
int aimMosquitoDataCount=0;
Coroutine waitToPostMosquitoDatas=null;
private void OnMosquitoDataReceived(MosquitoData mosquitoData)
{
DateTime now=DateTime.Now;
mosquitoDatas.Add(mosquitoData);
if(waitToPostMosquitoDatas!=null)
StopCoroutine(waitToPostMosquitoDatas);
if(mosquitoDatas.Count>=aimMosquitoDataCount&&aimMosquitoDataCount>0)
{
LoadingUI.Hide();
PostMosquitoDatas();
aimMosquitoDataCount=0;
waitToPostMosquitoDatas=null;
}
else if(mosquitoDatas.Count>0)
{
waitToPostMosquitoDatas=StartCoroutine(WaitToPostMosquitoDatas());
}
}
IEnumerator WaitToPostMosquitoDatas()
{
yield return new WaitForSeconds(2);
PostMosquitoDatas();
LoadingUI.Hide();
}
async void PostMosquitoDatas()
{
List<PostRecordData> postRecordDatas=new List<PostRecordData>();
foreach(var a in mosquitoDatas)
{
var b=new PostRecordData
{
device_sn=selectedDevice.ble_mac,
record_time=a.GetTimeString(),
angle=a.GetActualAngle(),
distance=a.GetActualDis()
};
postRecordDatas.Add(b);
}
Debug.Log("发送灭蚊数据:"+JsonUtility.ToJson(postRecordDatas));
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/stats/device/records", postRecordDatas);
ResponseCodeHandler.HandleResponse(response, null, null);
}
/// <summary>
/// 获取所有蚊虫数据 (0xA4)
/// 流程1.查询数量 -> 2.请求数据 -> 3.接收通知
/// </summary>
private void OnGetAllMosquitoDataClick()
{
LoadingUI.Show();
// 步骤1: 查询蚊虫数据数量
BLECommunicationManager.Instance.ReadMosquitoDataCount((count) =>
{
Loom.QueueOnMainThread(() =>
{
if (count.Count == 0)
{
Debug.Log("设备中没有蚊虫数据");
LoadingUI.Hide();
return;
}
Debug.Log($"检测到 {count.Count} 条蚊虫数据,正在请求...");
// 步骤2: 请求所有蚊虫数据
BLECommunicationManager.Instance.RequestMosquitoData(count.Count, (success) =>
{
Loom.QueueOnMainThread(() =>
{
if (success)
{
Debug.Log($"已请求 {count.Count} 条蚊虫数据,等待接收...");
mosquitoDatas=new List<MosquitoData>();
aimMosquitoDataCount=(int)count.Count;
}
else
{
Debug.Log("蚊虫数据请求失败");
LoadingUI.Hide();
}
});
});
});
});
}
/// <summary>
/// 写入语言设置
/// </summary>
private void OnWriteLanguageClick()
{
bool isChinese = LanguageManager.Instance.languageType == LanguageManager.LanguageType.Chinese;
BLECommunicationManager.Instance.WriteLanguageSetting(isChinese, (success) =>
{
Loom.QueueOnMainThread(() =>
{
ReceiveStatus();
});
});
}
/// <summary>
/// 写入时间设置
/// </summary>
private void OnWriteTimeClick()
{
TimeSetting timeSetting = new TimeSetting();
timeSetting.SetTime(DateTime.Now);
BLECommunicationManager.Instance.WriteTimeSetting(timeSetting, (success) =>
{
Loom.QueueOnMainThread(() =>
{
ReceiveStatus();
});
});
}
public GameObject tipPoint;
public async Task GetMessageTypeList()
{
LoadingUI.Show();
var response = await NetworkCtrl.Instance.Get<MessageTypeDataListResponse>("/api/v1/notifications/unread-count");
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
if(data.data.announcement>0||data.data.device>0||data.data.warning>0)
{
tipPoint.SetActive(true);
}
else
{
tipPoint.SetActive(false);
}
},(code,message)=>{tipPoint.SetActive(false);}
);
LoadingUI.Hide();
}
/// <summary>
/// 查询设备在线状态
/// </summary>
public async Task<bool> GetDeviceOnlineStatus()
{
if (selectedDevice == null || string.IsNullOrEmpty(selectedDevice.ble_mac))
{
Debug.LogWarning("[HomePageCtrl] 未选中设备");
return false;
}
var tcs = new TaskCompletionSource<bool>();
var response = await NetworkCtrl.Instance.Get<DeviceOnlineResponse>(
"/api/v1/device/online",
new Dictionary<string, string> { { "mac", selectedDevice.ble_mac } }
);
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log($"[HomePageCtrl] 设备在线状态: {data.data}");
tcs.TrySetResult(data.data);
DataManager.Instance.hasWifi=data.data;
},
onError: (code, msg) =>
{
Debug.LogError($"[HomePageCtrl] 查询设备在线状态失败: {msg}");
tcs.TrySetResult(false);
}
);
return await tcs.Task;
}
/// <summary>
/// 启动设备在线状态轮询始终运行后台检测WiFi状态变化
/// </summary>
private async void StartDeviceOnlineStatusPolling()
{
if (isPollingOnline) return;
isPollingOnline = true;
stopPolling = false;
while (!stopPolling && selectedDevice != null)
{
await System.Threading.Tasks.Task.Delay(30000);
if (stopPolling || selectedDevice == null)
break;
// 查询WiFi在线状态
bool wasOnline = hasWifi;
bool online = await GetDeviceOnlineStatus();
if (stopPolling) break;
hasWifi = online;
DataManager.Instance.hasWifi = online;
if (!online && !hasBluetooth)
{
// WiFi和蓝牙都断开
if (wasOnline)
{
Debug.Log("[HomePageCtrl] 设备WiFi离线");
pendingUIUpdates.Add(() =>
{
deviceState?.UpdateDeviceState(hasBluetooth, hasWifi);
});
}
}
else if (online && !wasOnline && !hasBluetooth)
{
// WiFi刚上线且没有蓝牙连接 → 初始化UI
Debug.Log("[HomePageCtrl] 设备WiFi上线初始化UI");
await DataManager.Instance.GetDeviceConfig(selectedDevice.ble_mac);
if (stopPolling) break;
await DataManager.Instance.GetScheduleTasks(selectedDevice.device_sn);
if (stopPolling) break;
ScheduleUIUpdate(() =>
{
scheduleSettingButton.interactable = true;
moreSettingButton.interactable = true;
deviceState?.UpdateDeviceState(hasBluetooth, hasWifi);
InitDeviceUIFromConfig();
});
}
else if (online && wasOnline)
{
// WiFi持续在线正常更新UI
pendingUIUpdates.Add(() =>
{
deviceState?.UpdateDeviceState(hasBluetooth, hasWifi);
});
}
}
isPollingOnline = false;
}
/// <summary>
/// 停止设备在线状态轮询(切换设备或销毁时调用)
/// </summary>
private void StopDeviceOnlineStatusPolling()
{
stopPolling = true;
isPollingOnline = false;
}
private void ScheduleUIUpdate(Action action)
{
pendingUIUpdates.Add(action);
}
/// <summary>
/// 从WiFi刷新主页定时任务显示
/// </summary>
private async Task RefreshHomeScheduleFromWifi()
{
await DataManager.Instance.GetScheduleTasks(selectedDevice.ble_mac);
var tasks = new List<ScheduleTask>();
foreach (var d in DataManager.Instance.scheduleTaskDatas)
{
// 过滤开始时间和结束时间都为0的无效任务
bool isInvalid = d.start_hour == 0 && d.start_minute == 0 &&
d.end_hour == 0 && d.end_minute == 0;
if (isInvalid) continue;
tasks.Add(new ScheduleTask
{
TaskId = d.task_id,
Enabled = d.enabled,
StartHour = d.start_hour,
StartMinute = d.start_minute,
EndHour = d.end_hour,
EndMinute = d.end_minute,
Mode = (ScheduleTaskMode)System.Enum.Parse(typeof(ScheduleTaskMode), d.mode, true),
Repeat = d.repeat_mask
});
}
pendingUIUpdates.Add(() =>
{
if (tasks.Count > 0)
deviceSchedule?.Init(tasks.ToArray());
else
deviceSchedule?.DisplayNoSchedule();
});
}
/// <summary>
/// 通过WiFi发送BLE指令到设备使用共通错误处理
/// </summary>
public async Task<bool> SendBleCommandByWifiAsync(byte command, byte[] data)
{
byte[] commandBytes = BLECommunicationManager.Instance.GetCommandBytes(
command, BLEConstants.RW_WRITE, data);
string commandHex = BitConverter.ToString(commandBytes).Replace("-", "");
var requestData = new DeviceControlRequest
{
device_sn = selectedDevice.ble_mac,
command = commandHex
};
var response = await NetworkCtrl.Instance.Post<DeviceControlResponse>(
"/api/v1/device/command", requestData);
if (response == null || !response.IsSuccess)
{
Debug.LogError($"[HomePageCtrl] WiFi命令发送失败(0x{command:X2}): 网络错误");
ToastUI.Show("100292");
return false;
}
var resData = response.Data?.data;
if (resData != null && resData.success)
{
return true;
}
Debug.LogError($"[HomePageCtrl] WiFi命令发送失败(0x{command:X2}): {resData?.message ?? ""}");
ToastUI.Show("100292");
return false;
}
/// <summary>
/// 刷新安全设置UI
/// </summary>
public void RefreshSafetyUI()
{
pendingUIUpdates.Add(() =>
{
deviceState?.UpdateDeviceState(hasBluetooth, hasWifi);
});
}
/// <summary>
/// 通过WiFi加载定时任务
/// </summary>
public async void LoadScheduleTasks()
{
await DataManager.Instance.GetScheduleTasks(selectedDevice.ble_mac);
}
/// <summary>
/// 通过WiFi保存定时任务与BLE WriteScheduleTasks协议一致每任务7字节不含TaskId
/// </summary>
public async Task SaveScheduleTasksAsync(List<ScheduleTask> tasks)
{
if (tasks == null || tasks.Count == 0)
{
Debug.LogWarning("[HomePageCtrl] 定时任务列表为空");
return;
}
// 每条任务7字节不含TaskId与BLE WriteScheduleTasks保持一致
byte[] data = new byte[tasks.Count * 7];
for (int i = 0; i < tasks.Count; i++)
{
byte[] taskBytes = tasks[i].ToBytesWithoutTaskId();
Array.Copy(taskBytes, 0, data, i * 7, 7);
}
bool success = await SendBleCommandByWifiAsync(
BLEConstants.CMD_SCHEDULE_TASK, data);
if (success)
{
Debug.Log($"[HomePageCtrl] WiFi定时任务保存成功共 {tasks.Count} 条");
}
// 失败时 SendBleCommandByWifiAsync 已显示 Toast "100292"
}
}
}