Linux 的魅力: 這個古老的機器:使用 X10 實現家庭自動化

發表于:2007-05-25來源:作者:點擊數: 標簽:
80 年代人們的夢想之一是,有朝一日,每個人都擁有火箭汽車,計算機控制著家里的所有東西,比如燈。我們還沒有擁有火箭汽車,但是 X10 協議使我們能夠遠程地開/關設備。在本文中,Peter Seebach 講解如何使用現有的硬件和幾百行簡單的代碼來設置和驅動 X10
80 年代人們的夢想之一是,有朝一日,每個人都擁有火箭汽車,計算機控制著家里的所有東西,比如燈。我們還沒有擁有火箭汽車,但是 X10 協議使我們能夠遠程地開/關設備。在本文中,Peter Seebach 講解如何使用現有的硬件和幾百行簡單的代碼來設置和驅動 X10 設備。

理解 X10

X10 協議是用于在電源線上傳輸數據的相當原始的工具??赡苷驗樗喈斣?,它也相當健壯,盡管好的線過濾器或電壓尖峰抑制器可能會干擾它。對于連網來說,X10 的數據傳輸速度太慢了,但是對于遠程開/關設備來說是合適的。

為了發送 X10 信號,需要在電子接線盒上插入某些東西并提供一個計算機接口。這些設備有 USB 和 RS232 串行接口兩種形式;我使用串行版本。它們的價格大約是 30 美元,可以從幾家廠商那里買到;我使用 Smarthome 的 1132B 型號(參見 參考資料)。真正的主要硬件是一個收發器:它接收 X10 信號并通過串行端口發送信號,還接收串行信號并通過線路發送它們。信號被廣播;每個設備都會接收它們。但是,為了防止造成混亂,每個信號包含編碼,表明它是發送給哪個或哪些設備的。

一般來說,信號包含房屋編碼、單元編碼和功能編碼。顧名思義,房屋編碼用于大的設備組;可以有 16 個房屋,名稱為 A 到 P。典型的 X10 控制器單元可能有 4 個搖臂開關(對應單元 1-4)和一個刻度盤(表示要使用哪個房屋編碼)。除非要使用大量設備,否則很可能可以為每個設備使用一個房屋代碼。單元編碼(1-16)指定特定的設備。一些比較老的硬件不支持 1-8 之外的單元編碼;同樣,一些比較老的設備只支持房屋編碼 A-H。

許多設備有某種刻度盤或開關組,用來決定房屋和單元編碼。一些比較新的設備可以以電子方式進行編程;以后這樣的設備會更多。





回頁首


硬件和連接

硬件很容易連接。我使用的設備是一個墻上插座附件,它有點兒像某些便攜電子設備的變壓器,底部有一個用來傳輸各種信號的 RJ45 端口。它連接一條信號線,提供標準的 9 針串行端口連接。沒有流控制,9600,8N1。非常標準。

在 Linux® 上訪問串行端口是相當簡單的。默認的設置是訪問只限于組 uucp 的成員;我將自己的帳號添加到這個組、注銷并再次登錄。

對端口進行初始化非常簡單。清單 1 中的代碼(取自示例程序)顯示需要的初始化:


清單 1. 打開串行端口并設置參數
            int fd;
            struct termios t;
            fd = open(dev, O_RDWR);
            if (fd < 0) {
            fprintf(stderr, "Error opening '%s': %s\n",
            dev, strerror(errno));
            return -1;
            }
            tcgetattr(fd, &t);
            cfsetspeed(&t, B9600);
            cfmakeraw(&t);
            t.c_cflag &= ~(CSIZE);
            t.c_cflag |= CS8;
            t.c_cflag &= ~(PARENB);
            tcsetattr(fd, TCSANOW, &t);
            

dev 變量保存設備的路徑;在默認情況下,它是 /dev/ttyS0。(在我用來實現這些項目的老式 Gateway 筆記本上,內置的串行端口是 COM1,或 ttyS0。本系列的 第一期 中介紹了這個筆記本。)主例程允許覆蓋 dev;另一個可能使用的值是 /dev/ttyUSB0,這是使用 USB 端口時的路徑。

