428 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			428 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html lang="de">
 | |
| <head>
 | |
|     <meta charset="utf-8">
 | |
|     <title>LED-Server :: KJ-intern</title>
 | |
|     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 | |
|     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
 | |
|     <!-- Font Awesome -->
 | |
|     <link rel="stylesheet" href="node_modules/font-awesome/css/font-awesome.min.css">
 | |
|     <!-- Bootstrap core CSS -->
 | |
|     <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
 | |
|     <!-- Material Design Bootstrap -->
 | |
|     <link href="node_modules/bootstrap-material-design/dist/css/bootstrap-material-design.min.css" rel="stylesheet">
 | |
|     <link href="node_modules/jquery-wheelcolorpicker/css/wheelcolorpicker.css" rel="stylesheet">
 | |
| 
 | |
|     <link href="node_modules/jquery-minicolors/jquery.minicolors.css" rel="stylesheet">
 | |
| 
 | |
|     <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
 | |
|     <!--[if lt IE 9]>
 | |
|     <script src="node_modules/html5shiv.min.js/html5shiv.min.js"></script>
 | |
|     <script src="node_modules/respond.min.js/respond.min.js"></script>
 | |
|     <![endif]-->
 | |
|     <style>
 | |
|         .text-nowrap {
 | |
|             white-space: nowrap;
 | |
|         }
 | |
| 
 | |
|         .dimmScreen
 | |
|         {
 | |
|             position:fixed;
 | |
|             padding:0;
 | |
|             margin:0;
 | |
| 
 | |
|             top:0;
 | |
|             left:0;
 | |
| 
 | |
|             width: 100%;
 | |
|             height: 100%;
 | |
|             background:rgba(0, 0, 0, 0.5);
 | |
|         }
 | |
|     </style>
 | |
| </head>
 | |
| <body  ng-app="LED-WebFrontend" ng-controller="LED-ServerCtrl" >
 | |
|     <div style="height: 100vh">
 | |
|         <div class="container">
 | |
|             <!-- Not Connected -->
 | |
|             <div class="row dimmScreen ng-show justify-content-center" ng-hide="connected">
 | |
|                 <div class=" col-md-6 ">
 | |
|                     <div class="row">
 | |
|                         <div class="col-12 mt-3" >
 | |
|                             <div class="card "  >            
 | |
|                                 <!-- Card content -->
 | |
|                                 <div class="card-body justify-content-center">
 | |
|                                     <!-- Title -->
 | |
|                                     <h4 class="card-title infinite animated headShake text-center"><strong>Verbindung wird hergestellt...</strong></h4>
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|             <div class="row ng-hide" ng-show="connected">
 | |
|                 <!--Left Col-->
 | |
|                 <div class="col-md-6 mt-3">
 | |
|                     <div class="row">
 | |
|                         <div class="col-12 mt-3" >
 | |
|                             <div class="card "  >            
 | |
|                                 <!-- Card content -->
 | |
|                                 <div class="card-body ">
 | |
|                                     <!-- Title -->
 | |
|                                     <h4 class="card-title"><strong>Neuen Effekt starten</strong></h4>
 | |
|                                     <form id="startNewEffectThread">
 | |
|                                         <div class="row">
 | |
|                                             <div class="col-12">
 | |
|                                                 <div class="form-group row">
 | |
|                                                     <label for="newEffectThread" class="col-sm-3 col-form-label"> Select Effect: </label><br>
 | |
|                                                     <select ng-change="newEffectThread.params=[]" name="newEffectThread" class="form-control col-sm-7 "  id="newEffectThread" ng-model="newEffectThread.effect" ng-options="effect.index as effect.name for effect in effects" ></select>
 | |
|                                                 </div>
 | |
|                                                 <div class="newEffectThreadDesc">{{effects[newEffectThread.effect].desc}}</div>
 | |
| 
 | |
|                                             </div>
 | |
|                                             <div class="col-12" ng-repeat="effectParam in effects[newEffectThread.effect].effectParams">
 | |
| 
 | |
|                                                 <input ng-if="effectParam.type=='colorpicker'"
 | |
|                                                     minicolors="colorpickerconfig"
 | |
|                                                     class="form-control"
 | |
|                                                     type="text"
 | |
|                                                     ng-init="
 | |
|                                                         newEffectThreadParamColorPicker[effectParam.index]=rgbToHex(
 | |
|                                                             effectParam.options[0][2],
 | |
|                                                             effectParam.options[1][2],
 | |
|                                                             effectParam.options[2][2]
 | |
|                                                         );
 | |
