几年前,我结束了为期 15 天的旅行回到家,当时正值热浪,我的公寓太热了——室内至少有 45 摄氏度(113 华氏度)。不用说,这不是最舒适的回家方式,尤其是我公寓里的嵌入式空调 (AC) 需要几个小时才能使公寓降温。
我的公寓里有两台空调;一台在客厅,另一台在卧室。为了最大限度地减少不必要的电力消耗,我在外出时关掉了空调。 在经历了这件事之后,我决定是时候找到一种远程控制空调的方法,这样当我回家时,我的公寓就不会太热(我也不会因为高温而损坏我的电脑)。 然而,我的公寓的空调不像大多数现代空调系统那样,没有恒温器可以让你设置房间的温度。我的空调只有开/关开关,这意味着我需要一个恒温器。
我的朋友们已经向我介绍了他们的家庭自动化设置有一段时间了,但直到现在我才明白它的意义。 我住在一个小的一居室公寓里,没有传感器或联网电器,我以为没有什么可以自动化的。我意识到自动化可以解决我的公寓温度问题。 我开始构建自己的恒温器,它可以读取我公寓的温度并根据温度调节空调。
硬件
首先,我需要一些硬件来读取公寓的温度并控制空调。 我从控制端开始,因为我认为处理温度传感器是比较简单的问题。我开始思考如何远程控制我的空调。 我的第一个想法是使用我可以从家庭网络访问的微控制器来接入现有的控制装置。
空调只有模拟控制,一个用于模式的旋转选择开关和一个用于风扇速度的电位器,因此很容易接入。

我的公寓自带的空调。
但是空调不是我的——它们是公寓自带的。 我认为我不应该拆开它们并将电线焊接到里面,否则当我搬出去时,我可能不得不买下这些空调。这绝对是我不想担心的事情。
我的下一个想法是实施一种机器人控制形式来转动空调装置上的旋钮。 虽然这在行动中会非常酷,但感觉不是最可靠的选择。旋钮以前坏过,我不得不从公寓大楼更换。 我觉得让东西自动转动旋钮只是在要求它们再次损坏。
然后,我意识到我不需要控制空调拨盘——相反,我可以控制空调装置的电源。 我可以将空调装置保持在开启状态,并在我需要冷却房间时打开电源,在不需要时关闭电源。 虽然我仍然需要在必要时手动调整模式,但仅仅控制电源状态就满足了我的需求。 因此,我开始寻找一个继电器来控制空调装置的电源。
我有两个约束条件需要考虑,这影响了我的选择。 首先,根据我的公寓布局以及空调装置在墙壁上的安装位置,我想要无线控制。 虽然我可以将电线连接到空调装置,但无线会更容易(尤其是在客厅里,因为空调装置附近没有任何东西)。 第二个约束条件是继电器需要额定承受空调装置的负载。我必须用钳形表测量它,因为装置上没有任何型号,我也没有它们的任何文档。

