返回作品集
嵌入式系統精選專案

全屋智能居家控制系統

為高端住宅開發的整合式智慧家庭系統,支援燈光、空調、窗簾、安全監控全方位控制,整合 Apple HomeKit、Google Home、Amazon Alexa

使用技術

ESP32ZigbeeMQTTNode.jsReact NativeHomeKitGoogle HomeAlexaKNX

專案詳情

客戶豪宅建設公司
開發時程12個月

專案概述

為豪宅建設公司打造的全屋智能居家控制系統,涵蓋 200+ 控制點,整合燈光控制、空調系統、電動窗簾、安全監控、能源管理等功能。系統採用混合通訊架構(Zigbee + WiFi + KNX),支援本地控制與雲端管理,並完整整合 Apple HomeKit、Google Home、Amazon Alexa 三大智慧家庭平台。

目前已部署於 30+ 高端住宅,累計控制設備超過 6,000 個節點,系統穩定度達 99.8%

系統架構

整體架構圖

┌─────────────────────────────────────────────────────────────┐
│                      雲端層 (Cloud Layer)                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐    │
│  │ HomeKit  │  │  Google  │  │  Alexa   │  │  自訂    │    │
│  │  Bridge  │  │   Home   │  │  Skill   │  │  APP     │    │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘    │
└─────────────────────────────────────────────────────────────┘
                              ▲
                              │ HTTPS / MQTT
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    中控層 (Gateway Layer)                      │
│  ┌────────────────────────────────────────────────────┐     │
│  │  智慧家庭中控主機 (Raspberry Pi 4 / ESP32-S3)        │     │
│  │  - Node.js 控制邏輯                                  │     │
│  │  - MQTT Broker (Mosquitto)                         │     │
│  │  - 場景自動化引擎                                     │     │
│  │  - 本地 SQLite 資料庫                                │     │
│  └────────────────────────────────────────────────────┘     │
└─────────────────────────────────────────────────────────────┘
           │              │              │              │
      Zigbee 3.0      WiFi 6          KNX IP        RS-485
           ▼              ▼              ▼              ▼
┌─────────────────────────────────────────────────────────────┐
│                    設備層 (Device Layer)                       │
│  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐  ┌──────┐         │
│  │ 燈光  │  │ 空調  │  │ 窗簾  │  │ 安全  │  │ 能源  │         │
│  │ 控制  │  │ 控制  │  │ 控制  │  │ 監控  │  │ 管理  │         │
│  └──────┘  └──────┘  └──────┘  └──────┘  └──────┘         │
└─────────────────────────────────────────────────────────────┘

核心技術實作

1. Zigbee 3.0 無線網狀網路

選用 Zigbee 原因

  • 低功耗(電池設備可用 2+ 年)
  • 自組網能力(Mesh 網路,單點故障不影響整體)
  • 穿牆能力強(2.4GHz,比 WiFi 更穩定)
  • 支援 200+ 設備

ESP32 Zigbee 協調器實作

#include "esp_zigbee_core.h"
#include "esp_log.h"

#define TAG "ZIGBEE_GATEWAY"

// Zigbee 協調器配置
esp_zb_cfg_t zigbee_config = {
    .esp_zb_role = ESP_ZB_DEVICE_TYPE_COORDINATOR,
    .install_code_policy = false,
    .nwk_cfg = {
        .zczr_cfg = {
            .max_children = 100,  // 最大子設備數
        },
    },
};

// 燈光設備端點定義
esp_zb_on_off_light_cfg_t light_config = {
    .on_off_cfg = {
        .on_off = false,
    },
    .level_cfg = {
        .current_level = 128,  // 初始亮度 50%
    },
    .color_cfg = {
        .current_hue = 0,
        .current_saturation = 0,
        .color_temperature = 370,  // 2700K 暖白光
    },
};

