Sistem Pemeriksaan Kesihatan Pintar MPHS

Majlis Perbandaran Hulu Selangor - Enhanced with HCBB11 Multi-Status Beacons

🌟 Enhanced Smart Multi-Beacon Detection System

Sistem revolusi berasaskan IoT dengan HCBB11 Multi-Status Visual Beacons.
Setiap premis mempunyai beacon pintar yang menunjukkan SEMUA status serentak
melalui kombinasi warna dan corak lampu yang berbeza.

šŸ’”
HCBB11 Smart Beacon
12 LED lights, 6 colors, sound alerts, 44-month battery
šŸŽØ
Multi-Status Display
Shows multiple issues simultaneously with color patterns
šŸ“±
Real-time Control
Inspector app controls beacon lights and sounds
šŸ‘ļø
Visual Navigation
Find premises easily with blinking lights and sounds
🚨
Instant Alerts
Critical issues trigger automatic visual warnings
šŸ“Š
Pattern Analytics
Identify problem areas from beacon patterns

šŸŽØ Sistem Kod Warna Status

Status Tunggal (Lampu Solid)

šŸ”“ MERAH = Gerai Tutup
🟠 OREN = Tiada Lesen
🟔 KUNING = Lesen Tamat Tempoh
šŸ”µ BIRU = Overdue Pemeriksaan
🟢 HIJAU = Semua OK
⚪ PUTIH = Belum Diperiksa

Gabungan Status (Corak Bergilir)

šŸ”“šŸŸ” Gerai Tutup + Lesen Tamat
🌈 Multiple Issues (3+ masalah)

šŸ’” HCBB11 Multi-Status Beacon Features

Live Beacon Status Demo

Semua OK

Hijau Solid - Tiada masalah

Lesen Tamat

Kuning Solid - 1 isu

Lesen Tamat + Overdue

Kuning-Biru bergilir

Kritikal!

Merah berkelip pantas + bunyi

Multiple Issues

Semua warna bergilir

HCBB11 Technical Specifications

šŸ”‹ Power & Battery
• 1000mAh replaceable battery
• 44 months battery life
• Low temperature resistant
• Standby: 31.4uA consumption
šŸ’” Visual Features
• 12 high-brightness LEDs
• 6 distinct colors
• Transparent shell design
• Visible from 50+ meters
šŸ”Š Audio Features
• Built-in buzzer
• Multiple sound patterns
• Volume control
• Emergency alert sounds
šŸ›”ļø Durability
• IP64 waterproof rating
• Special sealing glue
• QR code surface compatible
• Total weight: 20.2g

Senario Penggunaan Sebenar

šŸ“ Senario 1: Pasar Malam Kuala Kubu Bharu
Masalah: 50+ gerai, susah cari gerai bermasalah
Penyelesaian: Pemeriksa aktifkan "Show Issues" - semua gerai bermasalah mula berkelip
Hasil: Jimat 30 minit masa carian
šŸŖ Senario 2: Restoran 24 Jam
Status: Lesen tamat (kuning) + Overdue pemeriksaan (biru)
Beacon: Kuning-Biru bergilir setiap 1 saat
Action: Pemilik nampak status, boleh prepare dokumen
🚨 Senario 3: Kes Kecemasan
Kejadian: Suhu storan sejuk naik mendadak malam
Beacon: Auto trigger - Merah berkelip + bunyi kuat
Respons: Pemilik selamatkan RM50,000 stok makanan

šŸ“± Enhanced Inspector Flow dengan HCBB11

1
🚶
Pemeriksa Tiba
Masuk kawasan, semua beacon auto-detected dalam 100m
2
šŸ‘ļø
Visual Overview
Lihat status semua premis dari warna beacon - hijau OK, lain ada masalah
3
šŸ“±
App Filter
Pilih "Show Critical Only" - hanya beacon merah/oren berkelip
4
šŸŽÆ
Navigate to Premise
Tap premise - beacon mula bunyi untuk mudah cari
5
āœ…
Complete Inspection
Selepas periksa, beacon auto-update warna ikut hasil
6
šŸ“Š
Real-time Update
Command center lihat perubahan status instantly

šŸ”§ How Multi-Status Detection Works