tcgetattr/tcsetattr 操作(來自 termios.h)允許修改設備的設置。在幾乎所有情況下,最好是獲得原來的設置并修改它們,而不是自己完全填寫一個 termios 結構?;疽巹t是設置需要的任何標志并清除不需要的任何標志。其他東西都不變。

這條規則有時候有例外。清單 2 顯示第一個代碼片段:


清單 2. 配置字符大小的一次失敗的嘗試
            t.c_cflag |= CS8;
            t.c_cflag &= ~(PARENB | CS6 | CS7);
            

這段看似合理的代碼卻將字符大小設置為 5 位。為什么呢?CS6 是 0x10,CS7 是 0x20,CS8 是 0x30。設置 CS8,然后清除 CS6 和 CS7,結果的就是 0x00,也就是 CS5 的值。清除 CSIZE 位,然后設置顯式地設置需要的值,這樣才可以。





回頁首


協議

坦白地說,X10 協議是超現實的。RS232 有一個用來描述 X10 消息的協議,它甚至更不可思議。一個消息有 5 字節;0x63(“發送 X10 命令”)、房屋編碼、單元編碼、功能編碼和重復次數。這些都在表中查找。例如,重復編碼(表示重復一個信號;例如用于有衰減器的情況)作為字母 A 到 O 發送,A 代表 1,B 代表 2 等等。除了很少的幾個例外(比如 “發送命令” 字節)之外,發送的每個值的范圍是從 0x40 到 0x5F。

嘗試在這個協議中尋找模式似乎很有意思。X10 十六進制編碼的主要范圍在 0x00-1F;RS232 協議似乎只增加了 0x40 以避免使用控制字符。但是,X10 編碼采用的模式對于未經訓練的人不容易理解。前幾個單元編碼(代表 1-4)是 0x0C、0x1C、0x04 和 0x14。(偶數單元編碼總是設置了 0x10)。所有單元編碼都是偶數;所有命令編碼都是奇數。

協議還允許一些例外。一些命令(比如 “關閉所有單元”)不需要使用單元編碼。對于這些命令,省略單元編碼。不像您可能猜測的那樣,設置為零;而是省略。次序就變成了 0x63、房屋編碼、功能編碼、0x00和重復次數。但是,因為所有單元編碼都是偶數,所有命令編碼都是奇數,所以這不會引起誤解。





回頁首


設計軟件接口

驅動 X10 所用的代碼并不太復雜,但是到處重復編寫這些代碼也很麻煩。UNIX® 的解決方案是一個實用程序,它可以從命令行發送 X10 命令。其他程序可以根據需要運行這個實用程序。執行并調試這個實用程序之后,可以將這個程序的組改為 uucp 并給它設置 setgid 位,從而限制對 X10 硬件的訪問。

發送 X10 命令的次序在編寫時沒有二義性,但是對它進行解析很麻煩。我并不試圖查明哪個部分是哪個參數,而是編寫了一個實用程序來接收命令編碼、房屋編碼和單元編碼。如果指定的命令不需要單元,就不讀取單元。在表中查找命令、房屋編碼和單元;用戶以象征性方式指定它們。例如,命令 “x10 on a 1” 會打開房屋 A 中的單元 1。-h 選項或在一個字段中放上 “help” 會列出可用編碼以及傳輸給 X10 適配器的原始編碼。

我的初始設計忽略了重復編碼,因為我覺得不太需要它們。X10 協議很慢,所以多次調用這個程序的開銷不會導致顯著的效率下降。

用來進行編碼查找的結構將一個字符串和一個數值關聯起來??梢蕴砑右粋€ “標志” 字段,但是我在編寫好接口之后才想到這一點,所以只能將標志放在無符號字符范圍外的位上。這導致只有一個標志 SUPPRESS_UNIT,它用在不需要單元的命令上。特殊命令 none 用來發送沒有命令的消息;一些可編程 X10 硬件可以使用這些消息配置房屋和單元的設置。