公寓平面图,显示空调装置的位置。
我开始查看远程可控电源开关的选项。 市场上有许多不同的物联网 (IoT) 无线通信协议可供选择,但最受欢迎的选择是 Z-Wave 和 ZigBee。 我在大学里使用过 ZigBee 设备,处理它们真的很痛苦,所以我想要避免它们。
我的阅读建议 Z-Wave 设备易于使用且具有一致的生态系统。 我对 Z-Wave 的唯一犹豫是它不是一个开放平台。它的一些 规范 是公开的,并且有一个用于与 Z-Wave 网络交互的开源库,OpenZWave,它也具有 Python 绑定。 虽然不理想,但很可能我可以解决出现的任何问题。 因此,我订购了一个 USB Z-Wave 控制器 和两个支持 Z-Wave 的 电源开关(每个空调装置一个)。
我仍然需要一个温度传感器;既然我已经构建了一个 Z-Wave 网络,我订购了一个 Z-Wave MultiSensor 6。 它在一个小设备中包含各种传感器——包括温度传感器。 虽然我可以使用另一个温度传感器,但这似乎是一个不错的选择,因为它便携且无线,可以放置在我公寓的任何位置。
软件
接下来,我需要查看软件,将我的硬件购置用作恒温器。 虽然我的所有设备都是 Z-Wave,并且 OpenZWave 提供了 C++ 和 Python 接口,我可以用来访问和控制我的设备,但对于我的口味来说,它有点太底层了。
相反,我决定使用 Home Assistant 项目,原因有几个。 首先,我认识很多人使用它、破解它,或者两者兼而有之。 其次,虽然我目前的所有设备都是 Z-Wave,但如果我愿意,Home Assistant 将允许我扩展到使用其他类型的设备。 Home Assistant 支持大量不同的设备和服务——您可以查看 组件列表 以查看所有设备和服务。 对于 Z-Wave 支持,它利用 OpenZWave 并提供了一个更高级别的接口,更易于处理。 Home Assistant 是用 Python 3 编写的,这对我来说非常方便,因为我大部分编程都是用 Python 完成的。 它还有一个 活跃的社区,他们一直很积极响应并乐于助人。
我在我的一个服务器上安装了 Home Assistant,并继续配置其与我的设备的接口。 关于设置 Home Assistant 的详细信息有很多——您可以参考 官方文档 作为起点。 有关特定的 Z-Wave 说明,请参阅 Home Assistant 文档中的 Z-Wave 部分。
设置好 Home Assistant 后,我拥有了一个用于控制我的新电源开关并显示来自 MultiSensor 数据的单一 Web 界面和 API。 但是,我仍然没有恒温器——只是一个漂亮的界面(我可以远程使用),用于手动打开或关闭空调。
首次自动化尝试
Home Assistant 提供了一个自动化界面,使您能够编写规则,这些规则在来自任何设备的特定触发器上执行。 在阅读了关于 编写自动化规则的文档 后,我决定可以使用此界面来构建恒温器功能。 我继续编写了一堆像这样的规则,它表示如果客厅空调装置关闭且温度传感器读数高于 25 摄氏度,则打开空调装置。
alias: 'Turn on Living Room AC when above 25 C'
trigger:
platform: numeric_state
entity_id: sensor.aeotec_zw100_multisensor_6_temperature_4
above: 25
condition:
- condition: state
entity_id: switch.aeotec_zw096_smart_switch_6_switch_2
state: 'off'
action:
service: switch.turn_on
entity_id: switch.aeotec_zw096_smart_switch_6_switch_2
这种方法在某种程度上奏效了,但存在几个问题。 显而易见的问题是我必须为我认为系统可能遇到的每种情况编写单独的规则。 我最终会编写很多不同的规则(包括用于打开和关闭的单独规则)。 此外,如果我想更改恒温器的设定点,我必须手动修改所有规则并重新加载自动化配置。 然后是可靠性问题——如果由于某种原因规则没有被触发(要么是因为我没有预测到的状态,要么是因为错过了条件),则无法透明地了解为什么没有发生; 我只会知道规则从未运行其操作。 这让我处于一个奇怪的位置,因为我设想的方法行不通。
与其过于气馁,我开始浏览 Home Assistant 源代码,偶然发现了一个完美的解决方案。
恒温器组件
事实证明,Home Assistant 已经实现了一个组件,基本上用于我完全相同的用例。 在“恒温器”组件(此后已重命名为“气候”)下,有一个名为 heat_control
的组件。 该模块被编写为用作恒温器,带有温度传感器和电源继电器,用于控制插入式空间加热器。 这使用户可以设置温度,并让加热器一直打开,直到达到所需的温度,然后关闭。
这就是我需要做的,只不过是用于空调而不是空间加热器。 因此,我很快就拼凑了一个 补丁,以添加对使用冷却设备而不是加热器的支持。 它添加了一个配置选项,将开关设备视为空调装置(或任何其他冷却设备)而不是加热器。
在本地安装我的补丁并重新配置 Home Assistant 后,我基本上拥有了一个恒温器。 我还有一个漂亮的 Web 界面来控制设定点并查看空调装置的状态。

