index.html 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>MiLight Hub</title>
  6. <meta name="description" content="The HTML5 Herald">
  7. <meta name="author" content="SitePoint">
  8. <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
  9. <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
  10. <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.0/css/bootstrap-slider.min.css" rel="stylesheet"/>
  11. <!--[if lt IE 9]>
  12. <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
  13. <![endif]-->
  14. <style>
  15. .header-row { border-bottom: 1px solid #ccc; }
  16. label { display: block; }
  17. .radio-option { padding: 0 5px; cursor: pointer; }
  18. .command-buttons { list-style: none; margin: 0; padding: 0; }
  19. .command-buttons li { display: inline-block; margin-right: 1em; }
  20. .btn-secondary {
  21. background-color: #fff;
  22. border: 1px solid #ccc;
  23. }
  24. .hue-picker {
  25. height: 2em;
  26. width: 100%;
  27. display: block;
  28. }
  29. .hue-picker-inner {
  30. height: 2em;
  31. width: calc(100% - 3em);
  32. display: inline-block;
  33. cursor: pointer;
  34. background: linear-gradient(to right,
  35. rgb(255, 0, 0) 0%,
  36. rgb(255, 255, 0) 16.6667%,
  37. rgb(0, 255, 0) 33.3333%,
  38. rgb(0, 255, 255) 50%,
  39. rgb(0, 0, 255) 66.6667%,
  40. rgb(255, 0, 255) 83.3333%,
  41. rgb(255, 0, 0) 100%
  42. );
  43. }
  44. .hue-value-display {
  45. border: 1px solid #000;
  46. margin-left: 0.5em;
  47. width: 2em;
  48. height: 2em;
  49. display: inline-block;
  50. }
  51. </style>
  52. </head>
  53. <body>
  54. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  55. <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  56. <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
  57. <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
  58. <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.7.0/bootstrap-slider.min.js"></script>
  59. <script lang="text/javascript">
  60. var activeUrl = function() {
  61. return "/gateways/" +
  62. $('input[name="deviceId"]').val() +
  63. "/" +
  64. $('#groupId input:checked').data('value');
  65. }
  66. var updateGroup = _.throttle(
  67. function(params) {
  68. $.ajax(
  69. activeUrl(),
  70. {
  71. method: 'PUT',
  72. data: JSON.stringify(params),
  73. contentType: 'application/json'
  74. }
  75. );
  76. },
  77. 1000
  78. );
  79. var sniffRequest;
  80. var sniffing = false;
  81. var getTraffic = function() {
  82. sniffRequest = $.get('/gateway_traffic', function(data) {
  83. $('#sniffed-traffic').html(data + $('#sniffed-traffic').html());
  84. getTraffic();
  85. });
  86. };
  87. $(function() {
  88. $('.radio-option').click(function() {
  89. $(this).prev().prop('checked', true);
  90. });
  91. var hueDragging = false;
  92. var colorUpdated = function(e) {
  93. var x = e.pageX - $(this).offset().left
  94. , pct = x/(1.0*$(this).width())
  95. , hue = Math.round(360*pct)
  96. ;
  97. $('.hue-value-display').css({
  98. backgroundColor: "hsl(" + hue + ",100%,50%)"
  99. });
  100. updateGroup({hue: hue});
  101. };
  102. $('.hue-picker-inner')
  103. .mousedown(function(e) {
  104. hueDragging = true;
  105. colorUpdated.call(this, e);
  106. })
  107. .mouseup(function(e) {
  108. hueDragging = false;
  109. })
  110. .mouseout(function(e) {
  111. hueDragging = false;
  112. })
  113. .mousemove(function(e) {
  114. if (hueDragging) {
  115. colorUpdated.call(this, e);
  116. }
  117. });
  118. $('.slider').slider();
  119. $('.raw-update').change(function() {
  120. var data = {}
  121. , val = $(this).attr('type') == 'checkbox' ? $(this).is(':checked') : $(this).val()
  122. ;
  123. data[$(this).attr('name')] = val;
  124. updateGroup(data);
  125. });
  126. $('.command-btn').click(function() {
  127. updateGroup({command: $(this).data('command')});
  128. });
  129. $('#sniff').click(function() {
  130. if (sniffing) {
  131. sniffRequest.abort();
  132. sniffing = false;
  133. $(this).html('Start Sniffing');
  134. } else {
  135. sniffing = true;
  136. getTraffic();
  137. $(this).html('Stop Sniffing');
  138. }
  139. });
  140. });
  141. </script>
  142. <div class="container">
  143. <div class="row header-row">
  144. <div class="col-sm-12">
  145. <h1>
  146. Control Lights
  147. </h1>
  148. </div>
  149. </div>
  150. <div>&nbsp;</div>
  151. <div class="row">
  152. <div class="col-sm-4">
  153. <label for="deviceId">Device Id</label>
  154. <input type="text" class="input" name="deviceId" />
  155. </div>
  156. <div class="col-sm-8">
  157. <label for="groupId">Group</label>
  158. <div class="btn-group" id="groupId" data-toggle="buttons">
  159. <label class="btn btn-secondary active">
  160. <input type="radio" name="options" autocomplete="off" data-value="1" checked> 1
  161. </label>
  162. <label class="btn btn-secondary">
  163. <input type="radio" name="options" autocomplete="off" data-value="2"> 2
  164. </label>
  165. <label class="btn btn-secondary">
  166. <input type="radio" name="options" autocomplete="off" data-value="3"> 3
  167. </label>
  168. <label class="btn btn-secondary">
  169. <input type="radio" name="options" autocomplete="off" data-value="4"> 4
  170. </label>
  171. </div>
  172. </div>
  173. </div>
  174. <div class="row">
  175. <div class="col-sm-12">
  176. <h5>Hue</h5>
  177. </div>
  178. </div>
  179. <div class="row">
  180. <div class="col-sm-6">
  181. <span class="hue-picker">
  182. <span class="hue-picker-inner"></span>
  183. <span class="hue-value-display"></span>
  184. </span>
  185. </div>
  186. </div>
  187. <div class="row">
  188. <div class="col-sm-6">
  189. <h5>Brightness</h5>
  190. </div>
  191. </div>
  192. <div class="row">
  193. <div class="col-sm-12">
  194. <input class="slider raw-update" name="level"
  195. data-slider-min="0"
  196. data-slider-max="100"
  197. data-slider-value="100"
  198. />
  199. </div>
  200. </div>
  201. <div class="row">
  202. <div class="col-sm-12">
  203. <h5>Commands</h5>
  204. </div>
  205. </div>
  206. <div class="row">
  207. <div class="col-sm-12">
  208. <ul class="command-buttons">
  209. <li>
  210. <input type="checkbox" name="status" class="raw-update" data-toggle="toggle" checked/>
  211. </li>
  212. <li>
  213. <button type="button" class="btn btn-secondary command-btn" data-command="set_white">White</button>
  214. </li>
  215. <li>
  216. <button type="button" class="btn btn-success command-btn" data-command="pair">
  217. <i class="glyphicon glyphicon-plus"></i>
  218. Pair
  219. </button>
  220. </li>
  221. <li>
  222. <button type="button" class="btn btn-danger command-btn" data-command="unpair">
  223. <i class="glyphicon glyphicon-remove"></i>
  224. Unpair
  225. </button>
  226. </li>
  227. </ul>
  228. </div>
  229. </div>
  230. <div class="row header-row">
  231. <div class="col-sm-12">
  232. <h1>Sniff Traffic</h1>
  233. </div>
  234. </div>
  235. <div>&nbsp;</div>
  236. <div class="row">
  237. <div class="col-sm-12">
  238. <button type="button" id="sniff" class="btn btn-primary">Start Sniffing</button>
  239. <pre id="sniffed-traffic"></pre>
  240. </div>
  241. </div>
  242. </div>
  243. </body>
  244. </html>