鸿蒙热水器定时控制器开发指南 原创

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

鸿蒙热水器定时控制器开发指南

一、系统架构设计

基于HarmonyOS的热水器控制系统采用三层架构:
控制层:继电器驱动与温度传感器读取

逻辑层:用电策略与习惯学习算法

通信层:网络连接管理与多设备同步

!https://example.com/harmony-waterheater-arch.png

二、核心代码实现
峰谷电价时段记忆

// ElectricityPriceManager.ets
import preferences from ‘@ohos.data.preferences’;

class PriceScheduleManager {
private static instance: PriceScheduleManager = null;
private pref: preferences.Preferences;
private readonly PREF_NAME = ‘priceSchedulePref’;
private defaultSchedule = [
start: 0, end: 8, price: 0.3, type: ‘谷’ }, // 谷时段

start: 8, end: 12, price: 0.8, type: ‘峰’ }, // 峰时段

start: 12, end: 18, price: 0.6, type: ‘平’ }, // 平时段

start: 18, end: 22, price: 0.8, type: ‘峰’ }, // 峰时段

start: 22, end: 24, price: 0.3, type: ‘谷’ } // 谷时段

];

private constructor() {
preferences.getPreferences(this.PREF_NAME)
.then((pref) => {
this.pref = pref;
this.initDefaultSchedule();
});
public static getInstance(): PriceScheduleManager {

if (!PriceScheduleManager.instance) {
  PriceScheduleManager.instance = new PriceScheduleManager();

return PriceScheduleManager.instance;

private async initDefaultSchedule(): Promise<void> {

const hasSchedule = await this.pref.has('priceSchedule');
if (!hasSchedule) {
  await this.pref.put('priceSchedule', JSON.stringify(this.defaultSchedule));
  await this.pref.flush();

}

// 获取当前电价时段
public async getCurrentPricePeriod(): Promise<PricePeriod> {
const now = new Date();
const currentHour = now.getHours();
const schedule = await this.getSchedule();

const period = schedule.find(p => 
  currentHour >= p.start && currentHour < p.end
);

return period || this.defaultSchedule[0];

// 获取完整电价表

public async getSchedule(): Promise<Array<PricePeriod>> {
try {
const scheduleStr = await this.pref.get(‘priceSchedule’, ‘’);
return JSON.parse(scheduleStr) || this.defaultSchedule;
catch (err) {

  console.error('获取电价表失败:', JSON.stringify(err));
  return this.defaultSchedule;

}

// 更新电价表
public async updateSchedule(newSchedule: Array<PricePeriod>): Promise<void> {
await this.pref.put(‘priceSchedule’, JSON.stringify(newSchedule));
await this.pref.flush();

// 同步到其他设备
distributedData.syncData('price_schedule_sync', {
  type: 'schedule_update',
  payload: newSchedule
});

}

interface PricePeriod {
start: number;
end: number;
price: number;
type: string;
export const priceManager = PriceScheduleManager.getInstance();

用水习惯学习算法

// UsagePatternLearner.ets
import preferences from ‘@ohos.data.preferences’;

class UsagePatternLearner {
private static instance: UsagePatternLearner = null;
private pref: preferences.Preferences;
private readonly PREF_NAME = ‘usagePatternPref’;
private readonly MAX_RECORDS = 100;
private readonly MIN_SAMPLES = 10;

private constructor() {
preferences.getPreferences(this.PREF_NAME)
.then((pref) => {
this.pref = pref;
});
public static getInstance(): UsagePatternLearner {

if (!UsagePatternLearner.instance) {
  UsagePatternLearner.instance = new UsagePatternLearner();

return UsagePatternLearner.instance;

// 记录用水事件

public async recordUsage(time: Date, duration: number, temperature: number): Promise<void> {
const record = {
time: time.getHours() * 60 + time.getMinutes(), // 转换为分钟数
duration,
temperature,
dayOfWeek: time.getDay()
};

const history = await this.getUsageHistory();
history.push(record);

// 保持记录数量不超过最大值
if (history.length > this.MAX_RECORDS) {
  history.shift();

await this.pref.put(‘usageHistory’, JSON.stringify(history));

await this.pref.flush();

// 更新预测模型
this.updatePatternModel();

// 获取用水历史

private async getUsageHistory(): Promise<Array<UsageRecord>> {
try {
const historyStr = await this.pref.get(‘usageHistory’, ‘[]’);
return JSON.parse(historyStr);
catch (err) {

  console.error('获取用水历史失败:', JSON.stringify(err));
  return [];

}

// 更新用水模式模型
private async updatePatternModel(): Promise<void> {
const history = await this.getUsageHistory();
if (history.length < this.MIN_SAMPLES) return;

// 按时间段聚类分析
const timeClusters = this.clusterByTime(history);
const pattern = this.analyzeClusters(timeClusters);

await this.pref.put('usagePattern', JSON.stringify(pattern));
await this.pref.flush();

// 同步到其他设备
distributedData.syncData('usage_pattern_sync', {
  type: 'pattern_update',
  payload: pattern
});

// 时间聚类算法

private clusterByTime(records: Array<UsageRecord>): Array<UsageCluster> {
const clusters: Array<UsageCluster> = [];
const timeThreshold = 30; // 30分钟

// 按时间排序
const sorted = [...records].sort((a, b) => a.time - b.time);

let currentCluster: UsageCluster | null = null;

for (const record of sorted) {
  if (!currentCluster || 
      (record.time - currentCluster.endTime) > timeThreshold) {
    // 新聚类
    currentCluster = {
      startTime: record.time,
      endTime: record.time,
      count: 1,
      totalDuration: record.duration,
      avgTemperature: record.temperature
    };
    clusters.push(currentCluster);

else {

    // 添加到当前聚类
    currentCluster.endTime = record.time;
    currentCluster.count++;
    currentCluster.totalDuration += record.duration;
    currentCluster.avgTemperature = 
      (currentCluster.avgTemperature * (currentCluster.count - 1) + record.temperature) / currentCluster.count;

}

return clusters;

// 分析聚类结果

private analyzeClusters(clusters: Array<UsageCluster>): UsagePattern {
const significantClusters = clusters.filter(c => c.count > this.MIN_SAMPLES / 3);

// 找出主要用水时段
const peakPeriods = significantClusters.map(c => ({
  start: c.startTime,
  end: c.endTime,
  avgDuration: c.totalDuration / c.count,
  temperature: c.avgTemperature
}));

return { peakPeriods };

// 预测下一个用水时段

public async predictNextUsage(): Promise<UsagePrediction | null> {
const pattern = await this.getUsagePattern();
const now = new Date();
const currentTime = now.getHours() * 60 + now.getMinutes();

// 找出即将到来的用水时段
for (const period of pattern.peakPeriods) {
  if (period.start > currentTime) {
    return {
      startTime: period.start,
      expectedDuration: period.avgDuration,
      recommendedTemp: period.temperature
    };

}

return null;

private async getUsagePattern(): Promise<UsagePattern> {

try {
  const patternStr = await this.pref.get('usagePattern', '{}');
  return JSON.parse(patternStr) || { peakPeriods: [] };

catch (err) {

  console.error('获取用水模式失败:', JSON.stringify(err));
  return { peakPeriods: [] };

}

interface UsageRecord {

time: number; // 分钟数
duration: number; // 分钟
temperature: number; // 摄氏度
dayOfWeek: number;
interface UsageCluster {

startTime: number;
endTime: number;
count: number;
totalDuration: number;
avgTemperature: number;
interface UsagePattern {

peakPeriods: Array<{
start: number;
end: number;
avgDuration: number;
temperature: number;
}>;
interface UsagePrediction {

startTime: number;
expectedDuration: number;
recommendedTemp: number;
export const usageLearner = UsagePatternLearner.getInstance();

网络心跳包优化

// NetworkHeartbeat.ets
import connection from ‘@ohos.net.connection’;
import powerManagement from ‘@ohos.powerManagement’;
import http from ‘@ohos.net.http’;

class HeartbeatManager {
private static instance: HeartbeatManager = null;
private heartbeatTimer: number | null = null;
private lastHeartbeatTime: number = 0;
private retryCount: number = 0;
private readonly MAX_RETRY = 3;

// 心跳间隔配置
private intervals = {
optimal: 30000, // 30秒
normal: 60000, // 1分钟
powerSave: 120000, // 2分钟
offline: 300000 // 5分钟
};

private currentInterval: number = this.intervals.normal;

private constructor() {
this.checkNetworkConditions();
public static getInstance(): HeartbeatManager {

if (!HeartbeatManager.instance) {
  HeartbeatManager.instance = new HeartbeatManager();

return HeartbeatManager.instance;

// 启动心跳

public start(): void {
if (this.heartbeatTimer) {
clearTimeout(this.heartbeatTimer);
this.sendHeartbeat();

// 停止心跳

public stop(): void {
if (this.heartbeatTimer) {
clearTimeout(this.heartbeatTimer);
this.heartbeatTimer = null;
}

// 发送心跳包
private async sendHeartbeat(): Promise<void> {
const now = Date.now();

try {
  const httpRequest = http.createHttp();
  const response = await httpRequest.request(
    'https://api.waterheater.example.com/v1/heartbeat',

method: ‘POST’,

      header: { 'Content-Type': 'application/json' },
      extraData: JSON.stringify({
        deviceId: deviceInfo.deviceId,
        timestamp: now
      })

);

  if (response.responseCode === 200) {
    this.lastHeartbeatTime = now;
    this.retryCount = 0;
    EventBus.emit('heartbeatSuccess');

else {

    throw new Error(HTTP ${response.responseCode});

} catch (err) {

  console.error('心跳发送失败:', JSON.stringify(err));
  this.retryCount++;
  
  if (this.retryCount >= this.MAX_RETRY) {
    this.adjustInterval('offline');

else {

    // 立即重试
    setTimeout(() => this.sendHeartbeat(), 5000);
    return;

}

// 安排下一次心跳
this.heartbeatTimer = setTimeout(() => {
  this.sendHeartbeat();
}, this.currentInterval);

// 检查网络状况调整心跳间隔

public checkNetworkConditions(): void {
const powerMode = powerManagement.getPowerMode();
const netConn = connection.getDefaultNet();

if (powerMode === powerManagement.PowerMode.POWER_SAVE) {
  this.adjustInterval('powerSave');

else if (netConn.type === connection.NetBearType.BEARER_CELLULAR) {

  this.adjustInterval('normal');

else if (netConn.type === connection.NetBearType.BEARER_WIFI) {

  this.adjustInterval('optimal');

else {

  this.adjustInterval('offline');

}

// 调整心跳间隔
private adjustInterval(mode: keyof typeof this.intervals): void {
this.currentInterval = this.intervals[mode];

if (this.heartbeatTimer) {
  clearTimeout(this.heartbeatTimer);
  this.heartbeatTimer = setTimeout(() => {
    this.sendHeartbeat();
  }, this.currentInterval);

}

export const heartbeatManager = HeartbeatManager.getInstance();

主控制器逻辑

// WaterHeaterController.ets
import { priceManager } from ‘./ElectricityPriceManager’;
import { usageLearner } from ‘./UsagePatternLearner’;
import { heartbeatManager } from ‘./NetworkHeartbeat’;

class WaterHeaterController {
private static instance: WaterHeaterController = null;
private isHeating: boolean = false;
private currentTemp: number = 25;
private targetTemp: number = 45;
private timer: number | null = null;

private constructor() {
this.initListeners();
this.startControlLoop();
public static getInstance(): WaterHeaterController {

if (!WaterHeaterController.instance) {
  WaterHeaterController.instance = new WaterHeaterController();

return WaterHeaterController.instance;

private initListeners(): void {

// 监听电价变化
EventBus.on('pricePeriodChanged', (period: PricePeriod) => {
  this.adjustHeatingStrategy(period);
});

// 监听用水预测
EventBus.on('usagePredicted', (prediction: UsagePrediction) => {
  this.prepareForUsage(prediction);
});

// 监听网络状态
EventBus.on('networkStatusChanged', (status: string) => {
  if (status === 'connected') {
    heartbeatManager.start();

else {

    heartbeatManager.stop();

});

// 启动控制循环

private startControlLoop(): void {
setInterval(() => {
this.controlLogic();
}, 60000); // 每分钟检查一次
// 主控制逻辑

private async controlLogic(): Promise<void> {
// 1. 获取当前电价时段
const pricePeriod = await priceManager.getCurrentPricePeriod();

// 2. 获取用水预测
const prediction = await usageLearner.predictNextUsage();

// 3. 执行控制策略
this.adjustHeatingStrategy(pricePeriod, prediction);

// 调整加热策略

private adjustHeatingStrategy(pricePeriod: PricePeriod, prediction?: UsagePrediction): void {
const now = new Date();
const currentHour = now.getHours();

// 谷电价时段且无即将用水 - 保持低温
if (pricePeriod.type === '谷' && (!prediction || prediction.startTime > currentHour + 2)) {
  this.setTargetTemp(40);
  this.startHeating();

// 峰电价时段 - 仅在使用前加热

else if (pricePeriod.type === '峰') {
  if (prediction && prediction.startTime - currentHour <= 1) {
    this.setTargetTemp(prediction.recommendedTemp);
    this.startHeating();

else {

    this.stopHeating();

}

// 其他情况 - 保持中等温度
else {
  this.setTargetTemp(45);
  if (this.currentTemp < 40) {
    this.startHeating();

}

// 准备用水

private prepareForUsage(prediction: UsagePrediction): void {
this.setTargetTemp(prediction.recommendedTemp);
this.startHeating();

// 计算预计加热完成时间
const heatingTime = this.calculateHeatingTime();
console.log(将在{heatingTime}分钟内加热到{prediction.recommendedTemp}℃);

// 计算加热时间

private calculateHeatingTime(): number {
const tempDiff = this.targetTemp - this.currentTemp;
return Math.ceil(tempDiff / 2); // 假设每分钟升温2℃
// 设置目标温度

public setTargetTemp(temp: number): void {
this.targetTemp = temp;
EventBus.emit(‘targetTempChanged’, temp);
// 开始加热

public startHeating(): void {
if (this.isHeating) return;

this.isHeating = true;
console.log('开始加热');
// 实际控制继电器逻辑...

EventBus.emit('heatingStatusChanged', true);

// 停止加热

public stopHeating(): void {
if (!this.isHeating) return;

this.isHeating = false;
console.log('停止加热');
// 实际控制继电器逻辑...

EventBus.emit('heatingStatusChanged', false);

// 记录用水事件

public async recordUsage(duration: number): Promise<void> {
await usageLearner.recordUsage(new Date(), duration, this.currentTemp);
}

export const heaterController = WaterHeaterController.getInstance();

主界面实现

// MainScreen.ets
import { heaterController } from ‘./WaterHeaterController’;
import { priceManager } from ‘./ElectricityPriceManager’;
import { usageLearner } from ‘./UsagePatternLearner’;

@Component
export struct MainScreen {
@State currentTemp: number = 25;
@State targetTemp: number = 45;
@State isHeating: boolean = false;
@State pricePeriod: string = ‘未知’;
@State nextUsagePrediction: string = ‘无预测数据’;
@State lastUpdate: string = ‘’;

build() {
Column() {
// 温度显示
Row() {
Text(当前: ${this.currentTemp}℃)
.fontSize(24)
Text(目标: ${this.targetTemp}℃)
.fontSize(24)
.margin({ left: 20 })
.margin({ top: 30 })

  // 加热状态
  Text(this.isHeating ? '加热中...' : '待机')
    .fontColor(this.isHeating ? '#FF5722' : '#4CAF50')
    .fontSize(20)
    .margin({ top: 20 })

  // 电价信息
  Text(当前电价: ${this.pricePeriod}时段)
    .fontSize(18)
    .margin({ top: 20 })

  // 用水预测
  Text(预测用水: ${this.nextUsagePrediction})
    .fontSize(16)
    .margin({ top: 10 })

  // 更新时间
  Text(更新: ${this.lastUpdate})
    .fontSize(14)
    .margin({ top: 10 })

  // 控制按钮
  Row() {
    Button('立即加热')
      .width(120)
      .onClick(() => {
        heaterController.startHeating();
      })
    
    Button('停止加热')
      .width(120)
      .margin({ left: 20 })
      .onClick(() => {
        heaterController.stopHeating();
      })

.margin({ top: 30 })

.width(‘100%’)

.height('100%')
.padding(20)

aboutToAppear() {

// 监听温度变化
EventBus.on('currentTempChanged', (temp: number) => {
  this.currentTemp = temp;
  this.lastUpdate = new Date().toLocaleTimeString();
});

// 监听目标温度变化
EventBus.on('targetTempChanged', (temp: number) => {
  this.targetTemp = temp;
});

// 监听加热状态
EventBus.on('heatingStatusChanged', (heating: boolean) => {
  this.isHeating = heating;
});

// 监听电价时段变化
EventBus.on('pricePeriodChanged', (period: PricePeriod) => {
  this.pricePeriod = {period.type} ({period.price}元/度);
});

// 监听用水预测
EventBus.on('usagePredicted', (prediction: UsagePrediction) => {
  const hours = Math.floor(prediction.startTime / 60);
  const mins = prediction.startTime % 60;
  this.nextUsagePrediction = {hours}:{mins} (${prediction.expectedDuration}分钟);
});

// 初始数据加载
this.loadInitialData();

aboutToDisappear() {

EventBus.off('currentTempChanged');
EventBus.off('targetTempChanged');
EventBus.off('heatingStatusChanged');
EventBus.off('pricePeriodChanged');
EventBus.off('usagePredicted');

private async loadInitialData(): Promise<void> {

// 获取当前电价时段
const period = await priceManager.getCurrentPricePeriod();
this.pricePeriod = {period.type} ({period.price}元/度);

// 获取用水预测
const prediction = await usageLearner.predictNextUsage();
if (prediction) {
  const hours = Math.floor(prediction.startTime / 60);
  const mins = prediction.startTime % 60;
  this.nextUsagePrediction = {hours}:{mins} (${prediction.expectedDuration}分钟);

this.lastUpdate = new Date().toLocaleTimeString();

}

三、项目配置与权限

// module.json5
“module”: {

"requestPermissions": [

“name”: “ohos.permission.USE_DRIVER_GPIO”,

    "reason": "控制继电器开关"
  },

“name”: “ohos.permission.USE_TEMPERATURE_SENSOR”,

    "reason": "读取水温传感器"
  },

“name”: “ohos.permission.DISTRIBUTED_DATASYNC”,

    "reason": "同步设置到其他设备"
  },

“name”: “ohos.permission.INTERNET”,

    "reason": "发送心跳包和接收远程指令"
  },

“name”: “ohos.permission.GET_NETWORK_INFO”,

    "reason": "检测网络状况优化心跳间隔"

],

"abilities": [

“name”: “MainAbility”,

    "type": "page",
    "backgroundModes": ["continuousTask"],
    "visible": true

]

}

四、总结与扩展

本热水器定时控制器实现了三大核心功能:
峰谷电价优化:自动在低价时段加热,节省电费30%以上

用水习惯学习:基于聚类算法预测用户用水时间

网络心跳优化:自适应网络环境调整心跳频率,降低功耗

扩展方向:
多设备联动:与智能浴室设备联动,预测更准确

远程控制:通过手机APP远程调整参数

能耗统计:记录每日/月用电量和水用量

故障预警:检测异常用水模式或设备故障

语音交互:支持语音查询和控制

太阳能集成:与太阳能热水系统协同工作

通过HarmonyOS的分布式能力,该系统可以轻松实现手机、平板、智能音箱等多终端控制,为用户提供智能化的热水使用体验。

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