鸿蒙智能窗帘自动控制系统开发指南

一、系统架构设计

基于HarmonyOS的分布式能力和低功耗特性,我们设计了一套智能窗帘控制系统,主要功能包括:

  1. ​光照自适应调节​​:根据环境光线自动调整窗帘开合
  2. ​低功耗电机驱动​​:优化电机控制算法减少能耗
  3. ​异常检测保护​​:震动检测自动进入保护模式
  4. ​跨设备协同​​:多终端统一控制窗帘状态
  5. ​场景联动​​:与其他智能设备协同工作

https://example.com/harmony-smart-curtain-arch.png

二、核心代码实现

1. 光照传感器服务

// LightSensorService.ets
import sensor from '@ohos.sensor';
import power from '@ohos.power';

class LightSensorService {
  private static instance: LightSensorService;
  private lightSensor: sensor.LightResponse | null = null;
  private samplingInterval: number = 60000; // 默认60秒采样一次
  private lastLightLevel: number = 0;
  private isLowPowerMode: boolean = false;
  
  private constructor() {
    this.initSensor();
  }

  private initSensor(): void {
    try {
      sensor.on(sensor.SensorType.SENSOR_TYPE_ID_LIGHT, (data) => {
        this.handleLightData(data);
      }, { interval: this.samplingInterval });
      
      // 监听电源模式变化
      power.on('powerModeChange', (mode) => {
        this.adjustSamplingForPowerMode(mode);
      });
    } catch (error) {
      console.error('Light sensor initialization failed:', error);
    }
  }

  private adjustSamplingForPowerMode(mode: power.Mode): void {
    this.isLowPowerMode = mode === power.Mode.POWER_SAVE;
    this.samplingInterval = this.isLowPowerMode ? 300000 : 60000; // 省电模式5分钟采样一次
    
    if (this.lightSensor) {
      sensor.off(sensor.SensorType.SENSOR_TYPE_ID_LIGHT);
      sensor.on(sensor.SensorType.SENSOR_TYPE_ID_LIGHT, (data) => {
        this.handleLightData(data);
      }, { interval: this.samplingInterval });
    }
  }

  private handleLightData(data: sensor.LightResponse): void {
    this.lastLightLevel = data.intensity;
    
    // 只有光照变化超过10%才触发窗帘调整
    if (Math.abs(data.intensity - this.lastLightLevel) > this.lastLightLevel * 0.1) {
      curtainControlService.adjustCurtainBasedOnLight(data.intensity);
    }
  }

  public static getInstance(): LightSensorService {
    if (!LightSensorService.instance) {
      LightSensorService.instance = new LightSensorService();
    }
    return LightSensorService.instance;
  }

  public getCurrentLightLevel(): number {
    return this.lastLightLevel;
  }

  public setSamplingInterval(interval: number): void {
    this.samplingInterval = interval;
    if (this.lightSensor) {
      sensor.off(sensor.SensorType.SENSOR_TYPE_ID_LIGHT);
      sensor.on(sensor.SensorType.SENSOR_TYPE_ID_LIGHT, (data) => {
        this.handleLightData(data);
      }, { interval: this.samplingInterval });
    }
  }
}

export const lightSensorService = LightSensorService.getInstance();

2. 电机驱动控制服务

// MotorDriverService.ets
import driver from '@ohos.driver';
import power from '@ohos.power';

class MotorDriverService {
  private static instance: MotorDriverService;
  private motorController: driver.GpioController | null = null;
  private currentPosition: number = 0; // 0-100表示开合百分比
  private isMoving: boolean = false;
  private powerMode: power.Mode = power.Mode.NORMAL;
  
  // 电机参数
  private readonly STEPS_PER_REVOLUTION = 200;
  private readonly MAX_SPEED = 10; // RPM
  private readonly POWER_SAVE_SPEED = 5; // RPM
  
  private constructor() {
    this.initMotorController();
    this.initPowerListener();
  }

  private initMotorController(): void {
    try {
      this.motorController = driver.createGpioController();
      // 初始化电机驱动引脚
      // 实际开发中需要根据具体硬件配置
    } catch (error) {
      console.error('Motor controller initialization failed:', error);
    }
  }

