IMG_1598

不久前在 Youtube 上看到一則影片,主角只出一張嘴,就能透過 Siri 讓家裡的電器用品乖乖聽話,就像小時候的科幻片描述未來的居家生活,頗為神奇。只不過影片中並沒有說明實作的方法,只在影片下方留言中提到幾個關鍵字,引起了我的好奇。

從 iOS 開發者的角度來看,原以為是 iOS 10 的 Sirikit 的新功能,於是我嘗試呼叫 Siri ,得到的是以下的結果:

IMG_1599

Siri 回答提到「打理這個家」,大概能猜得到,iOS 使用 Homekit 控制家電 ,而 Siri 與 Homekit 整合已經是 iOS 10 內建的功能,所以 Siri 控制家電並非使用 Sirikit ,而是用 Homekit 來實現。換言之,所謂家電用品支援 Homekit 功能,就是除了能透過 iOS 10 內建的「家庭 App」來統一管理,並可自訂使用情境、場景與配件的設定,打造個人專屬的家電運作模式之外,還能透過 iOS 的 Siri 語音助理,「用講的」操控家電的部分功能。「家庭 App 管理家電」與「Siri 語音控制家電」兩項重點功能,就是 iOS 10 的 Homekit 智慧家電平台。

近年來有越來越多新的家電產品標榜「智慧家電」功能,但台灣民眾對這一塊的熱度不夠,目前市面上還不普及,現役家電產品也大多還能用個很多年,除非在裝修新房時就納入智慧家電的規劃,否則只有極少數的人為了享受「智慧家電生活」把家裏的電器產品全部換掉(據說有個社會名人就這樣搞,打造智慧家庭就花了四千萬台幣)。於是換個角度,有沒有辦法讓家裏面的現有家電,透過外掛手段來支援 Homekit 呢?答案是有的,價格也很低廉,只是要達到這樣的目標有一定的技術門檻,雖然不難,但也不算容易,因為不同的電器有不同的動作設定,納入 Homekit 之後更不一定支援家電原有的全部功能。

所以我可以理解為何一堆 Youtube 影片,尤其是中文的,大多沒有教學,畢竟有些實作步驟很有可能卡關,實作方式也會牽涉到特定的知識領域,寫了教學也不可能人人都能淺顯易懂。所以這篇文章是概略的實作方式,幫自己做紀錄,和提供給有興趣想嘗試的人做參考。

使用情境:以家裏運作多年的老冷氣機為例,利用 iOS 的 Homekit 功能來控制冷氣的基本功能「開」和「關」。

市售的傳統家用冷氣都有紅外線遙控器,但並不支援無線網路。所以要達到上述目標,實作方式概略分成兩大部分:

  • 實作一組可支援網路操控的自製紅外線WIFI遙控器
  • 在家裡的區域網路內,連接 Homekit 與自製的紅外線WIFI遙控器

一、支援網路操控的紅外線WIFI遙控器

這個部分教學就不少了,搜尋「Arduino+IRremote」就會跑出一堆。這裡再細分出兩階段:材料採購與軟體撰寫。

材料相當廉價,甚至於比你去夜市買一隻萬用遙控器還便宜。

  • MCU/SoC 晶片:直接用 NodeMCU V1.0 就好了,這東西越來越便宜,現在一個才 NT 120,CP 值爆表,屌打一堆動輒千元的物聯網模組。
  • 紅外線發射 LED :一顆才 2 元,台南市區的電子材料店約 10-15 元。因為發射時有方向性,可以併聯個2-3顆,每一顆朝不同的方向。
  • 電晶體:NPN 型,例如 2N3904,作用是放大紅外線發射訊號,一顆也是 2-5 元。

元件接法可參考這個網頁,自製紅外線搖控器的硬體配置就這樣而已,材料費才台幣一百多元。至於運作的電源,找條 Micro-USB 線連接 NodeMCU 與帶電的 USB 埠就行了(電腦/充電器/行動電源…)。