|                                                         newEffectThread.params[effectParam.index] = {};
 | |
|                                                         newEffectThread.params[effectParam.index][0] = hexToRgb(newEffectThreadParamColorPicker[effectParam.index]).r;
 | |
|                                                         newEffectThread.params[effectParam.index][1] = hexToRgb(newEffectThreadParamColorPicker[effectParam.index]).g;
 | |
|                                                         newEffectThread.params[effectParam.index][2] = hexToRgb(newEffectThreadParamColorPicker[effectParam.index]).b
 | |
|                                                     "
 | |
|                                                     ng-change="
 | |
|                                                         newEffectThread.params[effectParam.index][0] = hexToRgb(newEffectThreadParamColorPicker[effectParam.index]).r;
 | |
|                                                         newEffectThread.params[effectParam.index][1] = hexToRgb(newEffectThreadParamColorPicker[effectParam.index]).g;
 | |
|                                                         newEffectThread.params[effectParam.index][2] = hexToRgb(newEffectThreadParamColorPicker[effectParam.index]).b"
 | |
|                                                     ng-model="newEffectThreadParamColorPicker[effectParam.index]"
 | |
|                                                     >
 | |
| 
 | |
|                                                 <mdb-range-input ng-if="effectParam.type=='slider'"
 | |
|                                                     default="true" 
 | |
|                                                     id="range" 
 | |
|                                                     min="{{effectParam.options[0][0]}}"
 | |
|                                                     ng-value="effectParam.options[0][2]"
 | |
|                                                     ng-model="newEffectThread.params[effectParam.index][0]"
 | |
|                                                     max="{{effectParam.options[0][1]}}">
 | |
|                                                 </mdb-range-input>
 | |
|                                                     
 | |
|                                                 {{effectParam}}
 | |
|                                             </div>
 | |
|                                         </div>
 | |
|                                         <div class="row">
 | |
|                                             <div class="col-7 mt-3">
 | |
|                                                 <div class="row">
 | |
|                                                     <div class="col" ng-repeat="rgbStrip in rgbStrips">
 | |
|                                                         <!-- Material unchecked -->
 | |
|                                                         <div class="form-check" >
 | |
|                                                             <input type="checkbox" class="form-check-input" id="newEffectThreadRGBStrips{{rgbStrip.index}}" name="newEffectThreadRGBStrips[]" ng-model="newEffectThread.rgbStrips[rgbStrip.index]"/>
 | |
|                                                             <label class="form-check-label text-nowrap" for="newEffectThreadRGBStrips{{rgbStrip.index}}">{{rgbStrip.name}}</label>
 | |
|                                                         </div>
 | |
|                                                     </div>
 | |
|                                                 </div>
 | |
|                                             </div>
 | |
|                                             <div class="col-5 mt-3">
 | |
|                                                 <!-- Provides extra visual weight and identifies the primary action in a set of buttons --> 
 | |
|                                                 <a href="#" ng-click="startEffect(newEffectThread.effect,newEffectThread.rgbStrips,newEffectThread.params)" class="btn btn-primary float-right">Anwenden</a>
 | |
|                                             </div>
 | |
|                                         </div>
 | |
|                                     </form>
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                         </div>
 | |
|                         <!--Debug!-->
 | |
|                         <div class="col-12 mt-3" ng-show="false">
 | |
|                             <div class="card "  >            
 | |
|                                 <!-- Card content -->
 | |
|                                 <div class="card-body ">
 | |
|                                     <pre>{{rgbStrips | json}}{{effects | json}}{{effectThreads | json}}{{newEffectThread | json}}</pre>
 | |
|                                     
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|                 <!--/Left Col-->
 | |
|                 <!--Right Col-->
 | |
|                 <div class="col-md-6 mt-3">
 | |
|                     <div class="row" >
 | |
|                         <form name="moveRGBStripToEffectThreadForm">
 | |
|                             <div class="col-md-12 mt-3" ng-repeat="effectThread in effectThreads" >
 | |
|                                 <div class="card" >            
 | |
|                                     <!-- Card content -->
 | |
|                                     <div class="card-body ">
 | |
|                                 
 | |
|                                         <!-- Title -->
 | |
|                                         <h4 class="card-title"><strong>{{ effectThread.name }}</strong></h4>
 | |
|                                         <!-- Text -->
 | |
|                                         <p class="card-text">{{ effectThread.desc }}</p>
 | |
|                                         <div class="row">
 | |