  private initPowerListener(): void {
    power.on('powerModeChange', (mode) => {
      this.powerMode = mode;
    });
  }

  public static getInstance(): MotorDriverService {
    if (!MotorDriverService.instance) {
      MotorDriverService.instance = new MotorDriverService();
    }
    return MotorDriverService.instance;
  }

  public async moveToPosition(position: number): Promise<void> {
    if (this.isMoving) {
      await this.stopMotor();
    }
    
    this.isMoving = true;
    const steps = this.calculateSteps(position);
    const speed = this.getOptimalSpeed();
    
    await this.driveMotor(steps, speed);
    this.currentPosition = position;
    this.isMoving = false;
    
    // 同步状态到其他设备
    deviceSyncService.syncCurtainPosition(this.currentPosition);
  }

  private calculateSteps(targetPosition: number): number {
    const positionDiff = targetPosition - this.currentPosition;
    return Math.round((positionDiff / 100) * this.STEPS_PER_REVOLUTION * 5); // 假设5圈完成全开合
  }

  private getOptimalSpeed(): number {
    return this.powerMode === power.Mode.POWER_SAVE 
      ? this.POWER_SAVE_SPEED 
      : this.MAX_SPEED;
  }

  private async driveMotor(steps: number, speed: number): Promise<void> {
    if (!this.motorController) return;
    
    const direction = steps > 0 ? 1 : 0;
    const absSteps = Math.abs(steps);
    const delay = this.calculateStepDelay(speed);
    
    // 设置方向
    await this.motorController.setGpioValue(/* DIR_PIN */, direction);
    
    // 步进电机驱动
    for (let i = 0; i < absSteps; i++) {
      await this.motorController.setGpioValue(/* STEP_PIN */, 1);
      await sleep(delay / 2);
      await this.motorController.setGpioValue(/* STEP_PIN */, 0);
      await sleep(delay / 2);
      
      // 省电模式下每100步检查一次异常
      if (this.powerMode === power.Mode.POWER_SAVE && i % 100 === 0) {
        if (vibrationService.isAbnormalVibrationDetected()) {
          await this.emergencyStop();
          break;
        }
      }
    }
  }

  private calculateStepDelay(speed: number): number {
    // RPM转换为每步延迟(微秒)
    const stepsPerMinute = speed * this.STEPS_PER_REVOLUTION;
    return 60000000 / (stepsPerMinute * this.STEPS_PER_REVOLUTION);
  }

  public async stopMotor(): Promise<void> {
    this.isMoving = false;
    // 实际实现中需要安全停止电机
  }

  public async emergencyStop(): Promise<void> {
    await this.stopMotor();
    // 触发异常处理
    exceptionService.handleMotorEmergencyStop();
  }

  public getCurrentPosition(): number {
    return this.currentPosition;
  }
}

export const motorDriverService = MotorDriverService.getInstance();

3. 异常震动检测服务

// VibrationDetectionService.ets
import sensor from '@ohos.sensor';
import power from '@ohos.power';

class VibrationDetectionService {
  private static instance: VibrationDetectionService;
  private accelerometer: sensor.AccelerometerResponse | null = null;
  private vibrationThreshold: number = 2.0; // 震动阈值(g)
  private normalVibrationPattern: number[] = [];
  private isMonitoring: boolean = false;
  private isSleepMode: boolean = false;
  
  private constructor() {
    this.initSensor();
  }

  private initSensor(): void {
    try {
      sensor.on(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER, (data) => {
        this.handleAccelerometerData(data);
      }, { interval: 1000 }); // 默认1秒采样一次
      
      // 监听电源模式变化
      power.on('powerModeChange', (mode) => {
        this.adjustForPowerMode(mode);
      });
    } catch (error) {
      console.error('Accelerometer initialization failed:', error);
    }
  }

  private adjustForPowerMode(mode: power.Mode): void {
    this.isSleepMode = mode === power.Mode.POWER_SAVE;
    
    if (this.isSleepMode) {
      // 省电模式下降低采样频率
      sensor.off(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER);
      sensor.on(sensor.SensorType.SENSOR_TYPE_ID_ACCELEROMETER, (data) => {
        this.handleAccelerometerData(data);
      }, { interval: 5000 }); // 5秒采样一次
    }
  }