687474703a2f2f667269747a696e672e6f72672f6d656469612f667269747a696e672d7265706f2f70726f6a656374732f652f657370383236362d69722d7472616e736d69747465722f696d616765732f49522532305472616e736d69747465725f62622e706e67

再來是軟體撰寫的階段。倘若真的不會寫程式,那…請自行 Google 市面上已整合 WIFI + 紅外線 + 軟體 APP 的產品:Broadlink RM Pro(市價約 NT 980.-),以及如何把這產品掛上 Homekit 的教學,就可以按上一頁離開本文章了。

軟體撰寫使用 Arduino IDE + Arduino Code 開發撰寫,加掛以下三方套件,至於程式碼內容就不說明了,套件範例都有。

  • IRremoteESP8266:ESP8266 驅動紅外線的套件。
  • WiFiManager:ESP8266 超級好用的 Wifi 連線套件。
  • <ESP8266mDNS.h>、<ESP8266WebServer.h>:ESP8266 Arduino Code 內建。讓 ESP8266 變成具備 DNS Name 的 WebServer,負責接收 HTTP Request 內容。

不過一開始我們不可能知道冷氣的紅外線發射的編碼內容,所以要買一顆紅外線接收器(我是買模組化的這個,理論上可以買更便宜的 LED 型),再用 IRremoteESP8266 提供的標準範例程式寫個 ESP8266 接收紅外線編碼的程式,學習原廠的搖控器就可取得紅外線的編碼內容,存成文字後就可以作為紅外線發射器的資料來源,可參考這篇文章的說明。

這個部分最終的目標為:在家裡的網路中隨便找一台電腦/平板/手機,打開瀏覽器,輸入網址就能驅動自製的紅外線發射器進行指定的動作,例如輸入 http://esp8266.local/airconditioner/on 就能讓自製遙控器發射「開冷氣」的紅外線編碼,http://esp8266.local/airconditioner/off 讓自製遙控器發射「關冷氣」的紅外線編碼。

當這個階段完成之後,只要把自製紅外線 WIFI 遙控器擺在冷氣(家電)可接收紅外線訊號的固定位置,就等於可以在家裡用電腦/平板/手機等裝置,用透過家裡的區域網路來控制家裡的冷氣開關了。例如以下的幾個範例:

手機端的 Widget 工具:

IMG_1652

macOS 電腦端的應用程式:

2017-08-30-1.19.25

Windows PC 端的應用程式:

Image2 Image

其實「用裝置遙控 ESP8266 聯網裝置」的動作不一定要透過 HTTP 協定,有太多方式了,例如使用 MQTT 協定搭配國外免費的 Broker 服務,預設就能直接跨越家裡區網的限制,不論人在世界的哪個地方,拿起手機或平板執行 MQTT 客戶端程式,就能控制家裏的 ESP8266 聯網裝置,但也意味別人也有機會駭入你家,所以使用網路 MQTT 服務要非常小心,這部分就不多提了。

二、連結 iOS Homekit 與自製紅外線WIFI遙控器

這邊就進入重點了。目前還沒有找到 ESP8266 連接 Homekit 的 Arduino Code,現在看到大部分實作的方式是透過一個叫「homebridge」的服務作為橋接器,由這個橋接器負責周邊設備與 Homekit 的溝通,實作重點在軟體服務的安裝與設定。

(1) 安裝 homebridge 橋接器服務

知道上述動作原理之後,實作過程就是找台電腦建立「homebridge 」橋接器,並在橋接器上建立虛擬周邊與包含執行網址的設定(開/關冷氣的動作網址)。網路上大部分的教學是把 homebridge 安裝在「樹莓派(Raspberry Pi)」上,也有少部分教學是安裝在 UbuntuWindows 。每種作業系統安裝 homebridge 方式都不一樣,而 Ubuntu 不同版本安裝 homebridge 的過程也有些微差異。