|                                             <div class="col-12" ng-repeat="effectParam in effectThread.effectParams">
 | |
|                                                 <input ng-if="effectParam.type=='colorpicker'"
 | |
|                                                     minicolors="colorpickerconfig"
 | |
|                                                     class="form-control"
 | |
|                                                     type="text"
 | |
|                                                     ng-init="
 | |
|                                                         effectThreadParamColorPicker[effectThread.index][effectParam.index]=rgbToHex(
 | |
|                                                             effectParam.values[0],
 | |
|                                                             effectParam.values[1],
 | |
|                                                             effectParam.values[2]
 | |
|                                                         );
 | |
|                                                         effectThreadParamColorPicker[effectThread.index].params[effectParam.index] = {};
 | |
|                                                         effectThreadParamColorPicker[effectThread.index].params[effectParam.index][0] = hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).r;
 | |
|                                                         effectThreadParamColorPicker[effectThread.index].params[effectParam.index][1] = hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).g;
 | |
|                                                         effectThreadParamColorPicker[effectThread.index].params[effectParam.index][2] = hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).b
 | |
|                                                     "
 | |
|                                                     ng-change="
 | |
|                                                         effectThreadParamColorPicker[effectThread.index].params[effectParam.index][0] = hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).r;
 | |
|                                                         effectThreadParamColorPicker[effectThread.index].params[effectParam.index][1] = hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).g;
 | |
|                                                         effectThreadParamColorPicker[effectThread.index].params[effectParam.index][2] = hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).b;
 | |
|                                                         effectThreadChangeEffectParam(effectThread.index,effectThreadParamColorPicker[effectThread.index].params)
 | |
|                                                     "
 | |
| 
 | |
|                                                     ng-model="effectThreadParamColorPicker[effectThread.index][effectParam.index]"
 | |
|                                                     >
 | |
|                                                     {{effectParam.values}}
 | |
| 
 | |
|                                                 <!--
 | |
|                                                 <input ng-if="effectParam.type=='colorpicker'"
 | |
|                                                     minicolors="colorpickerconfig"
 | |
|                                                     id="color-input"
 | |
|                                                     class="form-control"
 | |
|                                                     type="text"
 | |
|                                                     ng-init="effectThreadParamColorPicker[effectThread.index][effectParam.index]=rgbToHex(effectParam.values[0][2],effectParam.values[1][2],effectParam.values[2][2]);"
 | |
|                                                     ng-change="effectThreadChangeEffectParam(effectThread.index,{0: {0: hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).r,1: hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).g, 2: hexToRgb(effectThreadParamColorPicker[effectThread.index][effectParam.index]).b}})"
 | |
|                                                     ng-model="effectThreadParamColorPicker[effectThread.index][effectParam.index]"
 | |
|                                                     >-->
 | |
|                                             </div>
 | |
|                                         </div>
 | |
|                                         <div class="row">
 | |
|                                             <div class="col" ng-repeat="rgbStrip in rgbStrips">
 | |
|                                                 <!-- Material unchecked -->
 | |
|                                                 <div class="form-check" >
 | |
|                                                         <input type="radio" ng-checked="isRGBStripActive(rgbStrip,effectThread.activeRGBStips)" ng-change="moveRGBStripToEffectThread(rgbStrip.index,effectThread.index)" class="form-check-input" id="{{ effectThread.name }}EffectThreadRGBStrip{{rgbStrip.index}}" ng-model="moveRGBStripToEffectThreadModel[rgbStrip.index]" name="{{rgbStrip.index}}" value="{{effect.index}}">
 | |
|                                                         <label class="form-check-label text-nowrap" for="{{ effectThread.name }}EffectThreadRGBStrip{{rgbStrip.index}}">{{rgbStrip.name}}</label>
 | |
|                                                 </div>
 | |
|                                             </div>
 | |
|                                         </div>
 | |
|                                         <p class="card-text">{{effectThread.dump}}</p>
 | |
|                                     </div>
 | |
|                                 </div>   
 | |
|                             </div>
 | |
|                         </form>
 | |
|                     </div>
 | |
|                 </div>
 | |
|                 <!--/Right Col-->
 | |
|             </div>
 | |
|         </div>
 | |
|     </div>
 | |
|     
 | |
|     <!-- SCRIPTS -->
 | |
|     <!-- JQuery -->
 | |
|     <script type="text/javascript" src="node_modules/jquery/dist/jquery.min.js"></script>
 | |
