Skip to content

Commit

Permalink
V2.1.0 (#122)
Browse files Browse the repository at this point in the history
* Merge master back into dev (#111)

* Fix typo in log message (#112)

* Fix typo in SDS011

* Documentation improvements for version 2.0.0 (#114)

* Replace event_loop with loop (#107)

* Changelog update (#116)

* Added entry for event loop change

* Additional changes

* Small changes - Accessory (#117)

* Improved bridge.to_HAP

* Updated changelog

* Fix another typo in SDS011 which prevented pm10 from getting updates.

* Added getter_callback to Characteristic #78

* Fix typo bridge.to_HAP (#119)

* Adding Code Style Checker (#118)

* Add basis for style checker

* Fixed lint errors

* Updated changelog

* Improvements 7 - Config class (#120)

Added a State class which keeps Accessory runtime properties such as port, address, paired clients, etc. This state is stored and managed by the driver.

* Remove the pyhap.accessories package. (#115)

* Remove the pyhap.accessories package.

All accessories are temporarily moved to the root accessories folder.
These will be moved into separate repositories as appropriate.

pyhap.accessories is now an implicit namespace package. See
pyhap/accessories/README.md for how others can share their accessories
as HAP-python subpackages.

* Release v2.1.0.
  • Loading branch information
ikalchev authored May 18, 2018
1 parent 01e1fe5 commit d30a72a
Show file tree
Hide file tree
Showing 44 changed files with 614 additions and 387 deletions.
10 changes: 7 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ branches:
- /^\d\.\d+\.\d+(rc\d+|\.dev\d+)?$/
matrix:
include:
- python: 3.5
- python: "3.5"
env: TOXENV=lint
# - python: "3.5"
# env: TOXENV=pylint
- python: "3.5"
env: TOXENV=py35
- python: 3.6
- python: "3.6"
env: TOXENV=py36
- python: 3.6
- python: "3.6"
env: TOXENV=docs
before-install:
- sudo apt-get -qq update
Expand Down
41 changes: 39 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
# Changelog

All notable changes to this project will be documented in this file (since version `1.1.8`).
All notable changes to this project will be documented in this file (since version `1.1.8`).
If you notice that something is missing, please open an issue or submit a PR.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

<!--
Sections
### Added
### Changed
### Deprecated
### Fixed
### Breaking Changes
### Developers
-->


## [2.1.0] - 2018-05-18

### Added
- Added `getter_callback` to Characteristics. [#90](https://github.com/ikalchev/HAP-python/pull/90)
- The `pincode` can now be assigned as a parameter for the driver. [#120](https://github.com/ikalchev/HAP-python/pull/120)

## [Unreleased]
### Changed
- Improved documentation for version `2.0.0`. [#114](https://github.com/ikalchev/HAP-python/pull/114)

### Deprecated
- The `accessory` and `bridge` parameter `mac` and `pincode` are now deprecated. [#120](https://github.com/ikalchev/HAP-python/pull/120)
- `Accessory.config_changed`, use `driver.config_changed` instead. [#120](https://github.com/ikalchev/HAP-python/pull/120)
- `Accessory.paired`, use `driver.state.paired` instead. [#120](https://github.com/ikalchev/HAP-python/pull/120)

### Fixed
- Typo in log message in `accessory_driver.stop`. [#112](https://github.com/ikalchev/HAP-python/pull/112)

### Breaking Changes
- Moved all accessories from `pyhap.accessories` to an `accessories` folder at the root of the project. [#115](https://github.com/ikalchev/HAP-python/pull/115)
- Removed unused method `accessory.create`. [#117](https://github.com/ikalchev/HAP-python/pull/117)
- Removed `iid_manager` and `setup_id` parameter from `accessory` and `bridge` `init` calls. [#117](https://github.com/ikalchev/HAP-python/pull/117)

### Developers
- The `driver` event loop name changed from `event_loop` to `loop`. [#107](https://github.com/ikalchev/HAP-python/pull/107)
- `pyhap.accessories` is now a native namespace package. See `pyhap/accessories/README.md` for details on how to integrate third party Accessories. [#115](https://github.com/ikalchev/HAP-python/pull/115)
- Added static code checks. To run them locally use `tox -e lint` and `tox -e pylint`. [#118](https://github.com/ikalchev/HAP-python/pull/118)
- Added `State` helper class to keep track of (semi-)static information. [#120](https://github.com/ikalchev/HAP-python/pull/120)
- Variables that are related to pairing and storing static information have been moved to `driver.state`. That includes from `accessory`: `config_version`, `mac`, `setup_id`, `private_key`, `public_key` and `paired_clients` as well as the `add_paired_client` and `removed_paired_client` methods. For `accessory_driver`: `address` and `port`. [#120](https://github.com/ikalchev/HAP-python/pull/120)



Expand Down
56 changes: 19 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
[![PyPI version](https://badge.fury.io/py/HAP-python.svg)](https://badge.fury.io/py/HAP-python) [![Build Status](https://travis-ci.org/ikalchev/HAP-python.svg?branch=master)](https://travis-ci.org/ikalchev/HAP-python) [![codecov](https://codecov.io/gh/ikalchev/HAP-python/branch/master/graph/badge.svg)](https://codecov.io/gh/ikalchev/HAP-python) [![Documentation Status](https://readthedocs.org/projects/hap-python/badge/?version=latest)](http://hap-python.readthedocs.io/en/latest/?badge=latest)
# HAP-python

HomeKit Accessory Protocol implementation in python 3 (tested with 3.4, 3.5 and 3.6).
With this project, you can integrate your own accessories and add them to your
HomeKit Accessory Protocol implementation in python 3.
With this project, you can integrate your own smart devices (called accessories) and add them to your
iOS Home app. Since Siri is integrated with the Home app, you can start voice-control your
accessories right away - e.g. "What is the temperature in my bedroom." and "Turn on the
lights in the Dining Room."
accessories right away - e.g. "What is the temperature in my bedroom".

The project was developed for a Raspberry Pi, but it should work on other platforms. You
can even integrate with HAP-python remotely using HTTP (see below). To kick-start things,
you can open `main.py`, where you can find out how to launch a mock temperature sensor.
Just run `python3 main.py` and you should see it in the Home app (be sure to be in the same network).
Stop it by hitting Ctrl+C.

There are example accessories in [the accessories folder](pyhap/accessories):

- AM2302 (DHT22) temperature and humidity sensor.
- SDS011 air particulate density sensor.
- TSL2591 light sensor.

It's very easy to add your own.
There are example accessories in [the accessories folder](pyhap/accessories).

## Table of Contents
1. [API](#API)
Expand All @@ -30,6 +23,10 @@ It's very easy to add your own.

## Installation <a name="Installation"></a>

As of version 2.0.0, HAP-python no longer supports python older than 3.5, because we
are moving to asyncio. If your platform does not have a compatible python out of the
box, you can install it manually or just use an older version of HAP-python.

As a prerequisite, you will need Avahi/Bonjour installed (due to zeroconf package).
On a Raspberry Pi, you can get it with:
```
Expand All @@ -48,7 +45,7 @@ $ pip3 uninstall HAP-python
## API <a name="API"></a>

A typical flow for using HAP-python starts with implementing an Accessory. This is done by
subclassing [Accessory](pyhap/accessory.py) and putting in place a few details
subclassing [AsyncAccessory](pyhap/accessory.py) and putting in place a few details
(see below). After that, you give your accessory to an AccessoryDriver to manage. This
will take care of advertising it on the local network, setting a HAP server and
running the Accessory. Take a look at [main.py](main.py) for a quick start on that.
Expand All @@ -67,42 +64,27 @@ class TemperatureSensor(AsyncAccessory):
"""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,
# because it calls _set_services and performs some other important actions.
super(TemperatureSensor, self).__init__(*args, **kwargs)
# 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')

self.temp_char = self.get_service("TemperatureSensor")\
.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 Characteristic
"""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).
NOTE: no need to set the value yourself, this is done for you, before the callback
is called.
"""
print("Temperature changed to: ", value)

def _set_services(self):
"""We override this method to add the services that we want our accessory to
support. Services have "mandatory" characteristics and optional
characteristics. Mandatory characteristics are automatically added
to your selected service, but you must add optional characteristics yourself.
Take a look at pyhap/accessories/FakeFan.py for an example of how to do that.
"""
super(TemperatureSensor, self)._set_services() # Adds some neccessary characteristics.
# A loader creates Service and Characteristic objects based on json representation
# such as the Apple-defined ones in pyhap/resources/.
temp_sensor_service = loader.get_serv_loader().get("TemperatureSensor")
self.add_service(temp_sensor_service)
print('Temperature changed to: ', value)

@AsyncAcessory.run_at_interval(3) # Run this method every 3 seconds
async def run(self):
"""We override this method to implement what the accessory will do when it is
started. An accessory is started and stopped from the AccessoryDriver.
started.
We set the current temperature to a random number. The decorator runs this method
every 3 seconds.
Expand All @@ -113,7 +95,7 @@ class TemperatureSensor(AsyncAccessory):
"""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.")
print('Stopping accessory.')

### Synchronouse accessory - run method is in a thread
class SyncTemperatureSensor(Accessory):
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 4 additions & 4 deletions pyhap/accessories/SDS011.py → accessories/SDS011.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def __init__(self, serial_port, *args, sleep_duration_s=15*60,
super().__init__(*args, **kwargs)

# PM2.5
air_quality_pm25 = self.add_preload_serivce(
air_quality_pm25 = self.add_preload_service(
'AirQualitySensor', chars=['Name', 'AirParticulateSize',
'AirParticulateDensity'])
air_quality_pm25.configure_char('AirParticulateSize', value=0)
Expand All @@ -67,13 +67,13 @@ def __init__(self, serial_port, *args, sleep_duration_s=15*60,
'AirParticulateDensity')

# PM10
air_quality_pm10 = self.add_preload_serivce(
air_quality_pm10 = self.add_preload_service(
'AirQualitySensor', chars=['Name', 'AirParticulateSize',
'AirParticulateDensity'])
air_quality_pm10.configure_char('AirParticulateSize', value=1)
air_quality_pm10.configure_char('Name', value='PM10')
self.pm25_quality = air_quality_pm10.configure_char('AirQuality')
self.pm25_density = air_quality_pm10.configure_char(
self.pm10_quality = air_quality_pm10.configure_char('AirQuality')
self.pm10_density = air_quality_pm10.configure_char(
'AirParticulateDensity')

self.sleep_duration_s = sleep_duration_s
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions docs/source/api/state.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. _api-state:

=====
State
=====

.. autoclass:: pyhap.state.State
:members:
8 changes: 3 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import time
import random

from pyhap.accessories.TemperatureSensor import TemperatureSensor
from pyhap.accessory import Bridge
from pyhap.accessory_driver import AccessoryDriver
import pyhap.loader as loader

# The below package can be found in the HAP-python github repo under accessories/
from TemperatureSensor import TemperatureSensor

logging.basicConfig(level=logging.INFO)


Expand All @@ -26,10 +28,6 @@ def get_bridge():
bridge.add_accessory(temp_sensor)
bridge.add_accessory(temp_sensor2)

# Uncomment if you have RPi module and want a LED LightBulb service on pin 16.
# from pyhap.accessories.LightBulb import LightBulb
# bulb = LightBulb("Desk LED", pin=16)
# bridge.add_accessory(bulb)
return bridge


Expand Down
12 changes: 5 additions & 7 deletions pyhap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@
CHARACTERISTICS_FILE = os.path.join(_RESOURCE_DIR, "characteristics.json")
SERVICES_FILE = os.path.join(_RESOURCE_DIR, "services.json")

HAP_PYTHON_VERSION = (2, 0, 0)
HAP_PYTHON_VERSION = (2, 1, 0)
"""
HAP-python current version.
"""


# Flag if QR Code dependencies are installed.
# Installation with `pip install HAP-python[QRCode]`.
SUPPORT_QR_CODE = False
try:
import base36 as _
import pyqrcode as _
import base36 # noqa: F401
import pyqrcode # noqa: F401
SUPPORT_QR_CODE = True
except ImportError:
pass
"""
Flag if QR Code dependencies are installed.
Installation with `pip install HAP-python[QRCode]`.
"""
34 changes: 34 additions & 0 deletions pyhap/accessories/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Adding accessories as HAP-python subpackages

If you have implemented an Accessory for a device for HAP-python
and want to share it with others as a subpackage, you can do so using native namespace
packages. Just do the following:

- Make sure you have the following directory structure:
```
pyhap/
# NO __init__.py here !!!
accessories/
# NO __init__.py here !!!
bulb/
__init__.py
... the code for the bulb accessory ...
```
- Have this in your `setup.py`:
```python
setup(
...
packages=['pyhap.accessories.bulb'],
...
)
```

If you upload your package to pip, other users can use your code as
`pip install HAP-python-bulb` or, alternatively, they can just `git clone` and do
`python3 setup.py install`. Others can then use your code by doing:
```
import pyhap.accessories.bulb
```

See [here](https://packaging.python.org/guides/packaging-namespace-packages/#native-namespace-packages)
for more information.
Loading

0 comments on commit d30a72a

Please sign in to comment.