智能手机上的恒温器界面。

Web 浏览器中的恒温器界面。
自从我推送该补丁以来,heat-control
恒温器模块和组件类型已重命名为 通用恒温器气候组件,这更好地描述了它在添加空调支持后的更大范围。 有了这个组件,我成功实现了我的最初目标,构建了一个恒温器,我甚至拥有一个漂亮的、移动友好的 Web 界面来控制空调。
更多问题解决
此时,我有一个非常酷的设置。 Home Assistant 就像一个真正的恒温器一样工作,我可以为我的公寓设置一个舒适的温度。 但它仍然不完美。
多区域
我的第一个问题是,位于客厅的单个温度传感器正在控制卧室和客厅的空调装置。 正如您在下图中看到的,房间大小不同。 空调装置是相同的,但卧室明显小于客厅,这意味着卧室比公寓的其他地方冷得多。

公寓平面图,显示卧室区域位于客厅空调装置上。
虽然我可以订购另一个 Z-Wave MultiSensor,但它们有点贵,而且对于我需要的来说有点过分。 我在卧室里也不需要相同的无线控制,因为它已经有用于其他机器的网络电缆。 我还想要两个不同的读数——一个在我的卧室,一个在我的卧室壁橱里,我在那里存放我的服务器和网络设备。
我记得我的壁橱里放着一台备用的 Raspberry Pi 2,所以我决定利用它,将几个温度传感器连接到它,并将其用作我卧室的数据源。 在网上阅读了我的选项后,我决定使用 DS18B20,一个 Dallas 1-Wire 温度传感器,它似乎在 Raspberry Pi 人群中非常受欢迎。 (这对我有所帮助,因为我在大学时摆弄过 1-Wire 协议,所以我对它有点熟悉。)

使用温度传感器的 Raspberry Pi 2 设置。
1-Wire 传感器的优点是您可以并行连接所有设备。 所有设备都是单独寻址的,因此子板只是并行连接两个传感器(带上拉电阻)。 将设备连接到我的 Raspberry Pi 2 后,我有一个界面可以在本地轮询我卧室(和我的“数据壁橱”)的温度,但我需要一个好的界面将该数据输入到 Home Assistant 中,后者在另一台机器上运行。
这让我利用了我在安装 Home Assistant 时设置的 MQTT 基础设施。 我编写了一个 守护程序,用于定期发布来自任意数量的 Dallas 1-Wire 传感器的结果(并且将来可以与其他类别的传感器一起使用)。 我将新的温度传感器(使用 MQTT 传感器 组件)添加到 Home Assistant 配置中,并重新配置卧室恒温器以使用新的传感器,因此现在我有两个单独可控的恒温器区域,以及我的壁橱和卧室的温度读数。
循环时间
在运行多区域设置几天后,我发现了另一个问题,这是我从未想过的问题:我正在短周期运行空调装置。 换句话说,一旦房间达到所需的温度,它就会立即为开关供电,这导致空调装置以两到四分钟的周期打开和关闭。 这在我看来不太对劲。