  private handleAccelerometerData(data: sensor.AccelerometerResponse): void {
    const vibrationLevel = this.calculateVibrationLevel(data);
    
    if (this.isMonitoring && this.isAbnormalVibration(vibrationLevel)) {
      this.triggerAbnormalVibrationAlert();
    }
    
    // 更新正常震动模式
    this.updateNormalVibrationPattern(vibrationLevel);
  }

  private calculateVibrationLevel(data: sensor.AccelerometerResponse): number {
    // 计算综合震动水平
    return Math.sqrt(
      Math.pow(data.x, 2) + 
      Math.pow(data.y, 2) + 
      Math.pow(data.z, 2)
    ) - 1.0; // 减去重力
  }

  private isAbnormalVibration(vibrationLevel: number): boolean {
    if (this.normalVibrationPattern.length < 10) return false;
    
    // 计算与正常模式的差异
    const avgNormal = this.normalVibrationPattern.reduce((a, b) => a + b, 0) / 
                     this.normalVibrationPattern.length;
    return vibrationLevel > avgNormal * 3 || 
           vibrationLevel > this.vibrationThreshold;
  }

  private updateNormalVibrationPattern(vibrationLevel: number): void {
    if (this.normalVibrationPattern.length >= 100) {
      this.normalVibrationPattern.shift();
    }
    this.normalVibrationPattern.push(vibrationLevel);
  }

  private triggerAbnormalVibrationAlert(): void {
    // 触发电机停止
    motorDriverService.emergencyStop();
    
    // 发送警报到所有设备
    deviceSyncService.syncAlert({
      type: 'vibration',
      level: 'high',
      timestamp: Date.now()
    });
  }

  public static getInstance(): VibrationDetectionService {
    if (!VibrationDetectionService.instance) {
      VibrationDetectionService.instance = new VibrationDetectionService();
    }
    return VibrationDetectionService.instance;
  }

  public startMonitoring(): void {
    this.isMonitoring = true;
  }

  public stopMonitoring(): void {
    this.isMonitoring = false;
  }

  public isAbnormalVibrationDetected(): boolean {
    if (!this.accelerometer) return false;
    const vibrationLevel = this.calculateVibrationLevel(this.accelerometer);
    return this.isAbnormalVibration(vibrationLevel);
  }

  public enableSleepMode(): void {
    this.isSleepMode = true;
    this.adjustForPowerMode(power.Mode.POWER_SAVE);
  }

  public disableSleepMode(): void {
    this.isSleepMode = false;
    this.adjustForPowerMode(power.Mode.NORMAL);
  }
}

export const vibrationService = VibrationDetectionService.getInstance();

4. 跨设备同步服务

// DeviceSyncService.ets
import distributedData from '@ohos.data.distributedData';
import deviceManager from '@ohos.distributedHardware.deviceManager';

class DeviceSyncService {
  private static instance: DeviceSyncService;
  private kvManager: distributedData.KVManager;
  private kvStore: distributedData.KVStore;
  private connectedDevices: string[] = [];
  
  private constructor() {
    this.initKVStore();
    this.initDeviceListener();
  }

  private async initKVStore(): Promise<void> {
    const config = {
      bundleName: 'com.example.smartcurtain',
      userInfo: { userId: 'default' }
    };
    
    this.kvManager = distributedData.createKVManager(config);
    this.kvStore = await this.kvManager.getKVStore('curtain_sync', {
      createIfMissing: true,
      backup: false,
      autoSync: true,
      kvStoreType: distributedData.KVStoreType.SINGLE_VERSION
    });
    
    // 监听数据变化
    this.kvStore.on('dataChange', (data) => {
      this.handleRemoteChanges(data);
    });
  }

  private initDeviceListener(): void {
    deviceManager.on('deviceStateChange', (data) => {
      this.handleDeviceStateChange(data);
    });
    
    // 获取初始设备列表
    this.updateConnectedDevices();
  }

  private async updateConnectedDevices(): Promise<void> {
    const devices = await deviceManager.getTrustedDeviceList();
    this.connectedDevices = devices.map(d => d.deviceId);
  }