由於我沒有樹莓派(雖然便宜,但一台也要一兩千元),所以我是採用建立 Ubuntu 14.04 (VirtualBox 虛擬機)的方式,來安裝啟動 homebridge 服務。VirtualBoxUbuntu 作業系統也是免費下載,花費 0 元。與 Ubuntu 系出同門的 Debian 作業系統(正確說法為 Ubuntu 是 Debian 的一項分支),在安裝完 sudo 與 設定 sudoers 之後,也能使用以下相同的方式安裝 homebridge 服務。

Ubuntu 作業系統開啟終端機視窗,依序執行指令如下:

1. 執行 sudo apt-get update

如果出現以下的錯誤訊息:
E: 無法將 /var/lib/dpkg/lock 鎖定 - open (11: 資源暫時無法取得)
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

可執行以下指令
sudo rm -rf /var/lib/dpkg/lock

2. 執行 sudo apt-get upgrade 等一段時間,這邊要等很久,14.04 虛擬機大概會跑10幾分鐘以上,甚至半個多小時。

如果一下子跑完,又說 xx 未被升級的話,可執行
apt-get dist-upgrade

3. 執行以下命令

sudo apt-get install -y samba screen git
sudo apt-get install curl
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo npm install node-gyp
sudo apt-get install libavahi-compat-libdnssd-dev


4. 安裝 homebridge
執行 sudo npm install -g --unsafe-perm homebridge

不過 Ubuntu 14.04 很可能會遇到以下的錯誤訊息

nas@nas:~$ sudo npm install -g --unsafe-perm homebridge
/usr/bin/homebridge -> /usr/lib/node_modules/homebridge/bin/homebridge

> mdns@2.3.3 install /usr/lib/node_modules/homebridge/node_modules/mdns
> node-gyp rebuild

make: Entering directory `/usr/lib/node_modules/homebridge/node_modules/mdns/build'
CXX(target) Release/obj.target/dns_sd_bindings/src/dns_sd.o
make: g++: Command not found
make: *** [Release/obj.target/dns_sd_bindings/src/dns_sd.o] Error 127
make: Leaving directory `/usr/lib/node_modules/homebridge/node_modules/mdns/build'
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2

 

可執行以下五行指令修正問題

sudo rm -rf /usr/lib/node_modules/
sudo apt-get install build-essential
sudo apt-get install libkrb5-dev
sudo apt-get remove nodejs
sudo apt-get install nodejs

之後再執行一次  sudo npm install -g --unsafe-perm homebridge 試試看。


5. 測試 homebridge
輸入homebridge

回應
......
Scan this code with your HomeKit App on your iOS device to pair with Homebridge:

┌────────────┐
│ 031-45-154 │
└────────────┘

[2017-08-02 16:12:05] Homebridge is running on port 43761.

如果出現反白配對碼「 XXX-XX-XXX」的訊息,表示 homebridge 安裝完成。

螢幕快照 2017-08-05 上午12.51.04

這時候就可以打開 iOS 10 手機的「家庭 App」了,一路循指示開啟 iCloud 的「家庭」權限-->新增配件,就能看到有個叫「Homebridge」的裝置顯示在清單上。

IMG_1602

不過這個時候先別急著設定,因為橋接器還沒有掛上虛擬周邊可供選取。先按「取消」離開。

(2) 安裝 homebridge 插件

homebridge 插件的目的,就是建立虛擬周邊設備掛進 homebridge 橋接器服務,並設定虛擬周邊的動作指令。有上百種插件任君挑選,每一種插件都有不同的週邊設備作用方式。要選哪個插件可以到這裡搜尋

homebridge-plugin

插件的功能可說是玲瑯滿目,坦白說要搞懂插件的運作與設定方式實在不容易,因為每一種的作用與目的都不同,甚至超出「周邊家電」的既定印象。例如這個「homebridge-openweathermap-temperature」插件,就是模擬一個溫度計周邊,用來顯示 OpenWeather 天氣服務網站的某指定城市現在氣溫。

