]> _ Git - tortuga-home.git/commitdiff
.
authorVincent <vincent@enhydra.fr>
Mon, 19 Apr 2021 19:39:33 +0000 (21:39 +0200)
committerVincent <vincent@enhydra.fr>
Mon, 19 Apr 2021 19:39:33 +0000 (21:39 +0200)
16 files changed:
.idea/workspace.xml
config/global.php
config/salon.php
images/rooms/medium/cuisine.jpg
images/rooms/medium/salon.jpg
images/rooms/originaux/cuisine.jpg
images/rooms/originaux/salon.jpg
images/rooms/small/cuisine.jpg
images/rooms/small/salon.jpg
scripts/homeconnect.php [new file with mode: 0644]
scripts/lib/homeconnect.php [new file with mode: 0644]
scripts/lib/http.php
scripts/lib/lib.php
scripts/lib/redis.php
scripts/lib/scenes.php
scripts/lib/state.php

index 72cb789d0ccdc68bd782a82747896276fb14f087..6cb04e6bed5036438998e7c51468e5a18a135d9a 100644 (file)
@@ -2,9 +2,22 @@
 <project version="4">
   <component name="ChangeListManager">
     <list default="true" id="352ce63a-b52a-41a2-979b-becda7920939" name="Default" comment=".">
+      <change afterPath="$PROJECT_DIR$/scripts/homeconnect.php" afterDir="false" />
+      <change afterPath="$PROJECT_DIR$/scripts/lib/homeconnect.php" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/scripts/lib/kodi.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/kodi.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/config/global.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/global.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/config/salon.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/salon.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/images/rooms/medium/cuisine.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/images/rooms/medium/cuisine.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/images/rooms/medium/salon.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/images/rooms/medium/salon.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/images/rooms/originaux/cuisine.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/images/rooms/originaux/cuisine.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/images/rooms/originaux/salon.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/images/rooms/originaux/salon.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/images/rooms/small/cuisine.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/images/rooms/small/cuisine.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/images/rooms/small/salon.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/images/rooms/small/salon.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/http.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/http.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/lib.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/lib.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/redis.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/redis.php" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/scripts/lib/scenes.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/scenes.php" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/scripts/lib/state.php" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/lib/state.php" afterDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
     <property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1553247665857" />
     <property name="dumpAutoload T:/Drive/Works/home/composer.json" value="--no-interaction --ansi --verbose --optimize" />
     <property name="editor.config.ad.shown" value="true" />
-    <property name="last_opened_file_path" value="$PROJECT_DIR$/images" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$/images/rooms/small" />
     <property name="list.type.of.created.stylesheet" value="Less" />
     <property name="node.js.detected.package.eslint" value="true" />
     <property name="node.js.detected.package.tslint" value="true" />
   </component>
   <component name="RecentsManager">
     <key name="CopyFile.RECENT_KEYS">
+      <recent name="T:\Drive\Works\home\images\rooms\small" />
+      <recent name="T:\Drive\Works\home\images\rooms\medium" />
       <recent name="T:\Drive\Works\home\images" />
       <recent name="T:\Drive\Works\home\style\fonts\fontawesome" />
       <recent name="T:\Drive\Works\home" />
-      <recent name="T:\Drive\Works\home\servers" />
-      <recent name="T:\Drive\Works\home\config" />
     </key>
     <key name="MoveFile.RECENT_KEYS">
       <recent name="T:\Drive\Works\home\images" />
         <option name="Make" enabled="true" />
       </method>
     </configuration>
+    <configuration default="true" type="ArquillianJUnit" factoryName="" nameIsGenerated="true">
+      <option name="arquillianRunConfiguration">
+        <value>
+          <option name="containerStateName" value="" />
+        </value>
+      </option>
+      <option name="TEST_OBJECT" value="class" />
+      <method v="2">
+        <option name="Make" enabled="true" />
+      </method>
+    </configuration>
     <configuration default="true" type="ArquillianTestNG" factoryName="">
       <option name="arquillianRunConfiguration">
         <value>
       <workItem from="1617801536336" duration="4107000" />
       <workItem from="1618050897134" duration="4462000" />
       <workItem from="1618158049208" duration="20700000" />
-      <workItem from="1618426400216" duration="472000" />
-    </task>
-    <task id="LOCAL-00419" summary=".">
-      <created>1607418039594</created>
-      <option name="number" value="00419" />
-      <option name="presentableId" value="LOCAL-00419" />
-      <option name="project" value="LOCAL" />
-      <updated>1607418039594</updated>
+      <workItem from="1618426400216" duration="1138000" />
+      <workItem from="1618656192286" duration="2313000" />
+      <workItem from="1618682288258" duration="2117000" />
+      <workItem from="1618740509693" duration="11544000" />
     </task>
     <task id="LOCAL-00420" summary=".">
       <created>1607546493721</created>
       <option name="project" value="LOCAL" />
       <updated>1618342660944</updated>
     </task>