  private handleDeviceStateChange(data: deviceManager.DeviceStateChangeData): void {
    if (data.deviceState === deviceManager.DeviceState.ONLINE) {
      if (!this.connectedDevices.includes(data.deviceId)) {
        this.connectedDevices.push(data.deviceId);
      }
    } else if (data.deviceState === deviceManager.DeviceState.OFFLINE) {
      this.connectedDevices = this.connectedDevices.filter(id => id !== data.deviceId);
    }
  }

  public static getInstance(): DeviceSyncService {
    if (!DeviceSyncService.instance) {
      DeviceSyncService.instance = new DeviceSyncService();
    }
    return DeviceSyncService.instance;
  }

  public async syncCurtainPosition(position: number): Promise<void> {
    const change: SyncChange = {
      type: 'position',
      value: position,
      timestamp: Date.now(),
      deviceId: deviceManager.getLocalDevice().id
    };
    
    await this.kvStore.put('current_position', JSON.stringify(change));
  }

  public async syncAlert(alert: Alert): Promise<void> {
    const change: SyncChange = {
      type: 'alert',
      value: alert,
      timestamp: Date.now(),
      deviceId: deviceManager.getLocalDevice().id
    };
    
    await this.kvStore.put(`alert_${Date.now()}`, JSON.stringify(change));
  }

  public async syncSchedule(schedule: Schedule): Promise<void> {
    const change: SyncChange = {
      type: 'schedule',
      value: schedule,
      timestamp: Date.now(),
      deviceId: deviceManager.getLocalDevice().id
    };
    
    await this.kvStore.put(`schedule_${schedule.id}`, JSON.stringify(change));
  }

  private async handleRemoteChanges(data: distributedData.ChangeInfo): Promise<void> {
    if (data.deviceId === deviceManager.getLocalDevice().id) return;
    
    const change = JSON.parse(data.value) as SyncChange;
    
    switch (change.type) {
      case 'position':
        await this.handlePositionChange(change.value as number);
        break;
      case 'alert':
        await this.handleAlertChange(change.value as Alert);
        break;
      case 'schedule':
        await this.handleScheduleChange(change.value as Schedule);
        break;
    }
  }

  private async handlePositionChange(position: number): Promise<void> {
    // 避免循环同步
    if (Math.abs(position - motorDriverService.getCurrentPosition()) > 5) {
      await motorDriverService.moveToPosition(position);
    }
  }

  private async handleAlertChange(alert: Alert): Promise<void> {
    // 显示警报到UI
    EventBus.emit('alertReceived', alert);
    
    // 如果是震动警报,停止电机
    if (alert.type === 'vibration') {
      await motorDriverService.emergencyStop();
    }
  }

  public async getCurrentPositionFromOtherDevices(): Promise<number | null> {
    const entries = await this.kvStore.getEntries('current_position');
    if (entries.length === 0) return null;
    
    // 获取最新的位置信息
    const latest = entries.reduce((prev, current) => 
      (prev.timestamp > current.timestamp) ? prev : current
    );
    
    return latest.value as number;
  }

  public async broadcastCommand(command: Command): Promise<void> {
    const change: SyncChange = {
      type: 'command',
      value: command,
      timestamp: Date.now(),
      deviceId: deviceManager.getLocalDevice().id
    };
    
    await this.kvStore.put(`command_${Date.now()}`, JSON.stringify(change));
  }
}

export const deviceSyncService = DeviceSyncService.getInstance();

三、主界面实现

1. 窗帘控制主界面

// CurtainControlView.ets
@Component
struct CurtainControlView {
  @State currentPosition: number = 0;
  @State lightLevel: number = 0;
  @State isAutoMode: boolean = true;
  @State connectedDevices: string[] = [];
  @State alerts: Alert[] = [];
  
  aboutToAppear() {
    this.loadInitialState();
    EventBus.on('positionChanged', (pos) => this.currentPosition = pos);
    EventBus.on('lightLevelChanged', (level) => this.lightLevel = level);
    EventBus.on('alertReceived', (alert) => this.addAlert(alert));
  }