先用這個插件為例,安裝的方式為:

A. 開啟終端機,執行命令 sudo npm install -g homebridge-openweathermap-temperature

B. 在 ~/.homebridge/ 建立(或修改)config.json,文字內容如下:

{
"bridge": {
"name": "控制中心",
"username": "AB:CD:EF:12:34:56",
"port": 51826,
"pin": "123-45-678"
},
"description": "HomeBridge HTTP Status Control",
"accessories": [
{
"accessory": "OpenweathermapTemperature",
"name": "台南市溫度",
"url": "http://api.openweathermap.org/data/2.5/weather?q=Tainan&appid=[apikey需註冊OpenWeather帳號取得]"
}
]
}

config_json

C.終端機執行 homebridge 指令

螢幕快照 2017-08-05 上午2.00.46

看到 Load x accessories... 以及配對的 XXX-XX-XX 訊息時,就表示 homebridge 和配件都成功掛載啟動了。

若要讓 homebridge 於每次 Ubuntu 開機時自動執行,請參考這裡

D. 回到 iOS 10 的「家庭 App」,依照畫面指示設定就行了。

IMG_1603

最後就能在「家庭 App」看到一個配件,內容顯示 OpenWeather 查詢的城市溫度。

也可以呼叫 Siri 用講的給你聽。不過因為是「家庭周邊配件」,問 Siri 的時候要問「家裏溫度」才會顯示配件數字,若是只問「溫度」或「室外溫度」,它就會找 iOS 內建的天氣預報服務,而不是 Homekit 。

IMG_1609  

搞懂如何掛載插件的方法後,接著就可以選擇適合的插件,透過 HTTP 網址來執行冷氣的開關動作了。我找到符合有「開」與「關」對應動作網址的插件是「homebridge-http

sudo sudo npm install -g homebridge-http

接著編輯 config.json 內容,在「"accessories"」節點內插入以下內容:

{
"accessory": "Http",
"name": "冷氣",
"switchHandling": "realtime",
"http_method": "GET",
"on_url": "http://[開冷氣的網址]",
"off_url": "http://[關冷氣的網址]",
"status_on": "ON",
"status_off": "OFF",
"service": "Switch",
"sendimmediately": "",
"username": "",
"password": ""
}

螢幕快照 2017-08-05 上午2.52.02 

重新執行 homebridge 之後,「家庭 App」就可以看到兩個配件按鈕。可以點擊冷氣配件按鈕進行開或關的動作。

IMG_1613

不過這個插件遇到網路問題時會發生找不到 callback 函數的 BUG 而跳出,修正方式: 

/usr/lib/node_modules/homebridge-http/index.js
從第 11 行加入
function callback(error){
if(error){
console.log('HTTP function failed: %s', error.message);
}
else{
console.log('HTTP function done with No Error...');
}
}

插件可以一直加掛進 homebridge 橋接器內,例如再繼續加掛「homebridge-httptemperaturehumidity」就可以透過 HTTP 協定取得家裏的 ESP8266+DHT22 溫濕度數值,並透過 Siri 語音控制這些周邊。

IMG_1598

這個插件也有類似的問題,修正方式: 

