propise.plugin.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. <?php
  2. /*
  3. @name Sonde ( modèle Poolp )
  4. @author Valentin CARRUESCO <idleman@idleman.fr>
  5. @link http://blog.idleman.fr
  6. @licence CC by nc sa
  7. @version 1.0.0
  8. @description Permet la récuperations d'informations de temperatures, humidités, lumière, mouvement et sons dans une pièce a travers la sonde yana "poolp"
  9. */
  10. function propise_vocal_command(&$response,$actionUrl){
  11. global $conf;
  12. $response['commands'][] = array(
  13. 'command'=>$conf->get('VOCAL_ENTITY_NAME').' diagnostique de la pièce',
  14. 'callback'=>'propise_diagnostic',
  15. 'confidence'=>0.8);
  16. }
  17. function propise_diagnostic($text,$confidence,$parameters,$myUser){
  18. global $conf;
  19. require_once('Sensor.class.php');
  20. require_once('Data.class.php');
  21. $data = new Data();
  22. $sensor = Sensor::load(array('location'=>$text));
  23. $data = Data::load(array('sensor'=>$sensor->id));
  24. $cli = new Client();
  25. $cli->connect();
  26. $cli->talk("Diagnostique pièce : ".$text);
  27. $cli->talk("Humidité : ".$data->humidity
  28. .", température : ".$data->temperature
  29. .", Luminosité : ".$data->temperature
  30. ."%, mouvement : ".$data->mouvment
  31. );
  32. $cli->disconnect();
  33. }
  34. function propise_action(){
  35. global $_,$conf;
  36. switch($_['action']){
  37. case 'propise_save_sensor':
  38. Action::write(
  39. function($_,&$response){
  40. require_once('Sensor.class.php');
  41. if(empty($_['labelSensor'])) throw new Exception("Le nom est obligatoire");
  42. $sensor = !empty($_['id']) ? Sensor::getById($_['id']): new Sensor();
  43. $sensor->label = $_['labelSensor'];
  44. $sensor->location = $_['locationSensor'];
  45. $sensor->save();
  46. //Reference device for other plugins
  47. $device = new Device();
  48. $device->label = $sensor->label;
  49. $device->plugin = 'propise';
  50. $device->type = Device::CAPTOR;
  51. $device->location = $sensor->location;
  52. $device->icon = 'fa-heartbeat';
  53. $device->setValue('humidity',0);
  54. $device->setValue('temperature',0);
  55. $device->setValue('light',0);
  56. $device->setValue('mouvment',0);
  57. $device->setValue('sound',0);
  58. $device->state = 1;
  59. $device->uid = $sensor->id;
  60. $device->save();
  61. $response['message'] = 'Sonde enregistrée avec succès';
  62. },
  63. array('propise'=>'c')
  64. );
  65. break;
  66. case 'propise_delete_sensor':
  67. Action::write(
  68. function($_,$response){
  69. require_once('Sensor.class.php');
  70. Data::delete(array('sensor'=>$_['id']));
  71. Sensor::deleteById($_['id']);
  72. },
  73. array('propise'=>'d')
  74. );
  75. break;
  76. case 'propise_get_data':
  77. Action::write(
  78. function($_,&$response){
  79. require_once('Sensor.class.php');
  80. require_once('Data.class.php');
  81. $datas = Data::loadAll(array('sensor'=>$_['id']),'time DESC');
  82. $response['light'] = propise_convert_light($datas[0]->light);
  83. $response['humidity'] = $datas[0]->humidity;
  84. $response['temperature'] = $datas[0]->temperature;
  85. $response['mouvment'] = $datas[0]->mouvment;
  86. },
  87. array('propise'=>'r') );
  88. break;
  89. case 'propise_add_data':
  90. require_once('Sensor.class.php');
  91. require_once('Data.class.php');
  92. $sensor = Sensor::getById($_['id']);
  93. if($sensor == null || $sensor->id==0) return;
  94. $sensor->ip = $_['ip'];
  95. $sensor->save();
  96. $data = new Data();
  97. $data->time = time();
  98. $data->humidity = $_['humidity'];
  99. $data->temperature = $_['temperature'];
  100. $data->light = $_['light'];
  101. $data->mouvment = $_['mouvment'];
  102. $data->sensor = $sensor->id;
  103. $data->save();
  104. echo '1';
  105. break;
  106. case 'propise_select_widget_menu':
  107. require_once(__DIR__.'/../dashboard/Widget.class.php');
  108. Action::write(
  109. function($_,&$response){
  110. $widget = new Widget();
  111. $widget = $widget->getById($_['id']);
  112. $data = $widget->data();
  113. $data['menu'] = $_['menu'];
  114. $widget->data($data);
  115. $widget->save();
  116. });
  117. break;
  118. case 'propise_load_widget':
  119. require_once(__DIR__.'/../dashboard/Widget.class.php');
  120. Action::write(
  121. function($_,&$response){
  122. $widget = new Widget();
  123. $widget = $widget->getById($_['id']);
  124. $parameters = $widget->data();
  125. if(empty($parameters['sensor'])){
  126. $content = 'Choisissez une localisation en cliquant sur l \'icone <i class="fa fa-wrench"></i> de la barre du widget';
  127. }else{
  128. global $conf;
  129. require_once('Data.class.php');
  130. require_once('Sensor.class.php');
  131. $sensor = Sensor::getById($parameters['sensor']);
  132. $datas = Data::loadAll(array('sensor'=>$sensor->id),'time DESC',1);
  133. $response['title'] = $sensor->label;
  134. $content = '
  135. <!-- CSS -->
  136. <style>
  137. .propise_menu{
  138. margin:0;
  139. }
  140. .propise_menu li{
  141. cursor: pointer;
  142. display: inline-block;
  143. font-size: 20px;
  144. height: 25px;
  145. margin-top: 3px;
  146. padding: 5px 5px 0 5px;
  147. text-align: center;
  148. color:#222222;
  149. transition: all 0.2s ease-in-out 0s;
  150. width: 30px;
  151. border-top:4px solid #222222;
  152. }
  153. .propise_menu li:hover{
  154. background:#222222;
  155. color:#ffffff;
  156. }
  157. .propise_view{
  158. background:#222222;
  159. color:#ffffff;
  160. margin:0px;
  161. padding:0px;
  162. width:100%;
  163. list-style-type:none;
  164. transition:all 0.2s ease-in-out;
  165. box-sizing: border-box;
  166. }
  167. .propise_view ul{
  168. padding:0;
  169. margin:0;
  170. }
  171. .propise_view li i{
  172. font-size:40px;
  173. }
  174. .propise_view li{
  175. font-family: "Open Sans Light",sans-serif;
  176. text-align:center;
  177. padding:30px 15px 15px 15px;
  178. list-style-type:none;
  179. float:left;
  180. height: 100px;
  181. width:50%;
  182. box-sizing:border-box;
  183. font-weight:300;
  184. font-size:30px;
  185. }
  186. .propise_view.propise_detail_view li{
  187. font-size:60px;
  188. width:100%;
  189. height:140px;
  190. font-size:50px;
  191. padding:40px 0 40px 0;
  192. float:none;
  193. }
  194. .propise_menu li[data-view="temperature"]{
  195. border-color:#36B3E1;
  196. }
  197. .propise_menu li[data-view="humidity"]{
  198. border-color:#50597B;
  199. }
  200. .propise_menu li[data-view="light"]{
  201. border-color:#EF4D66;
  202. }
  203. .propise_menu li[data-view="mouvment"]{
  204. border-color:#FFBF4C;
  205. }
  206. .propise_menu li[data-view="stats"]{
  207. border-color:#b3e021;
  208. }
  209. .propise_view li[data-type="temperature"]{
  210. background-color:#36B3E1;
  211. border-color:#36B3E1;
  212. }
  213. .propise_view li[data-type="humidity"]{
  214. background-color:#50597B;
  215. border-color:#50597B;
  216. }
  217. .propise_view li[data-type="light"]{
  218. background-color:#EF4D66;
  219. border-color:#EF4D66;
  220. }
  221. .propise_view li[data-type="mouvment"]{
  222. background-color:#FFBF4C;
  223. border-color:#FFBF4C;
  224. }
  225. .propise_view li[data-type="propise_stats"]{
  226. background-color:#C1004F;
  227. border-color:#C1004F;
  228. }
  229. </style>
  230. <!-- HTML -->
  231. ';
  232. $content .= '<div class="propise_widget" data-view="'.$parameters['menu'].'" data-id="'.$sensor->id.'">
  233. <div class="propise_view">
  234. <ul>
  235. <li data-type="light"><i class="fa fa-sun-o fa-spin-low"></i> <span ></span>%</li>
  236. <li data-type="temperature"><i class="fa fa-fire"></i> <span ></span>°</li>
  237. <li data-type="humidity"><i class="fa fa-tint"></i> <span ></span>%</li>
  238. <li data-type="mouvment"><i class="fa fa-eye"></i> <span ></span></li>
  239. </ul>
  240. <div class="clear"></div>
  241. ';
  242. $content .= '</div>';
  243. $content .= '<ul class="propise_menu">';
  244. $content .= '<li class="propise_global" onclick="propise_menu(this)" data-view=""><i class="fa fa-columns"></i></li>';
  245. $content .= '<li onclick="propise_menu(this)" data-view="light"><i class="fa fa-sun-o"></i></li>';
  246. $content .= '<li onclick="propise_menu(this)" data-view="temperature"><i class="fa fa-fire"></i></li>';
  247. $content .= '<li onclick="propise_menu(this)" data-view="humidity"><i class="fa fa-tint"></i></li>';
  248. $content .= '<li onclick="propise_menu(this)" data-view="mouvment"><i class="fa fa-eye"></i></li>';
  249. $content .= '<li onclick="window.open(\'index.php?module=propise&section=stats&id='.$sensor->id.'\')" data-view="stats"><i class="fa fa-line-chart"></i></li>';
  250. $content .= '</ul>';
  251. $content .= '</div>';
  252. $content .= '
  253. <!-- JS -->
  254. <script type="text/javascript">
  255. $("document").ready(function(){
  256. propise_refresh_data();
  257. setInterval(propise_refresh_data,5000);
  258. });
  259. function propise_refresh_data(){
  260. $(".propise_widget[data-id='.$sensor->id.']").each(function(i,element){
  261. var view = $(element).attr("data-view");
  262. if(view != $(element).attr("data-selected")){
  263. propise_show($(element),view);
  264. console.log("ee");
  265. }
  266. $.action({
  267. action:"propise_get_data",
  268. id:$(element).attr("data-id")
  269. },function(r){
  270. for(var key in r){
  271. var type = $(\'li[data-type="\'+key+\'"]\');
  272. if( key.length ==0 ) continue;
  273. $("span",type).html(r[key]);
  274. }
  275. var mouvment = $("[data-type=\'mouvment\']");
  276. $("i",mouvment).attr("class","fa fa-eye"+($("span",mouvment).text()==1?"":"-slash"));
  277. });
  278. });
  279. }
  280. function propise_menu(element,global){
  281. var line = $(element);
  282. var container = line.closest(".propise_widget");
  283. var view = $(element).attr("data-view");
  284. var widget = $(element).closest(\'.dashboard_bloc\').attr(\'data-id\');
  285. $(container).attr("data-view",view);
  286. $.action({
  287. action:"propise_select_widget_menu",
  288. id:widget,
  289. menu: view
  290. });
  291. propise_show(container,view);
  292. };
  293. function propise_show(container,view){
  294. $(container).attr("data-selected",view);
  295. if(view==\'\'){
  296. $(".propise_view ul li",container).fadeIn();
  297. $(".propise_view",container).removeClass("propise_detail_view")
  298. return;
  299. }
  300. $(".propise_view",container).addClass("propise_detail_view")
  301. $(".propise_view ul li",container).hide();
  302. $(".propise_view").css("background-color",$(".propise_view ul li[data-view=\'"+view+"\']",container).css("border-top-color"));
  303. $(".propise_view ul li[data-type=\'"+view+"\']",container).fadeIn();
  304. }
  305. </script>
  306. ';
  307. }
  308. $response['content'] = $content;
  309. }
  310. );
  311. break;
  312. case 'propise_edit_widget':
  313. require_once(dirname(__FILE__).'/../dashboard/Widget.class.php');
  314. require_once(dirname(__FILE__).'/Sensor.class.php');
  315. $widget = new Widget();
  316. $widget = $widget->getById($_['id']);
  317. $data = $widget->data();
  318. $sensor = new Sensor();
  319. $sensors = $sensor->populate();
  320. $content = '<h3>Choix de la sonde</h3>';
  321. if(count($sensors) == 0):
  322. $content = 'Aucune sonde enregistrée,<a href="setting.php?section=propise">enregistrer une sonde<a>';
  323. else :
  324. $content .= '<select id="sensor">';
  325. foreach($sensors as $sensor)
  326. $content .= '<option '.($sensor->id==$data['sensor']?'selected="selected"':'').' value="'.$sensor->id.'">'.$sensor->label.' ('.$sensor->uid.')</option>';
  327. $content .= '</select>';
  328. endif;
  329. echo $content;
  330. break;
  331. case 'propise_save_widget':
  332. require_once(dirname(__FILE__).'/../dashboard/Widget.class.php');
  333. $widget = new Widget();
  334. $widget = $widget->getById($_['id']);
  335. $data = $widget->data();
  336. $data['sensor'] = $_['sensor'];
  337. $widget->data($data);
  338. $widget->save();
  339. echo $content;
  340. break;
  341. }
  342. }
  343. function propise_convert_light($light){
  344. return round(($light*100)/1024,1);
  345. }
  346. function propise_plugin_setting_page(){
  347. global $_,$myUser,$conf;
  348. if(isset($_['section']) && $_['section']=='propise' ){
  349. require_once('Data.class.php');
  350. require_once('Sensor.class.php');
  351. if(!$myUser) throw new Exception('Vous devez être connecté pour effectuer cette action');
  352. $sensorManager = new Sensor();
  353. $sensors = $sensorManager->populate();
  354. $roomManager = new Room();
  355. $rooms = $roomManager->loadAll(array('state'=>'0'));
  356. $selected = new Sensor();
  357. //Si on est en mode modification
  358. if (isset($_['id']))
  359. $selected = $sensorManager->getById($_['id']);
  360. ?>
  361. <div class="span9 userBloc">
  362. <h1>Sondes Poolp</h1>
  363. <p>Gestion des multi-sondes</p>
  364. <fieldset>
  365. <legend>Ajouter/Modifier une sonde</legend>
  366. <div class="left">
  367. <label for="labelSensor">Nom</label>
  368. <input type="hidden" id="id" value="<?php echo $selected->id; ?>">
  369. <input type="text" id="labelSensor" value="<?php echo $selected->label; ?>" placeholder="Sonde du salon"/>
  370. <!-- <label for="uidSensor">UID</label>
  371. <input type="text" value="<?php echo $selected->uid; ?>" id="uidSensor" placeholder="sonde-1,sonde-2..." />
  372. -->
  373. <label for="locationSensor">Pièce de la maison</label>
  374. <select id="locationSensor">
  375. <?php foreach($rooms as $room){ ?>
  376. <option <?php if ($selected->location == $room->getId()){echo "selected";} ?> value="<?php echo $room->getId(); ?>"><?php echo $room->getName(); ?></option>
  377. <?php } ?>
  378. </select>
  379. </div>
  380. <div class="clear"></div>
  381. <br/><button onclick="plugin_propise_save(this)" class="btn">Enregistrer</button>
  382. </fieldset>
  383. <br/>
  384. <fieldset>
  385. <legend>Consulter les sondes existants</legend>
  386. <table class="table table-striped table-bordered table-hover">
  387. <thead>
  388. <tr>
  389. <th>Nom</th>
  390. <th>UID</th>
  391. <th>Pièce</th>
  392. <th>A copier dans la sonde</th>
  393. <th colspan="2"></th>
  394. </tr>
  395. </thead>
  396. <?php foreach($sensors as $sensor){
  397. $room = $roomManager->load(array('id'=>$sensor->location));
  398. ?>
  399. <tr>
  400. <td><?php echo $sensor->label; ?></td>
  401. <td><?php echo $sensor->uid; ?></td>
  402. <td><?php echo $room->getName(); ?></td>
  403. <td>
  404. <a onclick="$(this).next().toggle()" class="btn">Guide Installation</a>
  405. <ul style="display:none;">
  406. <li>Démarrer la sonde en appuyant sur le boutton jusqu'a ce que la lumière s'allume en bleu</li>
  407. <li>Se connecter au wifi de la sonde (PROPISE-XX) avec le mot de passe bananeflambee</li>
  408. <li>Ouvrir l'interface de la sonde sur <a href="http://192.168.4.1">http://192.168.4.1</a></li>
  409. <li>Remplir les identifiant WIFI de votre réseau</li>
  410. <li>Dans le dernier champs, mettre le lien suivant :
  411. <?php
  412. $url = YANA_URL.'/action.php?action=propise_add_data&id='.$sensor->id.'&light={{LIGHT}}&humidity={{HUMIDITY}}&temperature={{TEMPERATURE}}&mouvment={{MOUVMENT}}';
  413. echo '<a href="'.$url.'">'.$url.'</a>'; ?>
  414. </li>
  415. </ul>
  416. </td>
  417. <td>
  418. <a class="btn" href="setting.php?section=propise&id=<?php echo $sensor->id; ?>"><i class="fa fa-pencil"></i></a>
  419. <div class="btn" onclick="plugin_propise_delete(<?php echo $sensor->id; ?>,this);"><i class="fa fa-times"></i></div>
  420. </td>
  421. </td>
  422. </tr>
  423. <?php } ?>
  424. </table>
  425. </fieldset>
  426. </div>
  427. <?php
  428. }
  429. }
  430. function propise_plugin_setting_menu(){
  431. global $_;
  432. echo '<li '.(isset($_['section']) && $_['section']=='propise'?'class="active"':'').'><a href="setting.php?section=propise"><i class="fa fa-angle-right"></i> Sondes (Poolp)</a></li>';
  433. }
  434. function propise_plugin_page($_){
  435. if(!isset($_['module']) || $_['module']!='propise') return;
  436. require_once('Sensor.class.php');
  437. require_once('Data.class.php');
  438. $sensor = Sensor::getById($_['id']);
  439. $datas = Data::staticQuery('SELECT * FROM "yana_plugin_propise_data" WHERE time > strftime(\'%s\', \'now\') - 3600 ORDER BY time',array(),true);
  440. $tab = array('hours'=>array(),'temperature'=>array(),'humidity'=>array(),'light'=>array());
  441. foreach($datas as $data){
  442. if(date('i',$data->time) == "") continue;
  443. $tab['hours'][date('dmYHi',$data->time)] = date('H:i',$data->time);
  444. $tab['temperature'][date('dmYHi',$data->time)] =$data->temperature;
  445. $tab['humidity'][date('dmYHi',$data->time)]=$data->humidity;
  446. $tab['light'] [date('dmYHi',$data->time)]=$data->light;
  447. $tab['mouvment'] [date('dmYHi',$data->time)]=$data->mouvment;
  448. }
  449. ?>
  450. <h3>Température</h3>
  451. <canvas style="width:100%;" id="chart_temperature" data-label="Temperature" data-hours="<?php echo '[\''.implode('\',\'',$tab['hours']).'\']'; ?>" data-data="<?php echo '['.implode(',',$tab['temperature']).']'; ?>"></canvas>
  452. <h3>Humidité</h3>
  453. <canvas style="width:100%;" id="chart_humidity" data-label="Humidité" data-hours="<?php echo '[\''.implode('\',\'',$tab['hours']).'\']'; ?>" data-data="<?php echo '['.implode(',',$tab['humidity']).']'; ?>" ></canvas>
  454. <h3>Lumière</h3>
  455. <canvas style="width:100%;" id="chart_light" data-label="Lumière" data-hours="<?php echo '[\''.implode('\',\'',$tab['hours']).'\']'; ?>" data-data="<?php echo '['.implode(',',$tab['light']).']'; ?>"></canvas>
  456. <h3>Mouvement</h3>
  457. <canvas style="width:100%;" id="chart_mouvment" data-label="Mouvement" data-hours="<?php echo '[\''.implode('\',\'',$tab['hours']).'\']'; ?>" data-data="<?php echo '['.implode(',',$tab['mouvment']).']'; ?>"></canvas>
  458. <?php
  459. }
  460. function propise_plugin_widget(&$widgets){
  461. $widgets[] = array(
  462. 'uid' => 'dash_propise',
  463. 'icon' => 'fa fa-tint',
  464. 'label' => 'Sonde Poolp',
  465. 'background' => '#ffffff',
  466. 'color' => '#222222',
  467. 'onLoad' => 'action.php?action=propise_load_widget',
  468. 'onEdit' => 'action.php?action=propise_edit_widget',
  469. 'onSave' => 'action.php?action=propise_save_widget',
  470. );
  471. }
  472. Plugin::addJs("/js/main.js");
  473. //Lie wireRelay_plugin_setting_page a la zone réglages
  474. Plugin::addHook("setting_bloc", "propise_plugin_setting_page");
  475. //Lie wireRelay_plugin_setting_menu au menu de réglages
  476. Plugin::addHook("setting_menu", "propise_plugin_setting_menu");
  477. Plugin::addHook("action_post_case", "propise_action");
  478. Plugin::addHook("vocal_command", "propise_vocal_command");
  479. Plugin::addHook("widgets", "propise_plugin_widget");
  480. Plugin::addHook("home", "propise_plugin_page");
  481. ?>