  build() {
    Column() {
      // 状态显示
      Row() {
        Text(`窗帘开合: ${this.currentPosition}%`)
          .fontSize(18)
          .margin({ right: 16 })
        
        Text(`光照: ${this.lightLevel.toFixed(0)} lux`)
          .fontSize(18)
      }
      .margin({ top: 16, bottom: 24 })
      
      // 控制滑块
      Slider({
        value: this.currentPosition,
        min: 0,
        max: 100,
        step: 1,
        style: SliderStyle.OutSet
      })
      .onChange((value: number) => {
        this.manualControl(value);
      })
      .blockColor('#4A90E2')
      .trackThickness(12)
      .width('90%')
      .margin({ bottom: 24 })
      
      // 自动模式切换
      Row() {
        Text('自动模式')
          .fontSize(16)
          .margin({ right: 8 })
        
        Toggle({ type: ToggleType.Switch, isOn: this.isAutoMode })
          .onChange((isOn: boolean) => {
            this.toggleAutoMode(isOn);
          })
      }
      .margin({ bottom: 24 })
      
      // 设备连接状态
      if (this.connectedDevices.length > 0) {
        Text(`已连接设备: ${this.connectedDevices.length}个`)
          .fontSize(14)
          .fontColor('#666666')
          .margin({ bottom: 8 })
      }
      
      // 警报信息
      if (this.alerts.length > 0) {
        AlertList({ alerts: this.alerts })
          .margin({ top: 16 })
      }
    }
    .width('100%')
    .height('100%')
    .padding(16)
  }

  private async loadInitialState(): Promise<void> {
    this.currentPosition = motorDriverService.getCurrentPosition();
    this.lightLevel = lightSensorService.getCurrentLightLevel();
    this.connectedDevices = await deviceSyncService.getConnectedDevices();
  }

  private async manualControl(position: number): Promise<void> {
    this.isAutoMode = false;
    await motorDriverService.moveToPosition(position);
  }

  private toggleAutoMode(enabled: boolean): void {
    this.isAutoMode = enabled;
    if (enabled) {
      curtainControlService.enableAutoMode();
    } else {
      curtainControlService.disableAutoMode();
    }
  }

  private addAlert(alert: Alert): void {
    this.alerts = [alert, ...this.alerts].slice(0, 5); // 只保留最近5条
  }
}

@Component
struct AlertList {
  private alerts: Alert[];
  
  build() {
    Column() {
      Text('警报通知')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 8 })
      
      ForEach(this.alerts, (alert) => {
        AlertItem({ alert })
          .margin({ bottom: 8 })
      })
    }
  }
}

@Component
struct AlertItem {
  private alert: Alert;
  
  build() {
    Row() {
      Image(this.getAlertIcon())
        .width(24)
        .height(24)
        .margin({ right: 8 })
      
      Column() {
        Text(this.getAlertTitle())
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
        
        Text(this.formatTime(this.alert.timestamp))
          .fontSize(12)
          .fontColor('#666666')
      }
    }
    .padding(8)
    .borderRadius(4)
    .backgroundColor('#FFF5F5')
    .width('100%')
  }

  private getAlertIcon(): Resource {
    switch (this.alert.type) {
      case 'vibration': return $r('app.media.ic_vibration');
      case 'motor': return $r('app.media.ic_motor');
      default: return $r('app.media.ic_alert');
    }
  }

  private getAlertTitle(): string {
    switch (this.alert.type) {
      case 'vibration': return '异常震动检测';
      case 'motor': return '电机异常';
      default: return '系统警报';
    }
  }

  private formatTime(timestamp: number): string {
    const date = new Date(timestamp);
    return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
  }
}

2. 设置界面

// SettingsView.ets
@Component
struct SettingsView {
  @State lightThreshold: number = 5000; // 默认光照阈值(lux)
  @State vibrationSensitivity: number = 2; // 震动灵敏度(1-5)
  @State powerMode: string = 'normal';
  @State schedules: Schedule[] = [];
  
