Skip to content

Commit

Permalink
Merge branch 'master' into add_ota_commands
Browse files Browse the repository at this point in the history
  • Loading branch information
doudz committed Mar 18, 2019
2 parents 53b73e1 + e8e8118 commit 3381f16
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 85 deletions.
15 changes: 13 additions & 2 deletions Readme.md
Expand Up @@ -39,8 +39,9 @@ or
```
# Enable ZiGate
zigate:
port: /dev/ttyS0
port: /dev/ttyUSB0
channel: 24
enable_led : false
```

Expand All @@ -55,7 +56,17 @@ zigate:
```

Currently it supports sensor, binary_sensor and switch and light
If yo want to use PiZiGate, just add `gpio: true`. Other options are still available (channel, etc)

```
# Enable PiZiGate
zigate:
gpio: true
```


Currently it supports sensor, binary_sensor and switch, light and cover

## How enable debug log

Expand Down
7 changes: 5 additions & 2 deletions doc/zigate.markdown
Expand Up @@ -18,9 +18,10 @@ The `zigate` component allows you to use the ZiGate module (http://www.zigate.fr
Available ZiGate platforms:

- [Binary sensor](/components/binary_sensor/) (`binary_sensor`)
- [Light](/components/light/) (`light`) (not yet)
- [Light](/components/light/) (`light`)
- [Sensor](/components/sensor/) (`sensor`)
- [Switch](/components/switch/) (`switch`)
- [Cover](/components/cover/) (`cover`)

To integrate the ZiGate component in Home Assistant, add the following section to your `configuration.yaml` file:

Expand All @@ -32,7 +33,9 @@ To integrate the ZiGate component in Home Assistant, add the following section t

# Example configuration.yaml entry setting the USB port
[zigate]:
port: /dev/ttyS0
port: /dev/ttyUSB0
channel: 15
enable_led: false
```