|     <script type="text/javascript" src="node_modules/jquery-wheelcolorpicker/jquery.wheelcolorpicker-3.0.5.min.js"></script>
 | |
|     <script type="text/javascript" src="node_modules/jquery-minicolors/jquery.minicolors.min.js"></script>
 | |
|     <!-- Bootstrap tooltips -->
 | |
|     <script type="text/javascript" src="node_modules/popper.js/dist/umd/popper.min.js"></script>
 | |
|     <script type="text/javascript" src="node_modules/popper.js/dist/umd/popper-utils.min.js"></script>
 | |
|     <!-- Bootstrap core JavaScript-->
 | |
|     <script type="text/javascript" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
 | |
|     <!-- MDB core JavaScript -->
 | |
|     <script type="text/javascript" src="node_modules/bootstrap-material-design/dist/js/bootstrap-material-design.min.js"></script>
 | |
|     <script src="node_modules/angular/angular.min.js"></script>
 | |
|     <script type="text/javascript" src="node_modules/angular-minicolors/angular-minicolors.js"></script>
 | |
|     <script src="node_modules/reconnecting-websocket/dist/reconnecting-websocket-iife.min.js"></script>
 | |
|     <script>
 | |
|         var app = angular.module('LED-WebFrontend',['minicolors']);
 | |
|         app.factory('socket', [function() {
 | |
|             var stack = [];
 | |
|             var onmessageDefer;
 | |
|             var host = "localhost"
 | |
|             if (window.location.hostname != ""){
 | |
|                 host = window.location.hostname
 | |
|             }
 | |
|             var socket = {
 | |
|                 ws: new ReconnectingWebSocket("ws://"+host+":8001", null, {debug: false, reconnectInterval: 2000}),
 | |
|                 send: function(data) {
 | |
|                     if (socket.ws.readyState == 1) {
 | |
|                         socket.ws.send(data);
 | |
|                     } else {
 | |
|                         stack.push(data);
 | |
|                     }
 | |
|                 },
 | |
|                 onmessage: function(callback) {
 | |
|                     if (socket.ws.readyState == 1) {
 | |
|                         socket.ws.onmessage = callback;
 | |
|                     } else {
 | |
|                         onmessageDefer = callback;
 | |
|                     }
 | |
|                 }
 | |
|             };
 | |
|             socket.ws.onopen = function(event) {
 | |
|                 for (i in stack) {
 | |
|                     socket.ws.send(stack[i]);
 | |
|                 }
 | |
|                 stack = [];
 | |
|                 if (onmessageDefer) {
 | |
|                     socket.ws.onmessage = onmessageDefer;
 | |
|                     onmessageDefer = null;
 | |
|                 }
 | |
|             };
 | |
|             return socket;
 | |
|         }]);
 | |
| 
 | |