1. 修改 /usr/lib/node_modules/homebridge-httptemperaturehumidity/index.js
在 var res = request(this.http_method, this.url,{}); 與 if(res.statusCode > 400){ 之間加入

var res = request(this.http_method, this.url,{});
if (typeof res === 'undefined'){
this.log('HTTP power function NOT succeeded : undefined');
this.temperature = -1;
this.humidity = -1;
callback(null, this.temperature);
}
else if(res.statusCode > 400){

 

2. 修改 /usr/lib/node_modules/homebridge-httptemperaturehumidity/node_modules/sync-request/index.js ,目的是修正可能因網路問題造成 Javascript 程式錯誤或 JSON.parse 方法卡死的現象,修改內容重點在「標記 throw error 方法」與「增加 resErr 變數」的判斷,才不至於讓錯誤結果誤進 JSON 解析程序產生其他問題。

'use strict';

var fs = require('fs');
var spawnSync = require('child_process').spawnSync || require('spawn-sync');
var HttpResponse = require('http-response-object');
require('concat-stream');
require('then-request');
var JSON = require('./lib/json-buffer');

Function('', fs.readFileSync(require.resolve('./lib/worker.js'), 'utf8'));

module.exports = doRequest;
function doRequest(method, url, options) {
var req = JSON.stringify({
method: method,
url: url,
options: options
});
var res = spawnSync(process.execPath, [require.resolve('./lib/worker.js')], {input: req});
var resErr = 0;
if (res.status !== 0) {
console.log('doRequest res.stderr.toString: %s',res.stderr.toString());
resErr = 1;
//throw new Error(res.stderr.toString());
}
if (res.error) {
if (typeof res.error === 'string') res.error = new Error(res.error);
console.log('doRequest res.error === string ');
resErr = 1;
//throw res.error;
}
if (resErr === 0){
var response = JSON.parse(res.stdout);
if (typeof response === 'undefined'){
console.log('httptemperaturehumidity: response JSON is undefined');
}
else if (response.success) {
return new HttpResponse(response.response.statusCode, response.response.headers, response.response.body, response.response.url);
} else {
console.log('response not success: %s',response.error.message);
//throw new Error(response.error.message || response.error || response);
}
}
}

若是 iPhone 6s 以後的設備(支援免插電源線呼叫 Siri),或是家裡擺一台 Homepod ,就能實現完全不需動手,回到家出一張嘴喊個 Siri 就行了,敲方便。

實際運作影片

成本總結:

  • NodeMCU x 1 : NT 120.-
  • 紅外線 LED / NPN 電晶體 x1 : 10元 有找

其他必備條件:

  • Micro USB 連接線
  • 個人電腦一台
  • 行動電源 或 USB 充電器 或 電腦的 USB 連接埠(可提供 5V USB 連接埠)
  • iPhone 手機一支(需支援 iOS 10,最低要求為 iPhone 5 )
  • 家裡區域網路,與可連上 iCloud 的環境。
文章標籤
創作者介紹

-Ben's PHOTO-

benjenq 發表在 痞客邦 PIXNET 留言(2) 人氣()


留言列表 (2)

發表留言
  • teok
  • 感謝分享,已如法炮製一個電視版出來,只是家中冷氣紅外線編碼不同,尚在努力中~
  • 感謝回覆~我在考慮要不要弄一台樹莓派3,因為我把ubuntu虛擬機裝在Surface Pro的Win10內,會發生 homebridge 跑幾個小時後不明原因停止。

    benjenq 於 2017/09/03 00:10 回覆

  • teok
  • 如果是Hyper-v的話,建議換VMware看看,還有我Homebridge是架在16.04上,目前是還沒有中斷服務過,只是NodeMCU的效能真的差了點,紅外線Data多的話就會整張板子死當XD,我也考慮要升級板子了
  • 原本用的是 VMWare 會發生 homebridge 服務中斷的問題(虛擬機看似運行正常),後來我換成 VirtualBox 就解決了... 照理說 VMWare 應該會比較穩定才對,不知原因為何,。

    NodeMCU 使用的 ESP8266 常出現很多異常狀況,不過文章的自製WIFI紅外線方案倒是沒遇過怪事,運作好幾個月了。之前開發時遇過一個狀況,紅外線搭配的 IRremote 套件在某幾個 GPIO 很不穩定,發射頭溫度會熱熱的,也容易當機。現在紅外線接在 D5 腳就很穩定正常了,參考試試看囉~

    benjenq 於 2017/09/04 17:13 回覆

找更多相關文章與討論