Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5f99dae9b | ||
|
|
827a1fcdb8 |
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.3
|
||||||
|
|
||||||
|
- Standalone version
|
||||||
|
|
||||||
## 1.2
|
## 1.2
|
||||||
|
|
||||||
- RF listening and states managements on callback
|
- RF listening and states managements on callback
|
||||||
|
|||||||
@@ -18,8 +18,14 @@ Home Assistant Addon to control an AirSend device in a local network.
|
|||||||
|
|
||||||
## Install on an external machine
|
## Install on an external machine
|
||||||
1. Clone repository
|
1. Clone repository
|
||||||
2. Go to addons/airsend folder
|
2. Generate your API key: [link to your profile](https://my.home-assistant.io/redirect/profile/) (security tab, long-lived access tokens)
|
||||||
3. In DockerFile : replace `ARG BUILD_FROM FROM $BUILD_FROM` with your machine architecture build, example : `FROM ghcr.io/home-assistant/amd64-base:3.18`
|
3. Go to addons/airsend folder
|
||||||
4. In callback.php : replace $BASE_HASS_API and $HASS_API_TOKEN with your home automation machine values
|
4. Depending on your machine architecture, run in a terminal. Example with amd64: `docker build --build-arg "BUILD_FROM=ghcr.io/home-assistant/amd64-base:3.22" -t hass_airsend-addon .`
|
||||||
5. In terminal, run `docker build -t hass_airsend-addon .`
|
5. Depending on your home assistant server and your token, run in a terminal. Example with homeassistant.local:8123:
|
||||||
6. In terminal, run `docker run -dp 33863:33863 hass_airsend-addon`
|
```bash
|
||||||
|
docker run -dp 33863:33863 \
|
||||||
|
-e HASS_HOST='homeassistant.local:8123' \
|
||||||
|
-e HASS_TOKEN='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJiZDg1MWJlNjE1NmM0Zjc4YTRiNzhjZjRlMDc4MWZiMCIsImlhdCI6MTY5MTIyOTg5MCwiZXhwIjoyMDA2NTg5ODkwfQ._ECys-uPkM8fn1W2wvjzIJ9HLJcI7RHmZmix_2C9QgU' \
|
||||||
|
-e HASS_AUTOINCLUDE=0 \
|
||||||
|
hass_airsend-addon
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
ARG BUILD_FROM
|
ARG BUILD_FROM
|
||||||
FROM $BUILD_FROM
|
FROM $BUILD_FROM
|
||||||
|
|
||||||
|
ENV HASS_HOST=
|
||||||
|
ENV HASS_TOKEN=
|
||||||
|
ENV HASS_AUTOINCLUDE=0
|
||||||
|
|
||||||
# Copy data for add-on
|
# Copy data for add-on
|
||||||
COPY hassapi.class.php /home
|
COPY hassapi.class.php /home
|
||||||
COPY callback.php /home
|
COPY hass_cb.php /home
|
||||||
COPY poststate.sh /home
|
COPY state_post.sh /home
|
||||||
|
COPY states_get.sh /home
|
||||||
COPY run.sh /
|
COPY run.sh /
|
||||||
RUN chmod a+x /home/poststate.sh
|
RUN chmod a+x /home/state_post.sh
|
||||||
|
RUN chmod a+x /home/states_get.sh
|
||||||
RUN chmod a+x /run.sh
|
RUN chmod a+x /run.sh
|
||||||
|
|
||||||
# Install AirSendWebService
|
# Install AirSendWebService
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
build_from:
|
build_from:
|
||||||
aarch64: ghcr.io/home-assistant/aarch64-base:3.18
|
aarch64: ghcr.io/home-assistant/aarch64-base:3.22
|
||||||
amd64: ghcr.io/home-assistant/amd64-base:3.18
|
amd64: ghcr.io/home-assistant/amd64-base:3.22
|
||||||
armhf: ghcr.io/home-assistant/armhf-base:3.18
|
armhf: ghcr.io/home-assistant/armhf-base:3.22
|
||||||
armv7: ghcr.io/home-assistant/armv7-base:3.18
|
armv7: ghcr.io/home-assistant/armv7-base:3.22
|
||||||
i386: ghcr.io/home-assistant/i386-base:3.18
|
i386: ghcr.io/home-assistant/i386-base:3.22
|
||||||
codenotary:
|
codenotary:
|
||||||
signer: notary@home-assistant.io
|
signer: notary@home-assistant.io
|
||||||
base_image: notary@home-assistant.io
|
base_image: notary@home-assistant.io
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: "AirSend"
|
name: "AirSend"
|
||||||
description: "AirSend Web Service (local connection, no internet, no cloud)"
|
description: "AirSend Web Service (local connection, no internet, no cloud)"
|
||||||
version: "1.2"
|
version: "1.3"
|
||||||
slug: "airsend"
|
slug: "airsend"
|
||||||
url: https://github.com/devmel/hass_airsend-addon
|
url: https://github.com/devmel/hass_airsend-addon
|
||||||
codenotary: notary@home-assistant.io
|
codenotary: notary@home-assistant.io
|
||||||
|
|||||||
@@ -1,14 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once dirname(__FILE__) . "/hassapi.class.php";
|
require_once dirname(__FILE__) . "/hassapi.class.php";
|
||||||
|
|
||||||
$BASE_HASS_API = "http://supervisor/core/api";
|
$SUPERVISOR_TOKEN = @getenv("SUPERVISOR_TOKEN");
|
||||||
$HASS_API_TOKEN = @file_get_contents('hass_api.token');
|
$HASS_HOST= @getenv("HASS_HOST");
|
||||||
|
$HASS_TOKEN= @getenv("HASS_TOKEN");
|
||||||
|
|
||||||
//On an external machine, replace with your ha values
|
$auto_include = false;
|
||||||
//$BASE_HASS_API = "http://homeassistant.local:8123/api";
|
if(!empty($HASS_HOST) && !empty($HASS_TOKEN)){
|
||||||
//$HASS_API_TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3YTJjYjE2M2VjZjQ0MGM0OGUwYzdkOTc2MjM4YWY5MCIsImlhdCI6MTY2ODg5NzA4OCwiZXhwIjoxOTg0MjU3MDg4fQ.gyDg_jYbD561OdQ0IngAMga-4LE3DTsd6bEIGkITGTc';
|
$machine = HassAPI::extractHostAndPort($HASS_HOST);
|
||||||
|
$HASS_API_URL = "http://".$machine['hostname'].":".$machine['port']."/api";
|
||||||
|
$HASS_API_TOKEN = $HASS_TOKEN;
|
||||||
|
$HASS_AUTOINCLUDE = @getenv("HASS_AUTOINCLUDE");
|
||||||
|
$auto_include = filter_var($HASS_AUTOINCLUDE, FILTER_VALIDATE_BOOLEAN);
|
||||||
|
}else if(!empty($SUPERVISOR_TOKEN)){
|
||||||
|
$HASS_API_URL = "http://supervisor/core/api";
|
||||||
|
$HASS_API_TOKEN = $SUPERVISOR_TOKEN;
|
||||||
|
$fbvalue = @file_get_contents('auto_include.cfg');
|
||||||
|
$auto_include = filter_var($fbvalue, FILTER_VALIDATE_BOOLEAN);
|
||||||
|
}
|
||||||
|
|
||||||
$api = new HassAPI($BASE_HASS_API, $HASS_API_TOKEN);
|
$api = new HassAPI($HASS_API_URL, $HASS_API_TOKEN, $auto_include);
|
||||||
|
|
||||||
if(!$api->isAuthorized()){
|
if(!$api->isAuthorized()){
|
||||||
header("HTTP/1.1 401 Unauthorized");
|
header("HTTP/1.1 401 Unauthorized");
|
||||||
@@ -28,10 +39,10 @@ if (is_array($data) && isset($data['events'])) {
|
|||||||
if($val['type'] == 3 || $val['type'] == 2 || $val['type'] == 1){
|
if($val['type'] == 3 || $val['type'] == 2 || $val['type'] == 1){
|
||||||
$states = $api->convertNotesToStates($val['thingnotes']['notes']);
|
$states = $api->convertNotesToStates($val['thingnotes']['notes']);
|
||||||
foreach ($states as $j => $state) {
|
foreach ($states as $j => $state) {
|
||||||
$api->setState($entity_id, $state[0], $state[1], $val['timestamp']);
|
$api->setState($entity_id, $state[0], $state[1], $val['timestamp'], $val['channel']);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$api->setState($entity_id, 'error', 'error_'.$val['type'], $val['timestamp']);
|
$api->setState($entity_id, 'error', 'error_'.$val['type'], $val['timestamp'], $val['channel']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Interrupt event
|
//Interrupt event
|
||||||
@@ -47,7 +58,7 @@ if (is_array($data) && isset($data['events'])) {
|
|||||||
//Search entity and update
|
//Search entity and update
|
||||||
$entities = $api->searchEntitiesFromChannelAndType($val['channel'], $state[0]);
|
$entities = $api->searchEntitiesFromChannelAndType($val['channel'], $state[0]);
|
||||||
foreach ($entities as $k => $entity_id) {
|
foreach ($entities as $k => $entity_id) {
|
||||||
$api->setState($entity_id, $state[0], $state[1], $val['timestamp']);
|
$api->setState($entity_id, $state[0], $state[1], $val['timestamp'], $val['channel']);
|
||||||
}
|
}
|
||||||
//Creates if not exists
|
//Creates if not exists
|
||||||
if(count($entities) == 0){
|
if(count($entities) == 0){
|
||||||
@@ -3,15 +3,10 @@
|
|||||||
class HassAPI{
|
class HassAPI{
|
||||||
var $states = null;
|
var $states = null;
|
||||||
|
|
||||||
function __construct($BASE_HASS_API, $HASS_API_TOKEN) {
|
function __construct($BASE_HASS_API, $HASS_API_TOKEN, $auto_include = false) {
|
||||||
$this->BASE_HASS_API = $BASE_HASS_API;
|
$this->BASE_HASS_API = $BASE_HASS_API;
|
||||||
$this->HASS_API_TOKEN = $HASS_API_TOKEN;
|
$this->HASS_API_TOKEN = $HASS_API_TOKEN;
|
||||||
$this->auto_include = false;
|
$this->auto_include = $auto_include;
|
||||||
if($this->isAuthorized()){
|
|
||||||
$fbvalue = @file_get_contents('auto_include.cfg');
|
|
||||||
$this->auto_include = filter_var($fbvalue, FILTER_VALIDATE_BOOLEAN);
|
|
||||||
$this->loadStates();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isAuthorized() {
|
public function isAuthorized() {
|
||||||
@@ -24,7 +19,7 @@ class HassAPI{
|
|||||||
return $this->auto_include;
|
return $this->auto_include;
|
||||||
}
|
}
|
||||||
function searchEntityId($uid) {
|
function searchEntityId($uid) {
|
||||||
if($this->states){
|
if($this->loadStates()){
|
||||||
foreach ($this->states as $value) {
|
foreach ($this->states as $value) {
|
||||||
if($value['entity_uid_sha256'] == $uid){
|
if($value['entity_uid_sha256'] == $uid){
|
||||||
return $value['entity_id'];
|
return $value['entity_id'];
|
||||||
@@ -36,7 +31,7 @@ class HassAPI{
|
|||||||
|
|
||||||
function searchEntitiesFromChannelAndType($channel, $type) {
|
function searchEntitiesFromChannelAndType($channel, $type) {
|
||||||
$ret = array();
|
$ret = array();
|
||||||
if(isset($channel) && $this->states){
|
if(isset($channel) && $this->loadStates()){
|
||||||
foreach ($this->states as $value) {
|
foreach ($this->states as $value) {
|
||||||
if(array_key_exists('attributes', $value) && array_key_exists('channel', $value['attributes'])){
|
if(array_key_exists('attributes', $value) && array_key_exists('channel', $value['attributes'])){
|
||||||
if(self::isChannelCompatible($channel, $value['attributes']['channel'])){
|
if(self::isChannelCompatible($channel, $value['attributes']['channel'])){
|
||||||
@@ -66,8 +61,15 @@ class HassAPI{
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setState($entity_id, $type, $state, $timestamp_ms, $channel = null) {
|
function setState($entity_id, $type, $state, $timestamp_ms, $channel = null) {
|
||||||
|
$reloadcache = false;
|
||||||
$attributes = null;
|
$attributes = null;
|
||||||
|
if(isset($channel) && ((int)$channel["id"]) == 1){
|
||||||
|
if($type === 'data'){
|
||||||
|
return; //accept AirSend state only
|
||||||
|
}
|
||||||
|
}
|
||||||
if($entity_id == null && isset($channel)){
|
if($entity_id == null && isset($channel)){
|
||||||
|
$reloadcache = true;
|
||||||
//New entity
|
//New entity
|
||||||
$entity_id = "sensor.".self::toUniqueChannelName($channel);
|
$entity_id = "sensor.".self::toUniqueChannelName($channel);
|
||||||
$attributes = array('channel' => $channel);
|
$attributes = array('channel' => $channel);
|
||||||
@@ -104,11 +106,13 @@ class HassAPI{
|
|||||||
if(array_key_exists('state', $content) && $content['state'] == $state){
|
if(array_key_exists('state', $content) && $content['state'] == $state){
|
||||||
$state .= '+';
|
$state .= '+';
|
||||||
}
|
}
|
||||||
|
$reloadcache = true;
|
||||||
}
|
}
|
||||||
if($type === 'toggle'){
|
if($type === 'toggle'){
|
||||||
if(array_key_exists('state', $content) && $content['state'] == 'pressed'){
|
if(array_key_exists('state', $content) && $content['state'] == 'pressed'){
|
||||||
$state .= '+';
|
$state .= '+';
|
||||||
}
|
}
|
||||||
|
$reloadcache = true;
|
||||||
}
|
}
|
||||||
if($type === 'level'){
|
if($type === 'level'){
|
||||||
$is_cover = (stripos($entity_id, "cover.") !== false) ? true : false;
|
$is_cover = (stripos($entity_id, "cover.") !== false) ? true : false;
|
||||||
@@ -131,14 +135,14 @@ class HassAPI{
|
|||||||
unset($content['last_updated']);
|
unset($content['last_updated']);
|
||||||
//$dti = DateTimeImmutable::createFromFormat('U.u', ($timestamp_ms/1000));
|
//$dti = DateTimeImmutable::createFromFormat('U.u', ($timestamp_ms/1000));
|
||||||
//$content['last_updated'] = $dti->format('Y-m-d').'T'.$dti->format('H:i:s').'+00:00';
|
//$content['last_updated'] = $dti->format('Y-m-d').'T'.$dti->format('H:i:s').'+00:00';
|
||||||
$this->postState($entity_id, $content);
|
$this->state_post($entity_id, $content, $reloadcache);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getState($entity_id){
|
function getState($entity_id){
|
||||||
if($this->states && isset($entity_id)){
|
if($this->loadStates() && isset($entity_id)){
|
||||||
foreach ($this->states as $value) {
|
foreach ($this->states as $value) {
|
||||||
if($value['entity_id'] == $entity_id){
|
if($value['entity_id'] == $entity_id){
|
||||||
return $value;
|
return $value;
|
||||||
@@ -148,6 +152,24 @@ class HassAPI{
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function extractHostAndPort($input, $default_port = 8123){
|
||||||
|
$hostWithPort = preg_replace('#^https?://#', '', $input);
|
||||||
|
$hostWithPort = explode('/', $hostWithPort)[0];
|
||||||
|
if (strpos($hostWithPort, ':') !== false) {
|
||||||
|
list($hostname, $port) = explode(':', $hostWithPort, 2);
|
||||||
|
$port = (int)$port;
|
||||||
|
} else {
|
||||||
|
$hostname = $hostWithPort;
|
||||||
|
}
|
||||||
|
if(empty($port) || ($port <= 0 && $port >= 0x1000)){
|
||||||
|
$port = $default_port;
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'hostname' => $hostname,
|
||||||
|
'port' => $port
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public static function convertNotesToStates($notes){
|
public static function convertNotesToStates($notes){
|
||||||
$ret = array();
|
$ret = array();
|
||||||
if(is_array($notes) && count($notes) > 0){
|
if(is_array($notes) && count($notes) > 0){
|
||||||
@@ -253,31 +275,62 @@ class HassAPI{
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function postState($entity_id, $content){
|
private function state_post($entity_id, $content, $reloadcache = false){
|
||||||
$json = json_encode($content, JSON_FORCE_OBJECT);
|
$json = json_encode($content, JSON_FORCE_OBJECT);
|
||||||
if(strpos($this->BASE_HASS_API, "supervisor") !== false){
|
if(strpos($this->BASE_HASS_API, "supervisor") !== false){
|
||||||
//Bug in supervisor proxy => use bash
|
//Bug in supervisor proxy => use bash
|
||||||
exec('./poststate.sh "'.$entity_id.'" "'.base64_encode($json).'"', $output, $retval);
|
exec('./state_post.sh "'.$entity_id.'" "'.base64_encode($json).'"', $output, $retval);
|
||||||
}else{
|
}else{
|
||||||
$res = HassAPI::request($this->BASE_HASS_API."/states/".$entity_id, $json, 'POST', $this->HASS_API_TOKEN);
|
$res = HassAPI::request($this->BASE_HASS_API."/states/".$entity_id, $json, 'POST', $this->HASS_API_TOKEN);
|
||||||
}
|
}
|
||||||
trigger_error("postState ".$entity_id." ".$content['state'], E_USER_NOTICE);
|
trigger_error("state_post ".$reloadcache." : ".$entity_id." ".$content['state'], E_USER_NOTICE);
|
||||||
|
if($reloadcache){
|
||||||
|
$this->states_get_cache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private function states_get_cache(){
|
||||||
|
if(strpos($this->BASE_HASS_API, "supervisor") !== false){
|
||||||
|
//Bug in supervisor proxy => use bash
|
||||||
|
exec('./states_get.sh', $output, $retval);
|
||||||
|
}else{
|
||||||
|
$res = HassAPI::request($this->BASE_HASS_API."/states", null, 'GET', $this->HASS_API_TOKEN);
|
||||||
|
if($res !== false && isset($res) && is_array($res) && isset($res['data'])){
|
||||||
|
file_put_contents("states.json", $res['data']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadStates() {
|
private function loadStates() {
|
||||||
$res = HassAPI::request($this->BASE_HASS_API."/states", null, 'GET', $this->HASS_API_TOKEN);
|
$ret = false;
|
||||||
if($res !== false && isset($res) && is_array($res) && isset($res['data'])){
|
if($this->states){
|
||||||
$this->states = json_decode($res['data'], true);
|
$ret = true;
|
||||||
|
}else{
|
||||||
|
if($this->isAuthorized()){
|
||||||
|
$loaded = false;
|
||||||
|
$data_age = @(time() - filemtime('states.json'));
|
||||||
|
if($data_age > 100){
|
||||||
|
$this->states_get_cache();
|
||||||
|
}
|
||||||
|
$data = @file_get_contents('states.json');
|
||||||
|
if(isset($data)){
|
||||||
|
$this->states = json_decode($data, true);
|
||||||
if($this->states){
|
if($this->states){
|
||||||
foreach ($this->states as &$value) {
|
foreach ($this->states as &$value) {
|
||||||
$h = str_split(hash('sha256', $value['entity_id']),12)[0];
|
$h = str_split(hash('sha256', $value['entity_id']),12)[0];
|
||||||
$val = intval($h, 16);
|
$val = intval($h, 16);
|
||||||
$value['entity_uid_sha256'] = $val;
|
$value['entity_uid_sha256'] = $val;
|
||||||
}
|
}
|
||||||
|
$loaded = true;
|
||||||
|
$ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($loaded == false){
|
||||||
|
trigger_error("API GET states wrong response", E_USER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
private static function request($url, $data = null, $method = 'GET', $token = null) {
|
private static function request($url, $data = null, $method = 'GET', $token = null) {
|
||||||
$result = false;
|
$result = false;
|
||||||
@@ -301,9 +354,8 @@ class HassAPI{
|
|||||||
}
|
}
|
||||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
|
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, strtoupper($method));
|
||||||
if (isset($token)){
|
if (isset($token)){
|
||||||
$token = str_replace('"', "", $token);
|
$options = array('Content-Type: application/json', 'Authorization: Bearer ' . $token);
|
||||||
$options = array(CURLOPT_HTTPHEADER => array('Content-Type: application/json' , "Authorization: Bearer ".$token));
|
curl_setopt($curl, CURLOPT_HTTPHEADER, $options);
|
||||||
curl_setopt_array($curl, $options);
|
|
||||||
}
|
}
|
||||||
$result = array();
|
$result = array();
|
||||||
$result['data'] = curl_exec($curl);
|
$result['data'] = curl_exec($curl);
|
||||||
|
|||||||
+44
-12
@@ -10,18 +10,50 @@ case "$arch" in \
|
|||||||
i386) arch='x86' ;; \
|
i386) arch='x86' ;; \
|
||||||
esac;
|
esac;
|
||||||
echo "AirSendWebService arch: ${arch}"
|
echo "AirSendWebService arch: ${arch}"
|
||||||
hname="$(hostname -i)"
|
|
||||||
echo "internal_url: http://${hname}:33863/"
|
|
||||||
|
|
||||||
if [ -n "${SUPERVISOR_TOKEN:-}" ]
|
|
||||||
then
|
|
||||||
echo ${SUPERVISOR_TOKEN} > hass_api.token
|
|
||||||
echo $(bashio::config 'auto_include') > auto_include.cfg
|
|
||||||
else
|
|
||||||
echo "Not running on Home Assistant machine..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
# Start AirSendWebService
|
||||||
ulimit -n 4096
|
ulimit -n 4096
|
||||||
./bin/unix/${arch}/AirSendWebService 99399
|
./bin/unix/${arch}/AirSendWebService 99399
|
||||||
php -S 127.0.0.1:80 callback.php
|
|
||||||
sleep infinity
|
CALLBACK_PID=
|
||||||
|
if [ -n "${SUPERVISOR_TOKEN:-}" ]
|
||||||
|
then
|
||||||
|
hname="$(hostname -i)"
|
||||||
|
echo "internal_url: http://${hname}:33863/"
|
||||||
|
echo $(bashio::config 'auto_include') > auto_include.cfg
|
||||||
|
# Start hass callback service
|
||||||
|
php -S 127.0.0.1:80 hass_cb.php & CALLBACK_PID=$!
|
||||||
|
elif [ -n "${HASS_HOST:-}" ] && [ -n "${HASS_TOKEN:-}" ]
|
||||||
|
then
|
||||||
|
echo "internal_url: http://{YOUR_DOCKER_MACHINE_IP}:33863/"
|
||||||
|
# Start hass callback service
|
||||||
|
php -S 127.0.0.1:80 hass_cb.php & CALLBACK_PID=$!
|
||||||
|
else
|
||||||
|
echo "Running the AirSendWebService only..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Give services time to start
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Monitor services
|
||||||
|
ASW_PID=$(cat AirSendWebService.lock)
|
||||||
|
while true; do
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
# Check if AirSendWebService is still running
|
||||||
|
if ! kill -0 "$ASW_PID" 2>/dev/null; then
|
||||||
|
echo "ERROR: AirSendWebService (PID: $ASW_PID) died..." >&2
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if Callback service exists and if is still running
|
||||||
|
if [[ -n "$CALLBACK_PID" && "$CALLBACK_PID" =~ ^[0-9]+$ ]] && ! kill -0 "$CALLBACK_PID" 2>/dev/null; then
|
||||||
|
echo "ERROR: Callback Service (PID: $CALLBACK_PID) died..." >&2
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
kill $ASW_PID 2>/dev/null || true
|
||||||
|
kill $CALLBACK_PID 2>/dev/null || true
|
||||||
|
echo "exiting..."
|
||||||
|
exit 1
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/with-contenv bashio
|
||||||
|
|
||||||
|
curl -o states.json -s -X GET -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" -H "Content-Type: application/json" http://supervisor/core/api/states
|
||||||
Reference in New Issue
Block a user