public function toHtml($_version = 'dashboard')
 {
     if ($this->getConfiguration('noSpecifyWidget', 0) == 1) {
         return parent::toHtml($_version);
     }
     if ($_version == '') {
         throw new Exception(__('La version demandée ne peut pas être vide (mobile, dashboard ou scénario)', __FILE__));
     }
     if (!$this->hasRight('r')) {
         return '';
     }
     $version = jeedom::versionAlias($_version);
     if ($this->getDisplay('hideOn' . $version) == 1) {
         return '';
     }
     $cmd_html = '';
     $version = jeedom::versionAlias($_version);
     $vcolor = 'cmdColor';
     if ($version == 'mobile') {
         $vcolor = 'mcmdColor';
     }
     if ($this->getPrimaryCategory() == '') {
         $cmdColor = '';
     } else {
         $cmdColor = jeedom::getConfiguration('eqLogic:category:' . $this->getPrimaryCategory() . ':' . $vcolor);
     }
     $maps = array();
     $dynamic = array();
     $cmd_html = '';
     if ($this->getIsEnable()) {
         foreach ($this->getCmd(null, null, true) as $cmd) {
             if ($cmd->getConfiguration('mode') == 'travelTime') {
                 $from = $cmd->getConfiguration('from');
                 $to = $cmd->getConfiguration('to');
                 if (!isset($maps[$from . '_' . $to])) {
                     $maps[$from . '_' . $to] = array();
                 }
                 $maps[$from . '_' . $to]['travelTime'] = $cmd->execCmd();
             }
             if ($cmd->getConfiguration('mode') == 'distance') {
                 $from = $cmd->getConfiguration('from');
                 $to = $cmd->getConfiguration('to');
                 if (!isset($maps[$from . '_' . $to])) {
                     $maps[$from . '_' . $to] = array();
                 }
                 $maps[$from . '_' . $to]['distance'] = $cmd->execCmd();
             }
             if ($cmd->getConfiguration('mode') == 'travelDistance') {
                 $from = $cmd->getConfiguration('from');
                 $to = $cmd->getConfiguration('to');
                 if (!isset($maps[$from . '_' . $to])) {
                     $maps[$from . '_' . $to] = array();
                 }
                 $maps[$from . '_' . $to]['travelDistance'] = $cmd->execCmd();
             }
             if ($cmd->getConfiguration('mode') == 'dynamic') {
                 $dynamic[$cmd->getId()] = $cmd;
             }
         }
     }
     foreach ($maps as $key => $map) {
         $key = explode('_', $key);
         if (count($key) != 2) {
             continue;
         }
         foreach ($dynamic as $id => $cmd) {
             if (in_array($id, $key)) {
                 unset($dynamic[$id]);
             }
         }
         $from_cmd = cmd::byId($key[0]);
         $to_cmd = cmd::byId($key[1]);
         if (!is_object($from_cmd) || !is_object($to_cmd)) {
             contine;
         }
         $from = $from_cmd->execCmd();
         $to = $to_cmd->execCmd();
         $replace = array('#name#' => $from_cmd->getName() . ' <i class="fa fa-arrow-right"></i> ' . $to_cmd->getName(), '#from#' => $from, '#collectDate#' => $from_cmd->getCollectDate() > $to_cmd->getCollectDate() ? $from_cmd->getCollectDate() : $to_cmd->getCollectDate(), '#to#' => $to, '#travelDistance#' => isset($map['travelDistance']) ? $map['travelDistance'] : __('Inconnue', __FILE__), '#distance#' => isset($map['distance']) ? $map['distance'] : __('Inconnue', __FILE__), '#travelTime#' => isset($map['travelTime']) ? $map['travelTime'] : __('Inconnue', __FILE__));
         $cmd_html .= template_replace($replace, getTemplate('core', $version, 'geoloc', 'geoloc'));
     }
     foreach ($dynamic as $id => $cmd) {
         $replace = array('#state#' => $cmd->execCmd(), '#name#' => $cmd->getName(), '#collectDate#' => $cmd->getCollectDate(), '#id#' => $cmd->getId());
         $cmd_html .= template_replace($replace, getTemplate('core', $_version, 'geoloc_single', 'geoloc'));
     }
     $replace = array('#id#' => $this->getId(), '#name#' => $this->getName(), '#eqLink#' => $this->hasRight('w') ? $this->getLinkToConfiguration() : '#', '#category#' => $this->getPrimaryCategory(), '#background_color#' => $this->getBackgroundColor($version), '#cmd#' => $cmd_html, '#style#' => '', '#noResize#' => 1, '#max_width#' => '650px', '#logicalId#' => $this->getLogicalId(), '#battery#' => $this->getConfiguration('batteryStatus', -2), '#batteryDatetime#' => $this->getConfiguration('batteryStatusDatetime', __('inconnue', __FILE__)));
     if (($_version == 'dview' || $_version == 'mview') && $this->getDisplay('doNotShowObjectNameOnView', 0) == 0) {
         $object = $this->getObject();
         $replace['#object_name#'] = is_object($object) ? '(' . $object->getName() . ')' : '';
     } else {
         $replace['#object_name#'] = '';
     }
     if (($_version == 'dview' || $_version == 'mview') && $this->getDisplay('doNotShowNameOnView') == 1) {
         $replace['#name#'] = '';
     }
     if (($_version == 'mobile' || $_version == 'dashboard') && $this->getDisplay('doNotShowNameOnDashboard') == 1) {
         $replace['#name#'] = '';
     }
     if (($_version == 'dview' || $_version == 'mview') && $this->getDisplay('doNotDisplayBatteryLevelOnView') == 1) {
         $replace['#battery#'] = -1;
     }
     if ($_version == 'dashboard' && $this->getDisplay('doNotDisplayBatteryLevelOnDashboard') == 1) {
         $replace['#battery#'] = -1;
     }
     $parameters = $this->getDisplay('parameters');
     if (is_array($parameters)) {
         foreach ($parameters as $key => $value) {
             $replace['#' . $key . '#'] = $value;
         }
     }
     return template_replace($replace, getTemplate('core', $version, 'eqLogic'));
 }
 /**
  * Format le Widget "gCalendar"
  * @return void
  */
 public function toHtml($_version)
 {
     log::add('gCalendar', 'debug', '[' . $this->getId() . '] toHtml(' . $_version . ') start ...');
     // utilisation du widget "standard" jeedom //
     if ($this->getConfiguration('widgetOther') == '1') {
         log::add('gCalendar', 'debug', '[' . $this->getId() . '] toHtml(' . $_version . ') use jeedom widget (no plugin widget).');
         return parent::toHtml($_version);
     }
     // utilisation du widget du plugin //
     $_version = jeedom::versionAlias($_version);
     $mc = cache::byKey('gcalendarWidget' . $_version . $this->getId());
     if ($mc->getValue() != '') {
         log::add('gCalendar', 'debug', '[' . $this->getId() . '] toHtml(' . $_version . ') aborded !');
         return $mc->getValue();
     }
     $_sToday = $this->getConfiguration('hideDateDashboard') == 1 ? '' : __("aujourd'hui", __FILE__) . " : " . $this->getToday();
     $replace = array('#id#' => $this->getId(), '#name#' => $this->getIsEnable() ? $this->getName() : '<del>' . $this->getName() . '</del>', '#background_color#' => $this->getBackgroundColor($_version), '#today#' => $_version == 'mobile' ? date('d') : $_sToday, '#gCalArray#' => '0');
     if ($_version != 'mobile') {
         $replace['#eqLink#'] = $this->getLinkToConfiguration();
         $replace['#refreshDate#'] = !empty($this->_sRefreshDate) ? $this->_sRefreshDate : date('Y-m-d H:i:s');
         $replace['#txtView#'] = __("affichage", __FILE__);
         $replace['#txtGotoAG#'] = __("voir Agenda Google", __FILE__);
         $replace['#txtDay#'] = __("journée", __FILE__);
         $replace['#txtNextHour#'] = __("prochaine heure", __FILE__);
         $replace['#txtNow#'] = __("instantané", __FILE__);
     }
     // action sur l'affichage du nom //
     if (($_version == 'dview' || $_version == 'mview') && $this->getDisplay('doNotShowNameOnView') == 1) {
         $replace['#name#'] = '';
     }
     if ($_version == 'dashboard' && $this->getDisplay('doNotShowNameOnDashboard') == 1) {
         $replace['#name#'] = '';
     }
     if ($_version == 'mobile' && $this->getDisplay('doNotShowNameOnMobile') == 1) {
         $replace['#name#'] = '';
     }
     // pour chaque calendrier du widget //
     // tableau JS >> 0:nom jeedom / 1:type de vue / 2:date de mise à jour / 3:valeur affichée / 4:titre google / 5:url / 6:nb évènement //
     $nbCalRefresh = 0;
     foreach ($this->getCmd('info') as $cmdGCal) {
         if ($cmdGCal->getIsVisible()) {
             if (($_sEvents = $cmdGCal->execCmd()) != '') {
                 // génère le format en fonction de la vue //
                 if ($cmdGCal->getConfiguration('viewStyle') != 'current_titleOnly') {
                     $_aEvents = explode('||', $_sEvents);
                     $nbEvent = $cmdGCal->getConfiguration('defaultValue', GCALENDAR_TXT_DV) != $_sEvents ? count($_aEvents) : 0;
                     if ($nbEvent > 0) {
                         // pour chaque événement //
                         for ($i = 0; $i < count($_aEvents); $i++) {
                             $_aOneEvent = explode(';', $_aEvents[$i]);
                             // définit les valeurs à afficher : heure //
                             $_sEventHours = "<span class='gCalendar_hour'>(" . $_aOneEvent[0] . "-" . $_aOneEvent[1] . ")</span>";
                             if ($cmdGCal->getConfiguration('showHour') == 0) {
                                 $_sEventHours = "";
                             } else {
                                 if ($cmdGCal->getConfiguration('showHour24H') == 0 && $_aOneEvent[0] == "00:00" && $_aOneEvent[1] == "23:59") {
                                     $_sEventHours = "";
                                 }
                             }
                             // état //
                             if ($_aOneEvent[2] == 'DA') {
                                 $_sEventState = " <i class='fa fa-plus-circle' title='" . __('évènement actif: 1ère minute', __FILE__) . "' style='color:#FF0000;'></i>";
                             } elseif ($_aOneEvent[2] == 'FA') {
                                 $_sEventState = " <i class='fa fa-ban' title='" . __('évènement actif: dernière minute', __FILE__) . "' style='color:#FF0000;'></i>";
                             } elseif ($_aOneEvent[2] == 'A') {
                                 $_sEventState = " <i class='fa fa-check-circle-o' title='" . __('évènement actif', __FILE__) . "' style='color:#0000FF;'></i>";
                             } else {
                                 $_sEventState = "";
                             }
                             // titre //
                             $_sEventTxt = $_aOneEvent[3];
                             // gestion des scénarios //
                             if ($this->getConfiguration('acceptLaunchSc') == '1') {
                                 if ($_aOneEvent[4] == 'S' && $_aOneEvent[3] >= 1) {
                                     $_oSc = scenario::byId($_aOneEvent[3]);
                                     //log::add('gCalendar', 'debug', '[' . $this->getId() . '] toHtml() object scenario='.print_r($_oSc,true));
                                     if ($_oSc !== false) {
                                         $_aOneEvent[5] = $_aOneEvent[5] != '' ? ' (' . $_aOneEvent[5] . ')' : '';
                                         $_aOneEvent[7] = $_aOneEvent[7] != '' ? __('1er min', __FILE__) . '=' . $_aOneEvent[7] . ' | ' : '';
                                         $_aOneEvent[8] = $_aOneEvent[8] != '' ? __('dern. min', __FILE__) . '=' . $_aOneEvent[8] : '';
                                         if ($_version == 'mobile') {
                                             $_sIcon = "<i class='fa fa-cogs'></i> ";
                                         } else {
                                             $_sIcon = "<a href='index.php?v=d&p=scenario&id=" . $_aOneEvent[3] . "'><i class='fa fa-cogs' title='" . __('éditer le scénario', __FILE__) . "'></i></a> ";
                                         }
                                         $_sEventTxt = $_sIcon . '<span title="' . $_aOneEvent[7] . $_aOneEvent[8] . '">' . $_oSc->getName() . '</span>' . $_aOneEvent[5];
                                     } else {
                                         log::add('gCalendar', 'error', '[' . $this->getId() . '|' . $cmdGCal->getId() . '] toHtml().sc=' . $_aOneEvent[3] . ' ' . __("l'id du scénario n'existe pas, merci de vérifier.", __FILE__));
                                     }
                                 } else {
                                     $_sEventTxt = str_replace('{ERR}', "<span title='" . __('Erreur dans le format de la trame', __FILE__) . "'>{ERR}</span>", $_aOneEvent[3]);
                                 }
                             } else {
                                 // titre //
                                 if ($_aOneEvent[4] == 'S') {
                                     $_sEventTxt = 'sc=' . $_aOneEvent[3] . ';' . $_aOneEvent[5] . ';' . $_aOneEvent[6] . ';' . $_aOneEvent[7] . ';' . $_aOneEvent[8];
                                 }
                             }
                             if ($_version == 'mobile') {
                                 if ($_aOneEvent[2] == 'P') {
                                     $_aEvents[$i] = '';
                                     $nbEvent--;
                                 } else {
                                     $_aEvents[$i] = "<div class='gCalendar_itemActif'>" . $_sEventHours . $_sEventState . " " . $_sEventTxt . "</div>";
                                 }
                             } else {
                                 if ($i < count($_aEvents) - 1) {
                                     $_sBorder = 'border-bottom:1px solid #DDDDDD;';
                                 } else {
                                     $_sBorder = '';
                                 }
                                 if ($_aOneEvent[2] == 'P') {
                                     $_aEvents[$i] = "<div class='gCalendar_itemInactif' style='font-style:italic;color:#BBBBBB;" . $_sBorder . "'>" . $_sEventHours . $_sEventState . " " . $_sEventTxt . "</div>";
                                 } else {
                                     $_aEvents[$i] = "<div class='gCalendar_itemActif' style='" . $_sBorder . "'>" . $_sEventHours . $_sEventState . " " . $_sEventTxt . "</div>";
                                 }
                             }
                         }
                         $_sEvents = implode('', $_aEvents);
                     } else {
                         if ($_version == 'mobile') {
                             $_sEvents = "<div class='gCalendar_itemInactif'>" . $_sEvents . "</div>";
                         } else {
                             $_sEvents = "<span class='gCalendar_itemInactif'>" . $_sEvents . "</span>";
                         }
                     }
                 } else {
                     $nbEvent = $cmdGCal->getConfiguration('defaultValue', GCALENDAR_TXT_DV) != $_sEvents ? count(explode(' - ', $_sEvents)) : 0;
                     if ($_version == 'mobile') {
                         $_sEvents = "<div class='gCalendar_itemActif'>" . $_sEvents . "</div>";
                     } else {
                         $_sEvents = "<div class='gCalendar_itemActif'>" . $_sEvents . "</div>";
                     }
                 }
                 $_sEvents = str_replace('"', '\\"', $_sEvents);
                 $replace['#gCalArray#'] .= ',["' . str_replace('"', '\\"', $cmdGCal->getName()) . '", "' . $cmdGCal->getConfiguration('viewStyle') . '", "' . $cmdGCal->getCollectDate() . '", "' . $_sEvents . '", "' . str_replace('"', '\\"', $cmdGCal->getConfiguration('_sGCalTitle')) . '", "' . str_replace('"', '\\"', $cmdGCal->getConfiguration('_sGCalUrlCalendar')) . '", "' . $nbEvent . '"]';
                 $nbCalRefresh++;
             }
         }
     }
     $parameters = $this->getDisplay('parameters');
     if (is_array($parameters)) {
         foreach ($parameters as $key => $value) {
             $replace['#' . $key . '#'] = $value;
         }
     }
     log::add('gCalendar', 'debug', '[' . $this->getId() . '] toHtml().replace=' . print_r($replace, true));
     $html = template_replace($replace, getTemplate('core', $_version, 'gCalendar', 'gCalendar'));
     cache::set('gcalendarWidget' . $_version . $this->getId(), $html, 0);
     log::add('gCalendar', 'info', '[' . $this->getId() . '] toHtml(' . $_version . ') Refresh Widget (' . $nbCalRefresh . ' cal.): OK');
     return $html;
 }