Effects Configurator (#281)

* update translation

* add css

* Update JsonClientConnection.cpp

* add effectscreator

* remove udp

* fix title c/p issue for sparks

[skip ci]

* update schemas

[skip ci]

* typo

[skpi ci]
This commit is contained in:
brindosch 2016-10-30 17:54:38 +01:00 committed by GitHub
parent 33c91f73e3
commit 864538f188
20 changed files with 135 additions and 133 deletions

View File

@ -0,0 +1,34 @@
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header"><i class="fa fa-cogs fa-fw"></i><span lang="en" data-lang-token="main_menu_effectsconfigurator_token">Effects Configurator</span></h1>
<div class="introd">
<h4 lang="en" data-lang-token="effectsconfigurator_label_intro">Create out of the base effects new effects that are tuned to your liking. Depending on Effect there are options like color, speed, direction and more available.</h4>
</div>
<hr />
<div class="col-lg-12">
<div class="panel panel-default" >
<div class="panel-heading">
<label for="effectslist" lang="en" data-lang-token="effectsconfigurator_label_chooseeff">Choose Base-Effect:</label>
<select id="effectslist" class="form-control" style="color:black;width:auto;margin-left:10px;display:inline-block" />
</div>
<div class="panel-body">
<div class="form-group row">
<label for="name-input" class="col-xs-2 col-form-label" lang="en" data-lang-token="effectsconfigurator_label_effectname">Effect name:</label>
<div class="col-xs-10">
<input class="form-control" type="text" id="name-input">
</div>
</div>
<div id="editor_container" />
</div>
<div class="panel-footer">
<button class="btn btn-warning" id='btn_test' lang="en" data-lang-token="effectsconfigurator_button_testeffect">Test Effect (not implemented)</button>
<button class="btn btn-primary" id='btn_write' lang="en" data-lang-token="effectsconfigurator_button_saveeffect">Save Effect</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="/js/content_effectsconfigurator.js"></script>

View File

@ -120,8 +120,6 @@
<!-- /.dropdown-language -->
</li>
<!-- /.dropdown -->
</li>
<!-- /.dropdown -->
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-bell fa-fw"></i> <i class="fa fa-caret-down"></i>
@ -210,13 +208,14 @@
<ul class="nav nav-second-level">
<li> <a class="inactive" id="load_confLeds"><i class="fa fa-lightbulb-o fa-fw"></i><span lang="en" data-lang-token="main_menu_leds_conf_token">LED Hardware</span></a> </li>
<li> <a class="inactive" id="load_confGrabber"><i class="fa fa-camera fa-fw"></i><span lang="en" data-lang-token="main_menu_grabber_conf_token">Capturing Hardware</span></a> </li>
<li> <a class="inactive" id="load_confEffects"><i class="fa fa-spinner fa-fw"></i><span lang="en" data-lang-token="main_menu_general_conf_token">Effects</span></a> </li>
<li> <a class="inactive" id="load_confEffects"><i class="fa fa-spinner fa-fw"></i><span lang="en" data-lang-token="main_menu_effect_conf_token">Effects</span></a> </li>
<li> <a class="inactive" id="load_confColors"><i class="fa fa-photo fa-fw"></i><span lang="en" data-lang-token="main_menu_colors_conf_token">Image Processing</span></a> </li>
<li> <a class="inactive" id="load_confKodi"><i class="fa fa-play-circle-o fa-fw"></i><span lang="en" data-lang-token="main_menu_kodiwatch_token">KODI Connector</span></a> </li>
<li> <a class="inactive" id="load_confNetwork"><i class="fa fa-wrench fa-fw"></i><span lang="en" data-lang-token="main_menu_network_conf_token">Network</span></a> </li>
<li> <a class="inactive" id="load_confNetwork"><i class="fa fa-sitemap fa-fw"></i><span lang="en" data-lang-token="main_menu_network_conf_token">Network</span></a> </li>
</ul>
</li>
<li> <a class="inactive" id="load_remote"><i class="fa fa-wifi fa-fw"></i><span lang="en" data-lang-token="main_menu_remotecontrol_token">Remote Control</span></a> </li>
<li> <a class="inactive" id="load_effectsconfig"><i class="fa fa-cogs fa-fw"></i><span lang="en" data-lang-token="main_menu_effectsconfigurator_token">Effects Configurator</span></a> </li>
<li> <a class="inactive" id="load_support"><i class="fa fa-info fa-fw"></i><span lang="en" data-lang-token="main_menu_support_token">Support</span></a> </li>
<li>
<a class="inactive"><i class="fa fa-industry fa-fw"></i><span lang="en" data-lang-token="main_menu_system_token">System</span><span class="fa arrow"></span></a>
@ -235,8 +234,8 @@
<div id="page-wrapper" style="padding-top:10px">
<div id="hyperion_reload_notify" class="alert alert-warning" style="display:none;padding:10px;margin:0">
<div class="panel-danger" style="text-align:right">
<div style="float:left">Hyperion Configuration is modified. To make it active, restart Hyperion.</div>
<button id="btn_hyperion_reload" class="btn btn-danger">Restart Hyperion</button>
<div style="float:left;line-height:33px;" lang="en" data-lang-token="dashboard_alert_message_confedit">Your Hyperion configuration has been modified. To apply it, restart Hyperion.</div>
<button id="btn_hyperion_reload" class="btn btn-danger" lang="en" data-lang-token="dashboard_alert_button_restarthyerion">Restart Hyperion</button>
</div>
</div>
@ -248,17 +247,21 @@
<div id="container_connection_lost" style="display:none"></div>
<div id="error_dialog" class="modal fade" role="dialog">
<div id="modal_dialog" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title" />
<div class="modal-body">
<center>
<div class="modal-bodyicon"></div>
<h4 class="modal-bodytitle" style="font-weight:bold;text-transform:uppercase;"></h4>
<div class="modal-bodycontent"></div>
</center>
</div>
<div class="modal-body" />
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Okay!</button>
<center>
<div class="modal-footer-button"></div>
</center>
</div>
</div>
</div>

View File

@ -0,0 +1,53 @@
$(hyperion).one("cmd-config-getschema", function(event) {
effects = parsedConfSchemaJSON.properties.effectSchemas.internal
EffectsHtml = "";
for(var idx=0; idx<effects.length; idx++)
{
EffectsHtml += '<option value="'+effects[idx].schemaContent.script+'">'+effects[idx].schemaContent.title+'</option>';
}
$("#effectslist").html(EffectsHtml);
$("#effectslist").trigger("change");
});
effects_editor = null;
effectPy = "";
$("#effectslist").off().on("change", function(event) {
for(var idx=0; idx<effects.length; idx++){
if (effects[idx].schemaContent.script == this.value){
effects_editor = createJsonEditor('editor_container', {
args : effects[idx].schemaContent,
},false);
effectPy = ':';
effectPy += effects[idx].schemaContent.script;
}
}
});
$('#btn_write').off().on('click',function() {
effectName = $('#name-input').val();
if (effectName == "")
{
showInfoDialog('error','INVALID NAME FIELD','Effect name is empty! Please fill in a name and try again.')
}
else
{
var errors = effects_editor.validate();
if(errors.length)
{
showInfoDialog('error','INVALID VALUES','Please check for red marked inputs and try again.')
}
else
{
requestWriteEffect(effectName,effectPy,JSON.stringify(effects_editor.getValue()));
showInfoDialog('success','SUCCESS!','Your effect has been created successfully!')
}
}
});
$(document).ready( function() {
requestServerConfigSchema();
});

View File

@ -14,6 +14,7 @@ $(document).ready( function() {
bindNavToContent("#load_confGrabber","grabber",false);
bindNavToContent("#load_confColors","colors",false);
bindNavToContent("#load_confNetwork","network",false);
bindNavToContent("#load_effectsconfig","effects_configurator",false);
//Change all Checkboxes to Switches

View File

@ -203,3 +203,9 @@ function requestWriteConfig(config)
});
websocket.send('{"command":"config","subcommand":"setconfig", "tan":'+wsTan+', "config":'+JSON.stringify(complete_config)+'}');
}
function requestWriteEffect(effectName,effectPy,effectArgs)
{
var cutArgs = effectArgs.slice(1, -1);
websocket.send('{"command":"create-effect","name":"'+effectName+'", "script":"'+effectPy+'", '+cutArgs+'}');
}

