Story.class.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <?php
  2. /*
  3. @nom: Story
  4. @auteur: Idleman (idleman@idleman.fr)
  5. @description: Représente un scénario avec ses causes de déclenchement et ses effets associés
  6. */
  7. class Story extends SQLiteEntity{
  8. public $id,$date,$user,$label,$state,$log;
  9. protected $TABLE_NAME = 'plugin_story';
  10. protected $CLASS_NAME = 'Story';
  11. protected $object_fields =
  12. array(
  13. 'id'=>'key',
  14. 'date'=>'string',
  15. 'user'=>'int',
  16. 'label'=>'string',
  17. 'state'=>'int',
  18. 'log'=>'longstring'
  19. );
  20. function __construct(){
  21. parent::__construct();
  22. }
  23. public static function keywords(){
  24. global $myUser,$conf;
  25. $sunrise_time = $conf->get('YANA_LATITUDE') !=''? date_sunrise(time(), SUNFUNCS_RET_TIMESTAMP, $conf->get('YANA_LATITUDE'),$conf->get('YANA_LONGITUDE'), 90, 1):0;
  26. $sunset_time = $conf->get('YANA_LATITUDE') !='' ? date_sunset(time(), SUNFUNCS_RET_TIMESTAMP, $conf->get('YANA_LATITUDE'),$conf->get('YANA_LONGITUDE'), 90, 1):0;
  27. return array(
  28. '{DATE}'=>date('d-m-Y'),
  29. '{YEAR}'=>date('Y'),
  30. '{MONTH}'=>date('m'),
  31. '{DAY}'=>date('d'),
  32. '{HOUR}'=>date('H'),
  33. '{MINUT}'=>date('i'),
  34. '{TIME}'=>time(),
  35. '{USER.LOGIN}'=>$myUser->getLogin(),
  36. '{USER.ID}'=>$myUser->getId(),
  37. '{USER.MAIL}'=>$myUser->getMail(),
  38. '{YANA.URL}'=>YANA_URL,
  39. '{SUNRISE.TIMESTAMP}'=>$sunrise_time,
  40. '{SUNRISE.HOUR}'=>date('H',$sunrise_time),
  41. '{SUNRISE.MINUT}'=>date('i',$sunrise_time),
  42. '{SUNSET.TIMESTAMP}'=>$sunset_time,
  43. '{SUNSET.HOUR}'=>date('H',$sunset_time),
  44. '{SUNSET.MINUT}'=>date('i',$sunset_time)
  45. );
  46. }
  47. public static function check($event=array()){
  48. require_once(dirname(__FILE__).'/Cause.class.php');
  49. global $conf;
  50. self::out('Vérification des scénarios');
  51. $causeManager = new Cause('r');
  52. $storyCauses = $causeManager->loadAll(array());
  53. self::out('Vérification des '.count($storyCauses).' causes');
  54. //$sentence = $conf->get('last_sentence','var');
  55. list($i,$h,$d,$m,$y) = explode('-',date('i-H-d-m-Y'));
  56. $validCauses = array();
  57. if(isset($event['type']))
  58. self::out('Argument d entrée :'.$event['type']);
  59. //self::out('Dernière phrase énoncée : "'.$sentence.'"');
  60. self::out('Date actuelle '.$d.'/'.$m.'/'.$y.' '.$h.':'.$i);
  61. foreach($storyCauses as $storyCause){
  62. self::out("Vérification cause ID : $storyCause->id type : $storyCause->type");
  63. $values = $storyCause->getValues();
  64. switch ($storyCause->type){
  65. case 'listen':
  66. if(!isset($event['type']) || $event['type'] !='sentence') continue;
  67. if($values->value == $event['sentence']){
  68. $validCauses[$storyCause->story][] = $storyCause;
  69. self::out("Phrase correspondante, ajout $storyCause->id aux causes valides");
  70. }else{
  71. self::out("Phrase non correspondante");
  72. }
  73. break;
  74. case 'pin':
  75. if(!isset($event['type']) || $event['type'] !='gpio') continue;
  76. if($values->pin == $event['pin'] && $values->value == $event['state']){
  77. $validCauses[$storyCause->story][] = $storyCause;
  78. self::out("Pin et etat correspondant, ajout $storyCause->id aux causes valides");
  79. }else{
  80. self::out("Pin non correspondant");
  81. }
  82. break;
  83. case 'time':
  84. if ($storyCause->value != $i.'-'.$h.'-'.$d.'-'.$m.'-'.$y) $validate = false;
  85. if ((
  86. ($i == $values->minut || $values->minut == '*') &&
  87. ($h == $values->hour || $values->hour == '*') &&
  88. ($d == $values->day || $values->day == '*') &&
  89. ($m == $values->month || $values->month == '*') &&
  90. ($y == $values->year || $values->year == '*')
  91. )){
  92. self::out("Date correspondante, ajout $storyCause->id aux causes valides");
  93. $validCauses[$storyCause->story][] = $storyCause;
  94. }else{
  95. self::out("Date non correspondante");
  96. }
  97. break;
  98. case 'readvar':
  99. self::out($values->var.' ('.self::parse($values->var).') égale à '.self::parse($values->value).' ?');
  100. if (self::parse($values->var) == self::parse($values->value)) {
  101. $validCauses[$storyCause->story][] = $storyCause;
  102. self::out("Variable correspondante, ajout $storyCause->id aux causes valides");
  103. }else{
  104. self::out("Variable non correspondante");
  105. }
  106. break;
  107. }
  108. }
  109. self::out("Vérification de la somme des causes pour chaques scénario (".count($validCauses)." valides)");
  110. foreach($validCauses as $story=>$causes){
  111. self::out("Scénario ID : $story, ".count($causes)." causes valides.");
  112. if(count($causes) == $causeManager->rowCount(array('story'=>$story))){
  113. self::out("Execution des effets du Scénario ID : $story");
  114. self::execute($story);
  115. }else{
  116. self::out("Non execution des effets du Scénario ID : $story, nombre de causes insuffisantes");
  117. }
  118. }
  119. //$conf->put('last_sentence','','var');
  120. }
  121. public static function parse($value){
  122. global $conf;
  123. $keywords = self::keywords();
  124. $value = str_replace(array_keys($keywords),array_values($keywords),$value);
  125. preg_match_all("/(\{)(.*?)(\})/", $value, $matches, PREG_SET_ORDER);
  126. foreach($matches as $match){
  127. $value = str_replace($match[0],$conf->get($match[2],'var'),$value);
  128. }
  129. return $value;
  130. }
  131. public static function execute($storyId){
  132. global $conf;
  133. $story = new self();
  134. $story = $story->getById($storyId);
  135. $log = '====== Execution '.date('d/m/Y H:i').'======'.PHP_EOL;
  136. try{
  137. $cli = new Client();
  138. $cli->connect();
  139. require_once(dirname(__FILE__).'/Effect.class.php');
  140. $effectManager = new Effect('r');
  141. $effects = $effectManager->loadAll(array('story'=>$story->id),'sort');
  142. $log .= count($effects).' effets à executer'.PHP_EOL;
  143. foreach($effects as $effect){
  144. $data = $effect->getValues();
  145. $log .= '> Execution de l\'effet "'.$effect->type.'"'.PHP_EOL;
  146. try{
  147. switch ($effect->type) {
  148. case 'command':
  149. if($data->target=='server'){
  150. $log .= "\tcommande server lancée : ".self::parse($data->value).PHP_EOL;
  151. $return = System::commandSilent(self::parse($data->value));
  152. $conf->put('cmd_result',$return,'var');
  153. }else{
  154. $log .= "\tcommande client lancée : ".self::parse($data->value).PHP_EOL;
  155. $cli->execute(self::parse($data->value));
  156. }
  157. break;
  158. case 'image':
  159. $log .= "\tImage affichée : ".self::parse($data->value).PHP_EOL;
  160. $cli->image(self::parse($data->value));
  161. break;
  162. case 'var':
  163. $log .= "\tVariable ".$data->var.' définie à : "'.self::parse($data->value).'"'.PHP_EOL;
  164. $conf->put($data->var,self::parse($data->value),'var');
  165. break;
  166. case 'url':
  167. $log .= "\tExecution url ".$data->var.' définie à : "'.self::parse($data->value).'"'.PHP_EOL;
  168. $return = @file_get_contents(html_entity_decode(self::parse($data->value)));
  169. $conf->put('url_result',$return,'var');
  170. break;
  171. case 'gpio':
  172. $log .= "\tChangement GPIO $data->gpio définie à ".self::parse($data->value).PHP_EOL;
  173. $pins = explode(',',$data->gpio);
  174. foreach($pins as $pin)
  175. Gpio::write($pin,self::parse($data->value),true);
  176. break;
  177. case 'sleep':
  178. if(!is_numeric($data->value)) throw new Exception('Pause non numerique, pause annulée');
  179. $log .= "\tPause de ".self::parse($data->value)." secondes".PHP_EOL;
  180. sleep(self::parse($data->value));
  181. break;
  182. case 'talk':
  183. $log .= "\tParole : ".self::parse($data->value).PHP_EOL;
  184. $cli->talk(self::parse($data->value));
  185. break;
  186. case 'emotion':
  187. $log .= "\tEmotion : ".self::parse($data->value).PHP_EOL;
  188. $cli->emotion(self::parse($data->value));
  189. break;
  190. case 'sound':
  191. $log .= "\tSon client : ".self::parse($data->value).PHP_EOL;
  192. $cli->sound(self::parse($data->value));
  193. break;
  194. case 'image':
  195. $log .= "\tImage client : ".self::parse($data->value).PHP_EOL;
  196. $cli->image(self::parse($data->value));
  197. break;
  198. case 'story':
  199. if(!is_numeric($data->value)) throw new Exception('ID scénario non numerique, lancement scénario annulé');
  200. $log .= 'Execution : '.self::parse($data->value).PHP_EOL;
  201. self::execute(self::parse($data->value));
  202. break;
  203. default:
  204. $log .= "\tType effet inconnu : ".PHP_EOL;
  205. break;
  206. }
  207. }catch(Exception $e){
  208. $log .= "\tERREUR : ".$e->getMessage().PHP_EOL;
  209. }
  210. }
  211. $cli->disconnect();
  212. }catch(Exception $e){
  213. self::out('ERREUR : '.$e->getMessage());
  214. $log .= 'ERREUR : '.$e->getMessage().PHP_EOL;
  215. }
  216. $story->log = $log;
  217. $story->save();
  218. }
  219. public static function out($msg){
  220. global $_;
  221. if(!isset($_['mode']) || $_['mode'] != 'verbose') return;
  222. Functions::log($msg);
  223. echo '<pre>'.date('d/m/Y H:i:s').' | '.$msg.PHP_EOL;
  224. }
  225. }
  226. ?>