Python中的HomeKit配件协议实现
项目描述
ha-HAP-python
这是HAP-python的一个分支,用于在Home Assistant中提供对HAP-python的修复或故障排除。
Python 3中的HomeKit配件协议实现。使用此项目,您可以将自己的智能设备集成到iOS Home应用中。由于Siri与Home应用集成,您可以直接开始语音控制您的配件。
主要功能
- 摄像头 - HAP-python从2.3.0版本开始支持摄像头配件!
- asyncio支持 - 您可以在事件循环中运行各种任务或配件。
- 内置对Apple定义的服务支持 - 在资源文件夹中查看。
- 通过扫描二维码即可安全配对。
- 与智能家居框架Home Assistant集成。
该项目是为树莓派开发的,但它应该可以在其他平台上运行。为了启动,你可以打开 main.py
或 busy_home.py
,在那里你会找到一些虚拟配件。只需运行其中一个,例如 python3 busy_home.py
,然后你可以在“家居”应用中添加它(确保在同一网络中)。通过按Ctrl+C停止它。
在配件文件夹中有示例配件以及与真实产品的集成。在camera_main.py中查看如何配置你的相机。
目录
安装
从版本3.5.1开始,HAP-python不再支持低于3.6的Python版本,因为我们正在转向asyncio。如果你的平台默认没有兼容的Python,你可以手动安装它,或者只使用HAP-python的旧版本。
作为先决条件,你需要安装Avahi/Bonjour(由于zeroconf包)。在树莓派上,你可以使用以下命令获取它
$ sudo apt-get install libavahi-compat-libdnssd-dev
avahi-utils
也可能符合要求。然后,你可以使用pip3
安装(安装时可能需要sudo
或--user
)
$ pip3 install HAP-python[QRCode]
这将把HAP-python安装到你的Python包中,这样你就可以将其导入为pyhap
。要卸载,只需执行
$ pip3 uninstall HAP-python
API
使用HAP-python的典型流程是从实现配件开始。这是通过从Accessory派生并放置一些细节来完成的(见下文)。之后,你将配件交给配件驱动器来管理。这将负责在本地网络上广告它,设置HAP服务器并运行配件。查看main.py以快速入门。
from pyhap.accessory import Accessory, Category
import pyhap.loader as loader
class TemperatureSensor(Accessory):
"""Implementation of a mock temperature sensor accessory."""
category = Category.SENSOR # This is for the icon in the iOS Home app.
def __init__(self, *args, **kwargs):
"""Here, we just store a reference to the current temperature characteristic and
add a method that will be executed every time its value changes.
"""
# If overriding this method, be sure to call the super's implementation first.
super().__init__(*args, **kwargs)
# Add the services that this Accessory will support with add_preload_service here
temp_service = self.add_preload_service('TemperatureSensor')
self.temp_char = temp_service.get_characteristic('CurrentTemperature')
# Having a callback is optional, but you can use it to add functionality.
self.temp_char.setter_callback = self.temperature_changed
def temperature_changed(self, value):
"""This will be called every time the value of the CurrentTemperature
is changed. Use setter_callbacks to react to user actions, e.g. setting the
lights On could fire some GPIO code to turn on a LED (see pyhap/accessories/LightBulb.py).
"""
print('Temperature changed to: ', value)
@Acessory.run_at_interval(3) # Run this method every 3 seconds
# The `run` method can be `async` as well
def run(self):
"""We override this method to implement what the accessory will do when it is
started.
We set the current temperature to a random number. The decorator runs this method
every 3 seconds.
"""
self.temp_char.set_value(random.randint(18, 26))
# The `stop` method can be `async` as well
def stop(self):
"""We override this method to clean up any resources or perform final actions, as
this is called by the AccessoryDriver when the Accessory is being stopped.
"""
print('Stopping accessory.')
服务回调
当你处理如“开启”和“亮度”这样的紧密耦合特性时,你可能需要使用服务回调来接收单个请求中的所有更改。
使用特性回调,你现在知道在“开启”之后,“亮度”特性即将被处理,最终可能会将灯泡设置为100%,然后将其调暗到预期水平。
from pyhap.accessory import Accessory
from pyhap.const import Category
import pyhap.loader as loader
class Light(Accessory):
"""Implementation of a mock light accessory."""
category = Category.CATEGORY_LIGHTBULB # This is for the icon in the iOS Home app.
def __init__(self, *args, **kwargs):
"""Here, we just store a reference to the on and brightness characteristics and
add a method that will be executed every time their value changes.
"""
# If overriding this method, be sure to call the super's implementation first.
super().__init__(*args, **kwargs)
# Add the services that this Accessory will support with add_preload_service here
serv_light = self.add_preload_service('Lightbulb')
self.char_on = serv_light.configure_char('On', value=self._state)
self.char_brightness = serv_light.configure_char('Brightness', value=100)
serv_light.setter_callback = self._set_chars
def _set_chars(self, char_values):
"""This will be called every time the value of the on of the
characteristics on the service changes.
"""
if "On" in char_values:
print('On changed to: ', char_values["On"])
if "Brightness" in char_values:
print('Brightness changed to: ', char_values["Brightness"])
@Acessory.run_at_interval(3) # Run this method every 3 seconds
# The `run` method can be `async` as well
def run(self):
"""We override this method to implement what the accessory will do when it is
started.
We set the current temperature to a random number. The decorator runs this method
every 3 seconds.
"""
self.char_on.set_value(random.randint(0, 1))
self.char_brightness.set_value(random.randint(1, 100))
# The `stop` method can be `async` as well
def stop(self):
"""We override this method to clean up any resources or perform final actions, as
this is called by the AccessoryDriver when the Accessory is being stopped.
"""
print('Stopping accessory.')
设置相机
Camera配件实现了HomeKit协议,用于协商流设置,如图片宽度和高度、音频通道数量等。启动视频和/或音频流非常特定于平台。因此,你需要确定你的相机支持哪些视频和音频设置,并将它们设置在传递给Camera
配件的options
参数中。请参考Camera
构造函数的文档,以了解你需要指定的设置。
默认情况下,HAP-python将在流应该启动时执行带有协商参数的ffmpeg
命令,并在流应该停止时terminate
启动的过程(参见默认值:Camera.FFMPEG_CMD
)。如果默认命令不受支持或格式不正确,流可能失败。
对于这些情况,HAP-python有钩子,你可以插入自己的命令或实现启动或停止流的逻辑。有两种选择
-
传递自己的命令,在流应该启动时执行。
你将命令作为值传递给
Camera
配件构造函数的options
参数中的start_stream_cmd
键。该命令使用协商的流配置参数进行格式化。例如,如果协商的宽度为640,你传递foo start -width {width}
,则命令将格式化为foo start -width 640
。协商的流配置参数的完整列表可以在
Camera.start
方法的文档中找到。 -
实现自己的逻辑来启动、停止和重新配置流。
如果您需要更灵活地管理流,您可以直接实现
Camera
方法的start
、stop
和reconfigure
。每个方法将在分别启动、停止或重新配置流时被调用。启动和重新配置方法将提供协商的流配置参数。请查看这些方法的文档以获取更多信息。
最后,如果您可以从相机获取快照,您可能需要实现 Camera.snapshot
方法。默认情况下,它提供了一个库存照片。
在启动时运行
这是在 Raspberry Pi 上让 HAP-python
在启动时运行的一个快速方法。建议在 raspi-config
中打开“等待网络”。如果这变得不可靠,请参阅 这里。
将以下内容复制到 /etc/systemd/system/HAP-python.service
(需要sudo)。
[Unit]
Description = HAP-python daemon
Wants = pigpiod.service # Remove this if you don't depend on pigpiod
After = local-fs.target network-online.target pigpiod.service
[Service]
User = lesserdaemon # It's a good idea to use some unprivileged system user
# Script starting HAP-python, e.g. main.py
# Be careful to set any paths you use, e.g. for persisting the state.
ExecStart = /usr/bin/python3 /home/lesserdaemon/.hap-python/hap-python.py
[Install]
WantedBy = multi-user.target
通过以下方式测试一切是否正常:
> sudo systemctl start HAP-python
> systemctl status HAP-python
> sudo journalctl -u HAP-python # to see the output of the start up script.
> sudo systemctl stop HAP-python
要启用或禁用在启动时运行,请执行
> sudo systemctl enable HAP-python
> sudo systemctl disable HAP-python
关机开关
如果您在 Raspberry Pi 上运行 HAP-python
,您可能想在您的家中添加一个 关机开关。这是一个开关配件,当触发时,将执行 sudo shutdown -h now
,即关闭并停止 Pi。这允许您安全地拔掉它。
要使上述功能正常工作,您需要为运行 HAP-python
的用户启用无密码的 /sbin/shutdown
。例如,执行
$ sudo visudo # and add the line: "<hap-user> ALL=NOPASSWD: /sbin/shutdown".
注意
一些 HAP 知识来自 KhaosT 的 HAP-NodeJS。
我不知道有任何错误,但我非常确信确实存在。如果您发现任何错误,请报告,我将尽力修复它们。
建议总是受欢迎的。
祝您玩得开心!
项目详情
下载文件
下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关 安装包 的更多信息。
源代码发行版
构建发行版
ha-HAP-python-4.5.2.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | cd9023c65b21c65b8cb5ffe1cdad96dee97379a0e71f6fc0c7bbfe25c1f9372f |
|
MD5 | 0a0faeed9ea0ecba0a381a98d876d7ed |
|
BLAKE2b-256 | 2ebbabf9d8db4ddf122fe30020ef9b127a46ee8412e43d5de33533998eeb1829 |
ha_HAP_python-4.5.2-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 49398f53b5585c704a11a590cbe203b212d70ed5a4f3a042f6b673ade5f16b1a |
|
MD5 | 8e6618451609bc15f2e7f3a979e7eb52 |
|
BLAKE2b-256 | 011ff43dbde1faca045a09f095e84306c0206f53529f227ec9621e50fc6a21ad |