鸿蒙智能空调自动调温系统开发指南 原创

进修的泡芙
发布于 2025-6-23 13:07
浏览
0收藏

鸿蒙智能空调自动调温系统开发指南

一、系统架构设计

基于HarmonyOS的分布式能力,我们设计了一套智能空调控制系统,主要功能包括:
红外编码学习:支持学习各种品牌空调遥控器信号

室温预测:基于历史数据和环境因素预测温度变化

人体检测:通过多传感器融合检测室内人员存在

跨设备控制:多终端同步空调状态和控制权

智能场景:根据用户习惯自动调节温度

!https://example.com/harmony-ac-controller-arch.png

二、核心代码实现
红外编码学习服务

// InfraredService.ets
import infrared from ‘@ohos.infrared’;
import storage from ‘@ohos.data.storage’;

class InfraredService {
private static instance: InfraredService;
private learnedCodes: Map<string, InfraredCode> = new Map();
private currentBrand: string = ‘’;

private constructor() {
this.loadLearnedCodes();
private async loadLearnedCodes(): Promise<void> {

try {
  const codes = await storage.get('learnedIrCodes');
  if (codes) {
    this.learnedCodes = new Map(JSON.parse(codes));

} catch (error) {

  console.error('Failed to load IR codes:', error);

}

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

public async startLearning(brand: string): Promise<void> {

this.currentBrand = brand;
await infrared.startLearning({
  carrierFrequency: 38000, // 38kHz是常见红外载频
  onCodeReceived: (code) => this.handleLearnedCode(code)
});

private async handleLearnedCode(code: InfraredCode): Promise<void> {

if (!this.currentBrand) return;

// 保存学习到的编码
this.learnedCodes.set({this.currentBrand}_{code.function}, code);

try {
  // 持久化存储
  await storage.set('learnedIrCodes', 
    JSON.stringify(Array.from(this.learnedCodes.entries())));

catch (error) {

  console.error('Failed to save IR code:', error);

// 发送学习完成事件

EventBus.emit('irCodeLearned', {
  brand: this.currentBrand,
  function: code.function
});

public async sendCode(brand: string, functionName: string): Promise<void> {

const codeKey = {brand}_{functionName};
const code = this.learnedCodes.get(codeKey);

if (!code) {
  throw new Error(未学习{brand}品牌的{functionName}功能编码);

await infrared.transmit(code);

public getLearnedBrands(): string[] {

const brands = new Set<string>();
this.learnedCodes.forEach((_, key) => {
  brands.add(key.split('_')[0]);
});
return Array.from(brands);

public getBrandFunctions(brand: string): string[] {

const functions: string[] = [];
this.learnedCodes.forEach((_, key) => {
  if (key.startsWith(${brand}_)) {
    functions.push(key.split('_')[1]);

});

return functions;

public deleteCode(brand: string, functionName: string): void {

this.learnedCodes.delete({brand}_{functionName});
storage.set('learnedIrCodes', 
  JSON.stringify(Array.from(this.learnedCodes.entries())));

}

export const irService = InfraredService.getInstance();

室温预测服务

// TemperaturePredictionService.ets
import neuralNetwork from ‘@ohos.ai.neuralNetwork’;
import sensor from ‘@ohos.sensor’;

class TemperaturePredictionService {
private static instance: TemperaturePredictionService;
private model: neuralNetwork.Model | null = null;
private history: TemperatureData[] = [];
private predictionInterval: number = 30 60 1000; // 30分钟预测一次

private constructor() {
this.initModel();
this.startPredictionLoop();
private async initModel(): Promise<void> {

try {
  // 加载预训练的轻量级温度预测模型
  this.model = await neuralNetwork.loadModel({
    modelPath: 'models/temp_predict_lite.nn',
    quantization: true
  });
  
  // 加载历史数据
  this.loadHistory();

catch (error) {

  console.error('Failed to load prediction model:', error);

}

private async loadHistory(): Promise<void> {
const history = await storage.get(‘temperatureHistory’);
if (history) {
this.history = JSON.parse(history);
}

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

private startPredictionLoop(): void {

setInterval(() => {
  this.predictTemperature();
}, this.predictionInterval);

public async recordCurrentTemperature(temp: number): Promise<void> {

const now = Date.now();
const data: TemperatureData = {
  timestamp: now,
  temperature: temp,
  humidity: sensor.getHumidity(),
  outdoorTemp: await this.getOutdoorTemp(),
  acStatus: acService.getCurrentStatus()
};

this.history.push(data);

// 保留最近7天数据
if (this.history.length > 7  24  2) { // 每30分钟一条记录
  this.history.shift();

// 保存数据

await storage.set('temperatureHistory', JSON.stringify(this.history));

private async predictTemperature(): Promise<void> {

if (!this.model || this.history.length < 24) return; // 至少需要24条记录

try {
  // 准备输入数据
  const input = this.prepareInput();
  
  // 运行预测
  const output = await this.model.run(input);
  
  // 解析预测结果
  const predictions = this.parseOutput(output);
  
  // 触发预测事件
  EventBus.emit('temperaturePredicted', predictions);

catch (error) {

  console.error('Temperature prediction failed:', error);

}

private prepareInput(): neuralNetwork.Tensor {
// 使用最近24小时数据预测未来3小时
const recentData = this.history.slice(-24);

return {
  data: this.normalizeData(recentData),
  shape: [1, 24, 5] // [批次, 时间步, 特征]
};

private normalizeData(data: TemperatureData[]): number[] {

// 简单归一化处理
const maxTemp = Math.max(...data.map(d => d.temperature));
const maxHumidity = Math.max(...data.map(d => d.humidity));

return data.flatMap(d => [
  d.temperature / 50, // 假设最高50°C
  d.humidity / 100,
  d.outdoorTemp / 50,
  d.acStatus.temperature / 30,
  d.acStatus.power ? 1 : 0
]);

private parseOutput(output: neuralNetwork.Tensor): TemperaturePrediction[] {

const data = output.data as number[];
const now = Date.now();

return [

time: now + 3600000, temperature: data[0] * 50 }, // 1小时后

time: now + 7200000, temperature: data[1] * 50 }, // 2小时后

time: now + 10800000, temperature: data[2] * 50 } // 3小时后

];

private async getOutdoorTemp(): Promise<number> {

// 从天气服务获取室外温度
try {
  const weather = await weatherService.getCurrentWeather();
  return weather.temperature;

catch (error) {

  console.error('Failed to get outdoor temp:', error);
  return 25; // 默认值

}

public getHistory(): TemperatureData[] {
return […this.history];
public getLatestPrediction(): TemperaturePrediction | null {

const predictions = EventBus.getLastEvent('temperaturePredicted');
return predictions ? predictions[0] : null;

}

export const tempPrediction = TemperaturePredictionService.getInstance();

人体检测服务

// PresenceDetectionService.ets
import sensor from ‘@ohos.sensor’;
import neuralNetwork from ‘@ohos.ai.neuralNetwork’;
import power from ‘@ohos.power’;

class PresenceDetectionService {
private static instance: PresenceDetectionService;
private model: neuralNetwork.Model | null = null;
private isPresent: boolean = false;
private lastDetectionTime: number = 0;
private powerMode: power.Mode = power.Mode.NORMAL;

private constructor() {
this.initModel();
this.initSensors();
this.initPowerListener();
private async initModel(): Promise<void> {

try {
  // 加载轻量级人体存在检测模型
  this.model = await neuralNetwork.loadModel({
    modelPath: 'models/presence_detection.nn',
    quantization: true
  });

catch (error) {

  console.error('Failed to load presence model:', error);

}

private initSensors(): void {
// 使用PIR(被动红外)传感器
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_PIR, (data) => {
this.handlePirData(data);
}, { interval: 1000 });

// 使用毫米波雷达(如果可用)
if (sensor.hasSensor(sensor.SensorType.SENSOR_TYPE_ID_MMWAVE)) {
  sensor.on(sensor.SensorType.SENSOR_TYPE_ID_MMWAVE, (data) => {
    this.handleMmWaveData(data);
  }, { interval: 2000 });

}

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

// 根据电源模式调整检测参数
switch (this.powerMode) {
  case power.Mode.POWER_SAVE:
    sensor.off(sensor.SensorType.SENSOR_TYPE_ID_MMWAVE);
    sensor.setInterval(sensor.SensorType.SENSOR_TYPE_ID_PIR, 3000);
    break;
  case power.Mode.PERFORMANCE:
    if (sensor.hasSensor(sensor.SensorType.SENSOR_TYPE_ID_MMWAVE)) {
      sensor.on(sensor.SensorType.SENSOR_TYPE_ID_MMWAVE, (data) => {
        this.handleMmWaveData(data);
      }, { interval: 1000 });

sensor.setInterval(sensor.SensorType.SENSOR_TYPE_ID_PIR, 500);

    break;
  default:
    sensor.setInterval(sensor.SensorType.SENSOR_TYPE_ID_PIR, 1000);

}

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

private handlePirData(data: sensor.PirResponse): void {

if (data.value > 0.8 && Date.now() - this.lastDetectionTime > 5000) {
  this.detectPresence();

}

private handleMmWaveData(data: sensor.MmWaveResponse): void {
if (data.motionLevel > 0.7 && Date.now() - this.lastDetectionTime > 3000) {
this.detectPresence();
}

private async detectPresence(): Promise<void> {
if (!this.model) return;

try {
  // 获取环境传感器数据
  const envData = await this.getEnvironmentData();
  
  // 准备模型输入
  const input: neuralNetwork.Tensor = {
    data: this.normalizeInput(envData),
    shape: [1, 1, 5] // [批次, 时间步, 特征]
  };
  
  // 运行模型
  const output = await this.model.run(input);
  const presenceProb = (output.data as number[])[0];
  
  // 更新状态
  this.isPresent = presenceProb > 0.7;
  this.lastDetectionTime = Date.now();
  
  // 触发事件
  EventBus.emit('presenceChanged', this.isPresent);

catch (error) {

  console.error('Presence detection failed:', error);

}

private async getEnvironmentData(): Promise<EnvData> {
return {
temperature: sensor.getTemperature(),
humidity: sensor.getHumidity(),
lightLevel: sensor.getLight(),
soundLevel: sensor.getSound(),
co2Level: sensor.getCO2()
};
private normalizeInput(data: EnvData): number[] {

return [
  data.temperature / 50,
  data.humidity / 100,
  data.lightLevel / 1000,
  data.soundLevel / 100,
  data.co2Level / 2000
];

public isPersonPresent(): boolean {

return this.isPresent;

public getLastDetectionTime(): number {

return this.lastDetectionTime;

public getDetectionConfidence(): number {

// 基于最后检测时间和传感器数据计算置信度
const timeSinceLast = Date.now() - this.lastDetectionTime;
return Math.max(0, 1 - timeSinceLast / 600000); // 10分钟后置信度降为0

}

export const presenceDetection = PresenceDetectionService.getInstance();

跨设备同步服务

// SyncService.ets
import distributedData from ‘@ohos.data.distributedData’;
import deviceManager from ‘@ohos.distributedHardware.deviceManager’;

class SyncService {
private static instance: SyncService;
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.accontroller',
  userInfo: { userId: 'default' }
};

this.kvManager = distributedData.createKVManager(config);
this.kvStore = await this.kvManager.getKVStore('ac_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(): SyncService {
if (!SyncService.instance) {
SyncService.instance = new SyncService();
return SyncService.instance;

public async syncACStatus(status: ACStatus): Promise<void> {

const change: SyncChange = {
  type: 'acStatus',
  value: status,
  timestamp: Date.now(),
  deviceId: deviceManager.getLocalDevice().id
};

await this.kvStore.put('current_status', JSON.stringify(change));

public async syncTemperature(temp: number): Promise<void> {

const change: SyncChange = {
  type: 'temperature',
  value: temp,
  timestamp: Date.now(),
  deviceId: deviceManager.getLocalDevice().id
};

await this.kvStore.put(temp_${Date.now()}, JSON.stringify(change));

public async syncPresence(present: boolean): Promise<void> {

const change: SyncChange = {
  type: 'presence',
  value: present,
  timestamp: Date.now(),
  deviceId: deviceManager.getLocalDevice().id
};

await this.kvStore.put(presence_${Date.now()}, JSON.stringify(change));

private handleRemoteChanges(data: distributedData.ChangeInfo): void {

if (data.deviceId === deviceManager.getLocalDevice().id) return;

try {
  const change = JSON.parse(data.value) as SyncChange;
  
  switch (change.type) {
    case 'acStatus':
      EventBus.emit('remoteACStatus', change.value);
      break;
    case 'temperature':
      EventBus.emit('remoteTemperature', change.value);
      break;
    case 'presence':
      EventBus.emit('remotePresence', change.value);
      break;

} catch (error) {

  console.error('Failed to parse sync data:', error);

}

public async getConnectedDevices(): Promise<string[]> {
await this.updateConnectedDevices();
return […this.connectedDevices];
public async broadcastCommand(command: ACCommand): 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 syncService = SyncService.getInstance();

三、主界面实现
空调控制主界面

// ACControlView.ets
@Component
struct ACControlView {
@State currentTemp: number = 26;
@State targetTemp: number = 26;
@State isOn: boolean = false;
@State mode: ACMode = ‘cool’;
@State fanSpeed: FanSpeed = ‘auto’;
@State isPersonPresent: boolean = false;
@State connectedDevices: number = 0;

aboutToAppear() {
this.initEventListeners();
this.loadInitialState();
build() {

Column() {
  // 状态显示
  Row() {
    Text(当前温度: ${this.currentTemp}°C)
      .fontSize(16)
      .layoutWeight(1)
    
    Text(this.isPersonPresent ? '有人' : '无人')
      .fontSize(16)
      .fontColor(this.isPersonPresent ? '#4CAF50' : '#F44336')
      .margin({ right: 16 })

.margin({ top: 16, bottom: 8 })

  // 温度控制
  Row() {
    Button('-')
      .onClick(() => this.adjustTemp(-1))
      .width(48)
      .height(48)
    
    Text(${this.targetTemp}°C)
      .fontSize(32)
      .fontWeight(FontWeight.Bold)
      .margin({ left: 16, right: 16 })
    
    Button('+')
      .onClick(() => this.adjustTemp(1))
      .width(48)
      .height(48)

.margin({ bottom: 24 })

  // 模式选择
  ModeSelector({
    currentMode: this.mode,
    onChange: (mode) => this.changeMode(mode)
  })
  .margin({ bottom: 16 })
  
  // 风速选择
  FanSpeedSelector({
    currentSpeed: this.fanSpeed,
    onChange: (speed) => this.changeFanSpeed(speed)
  })
  .margin({ bottom: 24 })
  
  // 电源按钮
  Button(this.isOn ? '关闭' : '开启')
    .onClick(() => this.togglePower())
    .width(200)
    .height(48)
    .backgroundColor(this.isOn ? '#F44336' : '#4CAF50')
  
  // 设备连接状态
  if (this.connectedDevices > 0) {
    Text(${this.connectedDevices}设备连接中)
      .fontSize(14)
      .fontColor('#666666')
      .margin({ top: 16 })

}

.padding(16)

private initEventListeners(): void {

EventBus.on('remoteACStatus', (status) => {
  this.updateStatus(status);
});

EventBus.on('remoteTemperature', (temp) => {
  this.currentTemp = temp;
});

EventBus.on('remotePresence', (present) => {
  this.isPersonPresent = present;
});

private loadInitialState(): void {

const status = acService.getCurrentStatus();
this.isOn = status.power;
this.mode = status.mode;
this.fanSpeed = status.fanSpeed;
this.targetTemp = status.temperature;

this.currentTemp = tempSensor.getCurrentTemp();
this.isPersonPresent = presenceDetection.isPersonPresent();
this.connectedDevices = syncService.getConnectedDevices().length;

private updateStatus(status: ACStatus): void {

this.isOn = status.power;
this.mode = status.mode;
this.fanSpeed = status.fanSpeed;
this.targetTemp = status.temperature;

private adjustTemp(delta: number): void {

this.targetTemp += delta;
this.targetTemp = Math.max(16, Math.min(30, this.targetTemp));
acService.setTemperature(this.targetTemp);

private changeMode(mode: ACMode): void {

this.mode = mode;
acService.setMode(mode);

private changeFanSpeed(speed: FanSpeed): void {

this.fanSpeed = speed;
acService.setFanSpeed(speed);

private togglePower(): void {

this.isOn = !this.isOn;
if (this.isOn) {
  acService.turnOn();

else {

  acService.turnOff();

}

@Component

struct ModeSelector {
private currentMode: ACMode;
private onChange: (mode: ACMode) => void;

build() {
Row() {
ModeButton({
mode: ‘cool’,
active: this.currentMode === ‘cool’,
onClick: () => this.onChange(‘cool’)
})
.margin({ right: 8 })

  ModeButton({
    mode: 'heat',
    active: this.currentMode === 'heat',
    onClick: () => this.onChange('heat')
  })
  .margin({ right: 8 })
  
  ModeButton({
    mode: 'dry',
    active: this.currentMode === 'dry',
    onClick: () => this.onChange('dry')
  })
  .margin({ right: 8 })
  
  ModeButton({
    mode: 'fan',
    active: this.currentMode === 'fan',
    onClick: () => this.onChange('fan')
  })

}

@Component

struct ModeButton {
private mode: ACMode;
private active: boolean;
private onClick: () => void;

build() {
Button(this.getModeText())
.onClick(() => this.onClick())
.width(80)
.height(36)
.backgroundColor(this.active ? ‘#2196F3’ : ‘#FFFFFF’)
.fontColor(this.active ? ‘#FFFFFF’ : ‘#000000’)
private getModeText(): string {

switch (this.mode) {
  case 'cool': return '制冷';
  case 'heat': return '制热';
  case 'dry': return '除湿';
  case 'fan': return '送风';
  default: return '';

}

@Component

struct FanSpeedSelector {
private currentSpeed: FanSpeed;
private onChange: (speed: FanSpeed) => void;

build() {
Row() {
FanSpeedButton({
speed: ‘auto’,
active: this.currentSpeed === ‘auto’,
onClick: () => this.onChange(‘auto’)
})
.margin({ right: 8 })

  FanSpeedButton({
    speed: 'low',
    active: this.currentSpeed === 'low',
    onClick: () => this.onChange('low')
  })
  .margin({ right: 8 })
  
  FanSpeedButton({
    speed: 'medium',
    active: this.currentSpeed === 'medium',
    onClick: () => this.onChange('medium')
  })
  .margin({ right: 8 })
  
  FanSpeedButton({
    speed: 'high',
    active: this.currentSpeed === 'high',
    onClick: () => this.onChange('high')
  })

}

@Component

struct FanSpeedButton {
private speed: FanSpeed;
private active: boolean;
private onClick: () => void;

build() {
Button(this.getSpeedText())
.onClick(() => this.onClick())
.width(80)
.height(36)
.backgroundColor(this.active ? ‘#2196F3’ : ‘#FFFFFF’)
.fontColor(this.active ? ‘#FFFFFF’ : ‘#000000’)
private getSpeedText(): string {

switch (this.speed) {
  case 'auto': return '自动';
  case 'low': return '低风';
  case 'medium': return '中风';
  case 'high': return '高风';
  default: return '';

}

智能设置界面

// SmartSettingsView.ets
@Component
struct SmartSettingsView {
@State autoAdjust: boolean = true;
@State presenceControl: boolean = true;
@State learningEnabled: boolean = true;
@State preferredTemp: number = 24;
@State tempOffset: number = 0;

build() {
Column() {
// 自动调节开关
Row() {
Text(‘智能调温’)
.fontSize(16)
.layoutWeight(1)

    Toggle({ type: ToggleType.Switch, isOn: this.autoAdjust })
      .onChange((isOn) => this.toggleAutoAdjust(isOn))

.margin({ top: 16, bottom: 16 })

  // 人体感应控制
  Row() {
    Text('人体感应控制')
      .fontSize(16)
      .layoutWeight(1)
    
    Toggle({ type: ToggleType.Switch, isOn: this.presenceControl })
      .onChange((isOn) => this.togglePresenceControl(isOn))

.margin({ bottom: 16 })

  // 学习模式
  Row() {
    Text('学习使用习惯')
      .fontSize(16)
      .layoutWeight(1)
    
    Toggle({ type: ToggleType.Switch, isOn: this.learningEnabled })
      .onChange((isOn) => this.toggleLearning(isOn))

.margin({ bottom: 24 })

  // 偏好温度
  Text('偏好温度')
    .fontSize(16)
    .margin({ bottom: 8 })
  
  Slider({
    value: this.preferredTemp,
    min: 18,
    max: 30,
    step: 1
  })
  .onChange((value) => this.changePreferredTemp(value))
  .margin({ bottom: 24 })
  
  // 温度补偿
  Text('温度补偿: ' + (this.tempOffset > 0 ? '+' : '') + this.tempOffset + '°C')
    .fontSize(16)
    .margin({ bottom: 8 })
  
  Slider({
    value: this.tempOffset + 2, // -2到+2范围
    min: 0,
    max: 4,
    step: 0.5
  })
  .onChange((value) => this.changeTempOffset(value - 2))

.padding(16)

private toggleAutoAdjust(enabled: boolean): void {

this.autoAdjust = enabled;
smartControl.setAutoAdjust(enabled);

private togglePresenceControl(enabled: boolean): void {

this.presenceControl = enabled;
smartControl.setPresenceControl(enabled);

private toggleLearning(enabled: boolean): void {

this.learningEnabled = enabled;
smartControl.setLearningEnabled(enabled);

private changePreferredTemp(temp: number): void {

this.preferredTemp = temp;
smartControl.setPreferredTemp(temp);

private changeTempOffset(offset: number): void {

this.tempOffset = offset;
smartControl.setTempOffset(offset);

}

四、高级功能实现
智能控制服务

// SmartControlService.ets
import { acService } from ‘./ACService’;
import { presenceDetection } from ‘./PresenceDetectionService’;
import { tempPrediction } from ‘./TemperaturePredictionService’;

class SmartControlService {
private static instance: SmartControlService;
private isAutoAdjust: boolean = true;
private isPresenceControl: boolean = true;
private isLearning: boolean = true;
private preferredTemp: number = 24;
private tempOffset: number = 0;
private userHabits: UserHabit[] = [];

private constructor() {
this.initEventListeners();
this.loadUserHabits();
private initEventListeners(): void {

EventBus.on('temperaturePredicted', (predictions) => {
  if (this.isAutoAdjust) {
    this.adjustBasedOnPrediction(predictions);

});

EventBus.on('presenceChanged', (present) => {
  if (this.isPresenceControl) {
    this.handlePresenceChange(present);

});

EventBus.on('acStatusChanged', (status) => {
  if (this.isLearning) {
    this.recordUserHabit(status);

});

private async loadUserHabits(): Promise<void> {

const habits = await storage.get('userHabits');
if (habits) {
  this.userHabits = JSON.parse(habits);

}

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

public setAutoAdjust(enabled: boolean): void {

this.isAutoAdjust = enabled;

public setPresenceControl(enabled: boolean): void {

this.isPresenceControl = enabled;

public setLearningEnabled(enabled: boolean): void {

this.isLearning = enabled;

public setPreferredTemp(temp: number): void {

this.preferredTemp = temp;

public setTempOffset(offset: number): void {

this.tempOffset = offset;

private adjustBasedOnPrediction(predictions: TemperaturePrediction[]): void {

const nextHourTemp = predictions[0].temperature;
const targetTemp = this.calculateIdealTemp(nextHourTemp);

if (Math.abs(targetTemp - acService.getCurrentTemp()) > 1) {
  acService.setTemperature(targetTemp);

}

private calculateIdealTemp(outdoorTemp: number): number {
// 简单算法: 室内外温差保持在8-10度
let idealTemp: number;

if (outdoorTemp > 30) { // 炎热天气
  idealTemp = this.preferredTemp - 1;

else if (outdoorTemp < 10) { // 寒冷天气

  idealTemp = this.preferredTemp + 1;

else {

  idealTemp = this.preferredTemp;

return idealTemp + this.tempOffset;

private handlePresenceChange(present: boolean): void {

if (!present && acService.isOn()) {
  // 无人时调高温度(制冷)或调低温度(制热)以节能
  const currentTemp = acService.getCurrentTemp();
  const newTemp = acService.getMode() === 'cool' ? 
    Math.min(28, currentTemp + 2) : 
    Math.max(18, currentTemp - 2);
  
  acService.setTemperature(newTemp);

else if (present && !acService.isOn()) {

  // 有人时恢复偏好温度
  acService.turnOn();
  acService.setTemperature(this.preferredTemp);

}

private recordUserHabit(status: ACStatus): void {
const now = new Date();
const hour = now.getHours();
const dayOfWeek = now.getDay();
const weather = weatherService.getCurrentWeather();

const habit: UserHabit = {
  timestamp: now.getTime(),
  hour,
  dayOfWeek,
  weather,
  status
};

this.userHabits.push(habit);

// 保留最近3个月数据
if (this.userHabits.length > 90 * 24) {
  this.userHabits.shift();

// 保存数据

storage.set('userHabits', JSON.stringify(this.userHabits));

public getSuggestedSettings(): ACSettings {

if (this.userHabits.length === 0) {
  return {
    temperature: this.preferredTemp,
    mode: 'cool',
    fanSpeed: 'auto'
  };

// 简单推荐: 使用最频繁的设置组合

const settingCounts = new Map<string, number>();

this.userHabits.forEach(habit => {
  const key = {habit.status.temperature}_{habit.status.mode}_${habit.status.fanSpeed};
  settingCounts.set(key, (settingCounts.get(key) || 0) + 1);
});

let maxCount = 0;
let bestSetting = '';

settingCounts.forEach((count, key) => {
  if (count > maxCount) {
    maxCount = count;
    bestSetting = key;

});

const [temp, mode, fanSpeed] = bestSetting.split('_');

return {
  temperature: parseFloat(temp),
  mode: mode as ACMode,
  fanSpeed: fanSpeed as FanSpeed
};

}

export const smartControl = SmartControlService.getInstance();

空调控制服务

// ACService.ets
import { irService } from ‘./InfraredService’;
import { syncService } from ‘./SyncService’;

class ACService {
private static instance: ACService;
private currentStatus: ACStatus = {
power: false,
mode: ‘cool’,
temperature: 26,
fanSpeed: ‘auto’,
brand: ‘default’
};

private constructor() {
this.loadLastStatus();
private async loadLastStatus(): Promise<void> {

const status = await storage.get('lastACStatus');
if (status) {
  this.currentStatus = JSON.parse(status);

}

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

public turnOn(): void {

if (this.currentStatus.power) return;

this.currentStatus.power = true;
this.sendCommand('power');
this.saveAndSync();

public turnOff(): void {

if (!this.currentStatus.power) return;

this.currentStatus.power = false;
this.sendCommand('power');
this.saveAndSync();

public setMode(mode: ACMode): void {

if (this.currentStatus.mode === mode) return;

this.currentStatus.mode = mode;
this.sendCommand(mode);
this.saveAndSync();

public setTemperature(temp: number): void {

if (this.currentStatus.temperature === temp) return;

this.currentStatus.temperature = temp;
this.sendCommand('temperature');
this.saveAndSync();

public setFanSpeed(speed: FanSpeed): void {

if (this.currentStatus.fanSpeed === speed) return;

this.currentStatus.fanSpeed = speed;
this.sendCommand(speed);
this.saveAndSync();

private sendCommand(command: string): void {

try {
  irService.sendCode(this.currentStatus.brand, command);

catch (error) {

  console.error('Failed to send IR command:', error);

}

private saveAndSync(): void {
storage.set(‘lastACStatus’, JSON.stringify(this.currentStatus));
syncService.syncACStatus(this.currentStatus);
EventBus.emit(‘acStatusChanged’, this.currentStatus);
public getCurrentStatus(): ACStatus {

return { ...this.currentStatus };

public isOn(): boolean {

return this.currentStatus.power;

public getCurrentTemp(): number {

return this.currentStatus.temperature;

public getMode(): ACMode {

return this.currentStatus.mode;

public getFanSpeed(): FanSpeed {

return this.currentStatus.fanSpeed;

public setBrand(brand: string): void {

this.currentStatus.brand = brand;
this.saveAndSync();

}

export const acService = ACService.getInstance();

五、总结

本智能空调控制系统实现了以下核心价值:
万能遥控:学习支持各种品牌空调的红外编码

智能预测:基于环境数据预测温度变化趋势

人体感知:多传感器融合检测室内人员存在

跨端协同:多设备实时同步空调状态和控制

节能优化:根据使用习惯和场景自动调节

扩展方向:
增加语音控制功能

开发基于地理围栏的智能控制

集成到智能家居场景联动

添加能耗统计和节能报告

支持更多家电设备的控制

注意事项:
红外学习需要对准遥控器发射头

温度预测准确度依赖传感器数据质量

人体检测可能存在误判

多设备控制需登录相同账号

首次使用建议进行完整设置向导

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