|         app.controller('LED-ServerCtrl', ['$scope',  'socket', function($scope, socket) { 
 | |
| 
 | |
|             $scope.connected = false;
 | |
| 
 | |
|             $scope.rgbStrips = {};
 | |
|             $scope.effects = {};
 | |
|             $scope.effectThreads = {};
 | |
|             
 | |
|             $scope.newEffectThreadParamColorPicker = {}
 | |
|             $scope.newEffectThread = {}
 | |
|             $scope.newEffectThread.params = {};
 | |
|             $scope.newEffectThread.rgbStrips = {};
 | |
| 
 | |
| 
 | |
|             $scope.colorpickerconfig = {
 | |
|                 // control: 'saturation',
 | |
|                 control: 'hue',
 | |
|                 // control: 'brightness',
 | |
|                 // control: 'wheel',
 | |
|                 theme: 'bootstrap',
 | |
|                 inline: true,
 | |
|                 position: 'top left'
 | |
|             };
 | |
| 
 | |
|             socket.ws.addEventListener('close',function(event) { 
 | |
|                 $scope.$apply(function(){
 | |
|                     $scope.connected = false
 | |
|                 }); 
 | |
|             });
 | |
|             socket.ws.addEventListener('open',function(event) { 
 | |
|                 $scope.$apply(function(){
 | |
|                     socket.send(
 | |
|                         JSON.stringify({ 
 | |
|                             'register_client_type': 0
 | |
|                         })
 | |
|                     );
 | |
|                     $scope.connected = true
 | |
|                 }); 
 | |
|             });
 | |
|            
 | |
|             socket.onmessage(function(event) {
 | |
|                 $scope.$apply(function(){
 | |
|                     json = JSON.parse(event.data)
 | |
|                     console.log("Message: ",json)
 | |
|                     //remove strips from startEffect that may not exist anymore
 | |
|                     if(json.hasOwnProperty('rgbStrips')){
 | |
|                         jQuery.each($scope.newEffectThread.rgbStrips,function(key,value){
 | |
|                             if (!(key in json.rgbStrips)){
 | |
|                                 delete $scope.newEffectThread.rgbStrips[key];
 | |
|                             }
 | |
|                         });
 | |
| 
 | |
|                     }
 | |
|                     if(json.hasOwnProperty('effects') && json.hasOwnProperty('rgbStrips')){
 | |
|                         //$("#startNewEffectThread")[0].reset();
 | |
|                         //$("#newEffectThread").removeAttr("selected");
 | |
| 
 | |
|                         //$scope.effects = {}
 | |
|                         $scope.effects = json.effects
 | |
|                         //$scope.rgbStrips = {}
 | |
|                         $scope.rgbStrips = json.rgbStrips
 | |
|                     }
 | |
|                     if(json.hasOwnProperty('effectThreads')){
 | |
|                         $scope.effectThreads = {}
 | |
|                         $scope.effectThreads = json.effectThreads
 | |
|                         $scope.moveRGBStripToEffectThreadModel = {}
 | |
| 
 | |
|                         $scope.moveRGBStripToEffectThreadForm.$setUntouched();
 | |
|                         $scope.moveRGBStripToEffectThreadForm.$setPristine();
 | |
|                     }
 | |
|                 });
 | |
|             });
 | |
|             
 | |
|             $scope.isRGBStripActive=function(rgbStrip, activeRGBStrips) {
 | |
|                 rval = false;
 | |
|                 jQuery.each(
 | |
|                     activeRGBStrips, function() {
 | |
|                         if(this.index == rgbStrip.index){
 | |
|                             rval = true;
 | |
|                             return false;
 | |
|                         }
 | |
|                     });
 | |
|                 return rval;
 | |
|             };
 | |
| 
 | |
|             $scope.moveRGBStripToEffectThread = function(rgbStripIndex,effectThreadIndex){
 | |
|                 socket.send(
 | |
|                     JSON.stringify({ 
 | |
|                         'moveRGBStripToEffectThread': { 
 | |
|                             'rgbStrip': rgbStripIndex, 
 | |
|                             'effectThread': effectThreadIndex
 | |
|                         }
 | |
|                     })
 | |
|                 );
 | |
|             };
 | |
| 
 | |
|             $scope.effectThreadChangeEffectParam = function(effectThreadIndex,params){
 | |
|                 console.log(params)
 | |
|                 socket.send(
 | |
|                     JSON.stringify({ 
 | |
|                         'effectThreadChangeEffectParam': { 
 | |
|                             'params': Object.entries(params), 
 | |
|                             'effectThread': effectThreadIndex
 | |
|                         }
 | |
|                     })
 | |
|                 );
 | |
|             };
 | |
| 
 | |
|             $scope.startEffect = function(effectIndex,rgbStrips,params){
 | |
|                 console.log(params)
 | |
|                 socket.send(
 | |
|                     JSON.stringify({
 | |
|                         'startEffect': {
 | |
|                             'rgbStrips': Object.entries(rgbStrips), 
 | |
|                             'effect': effectIndex,
 | |
|                             'params': Object.entries(params)
 | |
|                         }
 | |
|                     })
 | |
|                 );
 | |
|             };
 | |
| 
 | |
|             $scope.changeEffectThreadParameters = function(effectThreadIndex,paramIndex,values){
 | |
| 
 | |
|             }
 | |
|             
 | |
|             //https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
 | |
|             $scope.hexToRgb = function(hex) {
 | |
|                 // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
 | |
|                 var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
 | |
|                 hex = hex.replace(shorthandRegex, function(m, r, g, b) {
 | |
|                     return r + r + g + g + b + b;
 | |
|                 });
 | |
| 
 | |
|                 var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
 | |
|                 return result ? {
 | |
|                     r: parseInt(result[1], 16),
 | |
|                     g: parseInt(result[2], 16),
 | |
|                     b: parseInt(result[3], 16)
 | |
|                 } : null;
 | |
|             }
 | |
| 
 | |
|             $scope.rgbToHex = function rgbToHex(r, g, b) {
 | |
|                 return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
 | |
|             }
 | |
|         
 | |
|         }]);
 | |
|     </script>
 | |
| </body>
 | |
| </html> |