显示空调短周期运行的图表。
在阅读了一些关于空调装置的资料后(并且深入研究了一些细节——例如找到 80 年代后期 ASHRAE 的论文,探讨循环时间对各种 HVAC 系统的影响),我了解到空调装置在稳态时效率最高,而在刚打开后的前几分钟效率要低得多。 我的软件恒温器的行为远非理想。
我需要在系统中添加一些 滞后(换句话说,一个微调系数),这样我就不会不断地循环运行装置。 恒温器执行此操作的一种方法是在设定温度附近添加一点滞后,因此它不会在完全达到设定温度时切换,而是等到它超过设定温度几度。 另一种方法是设置定义的最高切换频率,这将设置装置在房间内循环打开/关闭频率的上限。 这不是原始 heat-control
模块的一部分,因此我在 Home Assistant 中推出了 另一个补丁,添加了一个选项来设置最高切换频率。
新选项设置了最短循环持续时间,我认为这比将其描述为频率(您通常希望以 µHz 表示,因为通常您处理的频率是每几分钟一次)更清楚易懂。 自从我提交该补丁以来,其他人已经添加了用于手动调整恒温器切换行为的选项。 此选项允许我设置 Home Assistant 循环运行空调装置电源的频率。 我将其设置为至少等待 20 分钟才切换,主要是因为这似乎是一个合理的数值。 由于我没有空调装置的型号,因此我无法访问它们的数据表或规格。 因此,我不知道它们的效率曲线是什么样的,所以我不得不猜测一个好的数值是多少。

修正后的循环时间图表。
更上一层楼
既然我已经实现了我的最初目标,我决定玩得更开心,并将项目更进一步。 由于我使用家庭自动化平台构建了恒温器,因此很容易将其与其他设备和输入连接在一起。
基于位置的设置
我决定将其与我的位置数据联系起来,因为我大部分时间都携带多个联网设备。 使用 OwnTracks 项目,我让我的手机定期向 Home Assistant 发送消息并告知我的位置。 OwnTracks 使用 MQTT,但它允许我控制我的数据(并使用 TLS 加密数据流量),因此我的位置数据不会发送到第三方的系统。 它还使用后者的 OwnTracks 组件 很好地集成到 Home Assistant 中。 这使我能够编写自动化规则,以根据我是否在家来更改空调装置的设定点。
我也能够编写像这样的规则
alias: Set Living Room AC to 26 C when leaving starbucks route 9
trigger:
platform: state
entity_id: device_tracker.myphone
from: 'Starbucks Route 9'
action:
- delay:
minutes: 5
- service: climate.set_temperature
entity_id: climate.living_room
data:
temperature: 26
它表示当我离开当地的星巴克(有时我在家办公需要休息时会在那里工作)时,等待五分钟并将设定点更改为更舒适的温度。 五分钟的延迟是根据我从星巴克回家所需的时间以及在炎热的天气里公寓降温所需的时间来确定的。
环境条件
当我使用 Home Assistant 时,我意识到我拥有其他可以与系统连接的设备。 我编写了更多自动化规则,将它们与我的恒温器以不同的方式结合起来,例如
alias: Turn off AC when it's cold outside
trigger:
platform: numeric_state
entity_id: sensor.pws_temp_c
below: 22.0
action:
service: thermostat.set_operation_mode
entity_id: thermostat.living_room
data:
operation_mode: off
这会检查 Weather Underground,如果室外温度低于 22 摄氏度(72 华氏度),则关闭空调,因为在该温度下我应该只是打开窗户而不是运行空调。 我计划向此规则添加推送通知,以便 Home Assistant 向我的手机发送通知,提醒我打开窗户。
alias: Raise volume when AC turns on
trigger:
platform: state
entity_id: switch.aeotec_zw096_smart_switch_6_switch_2_0
to: 'on'
conditions:
- condition: state
entity_id: media_player.living_room_av_reciever
state: 'on'
- condition: template
value_template: |
'{{ states.media_player.reciever.volume_level < 0.7 }}'
action:
service: media_player.volume_up
entity_id: media_player.living_room_av_reciever
我最喜欢的规则是当我正在客厅看电视或听音乐时。 我的空调装置非常吵——通常比我的扬声器还吵。 当我的扬声器音量低于最大音量的 70% 时,当空调装置打开时,规则会自动将音量提高几个步长,这样我就不必手动调整它了。
我对这个系统非常满意。 我完成了我想要做的一切:在我离开时提供温度控制,这样当我回家时我的公寓就不会热得离谱。 但它也成为了我玩家庭自动化的入门,这已经成为一种有趣的爱好。
4 条评论