鸿蒙智能水浸报警系统开发指南 原创

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

鸿蒙智能水浸报警系统开发指南

一、系统架构设计

基于HarmonyOS的分布式能力和硬件感知框架,我们设计了一套水浸报警系统,主要功能包括:
电极式检测:高灵敏度水接触检测电路

智能过滤:多维度误报过滤算法

双通道报警:WiFi+蜂窝网络双保险通信

跨设备联动:多终端实时接收报警通知

场景联动:与其他智能设备协同响应

!https://example.com/harmony-water-sensor-arch.png

二、核心代码实现
电极检测服务

// WaterDetectionService.ets
import driver from ‘@ohos.driver’;
import power from ‘@ohos.power’;

class WaterDetectionService {
private static instance: WaterDetectionService;
private gpioController: driver.GpioController | null = null;
private detectionPin: number = 12; // 默认GPIO12
private isWet: boolean = false;
private lastDetectionTime: number = 0;
private powerMode: power.Mode = power.Mode.NORMAL;

private constructor() {
this.initGpio();
this.initPowerListener();
private initGpio(): void {

try {
  this.gpioController = driver.createGpioController();
  this.gpioController.setDirection(this.detectionPin, driver.GpioDirection.INPUT);
  this.gpioController.setPull(this.detectionPin, driver.GpioPull.PULL_UP);
  
  // 设置中断监听
  this.gpioController.onInterrupt(this.detectionPin, (value) => {
    this.handleWaterDetection(value);
  }, {
    trigger: driver.GpioInterruptTrigger.TRIGGER_BOTH,
    debounce: 50 // 50ms消抖
  });

catch (error) {

  console.error('GPIO initialization failed:', error);

}

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

if (this.powerMode === power.Mode.POWER_SAVE) {
  // 省电模式下降低检测频率
  this.gpioController?.setDebounce(this.detectionPin, 200); // 200ms消抖

else {

  // 正常模式下恢复默认设置
  this.gpioController?.setDebounce(this.detectionPin, 50);

}

private handleWaterDetection(value: number): void {
const now = Date.now();
const wet = value === 0; // 低电平表示有水

if (wet !== this.isWet && now - this.lastDetectionTime > 1000) {
  this.isWet = wet;
  this.lastDetectionTime = now;
  
  EventBus.emit('waterStateChanged', {
    wet,
    timestamp: now,
    confidence: this.calculateConfidence()
  });

}

private calculateConfidence(): number {
// 基于电源模式和检测历史计算置信度
let baseConfidence = 0.9;

if (this.powerMode === power.Mode.POWER_SAVE) {
  baseConfidence *= 0.8;

return baseConfidence;

public static getInstance(): WaterDetectionService {

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

return WaterDetectionService.instance;

public isWaterDetected(): boolean {

return this.isWet;

public getLastDetectionTime(): number {

return this.lastDetectionTime;

public setDetectionPin(pin: number): void {

if (this.detectionPin === pin) return;

// 先取消原有监听
this.gpioController?.offInterrupt(this.detectionPin);

// 设置新引脚
this.detectionPin = pin;
this.gpioController?.setDirection(pin, driver.GpioDirection.INPUT);
this.gpioController?.setPull(pin, driver.GpioPull.PULL_UP);
this.gpioController?.onInterrupt(pin, (value) => {
  this.handleWaterDetection(value);
}, {
  trigger: driver.GpioInterruptTrigger.TRIGGER_BOTH,
  debounce: 50
});

public calibrate(): void {

// 校准基准值
this.gpioController?.setPull(this.detectionPin, driver.GpioPull.PULL_UP);
this.isWet = false;

}

export const waterDetection = WaterDetectionService.getInstance();

误报过滤服务

// FalseAlarmFilterService.ets
import { waterDetection } from ‘./WaterDetectionService’;
import sensor from ‘@ohos.sensor’;

class FalseAlarmFilterService {
private static instance: FalseAlarmFilterService;
private history: DetectionEvent[] = [];
private environmentData: EnvironmentData | null = null;

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

// 温度传感器
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_TEMPERATURE, (data) => {
  this.environmentData = {
    ...this.environmentData,
    temperature: data.value
  };
}, { interval: 60000 }); // 1分钟采样一次

// 湿度传感器
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_HUMIDITY, (data) => {
  this.environmentData = {
    ...this.environmentData,
    humidity: data.value
  };
}, { interval: 60000 });

private initEventListeners(): void {

EventBus.on('waterStateChanged', (event) => {
  this.handleDetectionEvent(event);
});

public static getInstance(): FalseAlarmFilterService {

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

return FalseAlarmFilterService.instance;

private handleDetectionEvent(event: DetectionEvent): void {

this.history.push(event);

// 保留最近24小时记录
if (this.history.length > 1440) { // 每分钟一条
  this.history.shift();

// 检查是否为误报

if (event.wet && this.isLikelyFalseAlarm(event)) {
  EventBus.emit('falseAlarmDetected', {
    ...event,
    reason: this.getFalseAlarmReason(event)
  });

else {

  EventBus.emit('validWaterDetection', event);

}

private isLikelyFalseAlarm(event: DetectionEvent): boolean {
// 规则1: 短时间内多次触发
const recentEvents = this.history.filter(e =>
e.timestamp > event.timestamp - 300000 && e.wet
);
if (recentEvents.length > 5) {
return true;
// 规则2: 环境湿度异常高(可能导致误报)

if (this.environmentData?.humidity && this.environmentData.humidity > 90) {
  return true;

// 规则3: 温度变化剧烈(冷凝水可能导致误报)

const tempChanges = this.getRecentTemperatureChanges();
if (tempChanges.some(change => Math.abs(change) > 5)) {
  return true;

return false;

private getRecentTemperatureChanges(): number[] {

if (!this.environmentData) return [];

const tempReadings = this.history
  .filter(e => e.environmentData?.temperature)
  .map(e => e.environmentData!.temperature);

const changes: number[] = [];
for (let i = 1; i < tempReadings.length; i++) {
  changes.push(tempReadings[i] - tempReadings[i - 1]);

return changes;

private getFalseAlarmReason(event: DetectionEvent): string {

const recentEvents = this.history.filter(e => 
  e.timestamp > event.timestamp - 300000 && e.wet
);

if (recentEvents.length > 5) {
  return '短时间内多次触发';

if (this.environmentData?.humidity && this.environmentData.humidity > 90) {

  return '环境湿度过高';

const tempChanges = this.getRecentTemperatureChanges();

if (tempChanges.some(change => Math.abs(change) > 5)) {
  return '温度剧烈变化';

return ‘未知原因’;

public getDetectionHistory(): DetectionEvent[] {

return [...this.history];

public getCurrentEnvironment(): EnvironmentData | null {

return this.environmentData;

}

export const alarmFilter = FalseAlarmFilterService.getInstance();

双通道通信服务

// DualChannelService.ets
import net from ‘@ohos.net’;
import http from ‘@ohos.net.http’;
import telephony from ‘@ohos.telephony’;

class DualChannelService {
private static instance: DualChannelService;
private primaryChannel: ‘wifi’ | ‘cellular’ = ‘wifi’;
private backupMessageQueue: AlertMessage[] = [];
private isSendingBackup: boolean = false;

private constructor() {
this.initNetworkListener();
private initNetworkListener(): void {

net.on('networkStateChange', (state) => {
  this.handleNetworkChange(state);
});

private handleNetworkChange(state: net.NetworkState): void {

const wifiConnected = state.wifi && state.wifi.state === 'CONNECTED';
const cellularConnected = state.cellular && state.cellular.state === 'CONNECTED';

if (wifiConnected) {
  this.primaryChannel = 'wifi';
  this.processBackupQueue();

else if (cellularConnected) {

  this.primaryChannel = 'cellular';

}

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

public async sendAlert(message: AlertMessage): Promise<void> {

try {
  // 尝试主通道发送
  await this.sendViaPrimary(message);

catch (error) {

  console.error('Primary channel failed, adding to backup queue:', error);
  
  // 加入备用队列
  this.backupMessageQueue.push(message);
  
  // 如果当前没有在发送备用消息,开始处理
  if (!this.isSendingBackup) {
    this.processBackupQueue();

}

private async sendViaPrimary(message: AlertMessage): Promise<void> {

if (this.primaryChannel === 'wifi') {
  await this.sendViaWifi(message);

else {

  await this.sendViaCellular(message);

}

private async sendViaWifi(message: AlertMessage): Promise<void> {
const httpRequest = http.createHttp();
await httpRequest.request(
https://api.example.com/water-alert’,
method: ‘POST’,

    header: { 'Content-Type': 'application/json' },
    extraData: JSON.stringify(message)

);

private async sendViaCellular(message: AlertMessage): Promise<void> {

// 检查蜂窝数据是否可用
const simState = await telephony.getSimState();
if (simState !== telephony.SimState.SIM_STATE_READY) {
  throw new Error('Cellular network not ready');

// 使用短信作为备用通道

await telephony.sendMessage({
  slotId: 0, // 主卡
  content: 水浸报警: {message.location} {message.timestamp},
  destination: '13800138000' // 预设报警号码
});

private async processBackupQueue(): Promise<void> {

if (this.backupMessageQueue.length === 0 || this.isSendingBackup) return;

this.isSendingBackup = true;
const message = this.backupMessageQueue.shift()!;

try {
  await this.sendViaCellular(message);
  
  // 发送成功,继续处理下一条
  if (this.backupMessageQueue.length > 0) {
    setTimeout(() => this.processBackupQueue(), 1000);

else {

    this.isSendingBackup = false;

} catch (error) {

  console.error('Failed to send via backup channel:', error);
  
  // 放回队列前端
  this.backupMessageQueue.unshift(message);
  this.isSendingBackup = false;
  
  // 10秒后重试
  setTimeout(() => this.processBackupQueue(), 10000);

}

public getQueueSize(): number {
return this.backupMessageQueue.length;
public getCurrentChannel(): string {

return this.primaryChannel;

}

export const dualChannel = DualChannelService.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.wateralert',
  userInfo: { userId: 'default' }
};

this.kvManager = distributedData.createKVManager(config);
this.kvStore = await this.kvManager.getKVStore('water_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 syncAlert(alert: WaterAlert): Promise<void> {

const syncAlert: SyncAlert = {
  ...alert,
  deviceId: deviceManager.getLocalDevice().id,
  timestamp: Date.now()
};

await this.kvStore.put(alert_${alert.id}, JSON.stringify(syncAlert));

public async syncDeviceStatus(status: DeviceStatus): Promise<void> {

const syncStatus: SyncStatus = {
  ...status,
  deviceId: deviceManager.getLocalDevice().id,
  timestamp: Date.now()
};

await this.kvStore.put(status_${status.deviceId}, JSON.stringify(syncStatus));

public async syncEnvironmentData(data: EnvironmentData): Promise<void> {

const syncData: SyncEnvironment = {
  ...data,
  deviceId: deviceManager.getLocalDevice().id,
  timestamp: Date.now()
};

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

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

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

try {
  const parsed = JSON.parse(data.value);
  
  if (data.key.startsWith('alert_')) {
    EventBus.emit('remoteAlert', parsed);

else if (data.key.startsWith(‘status_’)) {

    EventBus.emit('remoteStatus', parsed);

else if (data.key.startsWith(‘env_’)) {

    EventBus.emit('remoteEnvData', parsed);

} 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: AlertCommand): Promise<void> {

const syncCommand: SyncCommand = {
  type: 'command',
  command,
  timestamp: Date.now(),
  deviceId: deviceManager.getLocalDevice().id
};

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

}

export const syncService = SyncService.getInstance();

三、主界面实现
报警主界面

// WaterAlertView.ets
@Component
struct WaterAlertView {
@State alerts: WaterAlert[] = [];
@State deviceStatus: DeviceStatus | null = null;
@State environment: EnvironmentData | null = null;
@State connectedDevices: number = 0;

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

Column() {
  // 状态栏
  StatusBar({
    status: this.deviceStatus,
    environment: this.environment,
    connectedDevices: this.connectedDevices
  })
  .margin({ top: 16, bottom: 16 })
  
  // 报警列表
  AlertList({
    alerts: this.alerts,
    onAcknowledge: (alert) => this.acknowledgeAlert(alert)
  })
  .layoutWeight(1)
  
  // 控制按钮
  ControlButtons({
    onTest: () => this.testAlarm(),
    onSilence: () => this.silenceAlarm(),
    onSettings: () => this.openSettings()
  })
  .margin({ bottom: 16 })

.padding(16)

private initEventListeners(): void {

EventBus.on('waterStateChanged', (event) => {
  this.handleWaterEvent(event);
});

EventBus.on('remoteAlert', (alert) => {
  this.addAlert(alert);
});

EventBus.on('remoteStatus', (status) => {
  this.deviceStatus = status;
});

EventBus.on('remoteEnvData', (env) => {
  this.environment = env;
});

private async loadInitialData(): Promise<void> {

this.alerts = await alertService.getRecentAlerts();
this.deviceStatus = await deviceService.getStatus();
this.environment = await environmentService.getCurrentData();
this.connectedDevices = (await syncService.getConnectedDevices()).length;

private handleWaterEvent(event: DetectionEvent): void {

if (event.wet) {
  const alert: WaterAlert = {
    id: generateId(),
    location: '客厅地板', // 从配置获取
    timestamp: event.timestamp,
    confidence: event.confidence,
    acknowledged: false
  };
  
  this.addAlert(alert);
  syncService.syncAlert(alert);
  dualChannel.sendAlert(this.createAlertMessage(alert));

}

private createAlertMessage(alert: WaterAlert): AlertMessage {
return {
location: alert.location,
timestamp: new Date(alert.timestamp).toLocaleString(),
severity: ‘critical’,
deviceId: deviceManager.getLocalDevice().id
};
private addAlert(alert: WaterAlert): void {

this.alerts = [alert, ...this.alerts].slice(0, 100); // 保留最近100条

private acknowledgeAlert(alert: WaterAlert): void {

const updated = { ...alert, acknowledged: true };
this.alerts = this.alerts.map(a => a.id === alert.id ? updated : a);
syncService.syncAlert(updated);

private testAlarm(): void {

const testAlert: WaterAlert = {
  id: 'test_' + Date.now(),
  location: '测试位置',
  timestamp: Date.now(),
  confidence: 1.0,
  acknowledged: true
};

this.addAlert(testAlert);
EventBus.emit('playTestSound');

private silenceAlarm(): void {

EventBus.emit('stopAlarmSound');

private openSettings(): void {

router.push({ url: 'pages/Settings' });

}

@Component
struct StatusBar {
private status: DeviceStatus | null;
private environment: EnvironmentData | null;
private connectedDevices: number;

build() {
Row() {
// 设备状态
Column() {
Text(this.status?.batteryLevel ? ${this.status.batteryLevel}% : ‘–%’)
.fontSize(16)
Text(‘电量’)
.fontSize(12)
.margin({ right: 16 })

  // 环境数据
  Column() {
    Text(this.environment?.temperature ? ${this.environment.temperature}°C : '--°C')
      .fontSize(16)
    Text('温度')
      .fontSize(12)

.margin({ right: 16 })

  Column() {
    Text(this.environment?.humidity ? ${this.environment.humidity}% : '--%')
      .fontSize(16)
    Text('湿度')
      .fontSize(12)

.margin({ right: 16 })

  // 连接设备
  Column() {
    Text(${this.connectedDevices})
      .fontSize(16)
    Text('设备')
      .fontSize(12)

}

}

@Component
struct AlertList {
private alerts: WaterAlert[];
private onAcknowledge: (alert: WaterAlert) => void;

build() {
List() {
ForEach(this.alerts, (alert) => {
ListItem() {
AlertItem({
alert,
onAcknowledge: () => this.onAcknowledge(alert)
})
})

}

@Component

struct AlertItem {
private alert: WaterAlert;
private onAcknowledge: () => void;

build() {
Row() {
Column() {
Text(this.alert.location)
.fontSize(16)
.fontWeight(FontWeight.Bold)

    Text(this.formatTime(this.alert.timestamp))
      .fontSize(14)
      .fontColor('#666666')

.layoutWeight(1)

  if (!this.alert.acknowledged) {
    Button('确认')
      .onClick(() => this.onAcknowledge())
      .width(80)

}

.padding(12)
.backgroundColor(this.alert.acknowledged ? '#E8F5E9' : '#FFEBEE')
.borderRadius(8)
.margin({ bottom: 8 })

private formatTime(timestamp: number): string {

const date = new Date(timestamp);
return {date.getHours()}:{date.getMinutes().toString().padStart(2, '0')};

}

@Component
struct ControlButtons {
private onTest: () => void;
private onSilence: () => void;
private onSettings: () => void;

build() {
Row() {
Button(‘测试’)
.onClick(() => this.onTest())
.width(100)

  Button('静音')
    .onClick(() => this.onSilence())
    .width(100)
    .margin({ left: 16, right: 16 })
  
  Button('设置')
    .onClick(() => this.onSettings())
    .width(100)

}

设置界面

// SettingsView.ets
@Component
struct SettingsView {
@State sensitivity: number = 50;
@State alarmVolume: number = 80;
@State notificationEnabled: boolean = true;
@State smsBackupEnabled: boolean = true;
@State location: string = ‘客厅地板’;

build() {
Column() {
// 检测灵敏度
Text(检测灵敏度: ${this.sensitivity}%)
.fontSize(16)
.margin({ top: 16, bottom: 8 })

  Slider({
    value: this.sensitivity,
    min: 10,
    max: 100,
    step: 5
  })
  .onChange((value) => this.changeSensitivity(value))
  .margin({ bottom: 24 })
  
  // 报警音量
  Text(报警音量: ${this.alarmVolume}%)
    .fontSize(16)
    .margin({ bottom: 8 })
  
  Slider({
    value: this.alarmVolume,
    min: 0,
    max: 100,
    step: 5
  })
  .onChange((value) => this.changeVolume(value))
  .margin({ bottom: 24 })
  
  // 通知开关
  Row() {
    Text('启用通知')
      .fontSize(16)
      .layoutWeight(1)
    
    Toggle({ type: ToggleType.Switch, isOn: this.notificationEnabled })
      .onChange((isOn) => this.toggleNotification(isOn))

.margin({ bottom: 16 })

  // 短信备用
  Row() {
    Text('短信备用通道')
      .fontSize(16)
      .layoutWeight(1)
    
    Toggle({ type: ToggleType.Switch, isOn: this.smsBackupEnabled })
      .onChange((isOn) => this.toggleSmsBackup(isOn))

.margin({ bottom: 16 })

  // 位置设置
  Text('设备位置')
    .fontSize(16)
    .margin({ bottom: 8 })
  
  TextInput({ text: this.location })
    .onChange((value) => this.changeLocation(value))
    .margin({ bottom: 24 })
  
  // 保存按钮
  Button('保存设置')
    .onClick(() => this.saveSettings())
    .width('100%')
    .height(48)

.padding(16)

private changeSensitivity(value: number): void {

this.sensitivity = value;
waterDetection.setSensitivity(value / 100);

private changeVolume(value: number): void {

this.alarmVolume = value;
audioService.setVolume(value);

private toggleNotification(enabled: boolean): void {

this.notificationEnabled = enabled;
notificationService.setEnabled(enabled);

private toggleSmsBackup(enabled: boolean): void {

this.smsBackupEnabled = enabled;
dualChannel.setBackupEnabled(enabled);

private changeLocation(location: string): void {

this.location = location;

private saveSettings(): void {

const settings: DeviceSettings = {
  sensitivity: this.sensitivity,
  alarmVolume: this.alarmVolume,
  notificationEnabled: this.notificationEnabled,
  smsBackupEnabled: this.smsBackupEnabled,
  location: this.location
};

storage.set('deviceSettings', JSON.stringify(settings));
syncService.syncSettings(settings);
prompt.showToast({ message: '设置已保存' });

}

四、高级功能实现
报警管理服务

// AlertService.ets
import { waterDetection } from ‘./WaterDetectionService’;
import { dualChannel } from ‘./DualChannelService’;
import { syncService } from ‘./SyncService’;

class AlertService {
private static instance: AlertService;
private alertHistory: WaterAlert[] = [];
private activeAlerts: Set<string> = new Set();
private alarmSoundPlaying: boolean = false;

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

const alerts = await storage.get('waterAlerts');
if (alerts) {
  this.alertHistory = JSON.parse(alerts);

}

private initEventListeners(): void {
EventBus.on(‘waterStateChanged’, (event) => {
this.handleDetection(event);
});

EventBus.on('remoteAlert', (alert) => {
  this.addAlert(alert);
});

EventBus.on('playTestSound', () => {
  this.playAlarmSound(true);
});

EventBus.on('stopAlarmSound', () => {
  this.stopAlarmSound();
});

public static getInstance(): AlertService {

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

return AlertService.instance;

private handleDetection(event: DetectionEvent): void {

if (event.wet) {
  const alert: WaterAlert = {
    id: generateId(),
    location: settings.getLocation(),
    timestamp: event.timestamp,
    confidence: event.confidence,
    acknowledged: false
  };
  
  this.addAlert(alert);
  this.playAlarmSound();
  
  // 通过双通道发送报警
  dualChannel.sendAlert({
    location: alert.location,
    timestamp: new Date(alert.timestamp).toLocaleString(),
    severity: 'critical'
  });

}

public addAlert(alert: WaterAlert): void {
this.alertHistory.unshift(alert);
this.activeAlerts.add(alert.id);

// 保存到本地存储
storage.set('waterAlerts', JSON.stringify(this.alertHistory));

// 同步到其他设备
syncService.syncAlert(alert);

// 触发事件
EventBus.emit('alertAdded', alert);

public acknowledgeAlert(id: string): void {

const alert = this.alertHistory.find(a => a.id === id);
if (alert && !alert.acknowledged) {
  alert.acknowledged = true;
  this.activeAlerts.delete(id);
  
  // 保存和同步
  storage.set('waterAlerts', JSON.stringify(this.alertHistory));
  syncService.syncAlert(alert);
  
  // 如果没有活动报警,停止声音
  if (this.activeAlerts.size === 0) {
    this.stopAlarmSound();

}

private playAlarmSound(test: boolean = false): void {

if (this.alarmSoundPlaying && !test) return;

this.alarmSoundPlaying = true;
audioService.playAlarm(test);

// 10秒后检查是否需要继续
setTimeout(() => {
  if (this.activeAlerts.size > 0 && !test) {
    this.playAlarmSound();

}, 10000);

private stopAlarmSound(): void {

this.alarmSoundPlaying = false;
audioService.stopAlarm();

public getRecentAlerts(count: number = 20): WaterAlert[] {

return this.alertHistory.slice(0, count);

public getActiveAlerts(): WaterAlert[] {

return this.alertHistory.filter(alert => 
  !alert.acknowledged && this.activeAlerts.has(alert.id)
);

public clearHistory(): void {

this.alertHistory = [];
this.activeAlerts.clear();
storage.set('waterAlerts', '[]');

}

export const alertService = AlertService.getInstance();

设备管理服务

// DeviceService.ets
import power from ‘@ohos.power’;
import sensor from ‘@ohos.sensor’;

class DeviceService {
private static instance: DeviceService;
private batteryLevel: number = 100;
private networkStatus: ‘wifi’ ‘cellular’
‘offline’ = ‘offline’;
private lastStatusUpdate: number = 0;

private constructor() {
this.initBatteryListener();
this.initNetworkListener();
private initBatteryListener(): void {

power.on('batteryLevelChange', (level) => {
  this.batteryLevel = level;
  this.updateStatus();
});

private initNetworkListener(): void {

net.on('networkStateChange', (state) => {
  if (state.wifi && state.wifi.state === 'CONNECTED') {
    this.networkStatus = 'wifi';

else if (state.cellular && state.cellular.state === ‘CONNECTED’) {

    this.networkStatus = 'cellular';

else {

    this.networkStatus = 'offline';

this.updateStatus();

});

public static getInstance(): DeviceService {

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

return DeviceService.instance;

private updateStatus(): void {

const now = Date.now();
if (now - this.lastStatusUpdate < 60000) return; // 1分钟更新一次

const status: DeviceStatus = {
  batteryLevel: this.batteryLevel,
  networkStatus: this.networkStatus,
  timestamp: now
};

this.lastStatusUpdate = now;
syncService.syncDeviceStatus(status);

public getStatus(): DeviceStatus {

return {
  batteryLevel: this.batteryLevel,
  networkStatus: this.networkStatus,
  timestamp: Date.now()
};

public isOnline(): boolean {

return this.networkStatus !== 'offline';

public isLowBattery(): boolean {

return this.batteryLevel < 20;

public getBatteryLevel(): number {

return this.batteryLevel;

public getNetworkStatus(): string {

return this.networkStatus;

}

export const deviceService = DeviceService.getInstance();

环境监测服务

// EnvironmentService.ets
import sensor from ‘@ohos.sensor’;

class EnvironmentService {
private static instance: EnvironmentService;
private temperature: number | null = null;
private humidity: number | null = null;
private lastUpdate: number = 0;

private constructor() {
this.initSensors();
private initSensors(): void {

// 温度传感器
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_TEMPERATURE, (data) => {
  this.temperature = data.value;
  this.updateEnvironmentData();
}, { interval: 60000 }); // 1分钟采样一次

// 湿度传感器
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_HUMIDITY, (data) => {
  this.humidity = data.value;
  this.updateEnvironmentData();
}, { interval: 60000 });

public static getInstance(): EnvironmentService {

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

return EnvironmentService.instance;

private updateEnvironmentData(): void {

const now = Date.now();
if (now - this.lastUpdate < 300000) return; // 5分钟更新一次

if (this.temperature ! null && this.humidity ! null) {
  const envData: EnvironmentData = {
    temperature: this.temperature,
    humidity: this.humidity,
    timestamp: now
  };
  
  this.lastUpdate = now;
  syncService.syncEnvironmentData(envData);

}

public getCurrentData(): EnvironmentData | null {
if (this.temperature = null || this.humidity = null) {
return null;
return {

  temperature: this.temperature,
  humidity: this.humidity,
  timestamp: Date.now()
};

public getTemperatureTrend(): number[] {

// 返回最近6小时温度变化趋势
return [22, 22, 23, 23, 22, 21]; // 示例数据

public getHumidityTrend(): number[] {

// 返回最近6小时湿度变化趋势
return [45, 46, 48, 50, 52, 55]; // 示例数据

}

export const environmentService = EnvironmentService.getInstance();

五、总结

本水浸报警系统实现了以下核心价值:
高可靠性检测:电极式电路结合智能算法确保准确识别

多重防误报:环境数据交叉验证降低误报率

双通道保障:主备通信通道确保报警必达

多终端联动:跨设备实时同步报警状态

智能场景响应:可联动关闭阀门、启动排水等设备

扩展方向:
增加水位高度检测功能

集成智能家居自动关闭水阀

开发漏水历史记录和分析

支持更多通信协议如LoRa、NB-IoT

添加自检和故障预警功能

注意事项:
电极需定期清洁防止氧化影响检测

安装位置应选择易积水区域

蜂窝网络需配置SIM卡并充值

首次使用建议进行功能测试

低电量时部分功能可能受限

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