-    <option name="localTasksCounter" value="468" />
+    <task id="LOCAL-00468" summary=".">
+      <created>1618426951296</created>
+      <option name="number" value="00468" />
+      <option name="presentableId" value="LOCAL-00468" />
+      <option name="project" value="LOCAL" />
+      <updated>1618426951296</updated>
+    </task>
+    <option name="localTasksCounter" value="469" />
     <servers />
   </component>
   <component name="TypeScriptGeneratedFilesManager">
index efc0ae0b0258ea63479e1af42fb6945b2981e399..66312e72fde89f879f5742625871c39f21eeace5 100644 (file)
@@ -10,6 +10,11 @@ define("SQUEEZEBOX_SPOTIFY_PASSWORD", '?Z8}#HK+SZrQ');
 define('HUE_BRIDGE', '192.168.13.85');
 define('HUE_USER', 'zZigF7nPQq9nTZ3GTB1zkntn98trOJVFHWAwFiqQ');
 
+define('HOMECONNECT_CLIENT_ID','97C087A66769555561D14306F34336C5D05AD97B56ED813E6BD44ECCFA980CE5');
+define('HOMECONNECT_CLIENT_SECRET','540F102E39E86F7F92C3A534C31017264A47458589E9E66D27427F35DD4F7BFC');
+define('HOMECONNECT_USERNAME','vincent@enhydra.fr');
+define('HOMECONNECT_PASSWORD','YcR%vNmYnu%e$3dx2idM');
+
 define('LATITUDE', 48.8758392);
 define('LONGITUDE', 2.3422104);
 
index 2661511573bd6d5cbd8e12e962666b54ff4ac7c9..b339380db75a6bcf711f401585c2d8cea4ea2956 100644 (file)
@@ -7,7 +7,7 @@ config('TVPLAYER', 'shield');
 config('VOLUME_DEVICE', 'DenonAVR');
 config('VIDEOPLAYER_DEVICE', 'salon');
 config('HIDEMASK_TIMEOUT', 250);
-config('THEME','#7a6854');
+config('THEME','#d0a25b');
 config('SLEEPSCREEN', 15);
 config('SCREENSAVER_BRIGHTNESS', 100);
 config('SLEEPTYPE', 'screensaver');
