
鸿蒙智能水浸报警系统开发指南 原创
鸿蒙智能水浸报警系统开发指南
一、系统架构设计
基于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卡并充值
首次使用建议进行功能测试
低电量时部分功能可能受限
