[3,1,1], CozyTouchStateName::CTSN_DHWMODE=>[4,0,1], CozyTouchStateName::EQ_ISHOTWATERHEATING=>[5,1,1], CozyTouchStateName::CTSN_TEMP=>[10,1,0], CozyTouchStateName::CTSN_MIDDLETEMP=>[10,1,0], CozyTouchStateName::CTSN_TARGETTEMP=>[11,0,0], CozyTouchStateName::CTSN_WATERCONSUMPTION=>[13,0,1], CozyTouchStateName::CTSN_ELECNRJCONSUMPTION=>[14,1,0], CozyTouchDeviceEqCmds::SET_BOOST=>[15,0,0], // CozyTouchStateName::CTSN_BOOSTMODEDURATION=>[15,0,0], CozyTouchStateName::CTSN_AWAYMODEDURATION=>[16,0,0], CozyTouchDeviceEqCmds::SET_THERMOSTAT=>[20,1,1], CozyTouchDeviceEqCmds::SET_AUTOMODE=>[21,1,0], CozyTouchDeviceEqCmds::SET_MANUECOACTIVE=>[22,0,0], CozyTouchDeviceEqCmds::SET_MANUECOINACTIVE=>[23,0,1], CozyTouchStateName::CTSN_CONNECT=>[99,1,1], 'refresh'=>[1,0,0] ]; public static function BuildEqLogic($device) { log::add('cozytouch', 'info', 'creation (ou mise à jour) '.$device->getVar(CozyTouchDeviceInfo::CTDI_LABEL)); $eqLogic =self::BuildDefaultEqLogic($device); $eqLogic->setCategory('energy', 1); if ($eqLogic->getConfiguration('order_max') === '') { $eqLogic->setConfiguration('order_max', 62); } if ($eqLogic->getConfiguration('order_min') === '') { $eqLogic->setConfiguration('order_min', 50); } $states = CozyTouchDeviceStateName::EQLOGIC_STATENAME[$device->getVar(CozyTouchDeviceInfo::CTDI_CONTROLLABLENAME)]; $sensors = array(); foreach ($device->getSensors() as $sensor) { $sensorURL = $sensor->getURL(); $sensors[] = array($sensorURL,$sensor->getModel()); log::add('cozytouch', 'info', 'Sensor : '.$sensorURL); // state du capteur foreach ($sensor->getStates() as $state) { if(in_array($state->name,$states)) { log::add('cozytouch', 'info', 'State : '.$state->name); $cmdId = $sensorURL.'_'.$state->name; $type ="info"; $subType = CozyTouchStateName::CTSN_TYPE[$state->name]; $name = CozyTouchStateName::CTSN_LABEL[$state->name]; $dashboard =CozyTouchCmdDisplay::DISPLAY_DASH[$subType]; $mobile =CozyTouchCmdDisplay::DISPLAY_MOBILE[$subType]; $value =$subType=="numeric"?0:($subType=="string"?'value':0); self::upsertCommand($eqLogic,$cmdId,$type,$subType,$name,1,$value,$dashboard,$mobile,$i+1); } } } $eqLogic->setConfiguration('sensors',$sensors); $eqLogic->save(); $is_heating = $eqLogic->getCmd(null,CozyTouchStateName::EQ_ISHOTWATERHEATING ); if (!is_object($is_heating)) { $is_heating = new cozytouchCmd(); $is_heating->setIsVisible(1); } $is_heating->setEqLogic_id($eqLogic->getId()); $is_heating->setName(__('Chauffe en cours', __FILE__)); $is_heating->setType('info'); $is_heating->setSubType('binary'); $is_heating->setLogicalId(CozyTouchStateName::EQ_ISHOTWATERHEATING); $is_heating->setTemplate('dashboard', 'heat'); $is_heating->setTemplate('mobile', 'heat'); $is_heating->save(); $hotWaterCoefficient = $eqLogic->getCmd(null,CozyTouchStateName::EQ_HOTWATERCOEFF ); if (!is_object($hotWaterCoefficient)) { $hotWaterCoefficient = new cozytouchCmd(); $hotWaterCoefficient->setIsVisible(1); } $hotWaterCoefficient->setEqLogic_id($eqLogic->getId()); $hotWaterCoefficient->setName(__('Proportion eau chaude', __FILE__)); $hotWaterCoefficient->setType('info'); $hotWaterCoefficient->setSubType('numeric'); $hotWaterCoefficient->setLogicalId(CozyTouchStateName::EQ_HOTWATERCOEFF); $hotWaterCoefficient->setTemplate('dashboard', 'cozytouch::hotwater'); $hotWaterCoefficient->setTemplate('mobile', 'cozytouch::hotwater'); $hotWaterCoefficient->save(); log::add('cozytouch', 'info', 'creation ou update thermostat'); $order = $eqLogic->getCmd(null, 'order'); if (!is_object($order)) { $order = new cozytouchCmd(); $order->setIsVisible(0); } $order->setEqLogic_id($eqLogic->getId()); $order->setName(__('Consigne', __FILE__)); $order->setType('info'); $order->setSubType('numeric'); $order->setIsHistorized(1); $order->setLogicalId('order'); $order->setUnite('°C'); $order->setConfiguration('maxValue', $eqLogic->getConfiguration('order_max')); $order->setConfiguration('minValue', $eqLogic->getConfiguration('order_min')); $order->save(); $thermostat = $eqLogic->getCmd(null, CozyTouchDeviceEqCmds::SET_THERMOSTAT); if (!is_object($thermostat)) { $thermostat = new cozytouchCmd(); } $thermostat->setEqLogic_id($eqLogic->getId()); $thermostat->setName(__('Thermostat', __FILE__)); $thermostat->setConfiguration('maxValue', $eqLogic->getConfiguration('order_max')); $thermostat->setConfiguration('minValue', $eqLogic->getConfiguration('order_min')); $thermostat->setType('action'); $thermostat->setSubType('slider'); $thermostat->setUnite('°C'); $thermostat->setLogicalId(CozyTouchDeviceEqCmds::SET_THERMOSTAT); $thermostat->setTemplate('dashboard', 'cozytouch::thermhotwater'); $thermostat->setTemplate('mobile', 'cozytouch::thermhotwater'); $thermostat->setIsVisible(1); $thermostat->setValue($order->getId()); $thermostat->setOrder(1); $thermostat->save(); $boost = $eqLogic->getCmd(null, 'boost_state'); if (!is_object($boost)) { $boost = new cozytouchCmd(); $boost->setIsVisible(0); } $boost->setEqLogic_id($eqLogic->getId()); $boost->setName(__('boost_state', __FILE__)); $boost->setType('info'); $boost->setSubType('binary'); $boost->setIsHistorized(1); $boost->setLogicalId('boost_state'); $boost->save(); $boost_toogle = $eqLogic->getCmd(null, CozyTouchDeviceEqCmds::SET_BOOST); if (!is_object($boost_toogle)) { $boost_toogle = new cozytouchCmd(); $boost_toogle->setLogicalId(CozyTouchDeviceEqCmds::SET_BOOST); } $boost_toogle->setEqLogic_id($eqLogic->getId()); $boost_toogle->setName(__('Boost', __FILE__)); $boost_toogle->setType('action'); $boost_toogle->setSubType('slider'); $boost_toogle->setTemplate('dashboard', 'cozytouch::toggle'); $boost_toogle->setTemplate('mobile', 'cozytouch::toggle'); $boost_toogle->setIsVisible(1); $boost_toogle->setValue($boost->getId()); $boost_toogle->save(); // 📅 Commande : Programmation des plages de chauffe $prog_slots = $eqLogic->getCmd(null, 'setProgrammingSlots'); if (!is_object($prog_slots)) { $prog_slots = new cozytouchCmd(); $prog_slots->setLogicalId('setProgrammingSlots'); } $prog_slots->setEqLogic_id($eqLogic->getId()); $prog_slots->setName(__('Plages de chauffe', __FILE__)); $prog_slots->setType('action'); $prog_slots->setSubType('message'); // pour pouvoir saisir un JSON dans Jeedom $prog_slots->setIsVisible(1); $prog_slots->save(); self::orderCommand($eqLogic); self::refresh($eqLogic); } public static function orderCommand($eqLogic) { $cmds = $eqLogic->getCmd(); foreach($cmds as $cmd) { $logicalId=explode('_',$cmd->getLogicalId()); $key = $logicalId[(count($logicalId)-1)]; log::add('cozytouch','debug','Mise en ordre : '.$key); if(array_key_exists($key,self::DISPLAY)) { $cmd->setIsVisible(1); $cmd->setOrder(self::DISPLAY[$key][0]); $cmd->setDisplay('forceReturnLineBefore',self::DISPLAY[$key][1]); $cmd->setDisplay('forceReturnLineAfter',self::DISPLAY[$key][2]); } else { $cmd->setIsVisible(0); } $cmd->save(); } } public static function Execute($cmd,$_options= array()) { log::add('cozytouch', 'debug', 'command : '.$cmd->getLogicalId()); $refresh=true; $eqLogic = $cmd->getEqLogic(); $device_url=$eqLogic->getConfiguration('device_url'); switch($cmd->getLogicalId()) { case 'refresh': log::add('cozytouch', 'debug', 'command : '.$device_url.' refresh'); break; case CozyTouchDeviceEqCmds::SET_AUTOMODE: log::add('cozytouch', 'debug', 'command : '.$device_url.' '.CozyTouchDeviceEqCmds::SET_AUTOMODE); self::setDHWMode($device_url,'autoMode'); break; case CozyTouchDeviceEqCmds::SET_MANUECOACTIVE: log::add('cozytouch', 'debug', 'command : '.$device_url.' '.CozyTouchDeviceEqCmds::SET_MANUECOACTIVE); self::setDHWMode($device_url,'manualEcoActive'); break; case CozyTouchDeviceEqCmds::SET_MANUECOINACTIVE: log::add('cozytouch', 'debug', 'command : '.$device_url.' '.CozyTouchDeviceEqCmds::SET_MANUECOINACTIVE); self::setDHWMode($device_url,'manualEcoInactive'); break; case CozyTouchDeviceEqCmds::SET_BOOST: log::add('cozytouch', 'debug', 'command : '.$device_url.' '.CozyTouchDeviceEqCmds::SET_BOOST." value : ".$_options['slider']); self::setBoostDuration($device_url,$_options['slider']); break; case CozyTouchDeviceEqCmds::SET_THERMOSTAT: $min = $cmd->getConfiguration('minValue'); $max = $cmd->getConfiguration('maxValue'); if (!isset($_options['slider']) || $_options['slider'] == '' || !is_numeric(intval($_options['slider']))) { $_options['slider'] = (($max - $min) / 2) + $min; } if ($_options['slider'] > $max) { $_options['slider'] = $max; } if ($_options['slider'] < $min) { $_options['slider'] = $min; } $eqLogic->getCmd(null, 'order')->event($_options['slider']); self::setTemperature($eqLogic,floatval($_options['slider'])); break; case 'setProgrammingSlots': self::setProgrammingSlots($eqLogic, $_options['message']); break; } if($refresh) { sleep(2); self::refresh($eqLogic); } } protected static function refresh($eqLogic) { log::add('cozytouch', 'debug', 'refresh : '.$eqLogic->getName()); try { $device_url=$eqLogic->getConfiguration('device_url'); $controllerName = $eqLogic->getConfiguration('device_model'); $clientApi = CozyTouchManager::getClient(); $states = $clientApi->getDeviceInfo($device_url,$controllerName); foreach ($states as $state) { $cmd_array = Cmd::byLogicalId($device_url."_".$state->name); if(is_array($cmd_array) && $cmd_array!=null) { $cmd=$cmd_array[0]; $value = CozyTouchManager::get_state_value($state); if (is_object($cmd) && $cmd->execCmd() !== $cmd->formatValue($value)) { $cmd->setCollectDate(''); $cmd->event($value); } } } self::refresh_boost($eqLogic); self::refresh_isheating($eqLogic); self::refresh_hotwatercoeff($eqLogic); self::refresh_thermostat($eqLogic); } catch (Exception $e) { } } public static function refresh_isheating($eqLogic) { log::add('cozytouch', 'debug', __('Refresh is heating', __FILE__)); $deviceURL = $eqLogic->getConfiguration('device_url'); $value=0; $cmd = Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),$deviceURL.'_'.CozyTouchStateName::CTSN_OPEMODECAPABILITIES); if (is_object($cmd)) { log::add('cozytouch', 'debug', __('Refresh is heating', __FILE__)); $tmp =json_decode($cmd->execCmd()); if($tmp->{'energyDemandStatus'}==1) { $value= 1; } } $cmd=Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),CozyTouchStateName::EQ_ISHOTWATERHEATING); if (is_object($cmd)) { $cmd->setCollectDate(''); $cmd->event($value); log::add('cozytouch', 'debug', __('Heating : ', __FILE__).$value); } } public static function refresh_boost($eqLogic) { log::add('cozytouch', 'debug', __('Refresh boost', __FILE__)); $deviceURL = $eqLogic->getConfiguration('device_url'); $value=""; $cmd = Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),$deviceURL.'_'.CozyTouchStateName::CTSN_BOOSTMODEDURATION); if (is_object($cmd)) { $value=$cmd->execCmd(); } $cmd=Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),'boost_state'); if (is_object($cmd)) { $boost =$value>0?1:0; $cmd->setCollectDate(''); $cmd->event($boost); log::add('cozytouch', 'debug', __('Boost : ', __FILE__).$boost. "(".$value.")"); } } public static function refresh_hotwatercoeff($eqLogic) { log::add('cozytouch', 'debug', __('Calcul proportion d eau chaude', __FILE__)); $deviceURL = $eqLogic->getConfiguration('device_url'); $valuetmp = array(); $cmd = Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),$deviceURL.'_'.CozyTouchStateName::CTSN_TARGETTEMP); if (is_object($cmd)) { $valuetmp['targettemp']=$cmd->execCmd(); } $cmd = Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),$deviceURL.'_'.CozyTouchStateName::CTSN_TEMP); if (is_object($cmd)) { $valuetmp['temp']=$cmd->execCmd(); } $cmd = Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),$deviceURL.'_'.CozyTouchStateName::CTSN_MIDDLETEMP); if (is_object($cmd)) { $valuetmp['middle_temp']=$cmd->execCmd(); } $cmd=Cmd::byEqLogicIdAndLogicalId($eqLogic->getId(),CozyTouchStateName::EQ_HOTWATERCOEFF); if (is_object($cmd)) { $temp=0; if(array_key_exists('middle_temp',$valuetmp)) { $temp=$valuetmp['middle_temp']; } else { $temp=$valuetmp['temp']; } $hotwatercoeff = 100*(floatval($temp)-self::cold_water)/(floatval($valuetmp['targettemp'])-self::cold_water); $cmd->setCollectDate(''); $cmd->event($hotwatercoeff); log::add('cozytouch', 'debug', __('Calcul proportion d eau chaude : ', __FILE__).$hotwatercoeff); } } public static function refresh_thermostat($eqDevice) { log::add('cozytouch', 'debug', 'Refresh thermostat'); $valuetmp = 55; $deviceURL = $eqDevice->getConfiguration('device_url'); $cmd=Cmd::byEqLogicIdAndLogicalId($eqDevice->getId(),$deviceURL.'_'.CozyTouchStateName::CTSN_TARGETTEMP); if (is_object($cmd)) { $valuetmp=$cmd->execCmd(); } $cmd=Cmd::byEqLogicIdAndLogicalId($eqDevice->getId(),'order'); if (is_object($cmd)) { $cmd->setCollectDate(''); $cmd->event($valuetmp); log::add('cozytouch', 'info', __('Temp ', __FILE__).$valuetmp); } } public static function setTemperature($eqDevice,$value) { $device_url= $eqDevice->getConfiguration('device_url'); $cmd=Cmd::byEqLogicIdAndLogicalId($eqDevice->getId(),$device_url.'_'.CozyTouchStateName::CTSN_DHWMODE); if (is_object($cmd)) { $mode=$cmd->execCmd(); } if($mode!='autoMode') { log::add('cozytouch', 'info', __('set target temperature ', __FILE__).$mode." ".$value); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_SETTARGETTEMP, "values"=>$value ), ); parent::genericApplyCommand($device_url,$cmds); sleep(1); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_RSHTARGETTEMP, "values"=>null ) ); parent::genericApplyCommand($device_url,$cmds); } else{ log::add('cozytouch', 'info', __('set temperature impossible : ', __FILE__).$mode); } } public static function setBoostDuration($device_url,$value) { if($value>0) { $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_SETCURRENTOPEMODE, "values"=>[ "relaunch"=>"on", "absence"=>"off" ] ) ); parent::genericApplyCommand($device_url,$cmds); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_SETBOOSTDUR, "values"=>intval($value) ) ); parent::genericApplyCommand($device_url,$cmds); } else { $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_SETCURRENTOPEMODE, "values"=>[ "relaunch"=>"off", "absence"=>"off" ] ) ); parent::genericApplyCommand($device_url,$cmds); } $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_RSHDHWMODE, "values"=>null ) ); parent::genericApplyCommand($device_url,$cmds); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_RSHTARGETTEMP, "values"=>null ) ); parent::genericApplyCommand($device_url,$cmds); sleep(5); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_RSHBOOSTDUR, "values"=>null ) ); parent::genericApplyCommand($device_url,$cmds); sleep(1); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_RSHTARGETTEMP, "values"=>null ) ); parent::genericApplyCommand($device_url,$cmds); } public static function setDHWMode($device_url,$value) { $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_SETDHWMODE, "values"=>$value ) ); parent::genericApplyCommand($device_url,$cmds); sleep(1); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_RSHDHWMODE, "values"=>null ) ); parent::genericApplyCommand($device_url,$cmds); $cmds = array( array( "name"=>CozyTouchDeviceActions::CTPC_RSHTARGETTEMP, "values"=>null ) ); parent::genericApplyCommand($device_url,$cmds); } public static function setProgrammingSlots($eqDevice, $value) { $device_url = $eqDevice->getConfiguration('device_url'); log::add('cozytouch', 'debug', '🧩 setProgrammingSlots appelé pour device_url: ' . $device_url); log::add('cozytouch', 'debug', 'Valeur brute reçue : ' . print_r($value, true)); // 🔹 Nettoyage pour compatibilité scénario if (is_string($value)) { $value = trim($value, "'\""); // supprime guillemets parasites $value = stripslashes($value); // 🧠 Cas particulier : format ["xx","xx"],["xx","xx"] if (preg_match_all('/\["([^"]+)","([^"]+)"\]/', $value, $matches, PREG_SET_ORDER)) { $decoded = []; foreach ($matches as $pair) { $decoded[] = [$pair[1], $pair[2]]; } $value = $decoded; } else { // sinon, essai standard JSON $decoded = json_decode($value, true); if ($decoded !== null) { $value = $decoded; } } } // 🔹 Conversion format simple → format Cozytouch if (isset($value[0]) && is_array($value[0]) && count($value[0]) === 2) { $slots = []; foreach ($value as $i => $pair) { $slots['slot'.($i+1)] = ['start'=>$pair[0], 'end'=>$pair[1]]; } } elseif (is_array($value)) { $slots = $value; } else { log::add('cozytouch', 'error', 'setProgrammingSlots: format invalide'); return; } // ✅ Commandes simplifiées $cmds = [ [ "name" => "setProgrammingSlots", "values" => $slots ], [ "name" => "refreshProgrammingSlots", "values" => null ] ]; $jsonPayload = json_encode($cmds, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); log::add('cozytouch', 'debug', "📤 JSON envoyé à Cozytouch :\n$jsonPayload"); parent::genericApplyCommand($device_url, $cmds); log::add('cozytouch', 'info', 'setProgrammingSlots: commandes appliquées avec succès pour ' . $device_url); } } ?>