
鸿蒙智慧厕所引导系统开发指南 原创
鸿蒙智慧厕所引导系统开发指南
一、系统架构设计
基于HarmonyOS的分布式能力,我们设计了一套智能厕所引导系统,主要功能包括:
人数统计:红外传感器精确统计厕所使用人数
动态引导:电子屏幕实时显示空闲厕位信息
智能消毒:根据使用情况自动触发消毒设备
多终端同步:管理员端、用户手机端数据实时同步
数据分析:使用数据统计与分析
!https://example.com/harmony-smart-toilet-arch.png
二、核心代码实现
红外人数统计服务
// PeopleCountingService.ets
import sensor from ‘@ohos.sensor’;
import power from ‘@ohos.power’;
class PeopleCountingService {
private static instance: PeopleCountingService;
private irSensor: sensor.InfraredResponse | null = null;
private currentCount: number = 0;
private maxCapacity: number = 10;
private powerMode: power.Mode = power.Mode.NORMAL;
private constructor() {
this.initSensor();
this.initPowerListener();
private initSensor(): void {
try {
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_INFRARED, (data) => {
this.handleInfraredData(data);
}, { interval: 1000 }); // 1秒采样一次
catch (error) {
console.error('Infrared sensor initialization failed:', error);
}
private initPowerListener(): void {
power.on(‘powerModeChange’, (mode) => {
this.powerMode = mode;
this.adjustSamplingRate();
});
private adjustSamplingRate(): void {
const interval = this.powerMode === power.Mode.POWER_SAVE ? 2000 : 1000;
sensor.off(sensor.SensorType.SENSOR_TYPE_ID_INFRARED);
sensor.on(sensor.SensorType.SENSOR_TYPE_ID_INFRARED, (data) => {
this.handleInfraredData(data);
}, { interval });
public static getInstance(): PeopleCountingService {
if (!PeopleCountingService.instance) {
PeopleCountingService.instance = new PeopleCountingService();
return PeopleCountingService.instance;
private handleInfraredData(data: sensor.InfraredResponse): void {
// 简单逻辑:检测到红外变化即认为有人进出
if (data.value > 0 && this.currentCount < this.maxCapacity) {
this.currentCount++;
this.triggerCountChange();
else if (data.value === 0 && this.currentCount > 0) {
this.currentCount--;
this.triggerCountChange();
}
private triggerCountChange(): void {
EventBus.emit(‘peopleCountChanged’, {
count: this.currentCount,
timestamp: Date.now()
});
// 同步到其他设备
syncService.syncPeopleCount(this.currentCount);
public getCurrentCount(): number {
return this.currentCount;
public setMaxCapacity(capacity: number): void {
this.maxCapacity = capacity;
public resetCounter(): void {
this.currentCount = 0;
this.triggerCountChange();
}
export const peopleCounter = PeopleCountingService.getInstance();
屏幕动态刷新服务
// DisplayService.ets
import display from ‘@ohos.display’;
import power from ‘@ohos.power’;
class DisplayService {
private static instance: DisplayService;
private refreshRate: number = 60; // 默认60Hz
private powerMode: power.Mode = power.Mode.NORMAL;
private lastUpdateTime: number = 0;
private isActive: boolean = true;
private constructor() {
this.initPowerListener();
this.startActivityCheck();
private initPowerListener(): void {
power.on('powerModeChange', (mode) => {
this.powerMode = mode;
this.adjustRefreshRate();
});
private startActivityCheck(): void {
setInterval(() => {
this.checkActivity();
}, 5000); // 每5秒检查一次活动状态
private checkActivity(): void {
const now = Date.now();
const timeSinceLastUpdate = now - this.lastUpdateTime;
// 超过30秒无更新则进入低功耗模式
this.isActive = timeSinceLastUpdate < 30000;
this.adjustRefreshRate();
public static getInstance(): DisplayService {
if (!DisplayService.instance) {
DisplayService.instance = new DisplayService();
return DisplayService.instance;
public updateContent(): void {
this.lastUpdateTime = Date.now();
if (!this.isActive) {
this.isActive = true;
this.adjustRefreshRate();
}
private adjustRefreshRate(): void {
let targetRate: number;
if (!this.isActive) {
targetRate = 30; // 非活动状态30Hz
else {
switch (this.powerMode) {
case power.Mode.POWER_SAVE:
targetRate = 45; // 省电模式45Hz
break;
case power.Mode.PERFORMANCE:
targetRate = 90; // 高性能模式90Hz
break;
default:
targetRate = 60; // 普通模式60Hz
}
if (targetRate !== this.refreshRate) {
this.setRefreshRate(targetRate);
}
private setRefreshRate(rate: number): void {
try {
display.setDefaultDisplayRefreshRate(rate);
this.refreshRate = rate;
catch (error) {
console.error('Failed to set refresh rate:', error);
}
public getCurrentRefreshRate(): number {
return this.refreshRate;
public getPowerMode(): power.Mode {
return this.powerMode;
}
export const displayService = DisplayService.getInstance();
消毒设备联动服务
// DisinfectionService.ets
import driver from ‘@ohos.driver’;
import { peopleCounter } from ‘./PeopleCountingService’;
class DisinfectionService {
private static instance: DisinfectionService;
private deviceController: driver.GpioController | null = null;
private disinfectionPin: number = 18; // GPIO18控制消毒设备
private isDisinfecting: boolean = false;
private lastDisinfectionTime: number = 0;
private disinfectionInterval: number = 3600000; // 1小时消毒一次
private constructor() {
this.initDevice();
this.initEventListeners();
this.startDisinfectionCheck();
private initDevice(): void {
try {
this.deviceController = driver.createGpioController();
this.deviceController.setDirection(this.disinfectionPin, driver.GpioDirection.OUTPUT);
catch (error) {
console.error('Failed to initialize disinfection device:', error);
}
private initEventListeners(): void {
EventBus.on(‘peopleCountChanged’, (data) => {
if (data.count === 0 && !this.isDisinfecting) {
this.checkDisinfection();
});
private startDisinfectionCheck(): void {
setInterval(() => {
if (peopleCounter.getCurrentCount() === 0) {
this.checkDisinfection();
}, this.disinfectionInterval);
public static getInstance(): DisinfectionService {
if (!DisinfectionService.instance) {
DisinfectionService.instance = new DisinfectionService();
return DisinfectionService.instance;
private checkDisinfection(): void {
const now = Date.now();
if (now - this.lastDisinfectionTime >= this.disinfectionInterval) {
this.startDisinfection();
}
public startDisinfection(): void {
if (this.isDisinfecting || !this.deviceController) return;
this.isDisinfecting = true;
this.deviceController.setGpioValue(this.disinfectionPin, 1); // 开启设备
// 消毒持续5分钟
setTimeout(() => {
this.stopDisinfection();
}, 300000);
EventBus.emit('disinfectionStarted', {
startTime: Date.now(),
duration: 300000
});
syncService.syncDisinfectionStatus(true);
public stopDisinfection(): void {
if (!this.isDisinfecting || !this.deviceController) return;
this.deviceController.setGpioValue(this.disinfectionPin, 0); // 关闭设备
this.isDisinfecting = false;
this.lastDisinfectionTime = Date.now();
EventBus.emit('disinfectionEnded', {
endTime: Date.now()
});
syncService.syncDisinfectionStatus(false);
public manualStart(): void {
this.startDisinfection();
public manualStop(): void {
this.stopDisinfection();
public setInterval(minutes: number): void {
this.disinfectionInterval = minutes * 60000;
public getStatus(): DisinfectionStatus {
return {
isActive: this.isDisinfecting,
lastTime: this.lastDisinfectionTime,
nextTime: this.lastDisinfectionTime + this.disinfectionInterval
};
}
export const disinfectionService = DisinfectionService.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.smarttoilet',
userInfo: { userId: 'default' }
};
this.kvManager = distributedData.createKVManager(config);
this.kvStore = await this.kvManager.getKVStore('toilet_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 syncPeopleCount(count: number): Promise<void> {
const syncData: SyncCount = {
count,
timestamp: Date.now(),
deviceId: deviceManager.getLocalDevice().id
};
await this.kvStore.put('people_count', JSON.stringify(syncData));
public async syncToiletStatus(status: ToiletStatus): Promise<void> {
const syncData: SyncStatus = {
...status,
timestamp: Date.now(),
deviceId: deviceManager.getLocalDevice().id
};
await this.kvStore.put(toilet_${status.id}, JSON.stringify(syncData));
public async syncDisinfectionStatus(active: boolean): Promise<void> {
const syncData: SyncDisinfection = {
active,
timestamp: Date.now(),
deviceId: deviceManager.getLocalDevice().id
};
await this.kvStore.put('disinfection', 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 === 'people_count') {
EventBus.emit('remotePeopleCount', parsed);
else if (data.key.startsWith(‘toilet_’)) {
EventBus.emit('remoteToiletStatus', parsed);
else if (data.key === ‘disinfection’) {
EventBus.emit('remoteDisinfection', 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: ToiletCommand): Promise<void> {
const syncCommand: SyncCommand = {
type: 'command',
command,
timestamp: Date.now(),
deviceId: deviceManager.getLocalDevice().id
};
await this.kvStore.put(command_${Date.now()}, JSON.stringify(syncCommand));
}
export const syncService = SyncService.getInstance();
三、主界面实现
厕所引导主界面
// ToiletGuideView.ets
@Component
struct ToiletGuideView {
@State toilets: ToiletStatus[] = [];
@State peopleCount: number = 0;
@State disinfecting: boolean = false;
@State lastDisinfection: string = ‘’;
@State connectedDevices: number = 0;
aboutToAppear() {
this.initEventListeners();
this.loadInitialData();
build() {
Column() {
// 顶部状态栏
StatusBar({
peopleCount: this.peopleCount,
disinfecting: this.disinfecting,
lastDisinfection: this.lastDisinfection,
devices: this.connectedDevices
})
.margin({ top: 16, bottom: 24 })
// 厕位状态网格
ToiletGrid({ toilets: this.toilets })
.layoutWeight(1)
// 控制按钮
ControlButtons({
onDisinfect: () => this.manualDisinfect(),
onRefresh: () => this.refreshData()
})
.margin({ bottom: 16 })
.padding(16)
private initEventListeners(): void {
EventBus.on('remotePeopleCount', (data) => {
this.peopleCount = data.count;
});
EventBus.on('remoteToiletStatus', (status) => {
this.updateToiletStatus(status);
});
EventBus.on('remoteDisinfection', (status) => {
this.disinfecting = status.active;
if (!status.active) {
this.lastDisinfection = this.formatTime(status.timestamp);
});
private async loadInitialData(): Promise<void> {
this.toilets = await toiletService.getAllStatus();
this.peopleCount = peopleCounter.getCurrentCount();
this.disinfecting = disinfectionService.getStatus().isActive;
this.lastDisinfection = this.formatTime(disinfectionService.getStatus().lastTime);
this.connectedDevices = (await syncService.getConnectedDevices()).length;
private updateToiletStatus(status: ToiletStatus): void {
const index = this.toilets.findIndex(t => t.id === status.id);
if (index >= 0) {
this.toilets[index] = status;
else {
this.toilets.push(status);
this.toilets = […this.toilets];
private manualDisinfect(): void {
if (this.disinfecting) {
disinfectionService.manualStop();
else {
disinfectionService.manualStart();
}
private refreshData(): void {
this.loadInitialData();
displayService.updateContent();
private formatTime(timestamp: number): string {
if (!timestamp) return '从未消毒';
const date = new Date(timestamp);
return {date.getHours()}:{date.getMinutes().toString().padStart(2, '0')};
}
@Component
struct StatusBar {
private peopleCount: number;
private disinfecting: boolean;
private lastDisinfection: string;
private devices: number;
build() {
Row() {
Column() {
Text(this.peopleCount.toString())
.fontSize(24)
.fontWeight(FontWeight.Bold)
Text(‘使用人数’)
.fontSize(12)
.margin({ right: 16 })
Column() {
Text(this.disinfecting ? '消毒中' : '空闲')
.fontSize(16)
.fontColor(this.disinfecting ? '#FF5722' : '#4CAF50')
Text(上次: ${this.lastDisinfection})
.fontSize(12)
.margin({ right: 16 })
Column() {
Text(${this.devices})
.fontSize(16)
Text('设备在线')
.fontSize(12)
}
}
@Component
struct ToiletGrid {
private toilets: ToiletStatus[];
build() {
Grid() {
ForEach(this.toilets, (toilet) => {
GridItem() {
ToiletItem({ toilet })
})
.columnsTemplate(‘1fr 1fr 1fr’)
.rowsGap(12)
.columnsGap(12)
}
@Component
struct ToiletItem {
private toilet: ToiletStatus;
build() {
Column() {
Image(this.getToiletImage())
.width(60)
.height(60)
.margin({ bottom: 8 })
Text(厕位 ${toilet.id})
.fontSize(14)
Text(this.getStatusText())
.fontSize(12)
.fontColor(this.getStatusColor())
.padding(8)
.backgroundColor('#FFFFFF')
.borderRadius(8)
private getToiletImage(): Resource {
return this.toilet.occupied ? r('app.media.ic_toilet_occupied') : r('app.media.ic_toilet_free');
private getStatusText(): string {
return this.toilet.occupied ? '使用中' : '空闲';
private getStatusColor(): string {
return this.toilet.occupied ? '#F44336' : '#4CAF50';
}
@Component
struct ControlButtons {
private onDisinfect: () => void;
private onRefresh: () => void;
build() {
Row() {
Button(‘消毒控制’)
.onClick(() => this.onDisinfect())
.width(120)
Button('刷新数据')
.onClick(() => this.onRefresh())
.width(120)
.margin({ left: 16 })
}
管理界面
// ManagementView.ets
@Component
struct ManagementView {
@State peopleHistory: PeopleCountHistory[] = [];
@State disinfectionLogs: DisinfectionLog[] = [];
@State settings: ToiletSettings = {
autoDisinfection: true,
disinfectionInterval: 60,
maxCapacity: 10
};
aboutToAppear() {
this.loadData();
build() {
Column() {
// 选项卡
Tabs({ index: 0 }) {
TabContent() {
StatisticsView({
history: this.peopleHistory,
logs: this.disinfectionLogs
})
.tabBar(‘统计数据’)
TabContent() {
SettingsView({
settings: this.settings,
onSave: (settings) => this.saveSettings(settings)
})
.tabBar(‘系统设置’)
.layoutWeight(1)
}
private async loadData(): Promise<void> {
this.peopleHistory = await statisticService.getPeopleHistory();
this.disinfectionLogs = await statisticService.getDisinfectionLogs();
this.settings = await settingsService.getSettings();
private async saveSettings(settings: ToiletSettings): Promise<void> {
await settingsService.saveSettings(settings);
this.settings = settings;
// 应用新设置
peopleCounter.setMaxCapacity(settings.maxCapacity);
disinfectionService.setInterval(settings.disinfectionInterval);
prompt.showToast({ message: '设置已保存' });
}
@Component
struct StatisticsView {
private history: PeopleCountHistory[];
private logs: DisinfectionLog[];
build() {
Column() {
Text(‘使用人数统计’)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 8 })
PeopleChart({ history: this.history })
.height(200)
.margin({ bottom: 24 })
Text('消毒记录')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 8 })
DisinfectionLogs({ logs: this.logs })
.layoutWeight(1)
.padding(16)
}
@Component
struct PeopleChart {
private history: PeopleCountHistory[];
build() {
Canvas({ context: this.getContext() })
.width(‘100%’)
.height(‘100%’)
.onReady(() => this.drawChart())
private getContext(): CanvasRenderingContext2D {
// 创建并返回Canvas上下文
return new CanvasRenderingContext2D();
private drawChart(): void {
// 实现绘制人数统计曲线图的逻辑
// 实际项目中可以使用第三方图表库
}
@Component
struct DisinfectionLogs {
private logs: DisinfectionLog[];
build() {
List() {
ForEach(this.logs, (log) => {
ListItem() {
LogItem({ log })
})
}
@Component
struct LogItem {
private log: DisinfectionLog;
build() {
Row() {
Column() {
Text(this.formatTime(log.startTime))
.fontSize(14)
.fontWeight(FontWeight.Bold)
Text(时长: ${log.duration}分钟)
.fontSize(12)
.layoutWeight(1)
Text(log.trigger === 'auto' ? '自动' : '手动')
.fontSize(12)
.fontColor(log.trigger === 'auto' ? '#2196F3' : '#FF9800')
.padding(8)
.backgroundColor('#FFFFFF')
.borderRadius(4)
private formatTime(timestamp: number): string {
const date = new Date(timestamp);
return {date.getMonth()+1}月{date.getDate()}日 {date.getHours()}:{date.getMinutes().toString().padStart(2, '0')};
}
@Component
struct SettingsView {
private settings: ToiletSettings;
private onSave: (settings: ToiletSettings) => void;
build() {
Column() {
// 自动消毒开关
Row() {
Text(‘自动消毒’)
.fontSize(16)
.layoutWeight(1)
Toggle({ type: ToggleType.Switch, isOn: this.settings.autoDisinfection })
.onChange((isOn) => {
this.settings.autoDisinfection = isOn;
})
.margin({ bottom: 16 })
// 消毒间隔
Text(消毒间隔: ${this.settings.disinfectionInterval}分钟)
.fontSize(16)
.margin({ bottom: 8 })
Slider({
value: this.settings.disinfectionInterval,
min: 30,
max: 180,
step: 10
})
.onChange((value) => {
this.settings.disinfectionInterval = value;
})
.margin({ bottom: 24 })
// 最大容量
Text(最大容量: ${this.settings.maxCapacity}人)
.fontSize(16)
.margin({ bottom: 8 })
Slider({
value: this.settings.maxCapacity,
min: 1,
max: 20,
step: 1
})
.onChange((value) => {
this.settings.maxCapacity = value;
})
.margin({ bottom: 24 })
// 保存按钮
Button('保存设置')
.onClick(() => this.onSave(this.settings))
.width('100%')
.height(48)
.padding(16)
}
四、高级功能实现
数据分析服务
// AnalyticsService.ets
import { peopleCounter } from ‘./PeopleCountingService’;
import { disinfectionService } from ‘./DisinfectionService’;
class AnalyticsService {
private static instance: AnalyticsService;
private peopleHistory: PeopleCountHistory[] = [];
private disinfectionLogs: DisinfectionLog[] = [];
private historySize: number = 1000;
private constructor() {
this.loadHistory();
this.initEventListeners();
private async loadHistory(): Promise<void> {
const peopleData = await storage.get('peopleHistory');
if (peopleData) {
this.peopleHistory = JSON.parse(peopleData);
const disinfectionData = await storage.get(‘disinfectionLogs’);
if (disinfectionData) {
this.disinfectionLogs = JSON.parse(disinfectionData);
}
private initEventListeners(): void {
EventBus.on(‘peopleCountChanged’, (data) => {
this.recordPeopleCount(data);
});
EventBus.on('disinfectionStarted', (data) => {
this.recordDisinfectionStart(data);
});
EventBus.on('disinfectionEnded', (data) => {
this.recordDisinfectionEnd(data);
});
public static getInstance(): AnalyticsService {
if (!AnalyticsService.instance) {
AnalyticsService.instance = new AnalyticsService();
return AnalyticsService.instance;
private recordPeopleCount(data: PeopleCountData): void {
this.peopleHistory.push({
timestamp: data.timestamp,
count: data.count
});
// 限制历史记录大小
if (this.peopleHistory.length > this.historySize) {
this.peopleHistory.shift();
storage.set(‘peopleHistory’, JSON.stringify(this.peopleHistory));
private recordDisinfectionStart(data: DisinfectionStartData): void {
this.disinfectionLogs.push({
startTime: data.startTime,
endTime: null,
duration: data.duration / 60000, // 转换为分钟
trigger: 'auto'
});
storage.set('disinfectionLogs', JSON.stringify(this.disinfectionLogs));
private recordDisinfectionEnd(data: DisinfectionEndData): void {
const lastLog = this.disinfectionLogs[this.disinfectionLogs.length - 1];
if (lastLog && !lastLog.endTime) {
lastLog.endTime = data.endTime;
storage.set(‘disinfectionLogs’, JSON.stringify(this.disinfectionLogs));
public getPeopleHistory(): PeopleCountHistory[] {
return [...this.peopleHistory];
public getDisinfectionLogs(): DisinfectionLog[] {
return [...this.disinfectionLogs];
public getPeakHours(): PeakHour[] {
const hourCounts = new Array(24).fill(0);
this.peopleHistory.forEach(record => {
const hour = new Date(record.timestamp).getHours();
hourCounts[hour] += record.count;
});
return hourCounts.map((count, hour) => ({
hour,
count
}));
public getAverageUsage(): number {
if (this.peopleHistory.length === 0) return 0;
const total = this.peopleHistory.reduce((sum, record) =>
sum + record.count, 0);
return total / this.peopleHistory.length;
public getDisinfectionFrequency(): number {
if (this.disinfectionLogs.length < 2) return 0;
const first = this.disinfectionLogs[0].startTime;
const last = this.disinfectionLogs[this.disinfectionLogs.length - 1].startTime;
const days = (last - first) / (1000 60 60 * 24);
return this.disinfectionLogs.length / days;
}
export const analyticsService = AnalyticsService.getInstance();
设置管理服务
// SettingsService.ets
class SettingsService {
private static instance: SettingsService;
private settings: ToiletSettings = {
autoDisinfection: true,
disinfectionInterval: 60,
maxCapacity: 10
};
private constructor() {
this.loadSettings();
private async loadSettings(): Promise<void> {
const saved = await storage.get('toiletSettings');
if (saved) {
this.settings = JSON.parse(saved);
}
public static getInstance(): SettingsService {
if (!SettingsService.instance) {
SettingsService.instance = new SettingsService();
return SettingsService.instance;
public async getSettings(): Promise<ToiletSettings> {
return { ...this.settings };
public async saveSettings(settings: ToiletSettings): Promise<void> {
this.settings = settings;
await storage.set('toiletSettings', JSON.stringify(settings));
// 触发设置变更事件
EventBus.emit('settingsChanged', settings);
public getAutoDisinfection(): boolean {
return this.settings.autoDisinfection;
public getDisinfectionInterval(): number {
return this.settings.disinfectionInterval;
public getMaxCapacity(): number {
return this.settings.maxCapacity;
}
export const settingsService = SettingsService.getInstance();
厕位状态服务
// ToiletStatusService.ets
import { syncService } from ‘./SyncService’;
class ToiletStatusService {
private static instance: ToiletStatusService;
private toilets: ToiletStatus[] = [];
private updateInterval: number = 5000; // 5秒更新一次
private constructor() {
this.initToilets();
this.startUpdateLoop();
private initToilets(): void {
// 初始化10个厕位
for (let i = 1; i <= 10; i++) {
this.toilets.push({
id: T${i},
occupied: false,
lastUsed: 0,
usageCount: 0
});
}
private startUpdateLoop(): void {
setInterval(() => {
this.updateStatus();
}, this.updateInterval);
public static getInstance(): ToiletStatusService {
if (!ToiletStatusService.instance) {
ToiletStatusService.instance = new ToiletStatusService();
return ToiletStatusService.instance;
private updateStatus(): void {
// 模拟随机使用状态变化
this.toilets.forEach(toilet => {
if (Math.random() > 0.8) { // 20%概率状态变化
toilet.occupied = !toilet.occupied;
if (toilet.occupied) {
toilet.lastUsed = Date.now();
toilet.usageCount++;
// 同步状态
syncService.syncToiletStatus(toilet);
});
public getAllStatus(): ToiletStatus[] {
return [...this.toilets];
public getToilet(id: string): ToiletStatus | null {
return this.toilets.find(t => t.id === id) || null;
public setOccupied(id: string, occupied: boolean): void {
const toilet = this.toilets.find(t => t.id === id);
if (toilet) {
toilet.occupied = occupied;
if (occupied) {
toilet.lastUsed = Date.now();
toilet.usageCount++;
syncService.syncToiletStatus(toilet);
}
public resetCounters(): void {
this.toilets.forEach(toilet => {
toilet.usageCount = 0;
});
}
export const toiletService = ToiletStatusService.getInstance();
五、总结
本智慧厕所引导系统实现了以下核心价值:
精准统计:红外传感器实时监测使用人数
智能引导:动态屏幕显示空闲厕位信息
自动消毒:根据使用情况智能触发消毒流程
多端协同:管理员与用户端数据实时同步
数据分析:使用记录统计与可视化展示
扩展方向:
增加人脸识别VIP用户引导
开发异味监测与自动除味功能
集成紧急呼叫按钮
支持更多厕所类型(无障碍/母婴等)
添加AR导航功能
注意事项:
红外传感器需定期清洁维护
消毒设备需按规范操作
网络中断时本地数据会暂存
首次使用建议进行系统校准
最大容量设置需符合实际限制
