鸿蒙智能空调自动调温系统开发指南 原创
鸿蒙智能空调自动调温系统开发指南
一、系统架构设计
基于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();
五、总结
本智能空调控制系统实现了以下核心价值:
万能遥控:学习支持各种品牌空调的红外编码
智能预测:基于环境数据预测温度变化趋势
人体感知:多传感器融合检测室内人员存在
跨端协同:多设备实时同步空调状态和控制
节能优化:根据使用习惯和场景自动调节
扩展方向:
增加语音控制功能
开发基于地理围栏的智能控制
集成到智能家居场景联动
添加能耗统计和节能报告
支持更多家电设备的控制
注意事项:
红外学习需要对准遥控器发射头
温度预测准确度依赖传感器数据质量
人体检测可能存在误判
多设备控制需登录相同账号
首次使用建议进行完整设置向导




