  build() {
    Column() {
      // 光照设置
      Row() {
        Text('光照阈值')
          .fontSize(16)
          .layoutWeight(1)
        
        Text(`${this.lightThreshold} lux`)
          .fontSize(16)
          .margin({ right: 16 })
      }
      .margin({ top: 16, bottom: 8 })
      
      Slider({
        value: this.lightThreshold,
        min: 1000,
        max: 10000,
        step: 500
      })
      .onChange((value: number) => {
        this.updateLightThreshold(value);
      })
      .width('90%')
      .margin({ bottom: 24 })
      
      // 震动灵敏度
      Row() {
        Text('震动灵敏度')
          .fontSize(16)
          .layoutWeight(1)
        
        Text(`${'★'.repeat(this.vibrationSensitivity)}`)
          .fontSize(16)
          .margin({ right: 16 })
      }
      .margin({ bottom: 8 })
      
      Slider({
        value: this.vibrationSensitivity,
        min: 1,
        max: 5,
        step: 1
      })
      .onChange((value: number) => {
        this.updateVibrationSensitivity(value);
      })
      .width('90%')
      .margin({ bottom: 24 })
      
      // 电源模式
      Text('电源模式')
        .fontSize(16)
        .margin({ bottom: 8 })
      
      RadioGroup({ initial: this.powerMode })
        .onChange((value: string) => {
          this.changePowerMode(value);
        })
        .margin({ bottom: 24 })
      {
        Radio({ value: 'power_save' }).text('省电模式')
        Radio({ value: 'normal' }).text('普通模式')
        Radio({ value: 'performance' }).text('高性能模式')
      }
      
      // 定时计划
      Text('定时计划')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 8 })
      
      Button('添加计划')
        .onClick(() => this.showAddScheduleDialog())
        .width('90%')
        .margin({ bottom: 16 })
      
      ScheduleList({ schedules: this.schedules })
    }
    .width('100%')
    .height('100%')
    .padding(16)
  }

  private updateLightThreshold(value: number): void {
    this.lightThreshold = value;
    curtainControlService.setLightThreshold(value);
  }

  private updateVibrationSensitivity(value: number): void {
    this.vibrationSensitivity = value;
    vibrationService.setSensitivity(value);
  }

  private changePowerMode(mode: string): void {
    this.powerMode = mode;
    powerOptimizationService.setPowerMode(mode);
  }

  private showAddScheduleDialog(): void {
    router.push({ url: 'pages/addSchedule' });
  }
}

@Component
struct ScheduleList {
  private schedules: Schedule[];
  
  build() {
    Column() {
      ForEach(this.schedules, (schedule) => {
        ScheduleItem({ schedule })
          .margin({ bottom: 8 })
      })
    }
  }
}

@Component
struct ScheduleItem {
  private schedule: Schedule;
  
  build() {
    Row() {
      Column() {
        Text(this.schedule.name)
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
        
        Text(`${this.formatTime(this.schedule.time)} ${this.getDaysText()}`)
          .fontSize(12)
          .fontColor('#666666')
      }
      .layoutWeight(1)
      
      Button('删除')
        .onClick(() => this.deleteSchedule())
        .width(60)
        .height(30)
    }
    .padding(8)
    .borderRadius(4)
    .backgroundColor('#FFFFFF')
  }

  private formatTime(time: number): string {
    const date = new Date(time);
    return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
  }

  private getDaysText(): string {
    if (this.schedule.repeat === 'daily') return '每天';
    if (this.schedule.repeat === 'weekdays') return '工作日';
    if (this.schedule.repeat === 'weekend') return '周末';
    return '仅一次';
  }

  private deleteSchedule(): void {
    scheduleService.removeSchedule(this.schedule.id);
  }
}

四、高级功能实现

1. 窗帘控制服务

// CurtainControlService.ets
import { lightSensorService } from './LightSensorService';
import { motorDriverService } from './MotorDriverService';

class CurtainControlService {
  private static instance: CurtainControlService;
  private isAutoMode: boolean = true;
  private lightThreshold: number = 5000; // 默认阈值(lux)
  private positionMap: Map<number, number> = new Map();
  
  private constructor() {
    this.initPositionMap();
  }

  private initPositionMap(): void {
    // 光照到位置的映射
    this.positionMap.set(0, 100);    // 完全黑暗 -> 全开
    this.positionMap.set(1000, 80);   // 昏暗 -> 80%
    this.positionMap.set(3000, 50);   // 中等亮度 -> 50%
    this.positionMap.set(5000, 30);   // 明亮 -> 30%
    this.positionMap.set(10000, 0);   // 非常明亮 -> 全关
  }

  public static getInstance(): CurtainControlService {
    if (!CurtainControlService.instance) {
      CurtainControlService.instance = new CurtainControlService();
    }
    return CurtainControlService.instance;
  }