index 78952416ad8eea479de626f7eb8148439c6dd0a4..b78ca7e11fd090456bc2fc117e1a75e81f0cea1a 100644 (file)
Binary files a/images/rooms/medium/cuisine.jpg and b/images/rooms/medium/cuisine.jpg differ
index fe0c1a448aba5571ef6aa1038d37ab9dc2b762c9..5d92fc5817a3babab7b84fc5ca1bc10e761bfa0f 100644 (file)
Binary files a/images/rooms/medium/salon.jpg and b/images/rooms/medium/salon.jpg differ
index 8ddf21e307ab32086a8e148574cace057fc320b1..b78ca7e11fd090456bc2fc117e1a75e81f0cea1a 100644 (file)
Binary files a/images/rooms/originaux/cuisine.jpg and b/images/rooms/originaux/cuisine.jpg differ
index 1e8b28c95133a0713609b9d05485de44a28cd04d..5d92fc5817a3babab7b84fc5ca1bc10e761bfa0f 100644 (file)
Binary files a/images/rooms/originaux/salon.jpg and b/images/rooms/originaux/salon.jpg differ
index fdd224275ce821dd152fbce9250101bdaa7842d9..b78ca7e11fd090456bc2fc117e1a75e81f0cea1a 100644 (file)
Binary files a/images/rooms/small/cuisine.jpg and b/images/rooms/small/cuisine.jpg differ
index 4fe3d2aaffcd070f85c306c9bcfda33373081ace..5d92fc5817a3babab7b84fc5ca1bc10e761bfa0f 100644 (file)
Binary files a/images/rooms/small/salon.jpg and b/images/rooms/small/salon.jpg differ
diff --git a/scripts/homeconnect.php b/scripts/homeconnect.php
new file mode 100644 (file)
index 0000000..50363f8
--- /dev/null
@@ -0,0 +1,4 @@
+<?php
+require_once "import.php";
+echo '<pre>';
+hc_setpower_state('Machine à café',false);
\ No newline at end of file
diff --git a/scripts/lib/homeconnect.php b/scripts/lib/homeconnect.php
new file mode 100644 (file)
index 0000000..94e88e9
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+function _hc_cmd($cmd, $data = [], $method = 'get', $auth = true)
+{
+    $client = getHttpClient(false);
+    $base = 'https://api.home-connect.com';
+    $uri = $base . '/' . $cmd;
+    $headers = [];
+    if ($auth) {
+        $headers['Authorization'] = 'Bearer ' . getState('hc_access_token');
+        $headers['Accept'] = 'application/vnd.bsh.sdk.v1+json';
+    }
+    $res = httpRequest($uri, $method, $data, null, 10, true, $headers);
+    $c = $res->getBody()->getContents();
+
+    if ($decoded = json_decode($c)) {
+        return $decoded;
+    } else {
+        return $c;
+    }
+}
+
+
+function hc_appliances()
+{
+    hc_connect();
+    $cacheId = 'hc_appliances';
+    $res = getStateIfMoreRecent($cacheId, time() - (86400 * 7), null);
+    if (null === $res) {
+        $res = [];
+        $appliances = _hc_cmd('api/homeappliances')->data->homeappliances;
+        foreach ($appliances as $item) {
+            $res[$item->name] = ['haid' => $item->haId, 'type' => $item->type];
+        }
+        setState($cacheId, $res);
+    }
+    return $res;
+}
+
+function hc_haid($name)
+{
+    $appliances = hc_appliances();
+    return $appliances[$name]['haid'];
+}
+
+function hc_type($name)
+{
+    $appliances = hc_appliances();
+    return $appliances[$name]['type'];
+}
+
+function hc_command($appliance, $cmd)
+{
+    $haid = hc_haid($appliance);
+}
+
+
+function hc_setpower_state($appliance, $state)
+{
+    $data = [];
+    $aptype = hc_type($appliance);
+    $stby = ['Oven', 'CoffeeMaker'];
+    if (in_array($aptype, $stby)) {
+        $states = ['On', 'Standby'];
+    } else {
+        $states = ['On', 'Off'];
+    }
+    $value = $state ? $states[0] : $states[1];
+    $data = ['key' => 'BSH.Common.Setting.PowerState',
+        'value' => 'BSH.Common.EnumType.PowerState.' . $value,
+        'type' => 'BSH.Common.EnumType.PowerState',
+        'contraints' => ['allowedvalues' => ['BSH.Common.EnumType.Powerstate.' . $states[0], 'BSH.Common.EnumType.Powerstate.' . $states[1]]]];
+
+    return _hc_cmd("api/homeappliances/" . hc_haid($appliance) . "/settings/BSH.Common.Setting.PowerState", ['data'=>$data], 'put');
+}
+
+function coffee_on(){
+    hc_setpower_state('Machine à café',true);
+}
+
+function coffee_off(){
+    hc_setpower_state('Machine à café',false);
+}
+
+function hc_connect()
+{
+    $scope = 'IdentifyAppliance Monitor Settings';
+    $appName = 'Tortuga';
+    $locale = 'fr';
+
+    if (null === getStateIfMoreRecent('hc_access_token', null, time() - 86400)) {
+        // Init connection
+        $connect = _hc_cmd('security/oauth/device_authorization', [
+            'client_id' => HOMECONNECT_CLIENT_ID,
+            'scope' => $scope,
+        ], 'post', false);
+        print_r($connect);
+
+        // Login
+        $login = _hc_cmd('security/oauth/device_login', [
+            'client_id' => HOMECONNECT_CLIENT_ID,
+            'user_code' => $connect->user_code,
+            'email' => HOMECONNECT_USERNAME,
+            'password' => HOMECONNECT_PASSWORD,
+        ], 'post', false);
+        preg_match('/<input type="hidden" name="session_id" value="([-a-z0-9]*)"\/>/', $login, $matches);
+        $session_id = $matches[1];
+
+        // Grant
+        $grant = _hc_cmd('security/oauth/device_grant',
+            [
+                'client_id' => HOMECONNECT_CLIENT_ID,
+                'app_name' => $appName,
+                'session_id' => $session_id,
+                'user_code' => $connect->user_code,
+                'input_aborted' => 'false',
+                'accept_language' => $locale,
+                'email' => HOMECONNECT_USERNAME,
+                "region" => "EU", "environment" => "PRD",
+                'scope' => $scope
+            ], 'post', false);
+
+        // Token request
+        $token = _hc_cmd('security/oauth/token',
+            [
+                'grant_type' => 'device_code',
+                'device_code' => $connect->device_code,
+                'client_id' => HOMECONNECT_CLIENT_ID,
+            ], 'post', false);
+    } else if (getState('hc_access_token_expires' < time())) {
+        $token = _hc_cmd('security/oauth/token',
+            [
+                'grant_type' => 'refresh_token',
+                'refresh_token' => getState('hc_refresh_token'),
+                'client_id' => HOMECONNECT_CLIENT_ID,
+            ], 'post', false);
+    } else {
+        return;
+    }
+
+    setState('hc_access_token', $token->access_token);
+    setState('hc_refresh_token', $token->refresh_token);
+}
\ No newline at end of file
index cd99e87101008d112bdd397f31211514315023f1..6db16645865d1afc9371063eee9bcd0ccba8b559 100644 (file)
@@ -48,7 +48,11 @@ function httpRequest($url, $method = 'get', $data = [], $auth = null, $timeout =
     }
     if ($method == 'GET') {
         $options['query'] = $data;
+    }
+    if ($method === 'PUT') {
+        $options['json']=$data;
     } else {
+
         if (is_string($data)) {
             $options['body'] = $data;
         } else {
index 4f1865a30e87c633303fc456747f6623e695720f..0fd8a87fb7dc6c8f7b72633071bffeb2d6fa4c84 100644 (file)
@@ -47,6 +47,7 @@ require_once ROOT . '/scripts/lib/proc.php';
 require_once ROOT . '/scripts/lib/shield.php';
 require_once ROOT . '/scripts/lib/kodi.php';
 require_once ROOT . '/scripts/lib/climacell.php';
+require_once ROOT . '/scripts/lib/homeconnect.php';
 
 
 profile('Loaded libraries', __FILE__, __LINE__);
index 76cf99a2fa80465364f8550b179613251401044d..e85ad30ed714c8963bae7b8c1a9eeacbeadd5aa6 100644 (file)
@@ -2,6 +2,8 @@
 
 use Predis\Client;
 
+
+
 class StringSetIb
     extends Predis\Command\StringSet
 {
index b17bb42eda89e7980e6d46e26d0fa8428e539941..0377826e9a944feaea7791ad91b82e047049f5b2 100644 (file)
@@ -34,7 +34,7 @@ $scenes = [
         ['type' => 'scene', 'scene' => 'chambre/planetarium/off'],
         ['type' => 'function', 'function' => 'bedbrightness', 'args' => [255]],
         ['type' => 'phonetask', 'phone' => 'vincent', 'task' => 'Matin'],
-        ['type' => 'ifttt', 'event' => 'coffee_on'],
+        ['type' => 'function', 'function' => 'coffee_on'],
         ['type' => 'scene', 'scene' => 'chambre/auto', 'delay' => 35],
     ],
     'chambre/deshumidificateur/on' => [
@@ -631,11 +631,10 @@ $scenes = [
         ['type' => 'scene', 'scene' => 'chambre/deshumidificateur/on'],
         ['type' => 'phonetask', 'phone' => 'vincent', 'task' => 'Stop All Sounds'],
         ['type' => 'scene', 'scene' => 'chambre/planetarium/off'],
-        ['type' => 'ifttt', 'event' => 'coffee_off'],
+        ['type' => 'function', 'function' => 'coffee_off'],
         ['type' => 'scene', 'scene' => 'home/hueoff'],
         ['type' => 'scene', 'scene' => 'salon/media/off'],
         ['type' => 'scene', 'scene' => 'salon/off', 'delay' => 2],
-        //['type' => 'ifttt', 'event' => 'oven_off'],
     ],
     'home/welcome' => [
         ['type' => 'scene', 'scene' => 'cuisine/on'],
index f5f73b0d9b00b1dfa7f4d5d323cc18191a7243ea..af2d5ba0ae322c3c78dc28fc0c015b6957171af5 100644 (file)
@@ -1,12 +1,16 @@
 <?php
 require_once __DIR__ . '/redis.php';
-function setState($key, $value)
+function setState($key, $value, $expires = false)
 {
     if (is_string($value)) {
         $value = trim($value);
     }
 
-    connectRedis()->igbset('state_' . $key, $value);
+    if (!$expires) {
+        connectRedis()->igbset('state_' . $key, $value);
+    } else {
+        connectRedis()->igbsetex('state_' . $key, $value, $expires);
+    }
 }
 
 function getState($key, $default = null)
@@ -21,6 +25,6 @@ function getState($key, $default = null)
 function getStateIfMoreRecent($key, $time, $default = null)
 {
     $redis = connectRedis();
-    $redis->expireAt($key, $time);
+    //$redis->expireAt($key, $time);
     return getState($key, $default);
 }
\ No newline at end of file