or
Expand Down
6 changes: 5 additions & 1 deletion tox.ini
Expand Up @@ -16,4 +16,8 @@ commands =
[flake8]
max-line-length = 119
exclude = .tox,*.egg,build/*,docs/*,
select = E,W,F
select = E,W,F
# E123/E133, E226 and E241/E242 are default ignores
# E402: module level import not at top of file
# W503: ignore operators after line break
ignore = E123,E133,E226,E241,E242,E402,W503
68 changes: 25 additions & 43 deletions zigate/__init__.py
Expand Up @@ -22,7 +22,8 @@

_LOGGER = logging.getLogger(__name__)

REQUIREMENTS = ['zigate==0.29.0']
REQUIREMENTS = ['zigate==0.29.3']
# REQUIREMENTS = ['https://github.com/doudz/zigate/archive/dev.zip#1.0.0']
DEPENDENCIES = ['persistent_notification']

DOMAIN = 'zigate'
Expand All @@ -41,7 +42,8 @@
vol.Optional(CONF_PORT): cv.string,
vol.Optional(CONF_HOST): cv.string,
vol.Optional('channel'): cv.positive_int,
vol.Optional('gpio'): cv.boolean
vol.Optional('gpio'): cv.boolean,
vol.Optional('enable_led'): cv.boolean
})
}, extra=vol.ALLOW_EXTRA)

Expand Down Expand Up @@ -152,6 +154,7 @@ def setup(hass, config):
port = config[DOMAIN].get(CONF_PORT)
host = config[DOMAIN].get(CONF_HOST)
gpio = config[DOMAIN].get('gpio', False)
enable_led = config[DOMAIN].get('enable_led', True)
channel = config[DOMAIN].get('channel')
persistent_file = os.path.join(hass.config.config_dir,
'zigate.json')
Expand All @@ -176,7 +179,7 @@ def device_added(**kwargs):
_LOGGER.debug('Add device {}'.format(device))
ieee = device.ieee or device.addr # compatibility
if ieee not in hass.data[DATA_ZIGATE_DEVICES]:
entity = ZiGateDeviceEntity(device)
entity = ZiGateDeviceEntity(hass, device)
hass.data[DATA_ZIGATE_DEVICES][ieee] = entity
component.add_entities([entity])
if 'signal' in kwargs:
Expand Down Expand Up @@ -219,36 +222,7 @@ def attribute_updated(**kwargs):
attribute = kwargs['attribute']
_LOGGER.debug('Update attribute for device {} {}'.format(device,
attribute))
key = '{}-{}-{}-{}'.format(ieee,
attribute['endpoint'],
attribute['cluster'],
attribute['attribute'],
)
entity = hass.data[DATA_ZIGATE_ATTRS].get(key)
if entity:
if entity.hass:
entity.schedule_update_ha_state()
key = '{}-{}-{}'.format(ieee,
'switch',
attribute['endpoint'],
)
entity = hass.data[DATA_ZIGATE_ATTRS].get(key)
if entity:
if entity.hass:
entity.schedule_update_ha_state()
key = '{}-{}-{}'.format(ieee,
'light',
attribute['endpoint'],
)
entity = hass.data[DATA_ZIGATE_ATTRS].get(key)
if entity:
if entity.hass:
entity.schedule_update_ha_state()
entity = hass.data[DATA_ZIGATE_DEVICES].get(ieee)
if entity:
if entity.hass:
entity.schedule_update_ha_state()

event_data = attribute.copy()
if type(event_data.get('type')) == type:
event_data['type'] = event_data['type'].__name__
Expand All @@ -267,12 +241,16 @@ def device_updated(**kwargs):
_LOGGER.debug('Update device {}'.format(device))
ieee = device.ieee or device.addr # compatibility
entity = hass.data[DATA_ZIGATE_DEVICES].get(ieee)
if entity:
if entity.hass:
entity.schedule_update_ha_state()
else:
if not entity:
_LOGGER.debug('Device not found {}, adding it'.format(device))
device_added(device=device)
event_data = {}
event_data['ieee'] = device.ieee
event_data['addr'] = device.addr
event_data['device_type'] = device.get_property_value('type')
if entity:
event_data['entity_id'] = entity.entity_id
hass.bus.fire('zigate.device_updated', event_data)

zigate.dispatcher.connect(device_updated,
zigate.ZIGATE_DEVICE_UPDATED, weak=False)
Expand All @@ -296,11 +274,12 @@ def zigate_cleanup(service):
def start_zigate(service_event=None):
myzigate.autoStart(channel)
myzigate.start_auto_save()
myzigate.set_led(enable_led)
version = myzigate.get_version_text()
if version < '3.0d':
if version < '3.0f':
hass.components.persistent_notification.create(
('Your zigate firmware is outdated, '
'Please upgrade to 3.0d or later !'),
'Please upgrade to 3.0f or later !'),
title='ZiGate')
# first load
for device in myzigate.devices:
Expand Down Expand Up @@ -435,9 +414,6 @@ def build_network_table(service):
if entity:
entity.network_table = table

def build_network_map(service):
myzigate.build_network_map(hass.config.config_dir)

def ota_load_image(service):
ota_image_path = service.data.get('imagepath')
myzigate.ota_load_image(ota_image_path)
Expand Down Expand Up @@ -492,7 +468,7 @@ def get_ota_status(service):
hass.services.register(DOMAIN, 'action_onoff', action_onoff,
schema=ACTION_ONOFF_SCHEMA)
hass.services.register(DOMAIN, 'build_network_table', build_network_table)
hass.services.register(DOMAIN, 'build_network_map', build_network_map)

hass.services.register(DOMAIN, 'ota_load_image', ota_load_image,
schema=OTA_LOAD_IMAGE_SCHEMA)
hass.services.register(DOMAIN, 'ota_image_notify', ota_image_notify,
Expand Down Expand Up @@ -553,11 +529,17 @@ def icon(self):
class ZiGateDeviceEntity(Entity):
'''Representation of ZiGate device'''

def __init__(self, device):
def __init__(self, hass, device):
"""Initialize the sensor."""
self._device = device
ieee = device.ieee or device.addr
self.entity_id = '{}.{}'.format(DOMAIN, ieee)
hass.bus.listen('zigate.attribute_updated', self._handle_event)
hass.bus.listen('zigate.device_updated', self._handle_event)

def _handle_event(self, call):
if self._device.ieee == call.data['ieee']:
self.schedule_update_ha_state()

@property
def should_poll(self):
Expand Down
39 changes: 22 additions & 17 deletions zigate/binary_sensor.py
Expand Up @@ -7,7 +7,6 @@
import logging
from homeassistant.components.binary_sensor import (BinarySensorDevice,
ENTITY_ID_FORMAT)
from homeassistant.const import STATE_UNAVAILABLE, STATE_ON, STATE_OFF
try:
from homeassistant.components.zigate import DOMAIN as ZIGATE_DOMAIN
from homeassistant.components.zigate import DATA_ZIGATE_ATTRS
Expand Down Expand Up @@ -53,7 +52,7 @@ def sync_attributes():
'for device '
'{} {}').format(device,
attribute))
entity = ZiGateBinarySensor(device, attribute)
entity = ZiGateBinarySensor(hass, device, attribute)
devs.append(entity)
hass.data[DATA_ZIGATE_ATTRS][key] = entity

Expand All @@ -67,11 +66,15 @@ def sync_attributes():
class ZiGateBinarySensor(BinarySensorDevice):
"""representation of a ZiGate binary sensor."""

def __init__(self, device, attribute):
def __init__(self, hass, device, attribute):
"""Initialize the sensor."""
self._device = device
self._attribute = attribute
self._device_class = None
if self._is_zone_status():
self._is_on = attribute.get('value', {}).get('alarm1', False)
else:
self._is_on = attribute.get('value', False)
name = attribute.get('name')
ieee = device.ieee or device.addr # compatibility
entity_id = 'zigate_{}_{}'.format(ieee,
Expand All @@ -87,6 +90,21 @@ def __init__(self, device, attribute):
self._device_class = 'smoke'
elif 'zone_status' in name:
self._device_class = 'safety'
hass.bus.listen('zigate.attribute_updated', self._handle_event)

def _handle_event(self, call):
if (
self._device.ieee == call.data['ieee']
and self._attribute['endpoint'] == call.data['endpoint']
and self._attribute['cluster'] == call.data['cluster']
and self._attribute['attribute'] == call.data['attribute']
):
_LOGGER.debug("Event received: %s", call.data)
if self._is_zone_status():
self._is_on = call.data['value'].get('alarm1', False)
else:
self._is_on = call.data['value']
self.schedule_update_ha_state()

@property
def device_class(self):
Expand Down Expand Up @@ -115,20 +133,7 @@ def name(self):
@property
def is_on(self):
"""Return true if the binary sensor is on."""
a = self._device.get_attribute(self._attribute['endpoint'],
self._attribute['cluster'],
self._attribute['attribute'])
if a:
value = a.get('value')
if self._is_zone_status():
return value.get('alarm1')
return value

@property
def state(self):
if self.is_on is None:
return STATE_UNAVAILABLE
return STATE_ON if self.is_on else STATE_OFF
return self._is_on

@property
def device_state_attributes(self):
Expand Down
24 changes: 18 additions & 6 deletions zigate/light.py
Expand Up @@ -57,7 +57,7 @@ def sync_attributes():
'for device '
'{} {}').format(device,
endpoint))
entity = ZiGateLight(device, endpoint)
entity = ZiGateLight(hass, device, endpoint)
devs.append(entity)
hass.data[DATA_ZIGATE_ATTRS][key] = entity

Expand All @@ -70,10 +70,14 @@ def sync_attributes():
class ZiGateLight(Light):
"""Representation of a ZiGate light."""

def __init__(self, device, endpoint):
def __init__(self, hass, device, endpoint):
"""Initialize the light."""
self._device = device
self._endpoint = endpoint
self._is_on = False
a = self._device.get_attribute(endpoint, 6, 0)
if a:
self._is_on = a.get('value', False)
ieee = device.ieee or device.addr # compatibility
entity_id = 'zigate_{}_{}'.format(ieee,
endpoint)
Expand All @@ -92,6 +96,17 @@ def __init__(self, device, endpoint):
elif action_type == zigate.ACTIONS_HUE:
supported_features.add(SUPPORT_COLOR)
self._supported_features = reduce(ior, supported_features)
hass.bus.listen('zigate.attribute_updated', self._handle_event)

def _handle_event(self, call):
if (
self._device.ieee == call.data['ieee']
and self._endpoint == call.data['endpoint']
):
_LOGGER.debug("Event received: %s", call.data)
if call.data['cluster'] == 6 and call.data['attribute'] == 0:
self._is_on = call.data['value']
self.schedule_update_ha_state()

@property
def should_poll(self) -> bool:
Expand Down Expand Up @@ -145,10 +160,7 @@ def color_temp(self) -> int:
@property
def is_on(self) -> bool:
"""Return true if light is on."""
a = self._device.get_attribute(self._endpoint, 6, 0)
if a:
return a.get('value', False)
return False
return self._is_on

@property
def supported_features(self) -> int:
Expand Down

0 comments on commit 3381f16

Please sign in to comment.