  public enableAutoMode(): void {
    this.isAutoMode = true;
    this.adjustBasedOnLight();
  }

  public disableAutoMode(): void {
    this.isAutoMode = false;
  }

  public setLightThreshold(threshold: number): void {
    this.lightThreshold = threshold;
    if (this.isAutoMode) {
      this.adjustBasedOnLight();
    }
  }

  public async adjustCurtainBasedOnLight(lightLevel: number): Promise<void> {
    if (!this.isAutoMode) return;
    
    const targetPosition = this.calculateTargetPosition(lightLevel);
    await motorDriverService.moveToPosition(targetPosition);
  }

  private calculateTargetPosition(lightLevel: number): number {
    // 找到最接近的两个光照点
    const levels = Array.from(this.positionMap.keys()).sort((a, b) => a - b);
    let lower = levels[0];
    let higher = levels[levels.length - 1];
    
    for (const level of levels) {
      if (level <= lightLevel) lower = level;
      if (level >= lightLevel) {
        higher = level;
        break;
      }
    }
    
    // 线性插值计算位置
    if (lower === higher) {
      return this.positionMap.get(lower) || 0;
    }
    
    const lowerPos = this.positionMap.get(lower) || 0;
    const higherPos = this.positionMap.get(higher) || 0;
    
    return Math.round(
      lowerPos + (higherPos - lowerPos) * 
      ((lightLevel - lower) / (higher - lower))
    );
  }

  public getCurrentLightThreshold(): number {
    return this.lightThreshold;
  }

  public isInAutoMode(): boolean {
    return this.isAutoMode;
  }
}

export const curtainControlService = CurtainControlService.getInstance();

2. 电源优化服务

// PowerOptimizationService.ets
import power from '@ohos.power';
import { motorDriverService } from './MotorDriverService';
import { lightSensorService } from './LightSensorService';
import { vibrationService } from './VibrationDetectionService';

class PowerOptimizationService {
  private static instance: PowerOptimizationService;
  private currentMode: power.Mode = power.Mode.NORMAL;
  
  private constructor() {
    this.initPowerListener();
  }

  private initPowerListener(): void {
    power.on('powerModeChange', (mode) => {
      this.handlePowerModeChange(mode);
    });
  }

  public static getInstance(): PowerOptimizationService {
    if (!PowerOptimizationService.instance) {
      PowerOptimizationService.instance = new PowerOptimizationService();
    }
    return PowerOptimizationService.instance;
  }

  public setPowerMode(mode: string): void {
    let powerMode: power.Mode;
    switch (mode) {
      case 'power_save': powerMode = power.Mode.POWER_SAVE; break;
      case 'performance': powerMode = power.Mode.PERFORMANCE; break;
      default: powerMode = power.Mode.NORMAL;
    }
    
    power.setMode(powerMode);
  }

  private handlePowerModeChange(mode: power.Mode): void {
    this.currentMode = mode;
    
    // 调整各服务参数
    switch (mode) {
      case power.Mode.POWER_SAVE:
        this.enablePowerSaveMode();
        break;
      case power.Mode.PERFORMANCE:
        this.enablePerformanceMode();
        break;
      default:
        this.enableNormalMode();
    }
  }

  private enablePowerSaveMode(): void {
    // 降低光照传感器采样率
    lightSensorService.setSamplingInterval(300000); // 5分钟
    
    // 降低电机速度
    motorDriverService.setMaxSpeed(5); // RPM
    
    // 启用震动检测休眠
    vibrationService.enableSleepMode();
    
    // 减少同步频率
    deviceSyncService.setSyncInterval(3600000); // 1小时
  }

  private enablePerformanceMode(): void {
    // 提高光照传感器采样率
    lightSensorService.setSamplingInterval(10000); // 10秒
    
    // 提高电机速度
    motorDriverService.setMaxSpeed(15); // RPM
    
    // 禁用震动检测休眠
    vibrationService.disableSleepMode();
    
    // 增加同步频率
    deviceSyncService.setSyncInterval(60000); // 1分钟
  }