1. Status Check Algorithm
function checkPremiseStatus(premise) { let statusFlags = []; // Check each condition if (premise.operationalStatus === 'CLOSED') { statusFlags.push({ color: 'RED', priority: 100 }); } if (!premise.hasLicense) { statusFlags.push({ color: 'ORANGE', priority: 80 }); } if (premise.licenseExpired) { statusFlags.push({ color: 'YELLOW', priority: 60 }); } if (premise.overdueInspection) { statusFlags.push({ color: 'BLUE', priority: 40 }); } return statusFlags; }
2. Beacon Pattern Generation
function generateBeaconPattern(statusFlags) { if (statusFlags.length === 0) { return { pattern: 'SOLID', colors: ['GREEN'], sound: 'OFF', interval: 0 }; } if (statusFlags.length === 1) { return { pattern: 'SOLID', colors: [statusFlags[0].color], sound: 'BEEP_SLOW', interval: 0 }; } // Multiple issues - create alternating pattern return { pattern: 'ALTERNATE', colors: statusFlags.map(s => s.color), sound: 'BEEP_FAST', interval: 1000 // 1 second per color }; }
3. Real-time Beacon Control
// WebSocket connection for instant updates ws.send({ action: 'UPDATE_BEACON', beaconId: 'HCBB11_2345', pattern: { type: 'ALTERNATE', colors: ['RED', 'YELLOW'], soundPattern: 'URGENT', brightness: 100 } }); // Beacon responds immediately // Visible to all nearby inspectors

šŸ‘® Enhanced Inspector Mobile Application

HCBB11 Control Features

šŸ’”
Visual Status Control
Control beacon lights remotely from app
šŸ”
Find Premise Mode
Activate beacon sound & light to locate
šŸŽØ
Multi-Status Display
See all issues at once via color patterns
🚨
Emergency Broadcast
Alert all premises simultaneously
šŸ“Š
Pattern Analytics
Identify problem zones from beacon colors
Pemeriksa Kesihatan MPHS
32
Detected
8
Critical
12
Multi-Issue
🌈 Multi-Issue (12)
šŸ”“ Tutup (3)
🟠 No License (5)
🟔 Expired (8)
KEUTAMAAN: 98
Restoran Ikan Bakar Jeram
🐟 Restoran Makanan Laut
2.5m
Gerai Tutup Lesen Tamat Overdue
šŸ“¶ Isyarat cemerlang
šŸŒ”ļø Suhu: 12°C (Kritikal!)
āš ļø MULTIPLE CRITICAL ISSUES
Beacon Status: šŸ”“šŸŸ”šŸ”µ Bergilir - Tindakan segera diperlukan
KEUTAMAAN: 85
Warung Pak Ali
šŸ› Warung Melayu
5.8m
Lesen Tamat Overdue 3 bulan
Beacon Status: šŸŸ”šŸ”µ Bergilir
Pemeriksaan + pembaharuan lesen diperlukan
KEUTAMAAN: 60
Medan Selera Batang Kali
šŸœ Medan Selera
8.2m
Lesen Tamat 5 hari
Beacon Status: 🟔 Solid
Perlu pembaharuan lesen sahaja
KEUTAMAAN: 10
Kafe D'Serendah
ā˜• Kafe
12.5m
Semua OK
Beacon Status: 🟢 Solid
Tiada masalah - Pemeriksaan rutin sahaja

šŸ“” Live Multi-Status Beacon Radar

3 Issues
1
āœ“
Beacon Status Legend
Semua OK (Hijau)
Single Issue (Solid)
2 Issues (Bergilir)
3+ Issues (Multi)

šŸ¢ Enhanced Command Center dengan HCBB11 Analytics

šŸ’” HCBB11 Beacon Status Overview

1,823
🟢 Hijau (OK)
423
šŸ”µ Overdue
312
🟔 Lesen Tamat
189
🟠 Tiada Lesen
87
šŸ”“ Tutup
234
🌈 Multi-Issue

šŸ“Š Beacon Pattern Analysis

Critical Multi-Issue Premises (3+ problems)

Restoran Ikan Bakar Jeram
Tutup Lesen Tamat Overdue
Gerai Pasar Malam Lot 23
Tiada Lesen Overdue

šŸ“ Zone Beacon Status Summary

Kuala Kubu Bharu
🟢 234 šŸ”µ 89 🟔 67 🟠 45 šŸ”“ 23 🌈 34
Batang Kali
🟢 189 šŸ”µ 67 🟔 45 🟠 23 šŸ”“ 12 🌈 19
Serendah
🟢 267 šŸ”µ 45 🟔 34 🟠 12 šŸ”“ 8 🌈 11

šŸŽ® Beacon Control Center

šŸ“” Live Beacon Activity Feed

Just now
🌈 Multi-Status Alert
Restoran Ikan Bakar - Beacon bergilir 3 warna (Tutup + Lesen + Overdue)
2 minit lalu
šŸŸ”šŸ”µ Status Update
Warung Pak Ali - Beacon mula berkelip kuning-biru
5 minit lalu
🟢 Status Cleared
Kafe D'Serendah - Semua isu selesai, beacon hijau
8 minit lalu
šŸ” Find Mode Activated
Inspector searching for Gerai #45 - Beacon bunyi aktif

šŸ”‹ HCBB11 Beacon Health Status

Total HCBB11 Deployed 2,847 units
Battery > 80% 2,456 units
Battery 50-80% 312 units
Battery < 50% 79 units
Average Battery Life 38 months remaining
Last OTA Update 2 days ago

šŸ”§ Enhanced Technical Implementation with HCBB11

HCBB11 Multi-Status Configuration
// HCBB11 Beacon Configuration for MPHS const HCBB11_CONFIG = { uuid: "550e8400-e29b-41d4-a716-446655440000", // MPHS UUID major: 1001, // Zone ID minor: 2345, // Unique Premise ID // Visual Configuration led: { count: 12, colors: ['RED', 'ORANGE', 'YELLOW', 'BLUE', 'GREEN', 'WHITE'], brightness: 100, // 0-100% patterns: { SOLID: { interval: 0 }, BLINK: { interval: 500 }, ALTERNATE: { interval: 1000 }, SEQUENCE: { interval: 800 }, RAPID: { interval: 200 } } }, // Audio Configuration buzzer: { patterns: { OFF: { frequency: 0, duration: 0 }, BEEP_SLOW: { frequency: 2000, duration: 100, interval: 2000 }, BEEP_FAST: { frequency: 2500, duration: 50, interval: 500 }, CONTINUOUS: { frequency: 3000, duration: -1 } } }, // Power Management battery: { type: 'CR2477', capacity: 1000, // mAh lowThreshold: 20, // % standbyConsumption: 31.4 // uA } };
Enhanced Multi-Status Detection Algorithm
class PremiseStatusManager { constructor(premise) { this.premise = premise; this.statusFlags = []; this.beacon = new HCBB11Controller(premise.beaconId); } analyzeStatus() { this.statusFlags = []; // Check all conditions with priorities if (this.premise.operationalStatus === 'CLOSED') { this.statusFlags.push({ type: 'CLOSED', color: 'RED', priority: 100, sound: 'BEEP_FAST' }); } if (!this.premise.hasValidLicense) { this.statusFlags.push({ type: 'NO_LICENSE', color: 'ORANGE', priority: 80, sound: 'BEEP_FAST' }); } if (this.premise.licenseExpired) { const daysExpired = this.getDaysExpired(); this.statusFlags.push({ type: 'LICENSE_EXPIRED', color: 'YELLOW', priority: 60 + Math.min(20, daysExpired * 0.5), sound: daysExpired > 30 ? 'BEEP_FAST' : 'BEEP_SLOW' }); } if (this.premise.overdueInspection) { const daysOverdue = this.getDaysOverdue(); this.statusFlags.push({ type: 'OVERDUE_INSPECTION', color: 'BLUE', priority: 40 + Math.min(20, daysOverdue * 0.2), sound: 'BEEP_SLOW' }); } // Temperature violations get special handling if (this.premise.hasTemperatureViolation) { this.statusFlags.push({ type: 'TEMP_VIOLATION', color: 'RED', priority: 95, sound: 'CONTINUOUS', override: true // This overrides other patterns }); } return this.statusFlags; } updateBeaconPattern() { const statuses = this.analyzeStatus(); if (statuses.length === 0) { // All OK this.beacon.setPattern({ colors: ['GREEN'], pattern: 'SOLID', sound: 'OFF' }); return; } // Check for override conditions const override = statuses.find(s => s.override); if (override) { this.beacon.setPattern({ colors: [override.color], pattern: 'RAPID', sound: override.sound, brightness: 100 }); return; } // Sort by priority statuses.sort((a, b) => b.priority - a.priority); // Generate pattern based on number of issues let pattern; if (statuses.length === 1) { pattern = { colors: [statuses[0].color], pattern: 'SOLID', sound: statuses[0].sound }; } else if (statuses.length === 2) { pattern = { colors: statuses.map(s => s.color), pattern: 'ALTERNATE', sound: 'BEEP_FAST' }; } else { // 3 or more issues pattern = { colors: statuses.slice(0, 4).map(s => s.color), // Max 4 colors pattern: 'SEQUENCE', sound: 'BEEP_FAST', brightness: 100 }; } this.beacon.setPattern(pattern); } }
Real-time Beacon Control API
// WebSocket API for real-time beacon control class BeaconControlAPI { constructor() { this.ws = new WebSocket('wss://api.mphs.gov.my/beacon-control'); this.setupHandlers(); } // Inspector controls specific beacon findPremise(beaconId) { this.send({ action: 'FIND_MODE', beaconId: beaconId, pattern: { colors: ['WHITE'], pattern: 'RAPID', sound: 'BEEP_FAST', duration: 30000 // 30 seconds } }); } // Command center broadcasts emergencyAlert(zoneId) { this.send({ action: 'EMERGENCY_BROADCAST', zoneId: zoneId, pattern: { colors: ['RED', 'WHITE'], pattern: 'RAPID', sound: 'CONTINUOUS', override: true } }); } // Batch update for efficiency batchUpdateBeacons(updates) { this.send({ action: 'BATCH_UPDATE', updates: updates.map(u => ({ beaconId: u.beaconId, pattern: this.generatePattern(u.statuses) })) }); } // Pattern analytics getZonePatternSummary(zoneId) { return this.request({ action: 'GET_ZONE_PATTERNS', zoneId: zoneId }).then(data => { return { total: data.beacons.length, byStatus: { green: data.beacons.filter(b => b.pattern === 'SOLID_GREEN').length, singleIssue: data.beacons.filter(b => b.issues === 1).length, multiIssue: data.beacons.filter(b => b.issues > 1).length, critical: data.beacons.filter(b => b.priority > 90).length } }; }); } }
Enhanced Database Schema for Multi-Status
-- Enhanced Premises Table CREATE TABLE premises ( id UUID PRIMARY KEY, beacon_minor INTEGER UNIQUE, name VARCHAR(255), type VARCHAR(100), -- License Information license_number VARCHAR(50), license_expiry DATE, license_status ENUM('VALID', 'EXPIRED', 'NONE'), -- Operational Status operational_status ENUM('OPEN', 'CLOSED', 'SUSPENDED'), closure_reason VARCHAR(255), -- Inspection Status last_inspection_date TIMESTAMP, next_inspection_due DATE, current_grade CHAR(1), -- Beacon Configuration beacon_pattern JSON, -- Current pattern settings beacon_battery_level INTEGER, beacon_last_seen TIMESTAMP, -- Multi-Status Flags status_flags JSON, -- Array of current issues priority_score INTEGER, -- Calculated priority created_at TIMESTAMP, updated_at TIMESTAMP ); -- Beacon Pattern History CREATE TABLE beacon_patterns ( id UUID PRIMARY KEY, premise_id UUID REFERENCES premises(id), timestamp TIMESTAMP, pattern JSON, -- Pattern configuration trigger_reason VARCHAR(100), -- What triggered the change inspector_id UUID, duration_seconds INTEGER ); -- Status Change Events CREATE TABLE status_events ( id UUID PRIMARY KEY, premise_id UUID REFERENCES premises(id), event_type VARCHAR(50), -- CLOSED, LICENSE_EXPIRED, etc event_timestamp TIMESTAMP, previous_status VARCHAR(50), new_status VARCHAR(50), beacon_pattern_change JSON, notes TEXT ); -- Real-time Analytics View CREATE VIEW premise_status_summary AS SELECT p.zone_id, COUNT(*) as total_premises, SUM(CASE WHEN status_flags = '[]' THEN 1 ELSE 0 END) as ok_count, SUM(CASE WHEN JSON_LENGTH(status_flags) = 1 THEN 1 ELSE 0 END) as single_issue, SUM(CASE WHEN JSON_LENGTH(status_flags) = 2 THEN 1 ELSE 0 END) as double_issue, SUM(CASE WHEN JSON_LENGTH(status_flags) >= 3 THEN 1 ELSE 0 END) as multi_issue, SUM(CASE WHEN priority_score >= 90 THEN 1 ELSE 0 END) as critical_count FROM premises p GROUP BY p.zone_id;
Complete System Integration Flow
// Complete integration flow async function completeInspectionFlow(inspectorId, location) { // 1. Detect all beacons in range const detectedBeacons = await scanForBeacons(location, 100); // 100m radius // 2. Batch fetch premise data with status const premises = await fetchPremiseData(detectedBeacons.map(b => b.id)); // 3. Calculate multi-status for each const premisesWithStatus = premises.map(premise => { const statusManager = new PremiseStatusManager(premise); const statuses = statusManager.analyzeStatus(); return { ...premise, statuses: statuses, priorityScore: calculatePriorityScore(premise, statuses), beaconPattern: statusManager.getBeaconPattern() }; }); // 4. Update all beacon patterns via batch API const beaconUpdates = premisesWithStatus.map(p => ({ beaconId: p.beaconMinor, pattern: p.beaconPattern })); await beaconControlAPI.batchUpdateBeacons(beaconUpdates); // 5. Sort by priority and return to app return premisesWithStatus.sort((a, b) => b.priorityScore - a.priorityScore); } // Inspector selects a premise async function startInspection(premiseId, inspectorId) { // 1. Activate find mode await beaconControlAPI.findPremise(premiseId); // 2. Log inspection start await logInspectionStart(premiseId, inspectorId); // 3. Get real-time updates during inspection const updateStream = subscribeToUpdates(premiseId); return { premiseId, startTime: new Date(), updateStream }; } // Complete inspection and update status async function completeInspection(inspection, results) { // 1. Calculate new status based on results const newStatuses = calculateNewStatus(results); // 2. Update beacon pattern immediately const pattern = generatePatternFromStatus(newStatuses); await beaconControlAPI.updateBeacon(inspection.premiseId, pattern); // 3. Save to database await saveInspectionResults(inspection, results, newStatuses); // 4. Notify command center await notifyCommandCenter({ premiseId: inspection.premiseId, previousStatus: inspection.previousStatus, newStatus: newStatuses, inspectorId: inspection.inspectorId }); }
Performance & Battery Optimization
// Intelligent battery management for HCBB11 class BeaconBatteryOptimizer { constructor() { this.batteryThresholds = { critical: 10, // % low: 20, // % medium: 50, // % good: 80 // % }; } optimizePattern(pattern, batteryLevel) { // Reduce brightness and frequency based on battery if (batteryLevel < this.batteryThresholds.critical) { // Critical battery - minimal operation return { ...pattern, brightness: 30, sound: 'OFF', pattern: pattern.colors.length > 1 ? 'SLOW_ALTERNATE' : 'SOLID', interval: pattern.interval * 3 // Triple the interval }; } else if (batteryLevel < this.batteryThresholds.low) { // Low battery - reduced operation return { ...pattern, brightness: 50, sound: pattern.sound === 'CONTINUOUS' ? 'BEEP_SLOW' : pattern.sound, interval: pattern.interval * 2 }; } else if (batteryLevel < this.batteryThresholds.medium) { // Medium battery - slight optimization return { ...pattern, brightness: 80, interval: pattern.interval * 1.5 }; } // Good battery - full operation return pattern; } // Predictive battery life calculation calculateRemainingLife(beacon) { const consumption = this.calculateConsumption(beacon.currentPattern); const remainingCapacity = beacon.batteryLevel * beacon.batteryCapacity / 100; return { days: Math.floor(remainingCapacity / (consumption * 24)), accuracy: this.getAccuracy(beacon.patternHistory) }; } }