Lufaneng 6 months ago
parent 9a3a0d27d2
commit c8192fe9a5

@ -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();
}

@ -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.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})

@ -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<T> {
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<BluetoothConfig>): void {
this.registerCallback(M9zCmd.Bluetooth, cb);
this.sendFrame(this.buildM9zCommand(M9zCmd.Bluetooth, CMD_READ, 0x00, []));
}
public setBluetoothConfig(config: BluetoothConfig, cb: Callback<boolean>): 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<nameBytes.length; i++) {
nameStr += String.fromCharCode(nameBytes[i]);
}
config.name = nameStr;
}
}
return config;
}
// 获取任务
public getTask(cmd: M9zCmd, index: number, cb: Callback<TaskProgram>): void {
this.registerCallback(cmd, cb);
@ -683,3 +735,4 @@ export class M9zService {
];
}
}

Loading…
Cancel
Save