Lufaneng 6 months ago
parent 9a3a0d27d2
commit c8192fe9a5

@ -26,6 +26,7 @@ export struct ManualControl {
private currentDeviceDate: Date | null = null; private currentDeviceDate: Date | null = null;
aboutToAppear() { aboutToAppear() {
console.info('ManualControl: aboutToAppear called');
this.initLoops(); this.initLoops();
if (this.deviceId) { if (this.deviceId) {
this.refreshData(); this.refreshData();
@ -34,6 +35,7 @@ export struct ManualControl {
} }
onTabChange() { onTabChange() {
console.info('ManualControl: onTabChange called, index:', this.currentTabIndex);
if (this.currentTabIndex === 0 && this.deviceId) { if (this.currentTabIndex === 0 && this.deviceId) {
this.refreshData(); 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'; import { promptAction } from '@kit.ArkUI';
@Component @Component
@ -12,6 +12,18 @@ export struct ParameterSettings {
@State sunRiseTime: SunRiseTimeData = new SunRiseTimeData(); @State sunRiseTime: SunRiseTimeData = new SunRiseTimeData();
@State weekModes: number[] = [0, 0, 0, 0, 0, 0, 0]; // Sun-Sat @State weekModes: number[] = [0, 0, 0, 0, 0, 0, 0]; // Sun-Sat
@State fullWeekModeData: number[] = []; // Store full config data to write back @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 days: string[] = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
private displayIndices: number[] = [1, 2, 3, 4, 5, 6, 0]; // Display order: Mon-Sat, Sun 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); this.weekModes = data.slice(startIndex);
console.info('WeeklyMode extracted:', JSON.stringify(this.weekModes)); console.info('WeeklyMode extracted:', JSON.stringify(this.weekModes));
} }
this.isLoading = false; this.fetchBluetoothConfig();
}, },
onError: (err: string): void => { onError: (err: string): void => {
console.error('WeeklyMode Error:', err); console.error('WeeklyMode Error:', err);
this.isLoading = false; this.fetchBluetoothConfig();
} }
}); });
}, },
onError: (err: string): void => { 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; 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() { syncLocation() {
// 模拟同步定位实际应调用定位API // 模拟同步定位实际应调用定位API
const newData = new LgnLatData(); const newData = new LgnLatData();
@ -185,6 +225,25 @@ export struct ParameterSettings {
Stack() { Stack() {
Scroll() { Scroll() {
Column() { 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() { Column() {
Text('经纬度设置').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#22fdc8').width('100%').margin({bottom: 10}) Text('经纬度设置').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#22fdc8').width('100%').margin({bottom: 10})

@ -25,7 +25,14 @@ export enum M9zCmd {
SubLoopParameters = 0x17,// 回路分控器参数 SubLoopParameters = 0x17,// 回路分控器参数
RelayStatus = 0x19, // 继电器状态 RelayStatus = 0x19, // 继电器状态
Restart = 0x7E, // 重启 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 // 定义联合类型以避免使用 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> { export interface Callback<T> {
onSuccess: (data: T) => void; onSuccess: (data: T) => void;
@ -388,6 +395,8 @@ export class M9zService {
return this.parseSunRiseTime(data); return this.parseSunRiseTime(data);
case M9zCmd.Mode: case M9zCmd.Mode:
return data.length > 0 ? data[0] : 0; // 模式 return data.length > 0 ? data[0] : 0; // 模式
case M9zCmd.Bluetooth:
return this.parseBluetoothConfig(data);
default: default:
return 0; // 默认返回 return 0; // 默认返回
} }
@ -640,6 +649,49 @@ export class M9zService {
this.sendFrame(this.buildM9zCommand(M9zCmd.Restart, CMD_WRITE, 0x00, [])); 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 { public getTask(cmd: M9zCmd, index: number, cb: Callback<TaskProgram>): void {
this.registerCallback(cmd, cb); this.registerCallback(cmd, cb);
@ -683,3 +735,4 @@ export class M9zService {
]; ];
} }
} }

Loading…
Cancel
Save