From c8192fe9a55e42f24d61c9a898deb53100c3c2e3 Mon Sep 17 00:00:00 2001 From: Lufaneng Date: Sun, 15 Feb 2026 11:08:48 +0800 Subject: [PATCH] 1 --- .../ets/pages/components/ManualControl.ets | 2 + .../pages/components/ParameterSettings.ets | 67 +++++++++++++++++-- entry/src/main/ets/utils/M9zService.ets | 57 +++++++++++++++- 3 files changed, 120 insertions(+), 6 deletions(-) diff --git a/entry/src/main/ets/pages/components/ManualControl.ets b/entry/src/main/ets/pages/components/ManualControl.ets index 82baebc..4832ce5 100644 --- a/entry/src/main/ets/pages/components/ManualControl.ets +++ b/entry/src/main/ets/pages/components/ManualControl.ets @@ -26,6 +26,7 @@ export struct ManualControl { private currentDeviceDate: Date | null = null; aboutToAppear() { + console.info('ManualControl: aboutToAppear called'); this.initLoops(); if (this.deviceId) { this.refreshData(); @@ -34,6 +35,7 @@ export struct ManualControl { } onTabChange() { + console.info('ManualControl: onTabChange called, index:', this.currentTabIndex); if (this.currentTabIndex === 0 && this.deviceId) { this.refreshData(); } diff --git a/entry/src/main/ets/pages/components/ParameterSettings.ets b/entry/src/main/ets/pages/components/ParameterSettings.ets index b821f95..dd93d4c 100644 --- a/entry/src/main/ets/pages/components/ParameterSettings.ets +++ b/entry/src/main/ets/pages/components/ParameterSettings.ets @@ -1,4 +1,4 @@ -import { M9zService, LgnLatData, SunRiseSetData, SunRiseTimeData } from '../../utils/M9zService'; +import { M9zService, LgnLatData, SunRiseSetData, SunRiseTimeData, BluetoothConfig } from '../../utils/M9zService'; import { promptAction } from '@kit.ArkUI'; @Component @@ -12,6 +12,18 @@ export struct ParameterSettings { @State sunRiseTime: SunRiseTimeData = new SunRiseTimeData(); @State weekModes: number[] = [0, 0, 0, 0, 0, 0, 0]; // Sun-Sat @State fullWeekModeData: number[] = []; // Store full config data to write back + @State bluetoothConfig: BluetoothConfig = new BluetoothConfig(); + + // ... (existing properties) + + // ... (refreshData chain) + // Inside fetchSunRiseTime -> onSuccess -> getWeekMode -> onSuccess: + // After getting week mode, call fetchBluetoothConfig? + // Or just call it in parallel since they are independent? The user requested sequential for AutoMode tasks, maybe good practice here too. + // I will add it to the chain to be safe. + + + private days: string[] = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; private displayIndices: number[] = [1, 2, 3, 4, 5, 6, 0]; // Display order: Mon-Sat, Sun @@ -85,20 +97,48 @@ export struct ParameterSettings { this.weekModes = data.slice(startIndex); console.info('WeeklyMode extracted:', JSON.stringify(this.weekModes)); } - this.isLoading = false; + this.fetchBluetoothConfig(); }, onError: (err: string): void => { console.error('WeeklyMode Error:', err); - this.isLoading = false; + this.fetchBluetoothConfig(); } }); }, onError: (err: string): void => { - this.isLoading = false; + this.fetchBluetoothConfig(); } }); } + fetchBluetoothConfig() { + this.m9zService.getBluetoothConfig({ + onSuccess: (data: BluetoothConfig): void => { + this.bluetoothConfig = data; + this.isLoading = false; + }, + onError: (err: string): void => { + console.error('Get Bluetooth Config failed', err); + this.isLoading = false; + } + }); + } + + saveBluetoothConfig() { + if (!this.bluetoothConfig.name) { + promptAction.showToast({ message: '蓝牙名称不能为空' }); + return; + } + this.m9zService.setBluetoothConfig(this.bluetoothConfig, { + onSuccess: (success: boolean): void => { + promptAction.showToast({ message: '蓝牙名称修改成功' }); + }, + onError: (err: string): void => { + promptAction.showToast({ message: '修改失败: ' + err }); + } + }); + } + syncLocation() { // 模拟同步定位,实际应调用定位API const newData = new LgnLatData(); @@ -185,6 +225,25 @@ export struct ParameterSettings { Stack() { Scroll() { Column() { + // 蓝牙设置 + Column() { + Text('蓝牙设置').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#22fdc8').width('100%').margin({bottom: 10}) + + Row() { + Text('蓝牙名称: ').fontColor('#eaf6fc') + TextInput({ text: this.bluetoothConfig.name }) + .layoutWeight(1) + .onChange((val) => { this.bluetoothConfig.name = val; }) + .fontColor('#fff').backgroundColor('#333') + Button('保存').fontSize(12).onClick(() => this.saveBluetoothConfig()).margin({left: 10}) + }.width('100%') + } + .padding(10) + .backgroundColor('rgba(20, 38, 81, 0.95)') + .borderRadius(8) + .margin({bottom: 15}) + .width('100%') + // 经纬度设置 Column() { Text('经纬度设置').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#22fdc8').width('100%').margin({bottom: 10}) diff --git a/entry/src/main/ets/utils/M9zService.ets b/entry/src/main/ets/utils/M9zService.ets index 9387dd3..87d9bfe 100644 --- a/entry/src/main/ets/utils/M9zService.ets +++ b/entry/src/main/ets/utils/M9zService.ets @@ -25,7 +25,14 @@ export enum M9zCmd { SubLoopParameters = 0x17,// 回路分控器参数 RelayStatus = 0x19, // 继电器状态 Restart = 0x7E, // 重启 - Save = 0x7F // 保存配置 + Save = 0x7F, // 保存配置 + Bluetooth = 0x16 // 蓝牙配置 +} + +export class BluetoothConfig { + enable: boolean = false; + offlineMin: number = 0; + name: string = ''; } // 接口定义 @@ -91,7 +98,7 @@ export class ControlTask { } // 定义联合类型以避免使用 any -export type ServiceData = boolean | number | number[] | Date | ManualData | LgnLatData | SunRiseSetData | SunRiseTimeData | TaskProgram | DeviceStatus; +export type ServiceData = boolean | number | number[] | Date | ManualData | LgnLatData | SunRiseSetData | SunRiseTimeData | TaskProgram | DeviceStatus | BluetoothConfig; export interface Callback { onSuccess: (data: T) => void; @@ -388,6 +395,8 @@ export class M9zService { return this.parseSunRiseTime(data); case M9zCmd.Mode: return data.length > 0 ? data[0] : 0; // 模式 + case M9zCmd.Bluetooth: + return this.parseBluetoothConfig(data); default: return 0; // 默认返回 } @@ -640,6 +649,49 @@ export class M9zService { this.sendFrame(this.buildM9zCommand(M9zCmd.Restart, CMD_WRITE, 0x00, [])); } + public getBluetoothConfig(cb: Callback): void { + this.registerCallback(M9zCmd.Bluetooth, cb); + this.sendFrame(this.buildM9zCommand(M9zCmd.Bluetooth, CMD_READ, 0x00, [])); + } + + public setBluetoothConfig(config: BluetoothConfig, cb: Callback): void { + const payload: number[] = []; + payload.push(config.enable ? 0xAA : 0x00); + payload.push(config.offlineMin); + + // Convert string to bytes + for (let i = 0; i < config.name.length && i < 20; i++) { + payload.push(config.name.charCodeAt(i)); + } + + this.registerCallback(M9zCmd.Bluetooth, cb); + this.sendFrame(this.buildM9zCommand(M9zCmd.Bluetooth, CMD_WRITE, 0x00, payload)); + } + + private parseBluetoothConfig(data: number[]): BluetoothConfig { + const config = new BluetoothConfig(); + if (data.length >= 2) { + config.enable = data[0] === 0xAA; + config.offlineMin = data[1]; + if (data.length > 2) { + // Convert bytes to string (typical ASCII/UTF8 handling for simplicity) + let nameBytes = data.slice(2); + // Find null terminator if any + const nullIndex = nameBytes.indexOf(0x00); + if (nullIndex >= 0) { + nameBytes = nameBytes.slice(0, nullIndex); + } + // Manual decode for ASCII/LATIN1 to safe string + let nameStr = ""; + for(let i=0; i): void { this.registerCallback(cmd, cb); @@ -683,3 +735,4 @@ export class M9zService { ]; } } +