View File

@ -95,6 +95,7 @@ function createJsonEditor(container,schema,setconfig)
form_name_root: 'sa',
disable_edit_json: 'true',
disable_properties: 'true',
disable_array_reorder: 'true',
no_additional_properties: 'true',
schema: {
title:'',

View File

@ -41,6 +41,7 @@
"main_menu_kodiwatch_token" : "Kodi Überwachung",
"main_menu_network_conf_token" : "Netzwerk",
"main_menu_remotecontrol_token" : "Fernbedienung",
"main_menu_effectsconfigurator_token" : "Effekt Konfigurator",
"main_menu_support_token" : "Hilfe",
"main_menu_update_token" : "Update",
"main_menu_system_token" : "System",
@ -81,6 +82,11 @@
"hue_button_pair" : "Verbinden",
"hue_failure_ip_token" : "Bitte überprüfe deine IP Adresse.",
"hue_label_username" : "Benutzername:",
"effectsconfigurator_label_intro" : "Erstelle auf Grundlage der Basiseffekte neue Effekt die nach deinen Wünschen angepasst sind. Je nach Effekt stehen Optionen wie Farbe, Geschwindigkeit, oder Richtung und vieles mehr zur Auswahl.",
"effectsconfigurator_label_chooseeff" : "Basis-Effekt auswählen:",
"effectsconfigurator_button_saveeffect" : "Effekt speichern",
"effectsconfigurator_label_effectname" : "Effektname:",
"effectsconfigurator_button_testeffect" : "Effekt testen (nicht implementiert)",
"support_label_title" : "Unterstütze Hyperion",
"support_label_intro" : "Hyperion ist ein kostenloses Open Source Projekt und ein kleines Team arbeitet an seiner Weiterentwicklung. Darum benötigen wir DEINE Unterstützung um den Ball weiter rollen zu lassen und um weiter in bessere Infrastruktur und Weiterentwicklung investieren zu können.",
"support_label_spreadtheword" : "Weitersagen!",

View File

@ -14,7 +14,7 @@
"color-start": {
"type": "array",
"title":"Color Start",
"default": "255,174,11",
"default": [255,174,11],
"items" : {
"type": "integer",
"minimum": 0,
@ -27,7 +27,7 @@
"color-end": {
"type": "array",
"title":"Color End",
"default": "100,100,100",
"default": [100,100,100],
"items" : {
"type": "integer",
"minimum": 0,

View File

@ -21,7 +21,7 @@
"color": {
"type": "array",
"title":"Color",
"default": "255,0,0",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,

View File

@ -7,7 +7,7 @@
"color": {
"type": "array",
"title":"Color",
"default": "255,0,0",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,

View File

@ -7,7 +7,7 @@
"color_one": {
"type": "array",
"title":"Color one",
"default": "255,0,0",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,
@ -20,7 +20,7 @@
"color_two": {
"type": "array",
"title":"Color two",
"default": "0,0,255",
"default": [0,0,255],
"items" : {
"type": "integer",
"minimum": 0,

View File

@ -14,7 +14,7 @@
"alarm-color": {
"type": "array",
"title":"Alarm color",
"default": "255,0,0",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,
@ -27,7 +27,7 @@
"post-color": {
"type": "array",
"title":"Post color",
"default": "255,174,11",
"default": [255,174,11],
"items" : {
"type": "integer",
"minimum": 0,

View File

@ -7,7 +7,7 @@
"color": {
"type": "array",
"title":"Color",
"default": "255,0,0",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,

View File

@ -7,7 +7,7 @@
"color_one": {
"type": "array",
"title":"Color",
"default": "255,0,0",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,
@ -26,21 +26,21 @@
},
"sleep-time": {
"type": "number",
"title":"Rotation time",
"title":"Sleep time",
"default": 0.05,
"minimum" : 0.01,
"propertyOrder" : 3
},
"brightness": {
"type": "number",
"title":"Rotation time",
"title":"Brightness",
"default": 1.0,
"minimum" : 0.01,
"propertyOrder" : 4
},
"saturation": {
"type": "number",
"title":"Rotation time",
"title":"Saturation",
"default": 1.0,
"minimum" : 0.01,
"propertyOrder" : 5

View File

@ -7,7 +7,7 @@
"color": {
"type": "array",
"title":"Color",
"default": "255,0,0",
"default": [255,0,0],
"items" : {
"type": "integer",
"minimum": 0,

View File

@ -1,22 +0,0 @@
{
"type":"object",
"script" : "udp.py",
"title":"UDP listener",
"required":true,
"properties":{
"ListenPort": {
"type": "Integer",
"title":"Listen Port",
"default": 2801,
"minimum" : 1,
"propertyOrder" : 1
},
"ListenIP": {
"type": "string",
"title":"Listen IP",
"default": "",
"propertyOrder" : 2
}
},
"additionalProperties": false
}

View File

@ -1,9 +0,0 @@
{
"name" : "UDP multicast listener",
"script" : "udp.py",
"args" :
{
"ListenPort" : 2801,
"ListenIP" : "239.255.28.01"
}
}

View File

@ -1,8 +0,0 @@
{
"name" : "UDP listener",
"script" : "udp.py",
"args" :
{
"ListenPort" : 2391
}
}

View File

@ -1,63 +0,0 @@
import hyperion
import time
import colorsys
import socket
import errno
import struct
# Get the parameters
ListenPort = int(hyperion.args.get('ListenPort', 2801))
ListenIP = hyperion.args.get('ListenIP', "")
octets = ListenIP.split('.');
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM, socket.IPPROTO_UDP)
UDPSock.setblocking(False)
listen_addr = (ListenIP,ListenPort)
UDPSock.bind(listen_addr)
if ListenIP == "":
print "udp.py: Listening on *.*.*.*:"+str(ListenPort)
else:
print "udp.py: Listening on "+ListenIP+":"+str(ListenPort)
if len(octets) == 4 and int(octets[0]) >= 224 and int(octets[0]) < 240:
print "ListenIP is a multicast address\n"
# Multicast handling
try:
mreq = struct.pack("4sl", socket.inet_aton(ListenIP), socket.INADDR_ANY)
UDPSock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
except socket.error:
print "ERROR enabling multicast\n"
hyperion.setColor(hyperion.ledCount * bytearray((int(0), int(0), int(0))) )
# Start the write data loop
while not hyperion.abort():
try:
data,addr = UDPSock.recvfrom(4500)
# print data.strip(),len(data),addr
if (len(data)%3 == 0):
# print "numleds ",len(data)/3
ledData = bytearray()
for i in range(hyperion.ledCount):
if (i<(len(data)/3)):
ledData += data[i*3+0]
ledData += data[i*3+1]
ledData += data[i*3+2]
else:
ledData += bytearray((int(0), int(0), int(0)))
hyperion.setColor(ledData)
else:
print "not div 3"
except IOError as e:
if e.errno == errno.EWOULDBLOCK:
pass
else:
print "errno:", e.errno
print "udp.py: closing socket"
UDPSock.close()

View File

@ -1053,16 +1053,16 @@ void JsonClientConnection::handleSchemaGetCommand(const QJsonObject& message, co
{
QJsonObject internal;
internal.insert("script", effectSchema.pyFile);
internal.insert("schema-location", effectSchema.schemaFile);
internal.insert("schema-content", effectSchema.pySchema);
internal.insert("schemaLocation", effectSchema.schemaFile);
internal.insert("schemaContent", effectSchema.pySchema);
in.append(internal);
}
else
{
QJsonObject external;
external.insert("script", effectSchema.pyFile);
external.insert("schema-location", effectSchema.schemaFile);
external.insert("schema-content", effectSchema.pySchema);
external.insert("schemaLocation", effectSchema.schemaFile);
external.insert("schemaContent", effectSchema.pySchema);
ex.append(external);
}
}