Skip to content

Commit 055cf05

Browse files
committed
async states
1 parent bb072fd commit 055cf05

File tree

7 files changed

+51
-35
lines changed

7 files changed

+51
-35
lines changed

README.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,18 @@ Component for sending radio commands through the AirSend (RF433) or AirSend duo
66

77
## Installation
88

9-
1. Into the terminal, run `wget -q -O - https://raw.githubusercontent.com/devmel/hass_airsend/master/install | bash -`
9+
1. Install and start [hass_airsend-addon](https://github.com/devmel/hass_airsend-addon).
10+
2. Go to `airsend.cloud -> import/export -> Export YAML` and copy the airsend.yaml file to the folder `config`
11+
2. Add `airsend: !include airsend.yaml` at the end of your `configuration.yaml` file
12+
3. Into the terminal, run `wget -q -O - https://raw.githubusercontent.com/devmel/hass_airsend/master/install | bash -`
1013
OR copy the `airsend` folder into your [custom_components folder](https://developers.home-assistant.io/docs/creating_integration_file_structure/#where-home-assistant-looks-for-integrations).
11-
2. To allow a local LAN connection please install and start [hass_airsend-addon](https://github.com/devmel/hass_airsend-addon).
12-
3. Restart Home Assistant
13-
4. Add `airsend:` to your HA configuration (see configuration below).
14-
5. Restart Home Assistant
14+
4. Restart Home Assistant
1515

1616
## Configuration
1717

18-
### YAML
19-
20-
To integrate `airsend` into Home Assistant, go to `airsend.cloud -> import/export -> Export YAML` and add the contents of the downloaded file into your HA configuration `configuration.yaml`.
21-
2218
#### Local LAN connection
23-
The configuration allows to use the local mode (if [hass_airsend-addon](https://github.com/devmel/hass_airsend-addon) is started) by adding the field `spurl: !secret spurl` in each device. In this mode you must modify the file `secrets.yaml` by adding the local url of the AirSend with its local ipv4 (ex: 192.168.x.x so `spurl: sp://airsend_password@192.168.x.x`), the local ipv6 `fe80::` does not work because of virtualization. You can also remove fields `apiKey`.
19+
The configuration allows to use the local mode by adding the field `spurl: !secret spurl` in each device. In this mode you must modify the file `secrets.yaml` by adding the local url of the AirSend with its local ipv4 (ex: 192.168.x.x so `spurl: sp://airsend_password@192.168.x.x`), the local ipv6 `fe80::` does not work because of virtualization. You can also remove fields `apiKey`.
20+
The local mode requires the execution of [hass_airsend-addon](https://github.com/devmel/hass_airsend-addon), if it is not on the same machine it is possible to add the field `internal_url: http://x.x.x.x:33863/` in airsend.conf
2421

2522
## Preview
2623

custom_components/airsend/__init__.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@
33
from homeassistant.helpers.typing import ConfigType
44
from homeassistant.helpers import discovery
55
from homeassistant.components.hassio import (
6-
async_get_addon_info,
6+
get_addons_info,
77
)
88
from homeassistant.const import CONF_INTERNAL_URL
99

1010
DOMAIN = "airsend"
1111
AS_TYPE = ["switch", "cover", "button"]
1212

13-
1413
async def async_setup(hass: HomeAssistant, config: ConfigType):
1514
"""Set up the AirSend component."""
1615
if DOMAIN not in config:
@@ -22,12 +21,16 @@ async def async_setup(hass: HomeAssistant, config: ConfigType):
2221
pass
2322
if internalurl == "":
2423
try:
25-
addon_info: dict = await async_get_addon_info(hass, "local_airsend")
26-
ip = addon_info["ip_address"]
27-
if ip:
28-
internalurl = "http://" + str(ip) + ":33863/"
29-
except KeyError:
24+
addons_info = get_addons_info(hass)
25+
for name, options in addons_info.items():
26+
if "_airsend" in name:
27+
ip = options["ip_address"]
28+
if ip:
29+
internalurl = "http://" + str(ip) + ":33863/"
30+
except:
3031
pass
32+
if internalurl != "" and not internalurl.endswith('/'):
33+
internalurl += "/"
3134
config[DOMAIN][CONF_INTERNAL_URL] = internalurl
3235
for plateform in AS_TYPE:
3336
discovery.load_platform(hass, plateform, DOMAIN, config[DOMAIN].copy(), config)

custom_components/airsend/button.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,5 @@ def assumed_state(self):
7272
def press(self, **kwargs: Any) -> None:
7373
"""Handle the button press."""
7474
note = {"method": 1, "type": 0, "value": "TOGGLE"}
75-
if self._device.transfer(note):
75+
if self._device.transfer(note, self.entity_id) == True:
7676
self.schedule_update_ha_state()

custom_components/airsend/cover.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from homeassistant.components.cover import CoverEntity
77
from homeassistant.core import HomeAssistant
88
from homeassistant.helpers.typing import ConfigType
9-
109
from homeassistant.const import CONF_DEVICES, CONF_INTERNAL_URL
1110

1211
from . import DOMAIN
@@ -75,12 +74,12 @@ def assumed_state(self):
7574
@property
7675
def is_closed(self):
7776
"""Return if the cover is closed."""
78-
return not self._closed
77+
return self._closed
7978

8079
def open_cover(self, **kwargs: Any) -> None:
8180
"""Open the cover."""
8281
note = {"method": 1, "type": 0, "value": "UP"}
83-
if self._device.transfer(note):
82+
if self._device.transfer(note, self.entity_id) == True:
8483
self._closed = False
8584
if self._device.is_cover_with_position:
8685
self._attr_current_cover_position = 100
@@ -89,7 +88,7 @@ def open_cover(self, **kwargs: Any) -> None:
8988
def close_cover(self, **kwargs: Any) -> None:
9089
"""Close cover."""
9190
note = {"method": 1, "type": 0, "value": "DOWN"}
92-
if self._device.transfer(note):
91+
if self._device.transfer(note, self.entity_id) == True:
9392
self._closed = True
9493
if self._device.is_cover_with_position:
9594
self._attr_current_cover_position = 0
@@ -98,7 +97,7 @@ def close_cover(self, **kwargs: Any) -> None:
9897
def stop_cover(self, **kwargs):
9998
"""Stop the cover."""
10099
note = {"method": 1, "type": 0, "value": "STOP"}
101-
if self._device.transfer(note):
100+
if self._device.transfer(note, self.entity_id) == True:
102101
self._closed = False
103102
if self._device.is_cover_with_position:
104103
self._attr_current_cover_position = 50
@@ -108,7 +107,7 @@ def set_cover_position(self, **kwargs):
108107
"""Move the cover to a specific position."""
109108
position = int(kwargs["position"])
110109
note = {"method": 1, "type": 9, "value": position}
111-
if self._device.transfer(note):
110+
if self._device.transfer(note, self.entity_id) == True:
112111
self._attr_current_cover_position = position
113112
self._closed = False
114113
if self._attr_current_cover_position == 0:

custom_components/airsend/device.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""AirSend device."""
22
import logging
33
import json
4+
import hashlib
45
from requests import get, post, exceptions
56
from . import DOMAIN
67

@@ -23,6 +24,7 @@ def __init__(
2324
self._rtype = None
2425
self._apikey = None
2526
self._spurl = None
27+
self._wait = False
2628
self._channel = {}
2729
self._note = None
2830
try:
@@ -41,6 +43,10 @@ def __init__(
4143
self._spurl = options["spurl"]
4244
except KeyError:
4345
pass
46+
try:
47+
self._wait = eval(str(options["wait"]))
48+
except KeyError:
49+
pass
4450
try:
4551
self._channel = options["channel"]
4652
except KeyError:
@@ -83,10 +89,15 @@ def is_switch(self) -> bool:
8389
return True
8490
return False
8591

86-
def transfer(self, note) -> bool:
92+
def transfer(self, note, entity_id = None) -> bool:
8793
"""Send a command."""
8894
status_code = 404
89-
if self._serviceurl and self._spurl:
95+
ret = False
96+
wait = 'false, "callback":"http://127.0.0.1/"'
97+
if self._wait == True:
98+
wait = 'true'
99+
if self._serviceurl and self._spurl and entity_id is not None:
100+
uid = hashlib.sha256(entity_id.encode('utf-8')).hexdigest()[:12]
90101
jnote = json.dumps(note)
91102
if (
92103
self._note is not None
@@ -101,9 +112,9 @@ def transfer(self, note) -> bool:
101112
):
102113
jnote = json.dumps(self._note)
103114
payload = (
104-
'{"wait": true, "channel":'
115+
'{"wait": '+wait+', "channel":'
105116
+ json.dumps(self._channel)
106-
+ ', "thingnotes":{"notes":['
117+
+ ', "thingnotes":{"uid":"0x'+uid+'", "notes":['
107118
+ jnote
108119
+ "]}}"
109120
)
@@ -119,9 +130,14 @@ def transfer(self, note) -> bool:
119130
data=payload,
120131
timeout=6,
121132
)
122-
status_code = 500
123-
jdata = json.loads(response.text)
124-
if jdata["type"] < 0x100:
133+
if self._wait == True:
134+
ret = True
135+
status_code = 500
136+
jdata = json.loads(response.text)
137+
if jdata["type"] < 0x100:
138+
status_code = response.status_code
139+
else:
140+
ret = None
125141
status_code = response.status_code
126142
except exceptions.RequestException:
127143
pass
@@ -164,9 +180,10 @@ def transfer(self, note) -> bool:
164180
try:
165181
response = get(cloud_url, headers=headers, timeout=10)
166182
status_code = response.status_code
183+
ret = True
167184
except exceptions.RequestException:
168185
pass
169186
if status_code == 200:
170-
return True
187+
return ret
171188
_LOGGER.error("Transfer error '%s' : '%s'", self.name, status_code)
172189
raise Exception("Transfer error " + self.name + " : " + str(status_code))

custom_components/airsend/switch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ def is_on(self):
7777
def turn_on(self, **kwargs: Any) -> None:
7878
"""Turn the device on."""
7979
note = {"method": 1, "type": 0, "value": "ON"}
80-
if self._device.transfer(note):
80+
if self._device.transfer(note, self.entity_id) == True:
8181
self._state = True
8282
self.schedule_update_ha_state()
8383

8484
def turn_off(self, **kwargs: Any) -> None:
8585
"""Turn the device off."""
8686
note = {"method": 1, "type": 0, "value": "OFF"}
87-
if self._device.transfer(note):
87+
if self._device.transfer(note, self.entity_id) == True:
8888
self._state = False
8989
self.schedule_update_ha_state()

install

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ if [ -n "$haPath" ]; then
5656
cd "$haPath/custom_components" || error "Could not change path to $haPath/custom_components"
5757

5858
info "Downloading AirSend Home Assistant Component"
59-
wget "https://github.com/devmel/hass_airsend/releases/download/1.0/hass_airsend.zip"
59+
wget "https://github.com/devmel/hass_airsend/releases/download/latest/hass_airsend.zip"
6060

6161
if [ -d "$haPath/custom_components/hass_airsend" ]; then
6262
warn "airsend directory already exist, cleaning up..."

0 commit comments

Comments
 (0)