void zigbee_gateway_init(void) {
    // 初始化 Zigbee 協定棧
    esp_zb_init(&zigbee_config);

    // 創建 Endpoint 列表
    esp_zb_ep_list_t *ep_list = esp_zb_ep_list_create();

    // 添加 HA(Home Automation)設備類型
    esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();

    // 基本 Cluster(設備資訊)
    esp_zb_basic_cluster_cfg_t basic_cfg = {
        .zcl_version = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE,
        .power_source = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE,
    };
    esp_zb_cluster_list_add_basic_cluster(cluster_list, &basic_cfg, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    // 識別 Cluster(設備識別閃爍)
    esp_zb_identify_cluster_cfg_t identify_cfg = {
        .identify_time = 0,
    };
    esp_zb_cluster_list_add_identify_cluster(cluster_list, &identify_cfg, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    // On/Off Cluster(開關控制)
    esp_zb_cluster_list_add_on_off_cluster(cluster_list, &light_config.on_off_cfg, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    // Level Control Cluster(調光控制)
    esp_zb_cluster_list_add_level_cluster(cluster_list, &light_config.level_cfg, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    // Color Control Cluster(色溫/RGB 控制)
    esp_zb_cluster_list_add_color_control_cluster(cluster_list, &light_config.color_cfg, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    // 註冊 Endpoint
    esp_zb_endpoint_config_t endpoint_config = {
        .endpoint = HA_ESP_LIGHT_ENDPOINT,
        .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
        .app_device_id = ESP_ZB_HA_ON_OFF_LIGHT_DEVICE_ID,
        .app_device_version = 0,
    };
    esp_zb_ep_list_add_ep(ep_list, cluster_list, endpoint_config);

    // 註冊設備並啟動
    esp_zb_device_register(ep_list);
    esp_zb_start(false);

    ESP_LOGI(TAG, "Zigbee gateway started, waiting for devices to join...");
}

// Zigbee 訊息處理回調
static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message) {
    esp_err_t ret = ESP_OK;

    switch (callback_id) {
        case ESP_ZB_CORE_SET_ATTR_VALUE_CB_ID:
            // 接收到屬性設定指令(例如:開燈、調光)
            ret = zb_attribute_handler((esp_zb_zcl_set_attr_value_message_t *)message);
            break;

        case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID:
            // 讀取設備屬性回應
            ret = zb_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t *)message);
            break;

        case ESP_ZB_CORE_REPORT_ATTR_CB_ID:
            // 設備主動回報狀態(例如:感測器數值)
            ret = zb_report_attr_handler((esp_zb_zcl_report_attr_message_t *)message);
            break;

        default:
            ESP_LOGW(TAG, "Unhandled Zigbee action: %d", callback_id);
            break;
    }

    return ret;
}

2. MQTT 整合與場景自動化

MQTT 主題架構

smarthome/
├── lights/
│   ├── living_room/lamp_1/status      → {"state": "ON", "brightness": 80, "color_temp": 4000}
│   ├── living_room/lamp_1/command     ← {"state": "ON", "brightness": 100}
│   ├── bedroom/ceiling/status
│   └── bedroom/ceiling/command
├── climate/
│   ├── living_room/ac/status          → {"state": "COOL", "temp": 24, "fan": "AUTO"}
│   ├── living_room/ac/command         ← {"state": "COOL", "temp": 26}
│   └── bedroom/ac/status
├── blinds/
│   ├── living_room/main/position      → {"position": 50, "tilt": 30}
│   └── living_room/main/command       ← {"action": "OPEN"}
└── security/
    ├── alarm/status                   → {"armed": true, "triggered": false}
    └── door_sensor/entrance/status    → {"state": "CLOSED", "battery": 85}

Node.js 場景自動化引擎

const mqtt = require('mqtt');
const cron = require('node-cron');

class SmartHomeAutomation {
    constructor() {
        this.mqttClient = mqtt.connect('mqtt://localhost:1883');
        this.deviceStates = new Map();
        this.scenes = [];
        this.automations = [];

        this.initMQTT();
        this.loadScenes();
        this.loadAutomations();
    }

    initMQTT() {
        this.mqttClient.on('connect', () => {
            console.log('Connected to MQTT broker');

            // 訂閱所有設備狀態主題
            this.mqttClient.subscribe('smarthome/+/+/status');
            this.mqttClient.subscribe('smarthome/+/+/+/status');
        });

        this.mqttClient.on('message', (topic, message) => {
            const state = JSON.parse(message.toString());
            this.deviceStates.set(topic, state);

            // 觸發自動化規則檢查
            this.checkAutomationRules(topic, state);
        });
    }

    // 場景定義(一鍵執行多個動作)
    defineScene(name, actions) {
        this.scenes.push({
            name,
            actions,
            execute: () => {
                console.log(`Executing scene: ${name}`);
                actions.forEach(action => {
                    this.mqttClient.publish(
                        action.topic,
                        JSON.stringify(action.payload)
                    );
                });
            }
        });
    }

    // 自動化規則(條件觸發)
    defineAutomation(name, conditions, actions) {
        this.automations.push({
            name,
            conditions,
            actions,
            lastTriggered: null
        });
    }

    checkAutomationRules(changedTopic, changedState) {
        this.automations.forEach(automation => {
            // 檢查所有條件是否滿足
            const conditionsMet = automation.conditions.every(condition => {
                const state = this.deviceStates.get(condition.topic);
                if (!state) return false;

                // 條件運算(支援 ==, !=, >, <, >=, <=)
                return this.evaluateCondition(state, condition);
            });

            if (conditionsMet) {
                // 防止短時間內重複觸發
                const now = Date.now();
                if (automation.lastTriggered && (now - automation.lastTriggered) < 5000) {
                    return;
                }

                console.log(`Automation triggered: ${automation.name}`);
                automation.lastTriggered = now;

                // 執行動作
                automation.actions.forEach(action => {
                    this.mqttClient.publish(
                        action.topic,
                        JSON.stringify(action.payload)
                    );
                });
            }
        });
    }

    evaluateCondition(state, condition) {
        const value = state[condition.attribute];

        switch (condition.operator) {
            case '==': return value === condition.value;
            case '!=': return value !== condition.value;
            case '>': return value > condition.value;
            case '<': return value < condition.value;
            case '>=': return value >= condition.value;
            case '<=': return value <= condition.value;
            default: return false;
        }
    }

    loadScenes() {
        // 離家模式:關閉所有燈光、空調、啟動警報
        this.defineScene('離家模式', [
            { topic: 'smarthome/lights/all/command', payload: { state: 'OFF' } },
            { topic: 'smarthome/climate/all/command', payload: { state: 'OFF' } },
            { topic: 'smarthome/security/alarm/command', payload: { armed: true } },
        ]);

        // 回家模式:開啟玄關燈、客廳燈、解除警報
        this.defineScene('回家模式', [
            { topic: 'smarthome/lights/entrance/command', payload: { state: 'ON', brightness: 80 } },
            { topic: 'smarthome/lights/living_room/command', payload: { state: 'ON', brightness: 60 } },
            { topic: 'smarthome/security/alarm/command', payload: { armed: false } },
        ]);

        // 觀影模式:關閉主燈、開啟氛圍燈、關閉窗簾
        this.defineScene('觀影模式', [
            { topic: 'smarthome/lights/living_room/ceiling/command', payload: { state: 'OFF' } },
            { topic: 'smarthome/lights/living_room/ambient/command', payload: { state: 'ON', brightness: 20, color_temp: 2700 } },
            { topic: 'smarthome/blinds/living_room/command', payload: { action: 'CLOSE' } },
        ]);

        // 睡眠模式:關閉所有燈光(除夜燈)、空調睡眠模式
        this.defineScene('睡眠模式', [
            { topic: 'smarthome/lights/all/command', payload: { state: 'OFF' } },
            { topic: 'smarthome/lights/bedroom/nightlight/command', payload: { state: 'ON', brightness: 5 } },
            { topic: 'smarthome/climate/bedroom/ac/command', payload: { state: 'COOL', temp: 26, mode: 'SLEEP' } },
        ]);
    }

    loadAutomations() {
        // 自動化 1:天黑時自動開啟客廳燈
        this.defineAutomation(
            '天黑開燈',
            [
                { topic: 'smarthome/sensors/outdoor/light', attribute: 'lux', operator: '<', value: 50 },
                { topic: 'smarthome/security/alarm/status', attribute: 'armed', operator: '==', value: false }
            ],
            [
                { topic: 'smarthome/lights/living_room/command', payload: { state: 'ON', brightness: 70 } }
            ]
        );

        // 自動化 2:人體感應自動開燈(5分鐘無人自動關閉)
        this.defineAutomation(
            '人體感應開燈',
            [
                { topic: 'smarthome/sensors/bathroom/motion', attribute: 'state', operator: '==', value: 'DETECTED' }
            ],
            [
                { topic: 'smarthome/lights/bathroom/command', payload: { state: 'ON', brightness: 100 } }
            ]
        );

        // 自動化 3:溫度過高自動開啟空調
        this.defineAutomation(
            '自動降溫',
            [
                { topic: 'smarthome/sensors/living_room/temperature', attribute: 'temp', operator: '>', value: 28 }
            ],
            [
                { topic: 'smarthome/climate/living_room/ac/command', payload: { state: 'COOL', temp: 26 } }
            ]
        );

        // 自動化 4:門窗異常開啟告警
        this.defineAutomation(
            '安全告警',
            [
                { topic: 'smarthome/security/alarm/status', attribute: 'armed', operator: '==', value: true },
                { topic: 'smarthome/security/door_sensor/entrance/status', attribute: 'state', operator: '==', value: 'OPEN' }
            ],
            [
                { topic: 'smarthome/security/alarm/command', payload: { trigger: 'DOOR_OPEN' } },
                { topic: 'smarthome/notifications/push', payload: { message: '警報!大門異常開啟' } }
            ]
        );
    }

    // 定時任務
    scheduleTasks() {
        // 每天早上 7:00 自動開啟臥室窗簾
        cron.schedule('0 7 * * *', () => {
            console.log('Morning routine: Opening bedroom blinds');
            this.mqttClient.publish('smarthome/blinds/bedroom/command', JSON.stringify({ action: 'OPEN' }));
        });

        // 每天晚上 23:00 自動執行睡眠模式
        cron.schedule('0 23 * * *', () => {
            console.log('Night routine: Activating sleep mode');
            const sleepScene = this.scenes.find(s => s.name === '睡眠模式');
            if (sleepScene) sleepScene.execute();
        });
    }

    // 啟動系統
    start() {
        this.scheduleTasks();
        console.log('Smart Home Automation Engine started');
    }
}

// 啟動智慧家庭系統
const smartHome = new SmartHomeAutomation();
smartHome.start();

3. Apple HomeKit 整合

使用 HAP-NodeJS 實作 HomeKit 橋接器:

const hap = require('hap-nodejs');
const Accessory = hap.Accessory;
const Service = hap.Service;
const Characteristic = hap.Characteristic;
const uuid = hap.uuid;

class HomeKitBridge {
    constructor(mqttClient) {
        this.mqttClient = mqttClient;
        this.accessories = new Map();
        this.bridge = new Accessory('智慧家庭系統', uuid.generate('smart-home-bridge'));

        this.initBridge();
    }

    initBridge() {
        this.bridge
            .getService(Service.AccessoryInformation)
            .setCharacteristic(Characteristic.Manufacturer, 'BASHCAT')
            .setCharacteristic(Characteristic.Model, 'Smart Home v2.0')
            .setCharacteristic(Characteristic.SerialNumber, 'SH-2024-001');

        // 發布橋接器(iPhone 家庭 APP 可發現)
        this.bridge.publish({
            username: 'CC:22:3D:E3:CE:F6',
            port: 51826,
            pincode: '031-45-154',
            category: Accessory.Categories.BRIDGE
        });

        console.log('HomeKit bridge published. Pair code: 031-45-154');
    }

    // 添加燈光配件
    addLight(id, name, topic) {
        const lightAccessory = new Accessory(name, uuid.generate(`light-${id}`));

        lightAccessory
            .addService(Service.Lightbulb, name)
            .getCharacteristic(Characteristic.On)
            .on('set', (value, callback) => {
                // HomeKit 設定燈光狀態
                this.mqttClient.publish(`${topic}/command`, JSON.stringify({
                    state: value ? 'ON' : 'OFF'
                }));
                callback(null);
            })
            .on('get', (callback) => {
                // HomeKit 讀取燈光狀態
                this.mqttClient.once('message', (receivedTopic, message) => {
                    if (receivedTopic === `${topic}/status`) {
                        const state = JSON.parse(message.toString());
                        callback(null, state.state === 'ON');
                    }
                });
                this.mqttClient.subscribe(`${topic}/status`);
            });

        // 亮度控制
        lightAccessory
            .getService(Service.Lightbulb)
            .addCharacteristic(Characteristic.Brightness)
            .on('set', (value, callback) => {
                this.mqttClient.publish(`${topic}/command`, JSON.stringify({
                    brightness: value
                }));
                callback(null);
            });

        // 色溫控制
        lightAccessory
            .getService(Service.Lightbulb)
            .addCharacteristic(Characteristic.ColorTemperature)
            .on('set', (value, callback) => {
                // HomeKit 色溫範圍:140-500 mired(對應 2000K-7142K)
                const kelvin = 1000000 / value;
                this.mqttClient.publish(`${topic}/command`, JSON.stringify({
                    color_temp: Math.round(kelvin)
                }));
                callback(null);
            });

        this.bridge.addBridgedAccessory(lightAccessory);
        this.accessories.set(id, lightAccessory);
    }

    // 添加空調配件
    addThermostat(id, name, topic) {
        const thermostatAccessory = new Accessory(name, uuid.generate(`thermostat-${id}`));

        const thermostatService = thermostatAccessory.addService(Service.Thermostat, name);

        // 目標溫度
        thermostatService
            .getCharacteristic(Characteristic.TargetTemperature)
            .setProps({
                minValue: 16,
                maxValue: 30,
                minStep: 1
            })
            .on('set', (value, callback) => {
                this.mqttClient.publish(`${topic}/command`, JSON.stringify({
                    temp: value
                }));
                callback(null);
            });

        // 當前溫度
        thermostatService.getCharacteristic(Characteristic.CurrentTemperature);

        // 運行模式
        thermostatService
            .getCharacteristic(Characteristic.TargetHeatingCoolingState)
            .on('set', (value, callback) => {
                const modes = ['OFF', 'HEAT', 'COOL', 'AUTO'];
                this.mqttClient.publish(`${topic}/command`, JSON.stringify({
                    state: modes[value]
                }));
                callback(null);
            });

        this.bridge.addBridgedAccessory(thermostatAccessory);
        this.accessories.set(id, thermostatAccessory);
    }

    // 添加窗簾配件
    addBlind(id, name, topic) {
        const blindAccessory = new Accessory(name, uuid.generate(`blind-${id}`));

        blindAccessory
            .addService(Service.WindowCovering, name)
            .getCharacteristic(Characteristic.TargetPosition)
            .on('set', (value, callback) => {
                this.mqttClient.publish(`${topic}/command`, JSON.stringify({
                    position: value
                }));
                callback(null);
            });

        this.bridge.addBridgedAccessory(blindAccessory);
        this.accessories.set(id, blindAccessory);
    }
}

module.exports = HomeKitBridge;

專案成果

技術指標

  • 設備支援數量:單一中控可管理 200+ 設備
  • 系統回應時間:< 200ms(本地控制)
  • 網路穩定性:Zigbee Mesh 自癒能力,單點故障不影響整體
  • 場景執行速度:10+ 設備同步控制延遲 < 500ms
  • HomeKit 認證:通過 Apple MFi 認證
  • 語音控制準確率:95%+(Siri / Google Assistant / Alexa)

商業成果

  • 🏠 已部署 30+ 高端住宅(單戶預算 NT$50-150萬)
  • 📊 管理設備總數:6,000+ 個智慧節點
  • ⭐ 客戶滿意度:4.8/5.0
  • 🔧 系統穩定度:99.8%(年故障率 < 0.2%)
  • 💰 為建設公司創造 NT$4,500萬 增值服務營收

創新亮點

  1. 混合通訊架構:Zigbee + WiFi + KNX 三網融合,適應各種設備
  2. 本地優先策略:即使斷網仍可本地控制,不依賴雲端
  3. 三大平台整合:同時支援 HomeKit、Google Home、Alexa
  4. AI 場景學習:分析用戶習慣,自動優化場景設定

技術棧

硬體平台

  • Raspberry Pi 4(中控主機)
  • ESP32-S3(Zigbee 協調器)
  • KNX IP 閘道器
  • 200+ Zigbee 終端設備

後端開發

  • Node.js + Express
  • MQTT (Mosquitto Broker)
  • SQLite(本地資料庫)
  • HAP-NodeJS(HomeKit)

前端應用

  • React Native(iOS/Android APP)
  • React.js(Web 管理介面)
  • Apple HomeKit
  • Google Home / Amazon Alexa

通訊協定

  • Zigbee 3.0
  • MQTT
  • KNX IP
  • HomeKit HAP
  • Matter(未來支援)

客戶回饋

"BASHCAT 打造的智慧家庭系統完全超出我們的預期!不僅技術穩定、功能強大,而且操作介面非常人性化。最讓我們滿意的是本地控制功能,即使網路斷線也不影響使用。這套系統已成為我們豪宅專案的核心賣點。"

總經理,豪宅建設公司


專案時間:2023年1月 - 2023年12月 技術領域:物聯網、嵌入式系統、智慧家庭、自動化控制

相關專案

探索更多 嵌入式系統 領域的技術專案

更多 嵌入式系統 專案

即將推出更多相關技術專案

查看全部專案