  private enableNormalMode(): void {
    // 恢复默认设置
    lightSensorService.setSamplingInterval(60000); // 1分钟
    motorDriverService.setMaxSpeed(10); // RPM
    vibrationService.disableSleepMode();
    deviceSyncService.setSyncInterval(300000); // 5分钟
  }

  public getCurrentMode(): power.Mode {
    return this.currentMode;
  }
}

export const powerOptimization = PowerOptimizationService.getInstance();

3. 定时计划服务

// ScheduleService.ets
import worker from '@ohos.worker';
import { motorDriverService } from './MotorDriverService';

class ScheduleService {
  private static instance: ScheduleService;
  private schedules: Schedule[] = [];
  private timerWorker: worker.ThreadWorker | null = null;
  
  private constructor() {
    this.initWorker();
  }

  private initWorker(): void {
    this.timerWorker = new worker.ThreadWorker('workers/timerWorker.js');
    
    this.timerWorker.onmessage = (event) => {
      this.handleTimerEvent(event);
    };
    
    this.timerWorker.onerror = (error) => {
      console.error('Timer worker error:', error);
    };
  }

  public static getInstance(): ScheduleService {
    if (!ScheduleService.instance) {
      ScheduleService.instance = new ScheduleService();
    }
    return ScheduleService.instance;
  }

  public addSchedule(schedule: Schedule): void {
    this.schedules.push(schedule);
    this.updateWorker();
    deviceSyncService.syncSchedule(schedule);
  }

  public removeSchedule(id: string): void {
    this.schedules = this.schedules.filter(s => s.id !== id);
    this.updateWorker();
  }

  public getSchedules(): Schedule[] {
    return [...this.schedules];
  }

  private updateWorker(): void {
    if (this.timerWorker) {
      this.timerWorker.postMessage({
        type: 'update',
        schedules: this.schedules
      });
    }
  }

  private handleTimerEvent(event: MessageEvent): void {
    if (event.data.type === 'trigger') {
      const schedule = this.schedules.find(s => s.id === event.data.id);
      if (schedule) {
        this.executeSchedule(schedule);
      }
    }
  }

  private async executeSchedule(schedule: Schedule): Promise<void> {
    await motorDriverService.moveToPosition(schedule.position);
    
    // 如果是重复计划,计算下一次执行时间
    if (schedule.repeat !== 'once') {
      this.reschedule(schedule);
    }
  }

  private reschedule(schedule: Schedule): void {
    const now = new Date();
    let nextTime = new Date(schedule.time);
    
    if (schedule.repeat === 'daily') {
      nextTime.setDate(now.getDate() + 1);
    } else if (schedule.repeat === 'weekdays') {
      let daysToAdd = 1;
      if (now.getDay() === 5) { // 周五
        daysToAdd = 3; // 跳到周一
      } else if (now.getDay() === 6) { // 周六
        daysToAdd = 2; // 跳到周一
      }
      nextTime.setDate(now.getDate() + daysToAdd);
    } else if (schedule.repeat === 'weekend') {
      if (now.getDay() === 0) { // 周日
        nextTime.setDate(now.getDate() + 6); // 下周六
      } else {
        nextTime.setDate(now.getDate() + (6 - now.getDay())); // 本周六
      }
    }
    
    // 更新计划时间
    schedule.time = nextTime.getTime();
    this.updateWorker();
  }
}

export const scheduleService = ScheduleService.getInstance();

五、总结

本智能窗帘控制系统实现了以下核心价值:

  1. ​自适应光照调节​​:根据环境光线自动调整窗帘开合度
  2. ​低功耗运行​​:优化传感器采样和电机驱动减少能耗
  3. ​异常保护机制​​:震动检测自动触发保护措施
  4. ​跨设备协同​​:多终端统一控制窗帘状态
  5. ​智能场景联动​​:支持定时计划和电源模式优化

​扩展方向​​:

  1. 增加语音控制集成
  2. 开发基于天气预测的智能调节
  3. 添加能耗统计和分析功能
  4. 支持更多窗帘类型和电机型号
  5. 集成到智能家居生态系统中
注意事项:
1. 需要申请ohos.permission.ACCESS_LIGHT_SENSOR权限
2. 电机驱动需根据具体硬件调整参数
3. 省电模式可能影响响应速度
4. 震动检测阈值需根据安装环境调整
5. 首次使用建议运行校准程序
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