擴展軟件

程序可以打開和關閉各種設備是很棒,但是它不夠靈活;可以以幾種方式改進這種狀況。

首先,給設備分配符號名會很方便。在測試期間,我一共使用了三個設備(其中兩個放在我家里),有幾次我忘了哪個編碼代表哪個設備。合理的做法是創建一個配置文件。我選擇使用一種傳統的相當典型的配置文件格式;每行有三個以空白分隔的字段,包含設備的符號名、房屋編碼和單元編碼。以 # 開頭的行是注釋。例如,清單 3 中的文件描述了幾個設備:


清單 3. 將設備名映射到房屋和單元編碼
            # the big lamp by the couch
            tvroom		 		  a		 		  1
            # I hooked up my little brother's nintendo so I can mess with him
            n64		 		  a		 		  2
            

按照與命令行相同的方式查找房屋和單元編碼。

對衰減器的支持是另一個可以添加的特性;我還沒有實現它,但是協議支持這么做。但是要注意一點:不要同時發送大量明/滅消息;接口太慢了。





回頁首


提供 Web 界面

遠程訪問自己的燈是非常方便的,但是其實在大多數時候用處不大,通過 Web 界面打開燈也沒什么意義。Web 頁面是很容易使用,但是電燈開關更簡單。這并不意味著 Web 界面沒有用。通過 Web 界面控制家里的復雜電器可能是有意義的,例如打開另一間屋子中的咖啡壺。如果您習慣于總是在咖啡壺中放上咖啡粉和水,那么點擊一下按鈕,就可以開始煮咖啡。

另一個可以添加的特性是配置新的 X10 設備。我使用的燈控制器預先設置為設備 A1,沒有開關或按鈕。為了對它進行編程,插入它,然后在 30 秒內發送 3 個包含特定房屋和單元編碼的 X10 消息;它就會設置成這個房屋和單元編碼。從一個簡單的 Web 界面執行這種操作是很棒的,盡管這種任務不需要頻繁地執行。以下腳本的效果就很好:


清單 4. 設置設備的房屋和單元編碼
            #!/bin/sh
            x10 none $*
            x10 none $*
            x10 none $*
            

用房屋和單元編碼或 x10.conf 中的設備名進行調用,它就會對設備進行編程。





回頁首


使用 cron 調度任務

使用 cron 調度某些操作(比如開燈)的執行時間非常簡單。如果在渡假期間希望自己的房屋在晚上開燈,裝出房子有人住的樣子,那么在每天晚上同一時間開燈可能不太好。需要有點兒隨機性。下面的簡單腳本會在一小時內的某一時間執行操作:


清單 5. 延遲一小時內的隨機時間
            #!/bin/bash
            sleep $((RANDOM / 10))
            $*
            

將這個腳本保存為 /usr/local/bin/soonish,然后可以使用下面這樣的 cron 項:


清單 6. 在晚上開燈
            0 18 * * *		 		  /usr/local/bin/soonish x10 on tvroom
            0 21 * * *		 		  /usr/local/bin/soonish x10 off tvroom
            





回頁首


結束語

這個月,我在送貨費上超過了預算(我編寫這個系列的動機和約束見 “Linux 的魅力:讓古老的機器重獲新生”)。X10 收發器、燈模塊和文檔的總價格是 49.97 美元。不幸的是,要加 8 美元的送貨費。文檔根本沒什么價值;不但可以下載更好的文檔,而且不知道為什么,送來的文檔是 5 本同樣的書,其中全是關于 X10 協議的技術信息,根本沒有關于將什么信號發送到收發器的參考資料。所以,我原本可以省下為文檔支付的 5 美元。

從長遠來看,有多個模塊可以控制是非常有好處的,但是這要花錢。我要注意控制預算;我有兩個 1997 年買的 X10 模塊,它們和新模塊一樣工作得很好。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97