Dynamic Device Selection/Configuration (#1164)

This commit is contained in:
LordGrey 2021-04-24 19:37:29 +02:00 committed by GitHub
parent a4d98fd916
commit 7eeb740177
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 4296 additions and 2567 deletions

View File

@ -41,7 +41,7 @@ jobs:
shell: bash
run: |
tr -d '\n' < version > temp && mv temp version
echo -n -PR#${{ github.event.pull_request.number }} >> version
echo -n "+PR${{ github.event.pull_request.number }}" >> version
# Build packages
- name: Build packages
@ -87,7 +87,7 @@ jobs:
shell: bash
run: |
tr -d '\n' < version > temp && mv temp version
echo -n "-PR#${{ github.event.pull_request.number }}" >> version
echo -n "+PR${{ github.event.pull_request.number }}" >> version
# Install dependencies
- name: Install dependencies
@ -136,7 +136,7 @@ jobs:
shell: bash
run: |
tr -d '\n' < version > temp && mv temp version
echo -n "-PR#${{ github.event.pull_request.number }}" >> version
echo -n "+PR${{ github.event.pull_request.number }}" >> version
- name: Cache Qt
uses: actions/cache@v2

View File

@ -1,374 +1,382 @@
<!DOCTYPE html>
<html>
<head>
<title>Hyperion - LED Device Configuration</title>
</head>
<div class="container-fluid">
<h3 class="page-header"><i class="fa fa-lightbulb-o fa-fw"></i><span data-i18n="main_menu_leds_conf_token">LED Hardware</span></h3>
<ul id="leds_cfg_nav" class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#menu_controller" data-i18n="conf_leds_nav_label_ledcontroller">LED Controller</a></li>
<li><a data-toggle="tab" href="#menu_gencfg" data-i18n="conf_leds_nav_label_ledlayout">LED Layout</a></li>
</ul>
<h3 class="page-header"><i class="fa fa-lightbulb-o fa-fw"></i><span data-i18n="main_menu_leds_conf_token">LED Hardware</span></h3>
<ul id="leds_cfg_nav" class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#menu_controller" data-i18n="conf_leds_nav_label_ledcontroller">LED Controller</a></li>
<li><a data-toggle="tab" href="#menu_gencfg" data-i18n="conf_leds_nav_label_ledlayout">LED Layout</a></li>
</ul>
<div class="tab-content">
<div class="tab-content">
<div id="menu_controller" class="tab-pane fade in active" style="padding-top:10px">
<div class="row">
<div class="col-lg-12" id="leddevice_intro"></div>
<div class="col-lg-6">
<div class="panel panel-default">
<div class="panel-heading form-group">
<label for="leddevices" class="panel-title" data-i18n="conf_leds_contr_label_contrtype">Controller type:</label>
<select id="leddevices" class="form-control" style="color:black;width:auto;margin-left:10px;display:inline-block"></select>
</div>
<div id="menu_controller" class="tab-pane fade in active" style="padding-top:10px">
<div class="row">
<div class="col-lg-12" id="leddevice_intro"></div>
<div class="col-lg-6">
<div class="panel panel-default">
<div class="panel-heading form-group">
<label for="leddevices" class="panel-title" data-i18n="conf_leds_contr_label_contrtype">Controller type:</label>
<select id="leddevices" class="form-control" style="color:black;width:auto;margin-left:10px;display:inline-block" />
</div>
<div class="panel-body">
<div id="btn_wiz_holder"></div>
<div id='editor_container_leddevice'></div>
<div class="bs-callout bs-callout-info" style="margin-top:0px"><h4 data-i18n="dashboard_infobox_label_title">Information</h4><span data-i18n="conf_leds_device_info_log"> In case your LEDs do not work, check here for errors: </span> <a onclick="SwitchToMenuItem('MenuItemLogging')" href="#" data-i18n="main_menu_logging_token"></a></div>
</div>
<div class="panel-footer" style="text-align:right">
<button id='btn_test_controller' class="btn btn-primary hidden" disabled data-toggle="tooltip" data-placement="top" title="Identify configured device by lighting it up">
<i class="fa fa-fw fa-save"></i><span data-i18n="wiz_identify">Identify/Test</span>
</button>
<button id='btn_submit_controller' class="btn btn-primary" data-toggle="tooltip" data-placement="top" title="Save the device's connectivity configuration">
<i class="fa fa-fw fa-save"></i><span data-i18n="general_button_savesettings">Save Settings</span>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="panel-body">
<div id="btn_wiz_holder"></div>
<div id="ledDeviceOptions"> <div id='editor_container'></div> </div>
</div>
<div class="panel-footer" style="text-align:right">
<button id='btn_submit_controller' class="btn btn-primary"><i class="fa fa-fw fa-save" /><span data-i18n="general_button_savesettings">Save Settings</span></button>
</div>
</div>
</div>
</div>
</div>
<div id="menu_gencfg" class="tab-pane fade" style="padding-top:10px">
<div id="menu_gencfg" class="tab-pane fade" style="padding-top:10px">
<div class="row">
<div class="col-lg-12" id="layout_intro"></div>
<div class="col-lg-6 col-md-12">
<div class="panel-group" id="accordion">
<div class="panel panel-primary">
<div class="panel-heading headcollapse" data-toggle="collapse" data-parent="#accordion" data-target="#collapse1">
<h4 class="panel-title">
<a><i class="fa fa-television fa-fw"></i><span data-i18n="conf_leds_layout_frame">Classic Layout (LED Frame)</span></a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse in">
<div class="panel-body">
<table class="table borderless">
<tbody>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_top" data-i18n="conf_leds_layout_cl_top">Top</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr " id="ip_cl_top" type="number" value="1" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_bottom" data-i18n="conf_leds_layout_cl_bottom">Bottom</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_bottom" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_left" data-i18n="conf_leds_layout_cl_left">Left</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_left" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_right" data-i18n="conf_leds_layout_cl_right">Right</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_right" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_glength" data-i18n="conf_leds_layout_cl_gaglength">Gap length</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_glength" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_gpos" data-i18n="conf_leds_layout_cl_gappos">Gap position</label>
</td>
<td class="itd">
<input class="form-control ledCLconstr" id="ip_cl_gpos" type="number" value="0" min="0" step="1">
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_position" data-i18n="conf_leds_layout_cl_inppos">Input position</label>
</td>
<td class="itd">
<input class="form-control ledCLconstr" id="ip_cl_position" type="number" value="0" min="0" step="1">
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_reverse" data-i18n="conf_leds_layout_cl_reversdir">Reverse direction</label>
</td>
<td class="itd">
<div class="checkbox">
<input class="ledCLconstr" id="ip_cl_reverse" type="checkbox" value="false"></input>
<label></label>
</div>
</td>
</tr>
</tbody>
</table>
<div class="panel panel-default">
<div class="panel-heading headcollapse" data-toggle="collapse" data-target="#collapse3">
<h4 class="panel-title">
<a><span data-i18n="conf_leds_layout_advanced">Advanced settings</span></a>
</h4>
</div>
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body ">
<table class="tableform borderless">
<tbody>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_hdepth" data-i18n="conf_leds_layout_cl_hleddepth">Horizontal LED depth</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_hdepth" type="number" value="8" min="1" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_vdepth" data-i18n="conf_leds_layout_cl_vleddepth">Vertical LED depth</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_vdepth" type="number" value="5" min="1" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_overlap" data-i18n="conf_leds_layout_cl_overlap">Edge Gap</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_overlap" type="number" value="0" min="0" max="200" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_edgegap" data-i18n="conf_leds_layout_cl_edgegap">Edge Gap</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_edgegap" type="number" value="0" min="0" max="50" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_ptl" data-i18n="conf_leds_layout_ptl">Point Top Left</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptlh" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%h</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptlv" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%v</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_ptr" data-i18n="conf_leds_layout_ptr">Point Top Right</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptrh" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptrv" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_pbr" data-i18n="conf_leds_layout_pbr">Point Bottom Right</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pbrh" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pbrv" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_pbl" data-i18n="conf_leds_layout_pbl">Point Bottom Left</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pblh" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pblv" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%</div>
</td>
</tr>
<!-- <tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_cornergap" data-i18n="conf_leds_layout_cl_cornergap">Corner Gap</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr " id="ip_cl_cornergap" type="number" value="0" min="0" max="50" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
-->
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="panel-footer" style="text-align:right;">
<button id="btn_cl_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
</div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading headcollapse" data-toggle="collapse" data-parent="#accordion" data-target="#collapse2">
<h4 class="panel-title">
<a><i class="fa fa-th fa-fw"></i><span data-i18n="conf_leds_layout_matrix">Matrix Configuration (LED wall)</span></a>
</h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">
<table>
<tbody>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_ledshoriz" data-i18n="conf_leds_layout_ma_horiz">Horizontal</label>
</td>
<td class="itd input-group">
<input class="form-control ledMAconstr" id="ip_ma_ledshoriz" type="number" value="1" min="1" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_ledsvert" data-i18n="conf_leds_layout_ma_vert">Vertical</label>
</td>
<td class="itd input-group">
<input class="form-control ledMAconstr" id="ip_ma_ledsvert" type="number" value="1" min="1" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_cabling" data-i18n="conf_leds_layout_ma_cabling">Cabling</label>
</td>
<td class="itd">
<select class="form-control ledMAconstr" id="ip_ma_cabling">
<option value="snake" data-i18n="conf_leds_layout_ma_optsnake">Snake</option>
<option value="parallel" data-i18n="conf_leds_layout_ma_optparallel">Parallel</option>
</select>
</td>
</tr>
<!--- <tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_order" data-i18n="conf_leds_layout_ma_order">Order</label>
</td>
<td class="itd">
<select class="form-control ledMAconstr" id="ip_ma_order">
<option value="horizontal" data-i18n="conf_leds_layout_ma_opthoriz">Horizontal</option>
<option value="vertical" data-i18n="conf_leds_layout_ma_optvert">Vertical</option>
</select>
</td>
</tr>
--->
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_start" data-i18n="conf_leds_layout_ma_position">Input</label>
</td>
<td class="itd">
<select class="form-control ledMAconstr" id="ip_ma_start">
<option value="top-left" data-i18n="conf_leds_layout_ma_opttopleft">Top left</option>
<option value="top-right" data-i18n="conf_leds_layout_ma_opttopright">Top right</option>
<option value="bottom-left" data-i18n="conf_leds_layout_ma_optbottomleft">Bottom left</option>
<option value="bottom-right" data-i18n="conf_leds_layout_ma_optbottomright">Bottom right</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel-footer" style="text-align:right;">
<button id="btn_ma_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
</div>
</div>
</div>
<div id="texfield_panel" class="panel panel-primary">
<div class="panel-heading headcollapse" data-toggle="collapse" data-parent="#accordion" data-target="#collapse4">
<h4 class="panel-title">
<a><i class="fa fa-wrench fa-fw"></i><span data-i18n="conf_leds_layout_generatedconf">Generated/Actual LED Configuration</span></a>
</h4>
</div>
<div id="collapse4" class="panel-collapse collapse">
<div class="panel-body">
<p id="leds_wl" data-i18n="conf_leds_layout_textf1">This textfield shows by default your current loaded layout and will be overwritten if you generate a new one above. Optional you could perform further edits.</p>
<div id="aceedit" style="width:100%;height:500px"></div>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-warning" id="leds_custom_updsim"><i class="fa fa-search fa-fw"></i><span data-i18n="conf_leds_layout_button_updsim">Update preview</span></button>
<button type="button" class="btn btn-primary pull-right" id="leds_custom_save"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
</div>
</div>
</div>
</div>
</div> <!-- accordion -->
<div class="col-lg-6 col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><i class="fa fa-search fa-fw"></i><span data-i18n="conf_leds_layout_peview">LED Layout preview</span></h4>
</div>
<div class="panel-body">
<p id="previewcreator" style="font-weight:bold"></p>
<p id="previewledcount" style="font-weight:bold"></p>
<p id="previewledpower" style="font-weight:bold"></p>
<div id="led_vis_help"></div>
<div class="col-lg-12 st_helper" style="padding-left:0px; padding-right:0px">
<div id="leds_preview"></div>
</div>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-danger" id="leds_prev_toggle_num"><i class="fa fa-info fa-fw"></i><span data-i18n="main_ledsim_btn_togglelednumber">toggle led numbers</span></button>
<button type="button" class="btn btn-primary" id="leds_prev_checklist"><i class="fa fa-info-circle fa-fw"></i><span data-i18n="conf_leds_layout_btn_checklist">toggle led numbers</span></button>
</div>
</div>
</div>
</div>
</div> <!-- row layout -->
</div>
</div>
</div> <!-- tab content -->
<div class="row">
<div class="col-lg-12" id="layout_intro"></div>
<div class="col-lg-6 col-md-12">
<div class="panel-group" id="accordion">
<div class="panel panel-primary">
<div class="panel-heading headcollapse" id="classic_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse1">
<h4 class="panel-title">
<a><i class="fa fa-television fa-fw"></i><span data-i18n="conf_leds_layout_frame">Classic Layout (LED Frame)</span></a>
</h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">
<table class="table borderless">
<tbody>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_top" data-i18n="conf_leds_layout_cl_top">Top</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr " id="ip_cl_top" type="number" value="1" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_bottom" data-i18n="conf_leds_layout_cl_bottom">Bottom</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_bottom" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_left" data-i18n="conf_leds_layout_cl_left">Left</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_left" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_right" data-i18n="conf_leds_layout_cl_right">Right</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_right" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_glength" data-i18n="conf_leds_layout_cl_gaglength">Gap length</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_glength" type="number" value="0" min="0" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_gpos" data-i18n="conf_leds_layout_cl_gappos">Gap position</label>
</td>
<td class="itd">
<input class="form-control ledCLconstr" id="ip_cl_gpos" type="number" value="0" min="0" step="1">
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_position" data-i18n="conf_leds_layout_cl_inppos">Input position</label>
</td>
<td class="itd">
<input class="form-control ledCLconstr" id="ip_cl_position" type="number" value="0" min="0" step="1">
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_reverse" data-i18n="conf_leds_layout_cl_reversdir">Reverse direction</label>
</td>
<td class="itd">
<div class="checkbox">
<input class="ledCLconstr" id="ip_cl_reverse" type="checkbox" value="false"></input>
<label></label>
</div>
</td>
</tr>
</tbody>
</table>
<div class="panel panel-default">
<div class="panel-heading headcollapse" data-toggle="collapse" data-target="#collapse3">
<h4 class="panel-title">
<a><span data-i18n="conf_leds_layout_advanced">Advanced settings</span></a>
</h4>
</div>
<div id="collapse3" class="panel-collapse collapse">
<div class="panel-body ">
<table class="tableform borderless">
<tbody>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_hdepth" data-i18n="conf_leds_layout_cl_hleddepth">Horizontal LED depth</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_hdepth" type="number" value="8" min="1" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_vdepth" data-i18n="conf_leds_layout_cl_vleddepth">Vertical LED depth</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_vdepth" type="number" value="5" min="1" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_overlap" data-i18n="conf_leds_layout_cl_overlap">Edge Gap</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_overlap" type="number" value="0" min="0" max="200" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_edgegap" data-i18n="conf_leds_layout_cl_edgegap">Edge Gap</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_edgegap" type="number" value="0" min="0" max="50" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_ptl" data-i18n="conf_leds_layout_ptl">Point Top Left</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptlh" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%h</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptlv" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%v</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_ptr" data-i18n="conf_leds_layout_ptr">Point Top Right</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptrh" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_ptrv" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_pbr" data-i18n="conf_leds_layout_pbr">Point Bottom Right</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pbrh" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pbrv" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_pbl" data-i18n="conf_leds_layout_pbl">Point Bottom Left</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pblh" type="number" value="0" min="0" max="40" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_h">%</div>
</td>
</tr>
<tr>
<td class="ltd"></td>
<td class="itd input-group">
<input class="form-control ledCLconstr" id="ip_cl_pblv" type="number" value="100" min="60" max="100" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent_v">%</div>
</td>
</tr>
<!-- <tr>
<td class="ltd">
<label class="ltdlabel" for="ip_cl_cornergap" data-i18n="conf_leds_layout_cl_cornergap">Corner Gap</label>
</td>
<td class="itd input-group">
<input class="form-control ledCLconstr " id="ip_cl_cornergap" type="number" value="0" min="0" max="50" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_percent">%</div>
</td>
</tr>
-->
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="panel-footer" style="text-align:right;">
<button id="btn_cl_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
</div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading headcollapse" id="matrix_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse2">
<h4 class="panel-title">
<a><i class="fa fa-th fa-fw"></i><span data-i18n="conf_leds_layout_matrix">Matrix Configuration (LED wall)</span></a>
</h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">
<table>
<tbody>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_ledshoriz" data-i18n="conf_leds_layout_ma_horiz">Horizontal</label>
</td>
<td class="itd input-group">
<input class="form-control ledMAconstr" id="ip_ma_ledshoriz" type="number" value="1" min="1" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_ledsvert" data-i18n="conf_leds_layout_ma_vert">Vertical</label>
</td>
<td class="itd input-group">
<input class="form-control ledMAconstr" id="ip_ma_ledsvert" type="number" value="1" min="1" step="1"></input>
<div class="input-group-addon" data-i18n="edt_append_leds">LEDs</div>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_cabling" data-i18n="conf_leds_layout_ma_cabling">Cabling</label>
</td>
<td class="itd">
<select class="form-control ledMAconstr" id="ip_ma_cabling">
<option value="snake" data-i18n="conf_leds_layout_ma_optsnake">Snake</option>
<option value="parallel" data-i18n="conf_leds_layout_ma_optparallel">Parallel</option>
</select>
</td>
</tr>
<tr>
<td class="ltd">
<label class="ltdlabel" for="ip_ma_start" data-i18n="conf_leds_layout_ma_position">Input</label>
</td>
<td class="itd">
<select class="form-control ledMAconstr" id="ip_ma_start">
<option value="top-left" data-i18n="conf_leds_layout_ma_opttopleft">Top left</option>
<option value="top-right" data-i18n="conf_leds_layout_ma_opttopright">Top right</option>
<option value="bottom-left" data-i18n="conf_leds_layout_ma_optbottomleft">Bottom left</option>
<option value="bottom-right" data-i18n="conf_leds_layout_ma_optbottomright">Bottom right</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel-footer" style="text-align:right;">
<button id="btn_ma_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
</div>
</div>
</div>
<div id="blacklist_panel" class="panel panel-primary">
<div class="panel-heading headcollapse" id="blacklist_config_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse4">
<h4 class="panel-title">
<a><i class="fa fa-ban fa-fw"></i><span data-i18n="conf_leds_layout_blacklistleds_title">Blacklist LEDs</span></a>
</h4>
</div>
<div id="collapse4" class="panel-collapse collapse">
<div class="panel-body">
<div id="editor_container_blacklist_conf"></div>
</div>
<div class="panel-footer" style="text-align:right;">
<button id="btn_bl_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
</div>
</div>
</div>
<div id="texfield_panel" class="panel panel-primary">
<div class="panel-heading headcollapse" id="current_config_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse5">
<h4 class="panel-title">
<a><i class="fa fa-wrench fa-fw"></i><span data-i18n="conf_leds_layout_generatedconf">Generated/Actual LED Configuration</span></a>
</h4>
</div>
<div id="collapse5" class="panel-collapse collapse in">
<div class="panel-body">
<p id="leds_wl" data-i18n="conf_leds_layout_textf1">This textfield shows by default your current loaded layout and will be overwritten if you generate a new one above. Optional you could perform further edits.</p>
<div id="aceedit" style="width:100%;height:500px"></div>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-warning" id="leds_custom_updsim"><i class="fa fa-search fa-fw"></i><span data-i18n="conf_leds_layout_button_updsim">Update preview</span></button>
<button type="button" class="btn btn-primary pull-right" id="leds_custom_save"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
</div>
</div>
</div>
</div>
</div> <!-- accordion -->
<div class="col-lg-6 col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><i class="fa fa-search fa-fw"></i><span data-i18n="conf_leds_layout_peview">LED Layout preview</span></h4>
</div>
<div class="panel-body">
<p id="previewcreator" style="font-weight:bold"></p>
<p id="previewledcount" style="font-weight:bold"></p>
<p id="previewledpower" style="font-weight:bold"></p>
<div id="led_vis_help"></div>
<div class="col-lg-12 st_helper" style="padding-left:0px; padding-right:0px">
<div id="leds_preview"></div>
</div>
</div>
<div class="panel-footer">
<button type="button" class="btn btn-danger" id="leds_prev_toggle_num"><i class="fa fa-info fa-fw"></i><span data-i18n="main_ledsim_btn_togglelednumber">toggle led numbers</span></button>
<button type="button" class="btn btn-primary" id="leds_prev_checklist"><i class="fa fa-info-circle fa-fw"></i><span data-i18n="conf_leds_layout_btn_checklist">toggle led numbers</span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="/js/content_leds.js"></script>

View File

@ -1,15 +1,4 @@
{
"InfoDialog_access_text": "Depending on settings level you could adjust more options or get access to more features. Recommended is the \"Default\" level.",
"InfoDialog_access_title": "Settings level",
"InfoDialog_changePassword_success": "Password successfully saved!",
"InfoDialog_changePassword_title": "Change Password",
"InfoDialog_iswitch_text": "If you run Hyperion more than once in your local network, you could switch between the web configurations. Select the Hyperion instance below and switch!",
"InfoDialog_iswitch_title": "Hyperion switcher",
"InfoDialog_lang_text": "If you don't like the result of the automatic language detection you could overwrite it here.",
"InfoDialog_lang_title": "Language setting",
"InfoDialog_nowrite_foottext": "The WebUI will be unlocked automatically after you solved the problem!",
"InfoDialog_nowrite_text": "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.",
"InfoDialog_nowrite_title": "write permission error!",
"about_3rd_party_licenses": "3rd party licenses",
"about_3rd_party_licenses_error": "We had trouble collecting 3rd party licenses information from web. <br />Please follow this link to the GitHub Resource.",
"about_build": "Build",
@ -45,9 +34,19 @@
"conf_grabber_v4l_intro": "USB capture is a (capture)device connected via USB which is used to input source pictures for processing.",
"conf_helptable_expl": "Explanation",
"conf_helptable_option": "Option",
"conf_leds_config_error": "Error in LED/LED layout configuration",
"conf_leds_config_warning": "Check your LED/LED layout configuration",
"conf_leds_contr_label_contrtype": "Controller type:",
"conf_leds_device_info_log": "In case your LEDs do not work, check here for errors:",
"conf_leds_device_intro": "Hyperion supports a lot of controllers to transmit data to your target device. Select a LED controller out of the sorted list and configure it. We have chosen the best default settings for each device.",
"conf_leds_error_hwled_gt_layout": "The hardware LED count ($1) is greater than LEDs configured via layout ($2),<br>$3 {{plural:$1|LED|LEDs}} will stay black if you continue.",
"conf_leds_error_hwled_lt_layout": "The hardware LED count ($1) is less than LEDs configured via layout ($2). <br> The number of LEDs configured in the layout must not exceed the available LEDs",
"conf_leds_layout_advanced": "Advanced Settings",
"conf_leds_layout_blacklist_num_title": "Number of LEDs",
"conf_leds_layout_blacklist_rule_title": "Blacklist rule",
"conf_leds_layout_blacklist_rules_title": "Blacklist rules",
"conf_leds_layout_blacklist_start_title": "Start LED",
"conf_leds_layout_blacklistleds_title": "Blacklist LEDs",
"conf_leds_layout_btn_checklist": "Show checklist",
"conf_leds_layout_button_savelay": "Save Layout",
"conf_leds_layout_button_updsim": "Update Preview",
@ -113,11 +112,12 @@
"conf_leds_layout_textf1": "This text field shows by default your current loaded layout and will be overwritten if you generate a new one with the options above. Optional you could perform further edits.",
"conf_leds_nav_label_ledcontroller": "LED Controller",
"conf_leds_nav_label_ledlayout": "LED Layout",
"conf_leds_note_layout_overwrite": "Note: Overwrite creates a default layout for {{plural:$1| $1 LED| all $1 LEDs}} given by the hardware LED count",
"conf_leds_optgroup_network": "Network",
"conf_leds_optgroup_other": "Other",
"conf_leds_optgroup_RPiGPIO": "RPi GPIO",
"conf_leds_optgroup_RPiPWM": "RPi PWM",
"conf_leds_optgroup_RPiSPI": "RPi SPI",
"conf_leds_optgroup_debug": "Debug",
"conf_leds_optgroup_network": "Network",
"conf_leds_optgroup_usb": "USB/Serial",
"conf_logging_btn_autoscroll": "Auto scrolling",
"conf_logging_btn_pbupload": "Upload a report for support requests",
@ -215,10 +215,10 @@
"edt_conf_color_black_title": "Black",
"edt_conf_color_blue_expl": "The calibrated blue value.",
"edt_conf_color_blue_title": "Blue",
"edt_conf_color_brightnessComp_expl": "Compensates brightness differences between red green blue, cyan magenta yellow and white. 100 means full compensation, 0 no compensation",
"edt_conf_color_brightnessComp_title": "Brightness compensation",
"edt_conf_color_brightness_expl": "set overall brightness of LEDs",
"edt_conf_color_brightness_title": "Brightness",
"edt_conf_color_brightnessComp_expl": "Compensates brightness differences between red green blue, cyan magenta yellow and white. 100 means full compensation, 0 no compensation",
"edt_conf_color_brightnessComp_title": "Brightness compensation",
"edt_conf_color_channelAdjustment_header_expl": "Create color profiles that could be assigned to a specific component. Adjust color, gamma, brightness, compensation and more.",
"edt_conf_color_channelAdjustment_header_itemtitle": "Profile",
"edt_conf_color_channelAdjustment_header_title": "Color channel adjustments",
@ -254,10 +254,6 @@
"edt_conf_effp_paths_expl": "You could define more folders that contain effects. The effect configurator will always save inside the first folder.",
"edt_conf_effp_paths_itemtitle": "Path",
"edt_conf_effp_paths_title": "Effect Path(s)",
"edt_conf_enum_NO_CHANGE": "Automatic",
"edt_conf_enum_NTSC": "NTSC",
"edt_conf_enum_PAL": "PAL",
"edt_conf_enum_SECAM": "SECAM",
"edt_conf_enum_automatic": "Automatic",
"edt_conf_enum_bbclassic": "Classic",
"edt_conf_enum_bbdefault": "Default",
@ -288,9 +284,14 @@
"edt_conf_enum_logverbose": "Verbose",
"edt_conf_enum_logwarn": "Warning",
"edt_conf_enum_multicolor_mean": "Multicolor",
"edt_conf_enum_NO_CHANGE": "Automatic",
"edt_conf_enum_NTSC": "NTSC",
"edt_conf_enum_PAL": "PAL",
"edt_conf_enum_please_select": "Please Select",
"edt_conf_enum_rbg": "RBG",
"edt_conf_enum_rgb": "RGB",
"edt_conf_enum_right_left": "Right to left",
"edt_conf_enum_SECAM": "SECAM",
"edt_conf_enum_top_down": "Top down",
"edt_conf_enum_transeffect_smooth": "Smooth",
"edt_conf_enum_transeffect_sudden": "Sudden",
@ -322,11 +323,12 @@
"edt_conf_fge_type_title": "Type",
"edt_conf_fw_flat_expl": "One flatbuffer target per line. Contains IP:PORT (Example: 127.0.0.1:19401)",
"edt_conf_fw_flat_itemtitle": "flatbuffer target",
"edt_conf_fw_flat_title": "List of flatbuffer clients",
"edt_conf_fw_flat_title": "List of flatbuffer targets",
"edt_conf_fw_heading_title": "Forwarder",
"edt_conf_fw_json_expl": "One json target per line. Contains IP:PORT (Example: 127.0.0.1:19446)",
"edt_conf_fw_json_itemtitle": "Json target",
"edt_conf_fw_json_title": "List of json clients",
"edt_conf_fw_json_title": "List of json targets",
"edt_conf_gen_configVersion_title": "Configuration version",
"edt_conf_gen_heading_title": "General Settings",
"edt_conf_gen_name_expl": "A user defined name which is used to detect Hyperion. (Helpful with more than one Hyperion instance)",
"edt_conf_gen_name_title": "Configuration name",
@ -354,9 +356,9 @@
"edt_conf_net_heading_title": "Network",
"edt_conf_net_internetAccessAPI_expl": "Allow access to the Hyperion API/Webinterface from the internet, disable for higher security.",
"edt_conf_net_internetAccessAPI_title": "Internet API Access",
"edt_conf_net_ip_itemtitle": "IP",
"edt_conf_net_ipWhitelist_expl": "You can whitelist IP addresses instead allowing all connections from internet to connect to the Hyperion API/Webinterface.",
"edt_conf_net_ipWhitelist_title": "Whitelisted IP's",
"edt_conf_net_ip_itemtitle": "IP",
"edt_conf_net_localAdminAuth_expl": "When enabled, administration access from your local network needs a password.",
"edt_conf_net_localAdminAuth_title": "Local Admin API Authentication",
"edt_conf_net_localApiAuth_expl": "When enabled, connections from your home network needs to authenticate themself against Hyperion with a token.",
@ -436,25 +438,25 @@
"edt_conf_webc_sslport_expl": "Port oft the HTTPS-Webserver",
"edt_conf_webc_sslport_title": "HTTPS Port",
"edt_dev_auth_key_title": "Authentication Token",
"edt_dev_auth_key_title_info": "Authentication Token required to acccess the device",
"edt_dev_enum_sub_min_cool_adjust": "Subtract cool white",
"edt_dev_enum_sub_min_warm_adjust": "Subtract warm white",
"edt_dev_enum_subtract_minimum": "Subtract minimum",
"edt_dev_enum_white_off": "White off",
"edt_dev_general_colorOrder_title": "RGB byte order",
"edt_dev_general_colorOrder_title_info": "The device's color order",
"edt_dev_general_hardwareLedCount_title": "Hardware LED count",
"edt_dev_general_hardwareLedCount_title_info": "The number of physical LEDs availabe for the given device",
"edt_dev_general_heading_title": "General Settings",
"edt_dev_general_name_title": "Configuration name",
"edt_dev_general_rewriteTime_title": "Refresh time",
"edt_dev_spec_FCledToOn_title": "Fadecandy LED set to on",
"edt_dev_spec_FCmanualControl_title": "Manual control of fadecandy LED",
"edt_dev_spec_FCsetConfig_title": "Set fadecandy configuration",
"edt_dev_spec_LBap102Mode_title": "LightBerry APA102 Mode",
"edt_dev_spec_PBFiFo_title": "Pi-Blaster FiFo",
"edt_dev_spec_baudrate_title": "Baudrate",
"edt_dev_spec_blackLightsTimeout_title": "Signal detection timeout on black",
"edt_dev_spec_brightness_title": "Brightness",
"edt_dev_spec_brightnessFactor_title": "Brightness factor",
"edt_dev_spec_brightnessMax_title": "Brightness maximum",
"edt_dev_spec_brightnessMin_title": "Brightness minimum",
"edt_dev_spec_brightnessOverwrite_title": "Overwrite brightness",
"edt_dev_spec_brightnessThreshold_title": "Signal detection brightness minimum",
"edt_dev_spec_chanperfixture_title": "Channels per Fixture",
"edt_dev_spec_cid_title": "CID",
@ -463,8 +465,16 @@
"edt_dev_spec_debugLevel_title": "Debug Level",
"edt_dev_spec_debugStreamer_title": "Streamer Debug",
"edt_dev_spec_delayAfterConnect_title": "Delay after connect",
"edt_dev_spec_devices_discovered_none": "No Devices Discovered",
"edt_dev_spec_devices_discovered_title": "Devices Discovered",
"edt_dev_spec_devices_discovered_title_info": "Select your LED-Device discovered",
"edt_dev_spec_devices_discovered_title_info_custom": "Select your LED-Device discovered or configure a custome one",
"edt_dev_spec_devices_discovery_inprogress": "Discovery in progress",
"edt_dev_spec_dithering_title": "Dithering",
"edt_dev_spec_dmaNumber_title": "DMA channel",
"edt_dev_spec_FCledToOn_title": "Fadecandy LED set to on",
"edt_dev_spec_FCmanualControl_title": "Manual control of fadecandy LED",
"edt_dev_spec_FCsetConfig_title": "Set fadecandy configuration",
"edt_dev_spec_gamma_title": "Gamma",
"edt_dev_spec_globalBrightnessControlMaxLevel_title": "Max Current Level",
"edt_dev_spec_globalBrightnessControlThreshold_title": "Adaptive Current Threshold",
@ -477,6 +487,8 @@
"edt_dev_spec_intervall_title": "Interval",
"edt_dev_spec_invert_title": "Invert signal",
"edt_dev_spec_latchtime_title": "Latch time",
"edt_dev_spec_latchtime_title_info": "Latch time is the time-frame a device requires until the next update can be processed. During that time-frame any updates done via ignored.",
"edt_dev_spec_LBap102Mode_title": "LightBerry APA102 Mode",
"edt_dev_spec_ledIndex_title": "LED index",
"edt_dev_spec_ledType_title": "LED Type",
"edt_dev_spec_lightid_itemtitle": "ID",
@ -484,8 +496,8 @@
"edt_dev_spec_lights_itemtitle": "Light",
"edt_dev_spec_lights_name": "Name",
"edt_dev_spec_lights_title": "Light(s)",
"edt_dev_spec_maxPacket_title": "Max packet",
"edt_dev_spec_maximumLedCount_title": "Maximum LED count",
"edt_dev_spec_maxPacket_title": "Max packet",
"edt_dev_spec_multicastGroup_title": "Multicast group",
"edt_dev_spec_networkDeviceName_title": "Network devicename",
"edt_dev_spec_networkDevicePort_title": "Port",
@ -496,23 +508,27 @@
"edt_dev_spec_outputPath_title": "Output path",
"edt_dev_spec_panel_start_position": "Start panel [0-max panels]",
"edt_dev_spec_panelorganisation_title": "Panel numbering sequence",
"edt_dev_spec_PBFiFo_title": "Pi-Blaster FiFo",
"edt_dev_spec_pid_title": "PID",
"edt_dev_spec_port_title": "Port",
"edt_dev_spec_printTimeStamp_title": "Add timestamp",
"edt_dev_spec_pwmChannel_title": "PWM channel",
"edt_dev_spec_restoreOriginalState_title": "Restore lights' original state when disabled",
"edt_dev_spec_restoreOriginalState_title": "Restore lights' state",
"edt_dev_spec_restoreOriginalState_title_info": "Restore the device's original state when device is disabled",
"edt_dev_spec_serial_title": "Serial number",
"edt_dev_spec_spipath_title": "SPI path",
"edt_dev_spec_spipath_title": "SPI Device",
"edt_dev_spec_sslHSTimeoutMax_title": "Streamer handshake timeout maximum",
"edt_dev_spec_sslHSTimeoutMin_title": "Streamer handshake timeout minimum",
"edt_dev_spec_sslReadTimeout_title": "Streamer read timeout",
"edt_dev_spec_switchOffOnBlack_title": "Switch off on black",
"edt_dev_spec_switchOffOnbelowMinBrightness_title": "Switch-off, below minimum",
"edt_dev_spec_targetIpHost_title": "Target IP/Hostname",
"edt_dev_spec_targetIp_title": "Target IP",
"edt_dev_spec_switchOffOnBlack_title": "Switch off on black",
"edt_dev_spec_syncOverwrite_title": "Disable synchronisation",
"edt_dev_spec_targetIp_title": "Target IP-address",
"edt_dev_spec_targetIpHost_title": "Target Hostname/IP-address",
"edt_dev_spec_targetIpHost_title_info": "The device's hostname or IP-address",
"edt_dev_spec_transeffect_title": "Transition effect",
"edt_dev_spec_transistionTimeExtra_title": "Extra time darkness",
"edt_dev_spec_transistionTime_title": "Transition time",
"edt_dev_spec_transistionTimeExtra_title": "Extra time darkness",
"edt_dev_spec_uid_title": "UID",
"edt_dev_spec_universe_title": "Universe",
"edt_dev_spec_useEntertainmentAPI_title": "Use Hue Entertainment API",
@ -538,16 +554,16 @@
"edt_eff_collision_header": "color collision",
"edt_eff_collision_header_desc": "Two color projectiles are sent from random positions and collide with each other",
"edt_eff_color": "Color",
"edt_eff_colorHour": "Color hour",
"edt_eff_colorMarker": "Marker color",
"edt_eff_colorMinute": "Color minute",
"edt_eff_colorSecond": "Color second",
"edt_eff_colorcount": "Color length",
"edt_eff_colorend": "Color end",
"edt_eff_colorendtime": "Time to hold start color",
"edt_eff_colorevel": "Color level",
"edt_eff_colorHour": "Color hour",
"edt_eff_colorMarker": "Marker color",
"edt_eff_colorMinute": "Color minute",
"edt_eff_colorone": "Color one",
"edt_eff_colorrandom": "Random color",
"edt_eff_colorSecond": "Color second",
"edt_eff_colorshift": "Color Shift",
"edt_eff_colorstart": "Color start",
"edt_eff_colorstarttime": "Time to hold end color",
@ -603,13 +619,13 @@
"edt_eff_postcolor": "Post color",
"edt_eff_rainbowmood_header": "Rainbow Mood",
"edt_eff_rainbowmood_header_desc": "All LEDs rainbow mood",
"edt_eff_randomCenter": "Random Center",
"edt_eff_random_header": "Random",
"edt_eff_random_header_desc": "Pixel Dot, dot, dot...",
"edt_eff_randomCenter": "Random Center",
"edt_eff_repeat": "Repeat",
"edt_eff_repeatcount": "Repeat count",
"edt_eff_reverseRandomTime": "Reverse every",
"edt_eff_reversedirection": "Reverse direction",
"edt_eff_reverseRandomTime": "Reverse every",
"edt_eff_rotationtime": "Rotation time",
"edt_eff_saturation": "Saturation",
"edt_eff_showseconds": "Show seconds",
@ -647,23 +663,23 @@
"edt_msg_button_expand": "Expand",
"edt_msg_button_move_down_title": "Move down",
"edt_msg_button_move_up_title": "Move up",
"edt_msg_error_additionalItems": "No additional items allowed in this array",
"edt_msg_error_additional_properties": "No additional properties allowed, but property $1 is set",
"edt_msg_error_additionalItems": "No additional items allowed in this array",
"edt_msg_error_anyOf": "Value must validate against at least one of the provided schemas",
"edt_msg_error_dependency": "Must have property $1",
"edt_msg_error_disallow": "Value must not be of type $1",
"edt_msg_error_disallow_union": "Value must not be one of the provided disallowed types",
"edt_msg_error_enum": "Value must be one of the enumerated values",
"edt_msg_error_maximum_excl": "Value must be less than $1",
"edt_msg_error_maximum_incl": "Value must be at most $1",
"edt_msg_error_maxItems": "Value must have at most $1 items",
"edt_msg_error_maxLength": "Value must be at most $1 characters long",
"edt_msg_error_maxProperties": "Object must have at most $1 properties",
"edt_msg_error_maximum_excl": "Value must be less than $1",
"edt_msg_error_maximum_incl": "Value must be at most $1",
"edt_msg_error_minimum_excl": "Value must be greater than $1",
"edt_msg_error_minimum_incl": "Value must be at least $1",
"edt_msg_error_minItems": "Value must have at least $1 items",
"edt_msg_error_minLength": "Value must be at least $1 characters long",
"edt_msg_error_minProperties": "Object must have at least $1 properties",
"edt_msg_error_minimum_excl": "Value must be greater than $1",
"edt_msg_error_minimum_incl": "Value must be at least $1",
"edt_msg_error_multipleOf": "Value must be a multiple of $1",
"edt_msg_error_not": "Value must not validate against the provided schema",
"edt_msg_error_notempty": "Value required",
@ -698,6 +714,7 @@
"general_btn_off": "Off",
"general_btn_ok": "OK",
"general_btn_on": "On",
"general_btn_overwrite": "Overwrite",
"general_btn_rename": "Rename",
"general_btn_restarthyperion": "Restart Hyperion",
"general_btn_save": "Save",
@ -745,20 +762,6 @@
"general_speech_zh-CN": "Chinese (simplified)",
"general_webui_title": "Hyperion - Web Configuration",
"general_wiki_moreto": "More information to \"$1\" at our Wiki",
"infoDialog_checklist_title": "Checklist!",
"infoDialog_effconf_created_text": "The effect \"$1\" has been created successfully!",
"infoDialog_effconf_deleted_text": "The effect \"$1\" has been deleted successfully!",
"infoDialog_general_error_title": "Error",
"infoDialog_general_success_title": "Success",
"infoDialog_general_warning_title": "Warning",
"infoDialog_import_comperror_text": "Sad! Your browser doesn't support a import. Please try again with another browser.",
"infoDialog_import_confirm_text": "Are you sure to import \"$1\"? This process can't be reverted!",
"infoDialog_import_confirm_title": "Confirm import",
"infoDialog_import_hyperror_text": "The selected configuration file \"$1\" can't be imported. It's not compatible with Hyperion 2.0 and higher!",
"infoDialog_import_jsonerror_text": "The selected configuration file \"$1\" is no .json file or it's corrupted. Error message: ($2)",
"infoDialog_wizrgb_text": "Your RGB Byte Order is already well adjusted.",
"infoDialog_writeconf_error_text": "Saving your configuration failed.",
"infoDialog_writeimage_error_text": "The selected file \"$1\" is no image file or it's corrupted! Please select another image file.",
"info_404": "The page you requested is not available!",
"info_conlost_label_autorecon": "We reconnect again after Hyperion is available.",
"info_conlost_label_autorefresh": "This page will be automatically refreshed.",
@ -772,6 +775,31 @@
"info_restart_contusa": "...with your last steps. Thank you!",
"info_restart_rightback": "Hyperion will be right back immediately!",
"info_restart_title": "Restarts currently...",
"InfoDialog_access_text": "Depending on settings level you could adjust more options or get access to more features. Recommended is the \"Default\" level.",
"InfoDialog_access_title": "Settings level",
"InfoDialog_changePassword_success": "Password successfully saved!",
"InfoDialog_changePassword_title": "Change Password",
"infoDialog_checklist_title": "Checklist!",
"infoDialog_effconf_created_text": "The effect \"$1\" has been created successfully!",
"infoDialog_effconf_deleted_text": "The effect \"$1\" has been deleted successfully!",
"infoDialog_general_error_title": "Error",
"infoDialog_general_success_title": "Success",
"infoDialog_general_warning_title": "Warning",
"infoDialog_import_comperror_text": "Sad! Your browser doesn't support a import. Please try again with another browser.",
"infoDialog_import_confirm_text": "Are you sure to import \"$1\"? This process can't be reverted!",
"infoDialog_import_confirm_title": "Confirm import",
"infoDialog_import_hyperror_text": "The selected configuration file \"$1\" can't be imported. It's not compatible with Hyperion 2.0 and higher!",
"infoDialog_import_jsonerror_text": "The selected configuration file \"$1\" is no .json file or it's corrupted. Error message: ($2)",
"InfoDialog_iswitch_text": "If you run Hyperion more than once in your local network, you could switch between the web configurations. Select the Hyperion instance below and switch!",
"InfoDialog_iswitch_title": "Hyperion switcher",
"InfoDialog_lang_text": "If you don't like the result of the automatic language detection you could overwrite it here.",
"InfoDialog_lang_title": "Language setting",
"InfoDialog_nowrite_foottext": "The WebUI will be unlocked automatically after you solved the problem!",
"InfoDialog_nowrite_text": "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.",
"InfoDialog_nowrite_title": "write permission error!",
"infoDialog_wizrgb_text": "Your RGB Byte Order is already well adjusted.",
"infoDialog_writeconf_error_text": "Saving your configuration failed.",
"infoDialog_writeimage_error_text": "The selected file \"$1\" is no image file or it's corrupted! Please select another image file.",
"main_ledsim_btn_togglelednumber": "LED numbers",
"main_ledsim_btn_toggleleds": "Show LEDs",
"main_ledsim_btn_togglelivevideo": "Live video",

View File

@ -101,7 +101,7 @@
<span class="icon-bar middle-bar"></span>
<span class="icon-bar bottom-bar"></span>
</button>
<a class="navbar-brand" href="https://www.hyperion-project.org?pk_campaign=WebUI&pk_kwd=mainlogo" target="_blank"><img src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!" height="55"></a>
<a class="navbar-brand" href="https://www.hyperion-project.org" target="_blank"><img src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!" height="55"></a>
</div>
<!-- /.navbar-header -->
@ -234,7 +234,7 @@
<a class="inactive"><i class="fa fa-industry fa-fw"></i><span data-i18n="main_menu_system_token">System</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
<li> <a class="inactive mnava" href="#conf_webconfig" id="load_webconfig"><i class="fa fa-wrench fa-fw"></i><span data-i18n="main_menu_webconfig_token">Webconfiguration</span></a> </li>
<li> <a class="inactive mnava" href="#conf_logging"><i class="fa fa-reorder fa-fw"></i><span data-i18n="main_menu_logging_token">Log</span></a> </li>
<li> <a class="inactive mnava" id="MenuItemLogging" href="#conf_logging"><i class="fa fa-reorder fa-fw"></i><span data-i18n="main_menu_logging_token">Log</span></a> </li>
<li> <a class="inactive mnava" href="#update"><i class="fa fa-download fa-fw"></i><span data-i18n="main_menu_update_token">Update</span></a> </li>
<li> <a class="inactive mnava" href="#about"><i class="fa fa-info-circle fa-fw"></i><span data-i18n="main_menu_about_token">About</span></a> </li>
</ul>

154
assets/webconfig/js/content_colors.js Normal file → Executable file
View File

@ -1,84 +1,80 @@
$(document).ready( function() {
performTranslation();
var editor_color = null;
var editor_smoothing = null;
var editor_blackborder = null;
if(window.showOptHelp)
{
//color
$('#conf_cont').append(createRow('conf_cont_color'));
$('#conf_cont_color').append(createOptPanel('fa-photo', $.i18n("edt_conf_color_heading_title"), 'editor_container_color', 'btn_submit_color'));
$('#conf_cont_color').append(createHelpTable(window.schema.color.properties, $.i18n("edt_conf_color_heading_title")));
//smoothing
$('#conf_cont').append(createRow('conf_cont_smoothing'));
$('#conf_cont_smoothing').append(createOptPanel('fa-photo', $.i18n("edt_conf_smooth_heading_title"), 'editor_container_smoothing', 'btn_submit_smoothing'));
$('#conf_cont_smoothing').append(createHelpTable(window.schema.smoothing.properties, $.i18n("edt_conf_smooth_heading_title")));
//blackborder
$('#conf_cont').append(createRow('conf_cont_blackborder'));
$('#conf_cont_blackborder').append(createOptPanel('fa-photo', $.i18n("edt_conf_bb_heading_title"), 'editor_container_blackborder', 'btn_submit_blackborder'));
$('#conf_cont_blackborder').append(createHelpTable(window.schema.blackborderdetector.properties, $.i18n("edt_conf_bb_heading_title")));
}
else
{
$('#conf_cont').addClass('row');
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_color_heading_title"), 'editor_container_color', 'btn_submit_color'));
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_smooth_heading_title"), 'editor_container_smoothing', 'btn_submit_smoothing'));
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_bb_heading_title"), 'editor_container_blackborder', 'btn_submit_blackborder'));
}
//color
editor_color = createJsonEditor('editor_container_color', {
color : window.schema.color
}, true, true);
$(document).ready(function () {
performTranslation();
var editor_color = null;
var editor_smoothing = null;
var editor_blackborder = null;
editor_color.on('change',function() {
editor_color.validate().length || window.readOnlyMode ? $('#btn_submit_color').attr('disabled', true) : $('#btn_submit_color').attr('disabled', false);
});
$('#btn_submit_color').off().on('click',function() {
requestWriteConfig(editor_color.getValue());
});
//smoothing
editor_smoothing = createJsonEditor('editor_container_smoothing', {
smoothing : window.schema.smoothing
}, true, true);
if (window.showOptHelp) {
//color
$('#conf_cont').append(createRow('conf_cont_color'));
$('#conf_cont_color').append(createOptPanel('fa-photo', $.i18n("edt_conf_color_heading_title"), 'editor_container_color', 'btn_submit_color'));
$('#conf_cont_color').append(createHelpTable(window.schema.color.properties, $.i18n("edt_conf_color_heading_title")));
editor_smoothing.on('change',function() {
editor_smoothing.validate().length || window.readOnlyMode ? $('#btn_submit_smoothing').attr('disabled', true) : $('#btn_submit_smoothing').attr('disabled', false);
});
$('#btn_submit_smoothing').off().on('click',function() {
requestWriteConfig(editor_smoothing.getValue());
});
//smoothing
$('#conf_cont').append(createRow('conf_cont_smoothing'));
$('#conf_cont_smoothing').append(createOptPanel('fa-photo', $.i18n("edt_conf_smooth_heading_title"), 'editor_container_smoothing', 'btn_submit_smoothing'));
$('#conf_cont_smoothing').append(createHelpTable(window.schema.smoothing.properties, $.i18n("edt_conf_smooth_heading_title")));
//blackborder
editor_blackborder = createJsonEditor('editor_container_blackborder', {
blackborderdetector: window.schema.blackborderdetector
}, true, true);
//blackborder
$('#conf_cont').append(createRow('conf_cont_blackborder'));
$('#conf_cont_blackborder').append(createOptPanel('fa-photo', $.i18n("edt_conf_bb_heading_title"), 'editor_container_blackborder', 'btn_submit_blackborder'));
$('#conf_cont_blackborder').append(createHelpTable(window.schema.blackborderdetector.properties, $.i18n("edt_conf_bb_heading_title")));
}
else {
$('#conf_cont').addClass('row');
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_color_heading_title"), 'editor_container_color', 'btn_submit_color'));
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_smooth_heading_title"), 'editor_container_smoothing', 'btn_submit_smoothing'));
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_bb_heading_title"), 'editor_container_blackborder', 'btn_submit_blackborder'));
}
editor_blackborder.on('change',function() {
editor_blackborder.validate().length || window.readOnlyMode ? $('#btn_submit_blackborder').attr('disabled', true) : $('#btn_submit_blackborder').attr('disabled', false);
});
$('#btn_submit_blackborder').off().on('click',function() {
requestWriteConfig(editor_blackborder.getValue());
});
//wiki links
$('#editor_container_blackborder').append(buildWL("user/moretopics/bbmode","edt_conf_bb_mode_title",true));
//create introduction
if(window.showOptHelp)
{
createHint("intro", $.i18n('conf_colors_color_intro'), "editor_container_color");
createHint("intro", $.i18n('conf_colors_smoothing_intro'), "editor_container_smoothing");
createHint("intro", $.i18n('conf_colors_blackborder_intro'), "editor_container_blackborder");
}
removeOverlay();
//color
editor_color = createJsonEditor('editor_container_color', {
color: window.schema.color
}, true, true);
editor_color.on('change', function () {
editor_color.validate().length || window.readOnlyMode ? $('#btn_submit_color').attr('disabled', true) : $('#btn_submit_color').attr('disabled', false);
});
$('#btn_submit_color').off().on('click', function () {
requestWriteConfig(editor_color.getValue());
});
//smoothing
editor_smoothing = createJsonEditor('editor_container_smoothing', {
smoothing: window.schema.smoothing
}, true, true);
editor_smoothing.on('change', function () {
editor_smoothing.validate().length || window.readOnlyMode ? $('#btn_submit_smoothing').attr('disabled', true) : $('#btn_submit_smoothing').attr('disabled', false);
});
$('#btn_submit_smoothing').off().on('click', function () {
requestWriteConfig(editor_smoothing.getValue());
});
//blackborder
editor_blackborder = createJsonEditor('editor_container_blackborder', {
blackborderdetector: window.schema.blackborderdetector
}, true, true);
editor_blackborder.on('change', function () {
editor_blackborder.validate().length || window.readOnlyMode ? $('#btn_submit_blackborder').attr('disabled', true) : $('#btn_submit_blackborder').attr('disabled', false);
});
$('#btn_submit_blackborder').off().on('click', function () {
requestWriteConfig(editor_blackborder.getValue());
});
//wiki links
$('#editor_container_blackborder').append(buildWL("user/advanced/Advanced.html#blackbar-detection", "edt_conf_bb_mode_title", true));
//create introduction
if (window.showOptHelp) {
createHint("intro", $.i18n('conf_colors_color_intro'), "editor_container_color");
createHint("intro", $.i18n('conf_colors_smoothing_intro'), "editor_container_smoothing");
createHint("intro", $.i18n('conf_colors_blackborder_intro'), "editor_container_blackborder");
}
removeOverlay();
});

575
assets/webconfig/js/content_index.js Normal file → Executable file
View File

@ -1,354 +1,357 @@
var instNameInit = false
$(document).ready(function () {
var darkModeOverwrite = getStorage("darkModeOverwrite", true);
var darkModeOverwrite = getStorage("darkModeOverwrite", true);
if (darkModeOverwrite == "false" || darkModeOverwrite == null) {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
handleDarkMode();
}
if(darkModeOverwrite == "false" || darkModeOverwrite == null)
{
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
handleDarkMode();
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
setStorage("darkMode", "off", false);
}
}
if(getStorage("darkMode", false) == "on")
{
handleDarkMode();
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
setStorage("darkMode", "off", false);
}
}
loadContentTo("#container_connection_lost", "connection_lost");
loadContentTo("#container_restart", "restart");
initWebSocket();
if (getStorage("darkMode", false) == "on") {
handleDarkMode();
}
$(window.hyperion).on("cmd-serverinfo", function (event) {
window.serverInfo = event.response.info;
window.readOnlyMode = window.sysInfo.hyperion.readOnlyMode;
// comps
window.comps = event.response.info.components
loadContentTo("#container_connection_lost", "connection_lost");
loadContentTo("#container_restart", "restart");
initWebSocket();
$(window.hyperion).trigger("ready");
$(window.hyperion).on("cmd-serverinfo", function (event) {
window.serverInfo = event.response.info;
window.comps.forEach(function (obj) {
if (obj.name == "ALL") {
if (obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
}
});
window.readOnlyMode = window.sysInfo.hyperion.readOnlyMode;
// determine button visibility
var running = window.serverInfo.instance.filter(entry => entry.running);
if (running.length > 1)
$('#btn_hypinstanceswitch').toggle(true)
else
$('#btn_hypinstanceswitch').toggle(false)
// update listing at button
updateHyperionInstanceListing()
if (!instNameInit) {
window.currentHyperionInstanceName = getInstanceNameByIndex(0);
instNameInit = true;
}
// comps
window.comps = event.response.info.components
updateSessions();
}); // end cmd-serverinfo
$(window.hyperion).trigger("ready");
// Update language selection
$("#language-select").on('changed.bs.select',function (e, clickedIndex, isSelected, previousValue){
var newLang = availLang[clickedIndex-1];
if (newLang !== storedLang)
{
setStorage("langcode", newLang);
reload();
}
});
window.comps.forEach(function (obj) {
if (obj.name == "ALL") {
if (obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
}
});
$("#language-select").selectpicker(
{
container: 'body'
});
// determine button visibility
var running = window.serverInfo.instance.filter(entry => entry.running);
if (running.length > 1)
$('#btn_hypinstanceswitch').toggle(true)
else
$('#btn_hypinstanceswitch').toggle(false)
// update listing at button
updateHyperionInstanceListing()
if (!instNameInit) {
window.currentHyperionInstanceName = getInstanceNameByIndex(0);
instNameInit = true;
}
$(".bootstrap-select").click(function () {
$(this).addClass("open");
});
updateSessions();
}); // end cmd-serverinfo
$(document).click(function(){
$(".bootstrap-select").removeClass("open");
});
// Update language selection
$("#language-select").on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
var newLang = availLang[clickedIndex - 1];
if (newLang !== storedLang) {
setStorage("langcode", newLang);
reload();
}
});
$(".bootstrap-select").click(function(e){
e.stopPropagation();
});
//End language selection
$(window.hyperion).on("cmd-sessions-update", function (event) {
window.serverInfo.sessions = event.response.data;
updateSessions();
});
$("#language-select").selectpicker(
{
container: 'body'
});
$(window.hyperion).on("cmd-authorize-tokenRequest cmd-authorize-getPendingTokenRequests", function (event) {
var val = event.response.info;
if (Array.isArray(event.response.info)) {
if (event.response.info.length == 0) {
return
}
val = event.response.info[0]
if (val.comment == '')
$('#modal_dialog').modal('hide');
}
$(".bootstrap-select").click(function () {
$(this).addClass("open");
});
showInfoDialog("grantToken", $.i18n('conf_network_tok_grantT'), $.i18n('conf_network_tok_grantMsg') + '<br><span style="font-weight:bold">App: ' + val.comment + '</span><br><span style="font-weight:bold">Code: ' + val.id + '</span>')
$("#tok_grant_acc").off().on('click', function () {
tokenList.push(val)
// forward event, in case we need to rebuild the list now
$(window.hyperion).trigger({ type: "build-token-list" });
requestHandleTokenRequest(val.id, true)
});
$("#tok_deny_acc").off().on('click', function () {
requestHandleTokenRequest(val.id, false)
});
});
$(document).click(function () {
$(".bootstrap-select").removeClass("open");
});
$(window.hyperion).one("cmd-authorize-getTokenList", function (event) {
tokenList = event.response.info;
requestServerInfo();
});
$(".bootstrap-select").click(function (e) {
e.stopPropagation();
});
$(window.hyperion).on("cmd-sysinfo", function (event) {
requestServerInfo();
window.sysInfo = event.response.info;
//End language selection
window.currentVersion = window.sysInfo.hyperion.version;
window.currentChannel = window.sysInfo.hyperion.channel;
});
$(window.hyperion).on("cmd-sessions-update", function (event) {
window.serverInfo.sessions = event.response.data;
updateSessions();
});
$(window.hyperion).one("cmd-config-getschema", function (event) {
window.serverSchema = event.response.info;
requestServerConfig();
$(window.hyperion).on("cmd-authorize-tokenRequest cmd-authorize-getPendingTokenRequests", function (event) {
var val = event.response.info;
if (Array.isArray(event.response.info)) {
if (event.response.info.length == 0) {
return
}
val = event.response.info[0]
if (val.comment == '')
$('#modal_dialog').modal('hide');
}
showInfoDialog("grantToken", $.i18n('conf_network_tok_grantT'), $.i18n('conf_network_tok_grantMsg') + '<br><span style="font-weight:bold">App: ' + val.comment + '</span><br><span style="font-weight:bold">Code: ' + val.id + '</span>')
$("#tok_grant_acc").off().on('click', function () {
tokenList.push(val)
// forward event, in case we need to rebuild the list now
$(window.hyperion).trigger({ type: "build-token-list" });
requestHandleTokenRequest(val.id, true)
});
$("#tok_deny_acc").off().on('click', function () {
requestHandleTokenRequest(val.id, false)
});
});
$(window.hyperion).one("cmd-authorize-getTokenList", function (event) {
tokenList = event.response.info;
requestServerInfo();
});
$(window.hyperion).on("cmd-sysinfo", function (event) {
requestServerInfo();
window.sysInfo = event.response.info;
window.currentVersion = window.sysInfo.hyperion.version;
window.currentChannel = window.sysInfo.hyperion.channel;
});
$(window.hyperion).one("cmd-config-getschema", function (event) {
window.serverSchema = event.response.info;
requestServerConfig();
requestTokenInfo();
requestGetPendingTokenRequests();
window.schema = window.serverSchema.properties;
});
window.schema = window.serverSchema.properties;
});
$(window.hyperion).on("cmd-config-getconfig", function (event) {
window.serverConfig = event.response.info;
requestSysInfo();
$(window.hyperion).on("cmd-config-getconfig", function (event) {
window.serverConfig = event.response.info;
requestSysInfo();
window.showOptHelp = window.serverConfig.general.showOptHelp;
});
window.showOptHelp = window.serverConfig.general.showOptHelp;
});
$(window.hyperion).on("cmd-config-setconfig", function (event) {
if (event.response.success === true) {
showNotification('success', $.i18n('dashboard_alert_message_confsave_success'), $.i18n('dashboard_alert_message_confsave_success_t'))
}
});
$(window.hyperion).on("cmd-config-setconfig", function (event) {
if (event.response.success === true) {
showNotification('success', $.i18n('dashboard_alert_message_confsave_success'), $.i18n('dashboard_alert_message_confsave_success_t'))
}
});
$(window.hyperion).on("cmd-authorize-login", function (event) {
$("#main-nav").removeAttr('style')
$("#top-navbar").removeAttr('style')
$(window.hyperion).on("cmd-authorize-login", function (event) {
$("#main-nav").removeAttr('style')
$("#top-navbar").removeAttr('style')
if (window.defaultPasswordIsSet === true && getStorage("suppressDefaultPwWarning") !== "true" )
{
var supprPwWarnCheckbox = '<div class="text-right">'+$.i18n('dashboard_message_do_not_show_again')
+ ' <input id="chk_suppressDefaultPw" type="checkbox" onChange="suppressDefaultPwWarning()"> </div>'
showNotification('warning', $.i18n('dashboard_message_default_password'), $.i18n('dashboard_message_default_password_t'), '<a style="cursor:pointer" onClick="changePassword()">'
+ $.i18n('InfoDialog_changePassword_title') + '</a>' + supprPwWarnCheckbox)
}
else
//if logged on and pw != default show option to lock ui
$("#btn_lock_ui").removeAttr('style')
if (window.defaultPasswordIsSet === true && getStorage("suppressDefaultPwWarning") !== "true") {
var supprPwWarnCheckbox = '<div class="text-right">' + $.i18n('dashboard_message_do_not_show_again')
+ ' <input id="chk_suppressDefaultPw" type="checkbox" onChange="suppressDefaultPwWarning()"> </div>'
showNotification('warning', $.i18n('dashboard_message_default_password'), $.i18n('dashboard_message_default_password_t'), '<a style="cursor:pointer" onClick="changePassword()">'
+ $.i18n('InfoDialog_changePassword_title') + '</a>' + supprPwWarnCheckbox)
}
else
//if logged on and pw != default show option to lock ui
$("#btn_lock_ui").removeAttr('style')
if (event.response.hasOwnProperty('info'))
setStorage("loginToken", event.response.info.token, true);
if (event.response.hasOwnProperty('info'))
setStorage("loginToken", event.response.info.token, true);
requestServerConfigSchema();
});
requestServerConfigSchema();
});
$(window.hyperion).on("cmd-authorize-newPassword", function (event) {
if (event.response.success === true) {
showInfoDialog("success", $.i18n('InfoDialog_changePassword_success'));
// not necessarily true, but better than nothing
window.defaultPasswordIsSet = false;
}
});
$(window.hyperion).on("cmd-authorize-newPassword", function (event) {
if (event.response.success === true) {
showInfoDialog("success", $.i18n('InfoDialog_changePassword_success'));
// not necessarily true, but better than nothing
window.defaultPasswordIsSet = false;
}
});
$(window.hyperion).on("cmd-authorize-newPasswordRequired", function (event) {
var loginToken = getStorage("loginToken", true)
$(window.hyperion).on("cmd-authorize-newPasswordRequired", function (event) {
var loginToken = getStorage("loginToken", true)
if (event.response.info.newPasswordRequired == true) {
window.defaultPasswordIsSet = true;
if (event.response.info.newPasswordRequired == true) {
window.defaultPasswordIsSet = true;
if (loginToken)
requestTokenAuthorization(loginToken)
else
requestAuthorization('hyperion');
}
else {
$("#main-nav").attr('style', 'display:none')
$("#top-navbar").attr('style', 'display:none')
if (loginToken)
requestTokenAuthorization(loginToken)
else
requestAuthorization('hyperion');
}
else {
$("#main-nav").attr('style', 'display:none')
$("#top-navbar").attr('style', 'display:none')
if (loginToken)
requestTokenAuthorization(loginToken)
else
loadContentTo("#page-content", "login")
}
});
if (loginToken)
requestTokenAuthorization(loginToken)
else
loadContentTo("#page-content", "login")
}
});
$(window.hyperion).on("cmd-authorize-adminRequired", function (event) {
//Check if a admin login is required.
//If yes: check if default pw is set. If no: go ahead to get server config and render page
if (event.response.info.adminRequired === true)
requestRequiresDefaultPasswortChange();
else
requestServerConfigSchema();
});
$(window.hyperion).on("cmd-authorize-adminRequired", function (event) {
//Check if a admin login is required.
//If yes: check if default pw is set. If no: go ahead to get server config and render page
if (event.response.info.adminRequired === true)
requestRequiresDefaultPasswortChange();
else
requestServerConfigSchema();
});
$(window.hyperion).on("error", function (event) {
//If we are getting an error "No Authorization" back with a set loginToken we will forward to new Login (Token is expired.
//e.g.: hyperiond was started new in the meantime)
if (event.reason == "No Authorization" && getStorage("loginToken", true)) {
removeStorage("loginToken", true);
requestRequiresAdminAuth();
}
else {
showInfoDialog("error", "Error", event.reason);
}
});
$(window.hyperion).on("error", function (event) {
//If we are getting an error "No Authorization" back with a set loginToken we will forward to new Login (Token is expired.
//e.g.: hyperiond was started new in the meantime)
if (event.reason == "No Authorization" && getStorage("loginToken", true)) {
removeStorage("loginToken", true);
requestRequiresAdminAuth();
}
else {
showInfoDialog("error", "Error", event.reason);
}
});
$(window.hyperion).on("open", function (event) {
requestRequiresAdminAuth();
});
$(window.hyperion).on("open", function (event) {
requestRequiresAdminAuth();
});
$(window.hyperion).one("ready", function (event) {
loadContent();
});
$(window.hyperion).one("ready", function (event) {
loadContent();
});
$(window.hyperion).on("cmd-adjustment-update", function (event) {
window.serverInfo.adjustment = event.response.data
});
$(window.hyperion).on("cmd-adjustment-update", function (event) {
window.serverInfo.adjustment = event.response.data
});
$(window.hyperion).on("cmd-videomode-update", function (event) {
window.serverInfo.videomode = event.response.data.videomode
});
$(window.hyperion).on("cmd-videomode-update", function (event) {
window.serverInfo.videomode = event.response.data.videomode
});
$(window.hyperion).on("cmd-components-update", function (event) {
let obj = event.response.data
$(window.hyperion).on("cmd-components-update", function (event) {
let obj = event.response.data
// notfication in index
if (obj.name == "ALL") {
if (obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
}
// notfication in index
if (obj.name == "ALL") {
if (obj.enabled)
$("#hyperion_disabled_notify").fadeOut("fast");
else
$("#hyperion_disabled_notify").fadeIn("fast");
}
window.comps.forEach((entry, index) => {
if (entry.name === obj.name) {
window.comps[index] = obj;
}
});
// notify the update
$(window.hyperion).trigger("components-updated", event.response.data);
});
window.comps.forEach((entry, index) => {
if (entry.name === obj.name) {
window.comps[index] = obj;
}
});
// notify the update
$(window.hyperion).trigger("components-updated", event.response.data);
});
$(window.hyperion).on("cmd-instance-update", function (event) {
window.serverInfo.instance = event.response.data
var avail = event.response.data;
// notify the update
$(window.hyperion).trigger("instance-updated");
$(window.hyperion).on("cmd-instance-update", function (event) {
window.serverInfo.instance = event.response.data
var avail = event.response.data;
// notify the update
$(window.hyperion).trigger("instance-updated");
// if our current instance is no longer available we are at instance 0 again.
var isInData = false;
for (var key in avail) {
if (avail[key].instance == currentHyperionInstance && avail[key].running) {
isInData = true;
}
}
// if our current instance is no longer available we are at instance 0 again.
var isInData = false;
for (var key in avail) {
if (avail[key].instance == currentHyperionInstance && avail[key].running) {
isInData = true;
}
}
if (!isInData) {
//Delete Storage information about the last used but now stopped instance
if (getStorage('lastSelectedInstance', false))
removeStorage('lastSelectedInstance', false)
if (!isInData) {
//Delete Storage information about the last used but now stopped instance
if (getStorage('lastSelectedInstance', false))
removeStorage('lastSelectedInstance', false)
currentHyperionInstance = 0;
currentHyperionInstanceName = getInstanceNameByIndex(0);
requestServerConfig();
setTimeout(requestServerInfo, 100)
setTimeout(requestTokenInfo, 200)
setTimeout(loadContent, 300, undefined, true)
}
currentHyperionInstance = 0;
currentHyperionInstanceName = getInstanceNameByIndex(0);
requestServerConfig();
setTimeout(requestServerInfo, 100)
setTimeout(requestTokenInfo, 200)
setTimeout(loadContent, 300, undefined, true)
}
// determine button visibility
var running = serverInfo.instance.filter(entry => entry.running);
if (running.length > 1)
$('#btn_hypinstanceswitch').toggle(true)
else
$('#btn_hypinstanceswitch').toggle(false)
// determine button visibility
var running = serverInfo.instance.filter(entry => entry.running);
if (running.length > 1)
$('#btn_hypinstanceswitch').toggle(true)
else
$('#btn_hypinstanceswitch').toggle(false)
// update listing for button
updateHyperionInstanceListing()
});
// update listing for button
updateHyperionInstanceListing()
});
$(window.hyperion).on("cmd-instance-switchTo", function (event) {
requestServerConfig();
setTimeout(requestServerInfo, 200)
setTimeout(requestTokenInfo, 400)
setTimeout(loadContent, 400, undefined, true)
});
$(window.hyperion).on("cmd-instance-switchTo", function (event) {
requestServerConfig();
setTimeout(requestServerInfo, 200)
setTimeout(requestTokenInfo, 400)
setTimeout(loadContent, 400, undefined, true)
});
$(window.hyperion).on("cmd-effects-update", function (event) {
window.serverInfo.effects = event.response.data.effects
});
$(".mnava").bind('click.menu', function (e) {
loadContent(e);
window.scrollTo(0, 0);
});
$(window.hyperion).on("cmd-effects-update", function (event) {
window.serverInfo.effects = event.response.data.effects
});
$(".mnava").bind('click.menu', function (e) {
loadContent(e);
window.scrollTo(0, 0);
});
});
function suppressDefaultPwWarning(){
if (document.getElementById('chk_suppressDefaultPw').checked)
setStorage("suppressDefaultPwWarning", "true");
else
setStorage("suppressDefaultPwWarning", "false");
function suppressDefaultPwWarning() {
if (document.getElementById('chk_suppressDefaultPw').checked)
setStorage("suppressDefaultPwWarning", "true");
else
setStorage("suppressDefaultPwWarning", "false");
}
$(function () {
var sidebar = $('#side-menu'); // cache sidebar to a variable for performance
sidebar.delegate('a.inactive', 'click', function () {
sidebar.find('.active').toggleClass('active inactive');
$(this).toggleClass('active inactive');
});
var sidebar = $('#side-menu'); // cache sidebar to a variable for performance
sidebar.delegate('a.inactive', 'click', function () {
sidebar.find('.active').toggleClass('active inactive');
$(this).toggleClass('active inactive');
});
});
// hotfix body padding when bs modals overlap
$(document.body).on('hide.bs.modal,hidden.bs.modal', function () {
$('body').css('padding-right', '0');
$('body').css('padding-right', '0');
});
//Dark Mode
$("#btn_darkmode").off().on("click",function(e){
if(getStorage("darkMode", false) != "on")
{
handleDarkMode();
setStorage("darkModeOverwrite", true, true);
}
else {
setStorage("darkMode", "off", false);
setStorage("darkModeOverwrite", true, true);
location.reload();
}
$("#btn_darkmode").off().on("click", function (e) {
if (getStorage("darkMode", false) != "on") {
handleDarkMode();
setStorage("darkModeOverwrite", true, true);
}
else {
setStorage("darkMode", "off", false);
setStorage("darkModeOverwrite", true, true);
location.reload();
}
});
// Menuitem toggle;
function SwitchToMenuItem(target) {
document.getElementById(target).click(); // Get <a href menu item;
let sidebar = $('#side-menu'); // Get sidebar menu;
sidebar.find('.active').toggleClass('inactive'); // find all active classes and set inactive;
sidebar.find('.in').removeClass("in"); // Find all collapsed menu items and close it by remove "in" class;
$('#' + target).removeClass('inactive'); // Remove inactive state by classname;
$('#' + target).addClass('active'); // Add active state by classname;
let cl_object = $('#' + target).closest('ul'); // Find closest ul sidemenu header;
cl_object.addClass('in'); // add class "in" to expand header in sidebar menu;
};

2019
assets/webconfig/js/content_leds.js Normal file → Executable file

File diff suppressed because it is too large Load Diff

239
assets/webconfig/js/ui_utils.js Normal file → Executable file
View File

@ -53,7 +53,7 @@ function updateSessions() {
if (sess && sess.length) {
window.wSess = [];
for (var i = 0; i < sess.length; i++) {
if (sess[i].type == "_hyperiond-http._tcp.") {
if (sess[i].type == "_http._tcp." || sess[i].type == "_https._tcp." || sess[i].type == "_hyperiond-http._tcp.") {
window.wSess.push(sess[i]);
}
}
@ -134,13 +134,13 @@ function updateHyperionInstanceListing() {
var currInstMarker = (data[key].instance == window.currentHyperionInstance) ? "component-on" : "";
var html = '<li id="hyperioninstance_' + data[key].instance + '"> \
<a> \
<div> \
<i class="fa fa-circle fa-fw '+ currInstMarker + '"></i> \
<span>'+ data[key].friendly_name + '</span> \
</div> \
</a> \
</li> '
<a> \
<div> \
<i class="fa fa-circle fa-fw '+ currInstMarker + '"></i> \
<span>'+ data[key].friendly_name + '</span> \
</div> \
</a> \
</li> '
if (data.length - 1 > key)
html += '<li class="divider"></li>'
@ -183,7 +183,6 @@ function initLanguageSelection() {
langText = availLangText[langIdx];
}
}
//console.log("langLocale: ", langLocale, "langText: ", langText);
$('#language-select').prop('title', langText);
$("#language-select").val(langIdx);
@ -463,6 +462,170 @@ function createJsonEditor(container, schema, setconfig, usePanel, arrayre) {
return editor;
}
function updateJsonEditorSelection(editor, key, addElements, newEnumVals, newTitelVals, newDefaultVal, addSelect, addCustom, addCustomAsFirst, customText) {
var orginalProperties = editor.schema.properties[key];
var newSchema = [];
newSchema[key] =
{
"type": "string",
"enum": [],
"required": true,
"options": { "enum_titles": [], "infoText": "" },
"propertyOrder": 1
};
//Add additional elements to overwrite defaults
for (var item in addElements) {
newSchema[key][item] = addElements[item];
}
if (orginalProperties) {
if (orginalProperties["title"]) {
newSchema[key]["title"] = orginalProperties["title"];
}
if (orginalProperties["options"] && orginalProperties["options"]["infoText"]) {
newSchema[key]["options"]["infoText"] = orginalProperties["options"]["infoText"];
}
if (orginalProperties["propertyOrder"]) {
newSchema[key]["propertyOrder"] = orginalProperties["propertyOrder"];
}
}
if (addCustom) {
if (newTitelVals.length === 0) {
newTitelVals = [...newEnumVals];
}
if (!!!customText) {
customText = "edt_conf_enum_custom";
}
if (addCustomAsFirst) {
newEnumVals.unshift("CUSTOM");
newTitelVals.unshift(customText);
} else {
newEnumVals.push("CUSTOM");
newTitelVals.push(customText);
}
if (newSchema[key].options.infoText) {
var customInfoText = newSchema[key].options.infoText + "_custom";
newSchema[key].options.infoText = customInfoText;
}
}
if (addSelect) {
newEnumVals.unshift("SELECT");
newTitelVals.unshift("edt_conf_enum_please_select");
newDefaultVal = "SELECT";
}
if (newEnumVals) {
newSchema[key]["enum"] = newEnumVals;
}
if (newTitelVals) {
newSchema[key]["options"]["enum_titles"] = newTitelVals;
}
if (newDefaultVal) {
newSchema[key]["default"] = newDefaultVal;
}
editor.original_schema.properties[key] = orginalProperties;
editor.schema.properties[key] = newSchema[key];
editor.removeObjectProperty(key);
delete editor.cached_editors[key];
editor.addObjectProperty(key);
}
function updateJsonEditorMultiSelection(editor, key, addElements, newEnumVals, newTitelVals, newDefaultVal) {
var orginalProperties = editor.schema.properties[key];
var newSchema = [];
newSchema[key] =
{
"type": "array",
"format": "select",
"items": {
"type": "string",
"enum": [],
"options": { "enum_titles": [] },
},
"options": { "infoText": "" },
"default": [],
"propertyOrder": 1
};
//Add additional elements to overwrite defaults
for (var item in addElements) {
newSchema[key][item] = addElements[item];
}
if (orginalProperties) {
if (orginalProperties["title"]) {
newSchema[key]["title"] = orginalProperties["title"];
}
if (orginalProperties["options"] && orginalProperties["options"]["infoText"]) {
newSchema[key]["options"]["infoText"] = orginalProperties["options"]["infoText"];
}
if (orginalProperties["propertyOrder"]) {
newSchema[key]["propertyOrder"] = orginalProperties["propertyOrder"];
}
}
if (newEnumVals) {
newSchema[key]["items"]["enum"] = newEnumVals;
}
if (newTitelVals) {
newSchema[key]["items"]["options"]["enum_titles"] = newTitelVals;
}
if (newDefaultVal) {
newSchema[key]["default"] = newDefaultVal;
}
editor.original_schema.properties[key] = orginalProperties;
editor.schema.properties[key] = newSchema[key];
editor.removeObjectProperty(key);
delete editor.cached_editors[key];
editor.addObjectProperty(key);
}
function updateJsonEditorRange(editor, key, minimum, maximum, defaultValue, step) {
var orginalProperties = editor.schema.properties[key];
var newSchema = [];
newSchema[key] = orginalProperties;
if (minimum) {
newSchema[key]["minimum"] = minimum;
}
if (maximum) {
newSchema[key]["maximum"] = maximum;
}
if (defaultValue) {
newSchema[key]["default"] = defaultValue;
}
if (step) {
newSchema[key]["step"] = step;
}
editor.original_schema.properties[key] = orginalProperties;
editor.schema.properties[key] = newSchema[key];
editor.removeObjectProperty(key);
delete editor.cached_editors[key];
editor.addObjectProperty(key);
}
function buildWL(link, linkt, cl) {
var baseLink = "https://docs.hyperion-project.org/";
var lang;
@ -655,6 +818,48 @@ function createOptPanel(phicon, phead, bodyid, footerid) {
return createPanel(phead, "", pfooter, "panel-default", bodyid);
}
function compareTwoValues(key1, key2, order = 'asc') {
return function innerSort(a, b) {
if (!a.hasOwnProperty(key1) || !b.hasOwnProperty(key1)) {
// property key1 doesn't exist on either object
return 0;
}
const varA1 = (typeof a[key1] === 'string')
? a[key1].toUpperCase() : a[key1];
const varB1 = (typeof b[key1] === 'string')
? b[key1].toUpperCase() : b[key1];
let comparison = 0;
if (varA1 > varB1) {
comparison = 1;
} else {
if (varA1 < varB1) {
comparison = -1;
} else {
if (!a.hasOwnProperty(key2) || !b.hasOwnProperty(key2)) {
// property key2 doesn't exist on either object
return 0;
}
const varA2 = (typeof a[key2] === 'string')
? a[key2].toUpperCase() : a[key2];
const varB2 = (typeof b[key1] === 'string')
? b[key2].toUpperCase() : b[key2];
if (varA2 > varB2) {
comparison = 1;
} else {
comparison = -1;
}
}
}
return (
(order === 'desc') ? (comparison * -1) : comparison
);
};
}
function sortProperties(list) {
for (var key in list) {
list[key].key = key;
@ -876,3 +1081,19 @@ function handleDarkMode() {
$('#btn_darkmode_icon').removeClass('fa fa-moon-o');
$('#btn_darkmode_icon').addClass('fa fa-sun-o');
}
function isAccessLevelCompliant(accessLevel) {
var isOK = true;
if (accessLevel) {
if (accessLevel === 'system') {
isOK = false;
}
else if (accessLevel === 'advanced' && storedAccess === 'default') {
isOK = false;
}
else if (accessLevel === 'expert' && storedAccess !== 'expert') {
isOK = false;
}
}
return isOK
}

437
assets/webconfig/js/wizard.js Normal file → Executable file
View File

@ -424,7 +424,7 @@ function startWizardCC() {
}
//create html
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n('wiz_cc_title'));
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n('wiz_cc_title') + '</h4><p>' + $.i18n('wiz_cc_intro1') + '</p><label>' + $.i18n('wiz_cc_kwebs') + '</label><input class="form-control" style="width:170px;margin:auto" id="wiz_cc_kodiip" type="text" placeholder="' + kodiAddress + '" value="' + kodiAddress + '" /><span id="kodi_status"></span><span id="multi_cali"></span>');
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n('wiz_cc_title') + '</h4><p>' + $.i18n('wiz_cc_intro1') + '</p><label>' + $.i18n('wiz_cc_kwebs') + '</label><input class="form-control" style="width:170px;margin:auto" id="wiz_cc_kodiip" type="text" placeholder="' + kodiAddress + '" value="' + kodiAddress + '" /><span id="kodi_status"></span><span id="multi_cali"></span>');
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont" disabled="disabled"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
$('#wizp2_body').html('<div id="wiz_cc_desc" style="font-weight:bold"></div><div id="editor_container_wiz"></div>');
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_back"><i class="fa fa-fw fa-chevron-left"></i>' + $.i18n('general_btn_back') + '</button><button type="button" class="btn btn-primary" id="btn_wiz_next">' + $.i18n('general_btn_next') + '<i style="margin-left:4px;"class="fa fa-fw fa-chevron-right"></i></button><button type="button" class="btn btn-warning" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>' + $.i18n('general_btn_save') + '</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
@ -437,10 +437,9 @@ function startWizardCC() {
});
$('#wiz_cc_kodiip').off().on('change', function () {
kodiAddress = $(this).val().trim();
$('#wizp1_body').find("kodiAddress").val(kodiAddress);
$('#kodi_status').html('');
// Remove Kodi's default Web-Socket port (9090) from display and ensure Kodi's default REST-API port (8080) is mapped to web-socket port to ease migration
@ -788,8 +787,6 @@ async function discover_hue_bridges() {
const r = res.info;
// Process devices returned by discovery
console.log(r);
if (r.devices.length == 0)
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
else {
@ -832,7 +829,7 @@ async function identify_hue_device(hostAddress, username, id) {
$('#btn_wiz_save').attr('disabled', true);
let params = { host: hostAddress, user: username, lightId: id };
const res = await requestLedDeviceIdentification('philipshue', params);
await requestLedDeviceIdentification('philipshue', params);
if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false);
@ -1187,7 +1184,6 @@ function get_hue_lights() {
}
(cC == 0 || window.readOnlyMode) ? $('#btn_wiz_save').attr("disabled", true) : $('#btn_wiz_save').attr("disabled", false);
});
}
$('.hue_sel_watch').trigger('change');
@ -1208,108 +1204,6 @@ function abortConnection(UserInterval) {
$("#wiz_hue_usrstate").html($.i18n('wiz_hue_failure_connection'));
}
//****************************
// Wizard WLED
//****************************
var lights = null;
function startWizardWLED(e) {
//create html
var wled_title = 'wiz_wled_title';
var wled_intro1 = 'wiz_wled_intro1';
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(wled_title));
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(wled_title) + '</h4><p>' + $.i18n(wled_intro1) + '</p>');
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
/*$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p style="font-weight:bold" id="hue_id_headline">'+$.i18n('wiz_wled_desc2')+'</p></div>');
createTable("lidsh", "lidsb", "hue_ids_t");
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lights_title'),$.i18n('wiz_pos'),$.i18n('wiz_identify')], true));
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_save')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
*/
//open modal
$("#wizard_modal").modal({
backdrop: "static",
keyboard: false,
show: true
});
//listen for continue
$('#btn_wiz_cont').off().on('click', function () {
/* For testing only
discover_wled();
var hostAddress = conf_editor.getEditor("root.specificOptions.host").getValue();
if(hostAddress != "")
{
getProperties_wled(hostAddress,"info");
identify_wled(hostAddress)
}
For testing only */
});
}
async function discover_wled() {
const res = await requestLedDeviceDiscovery('wled');
// TODO: error case unhandled
// res can be: false (timeout) or res.error (not found)
if (res && !res.error) {
const r = res.info
// Process devices returned by discovery
console.log(r);
if (r.devices.length == 0)
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
else {
for (const device of r.devices) {
console.log("Device:", device);
var ip = device.hostname + ":" + device.port;
console.log("Host:", ip);
//wledIPs.push({internalipaddress : ip});
}
}
}
}
async function getProperties_wled(hostAddress, resourceFilter) {
let params = { host: hostAddress, filter: resourceFilter };
const res = await requestLedDeviceProperties('wled', params);
// TODO: error case unhandled
// res can be: false (timeout) or res.error (not found)
if (res && !res.error) {
const r = res.info
// Process properties returned
console.log(r);
}
}
async function identify_wled(hostAddress) {
// Take care that new record cannot be save during background process
$('#btn_wiz_save').attr('disabled', true);
let params = { host: hostAddress };
const res = await requestLedDeviceIdentification('wled', params);
if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false);
}
}
//****************************
// Wizard Yeelight
//****************************
@ -1438,8 +1332,17 @@ async function discover_yeelight_lights() {
var light = {};
light.host = device.hostname;
light.port = device.port;
light.name = device.other.name;
light.model = device.other.model;
if (device.txt) {
light.name = device.name;
light.model = device.txt.md;
//Yeelight does not provide correct API port with mDNS response, use default one
light.port = 55443;
}
else {
light.name = device.other.name;
light.model = device.other.model;
}
lights.push(light);
}
}
@ -1469,7 +1372,8 @@ async function discover_yeelight_lights() {
}
function assign_yeelight_lights() {
var models = ['color', 'color1', 'color2', 'color4', 'stripe', 'strip1'];
// Model mappings, see https://www.home-assistant.io/integrations/yeelight/
var models = ['color', 'color1', 'YLDP02YL', 'YLDP02YL', 'color2', 'YLDP06YL', 'color4', 'YLDP13YL', 'stripe', 'YLDD04YL', 'strip1', 'YLDD01YL', 'YLDD02YL'];
// If records are left for configuration
if (Object.keys(lights).length > 0) {
@ -1534,7 +1438,7 @@ function assign_yeelight_lights() {
$('.yee_sel_watch').trigger('change');
}
else {
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights','Yeelights') + '</p>';
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights', 'Yeelights') + '</p>';
$('#wizp2_body').append(noLightsTxt);
}
}
@ -1555,15 +1459,14 @@ async function getProperties_yeelight(hostname, port) {
}
async function identify_yeelight_device(hostname, port) {
// Take care that new record cannot be save during background process
$('#btn_wiz_save').attr('disabled', true);
let params = { hostname: hostname, port: port };
const res = await requestLedDeviceIdentification("yeelight", params);
await requestLedDeviceIdentification("yeelight", params);
if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false);
$('#btn_wiz_save').attr('disabled', false);
}
}
@ -1675,14 +1578,12 @@ async function discover_atmoorb_lights(multiCastGroup, multiCastPort) {
var light = {};
var params = {};
if (multiCastGroup !== "")
{
if (multiCastGroup !== "") {
params.multiCastGroup = multiCastGroup;
}
if (multiCastPort !== 0)
{
params.multiCastPort = multiCastPort;
if (multiCastPort !== 0) {
params.multiCastPort = multiCastPort;
}
// Get discovered lights
@ -1692,7 +1593,7 @@ async function discover_atmoorb_lights(multiCastGroup, multiCastPort) {
// res can be: false (timeout) or res.error (not found)
if (res && !res.error) {
const r = res.info;
// Process devices returned by discovery
for (const device of r.devices) {
if (device.id !== "") {
@ -1774,7 +1675,7 @@ function assign_atmoorb_lights() {
$('.lidsb').append(createTableRow([orbId + lightAnnotation, '<select id="orb_' + lightid + '" ' + enabled + ' class="orb_sel_watch form-control">'
+ options
+ '</select>', '<button class="btn btn-sm btn-primary" ' + enabled + ' onClick=identify_atmoorb_device(' + orbId + ')>'
+ '</select>', '<button class="btn btn-sm btn-primary" ' + enabled + ' onClick=identify_atmoorb_device("' + orbId + '")>'
+ $.i18n('wiz_identify_light', orbId) + '</button>']));
}
@ -1793,303 +1694,19 @@ function assign_atmoorb_lights() {
$('.orb_sel_watch').trigger('change');
}
else {
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights','AtmoOrbs') + '</p>';
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights', 'AtmoOrbs') + '</p>';
$('#wizp2_body').append(noLightsTxt);
}
}
async function identify_atmoorb_device(orbId) {
// Take care that new record cannot be save during background process
$('#btn_wiz_save').attr('disabled', true);
let params = { id: orbId };
const res = await requestLedDeviceIdentification("atmoorb", params);
await requestLedDeviceIdentification("atmoorb", params);
if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false);
}
}
//****************************
// Wizard/Routines Nanoleaf
//****************************
async function discover_nanoleaf() {
const res = await requestLedDeviceDiscovery('nanoleaf');
// TODO: error case unhandled
// res can be: false (timeout) or res.error (not found)
if (res && !res.error) {
const r = res.info
// Process devices returned by discovery
console.log(r);
if (r.devices.length == 0)
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
else {
for (const device of r.devices) {
console.log("Device:", device);
var ip = device.hostname + ":" + device.port;
console.log("Host:", ip);
//nanoleafIPs.push({internalipaddress : ip});
}
}
}
}
async function getProperties_nanoleaf(hostAddress, authToken, resourceFilter) {
let params = { host: hostAddress, token: authToken, filter: resourceFilter };
const res = await requestLedDeviceProperties('nanoleaf', params);
// TODO: error case unhandled
// res can be: false (timeout) or res.error (not found)
if (res && !res.error) {
const r = res.info
// Process properties returned
console.log(r);
}
}
async function identify_nanoleaf(hostAddress, authToken) {
// Take care that new record cannot be save during background process
$('#btn_wiz_save').attr('disabled', true);
let params = { host: hostAddress, token: authToken };
const res = await requestLedDeviceIdentification('nanoleaf', params);
if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false);
}
}
//****************************
// Wizard Cololight
//****************************
var lights = null;
var selectedLightId = null;
function startWizardCololight(e) {
//create html
var cololight_title = 'wiz_cololight_title';
var cololight_intro1 = 'wiz_cololight_intro1';
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(cololight_title));
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(cololight_title) + '</h4><p>' + $.i18n(cololight_intro1) + '</p>');
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
$('#wizp2_body').append('<div id="colo_ids_t" style="display:none"><p style="font-weight:bold" id="colo_id_headline">' + $.i18n('wiz_cololight_desc2') + '</p></div>');
createTable("lidsh", "lidsb", "colo_ids_t");
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lights_title'), $.i18n('wiz_identify')], true));
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'
+ $.i18n('general_btn_save') + '</button><buttowindow.serverConfig.device = d;n type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'
+ $.i18n('general_btn_cancel') + '</button>');
//open modal
$("#wizard_modal").modal({
backdrop: "static",
keyboard: false,
show: true
});
//listen for continue
$('#btn_wiz_cont').off().on('click', function () {
beginWizardCololight();
$('#wizp1').toggle(false);
$('#wizp2').toggle(true);
});
}
function beginWizardCololight() {
lights = [];
discover_cololights();
$('#btn_wiz_save').off().on("click", function () {
//LED device config
//Start with a clean configuration
var d = {};
d.type = 'cololight';
//Cololight does not resolve into stable hostnames (as devices named the same), therefore use IP
if (!lights[selectedLightId].ip) {
d.host = lights[selectedLightId].host;
} else {
d.host = lights[selectedLightId].ip;
}
var coloLightProperties = lights[selectedLightId].props.properties;
if (Object.keys(coloLightProperties).length === 0) {
alert($.i18n('wiz_cololight_noprops'));
d.hardwareLedCount = 1;
}
else {
d.hardwareLedCount = coloLightProperties.ledCount;
}
d.colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder").getValue();
d.latchTime = parseInt(conf_editor.getEditor("root.specificOptions.latchTime").getValue());;
window.serverConfig.device = d;
//LED layout - have initial layout prepared matching the LED-count
var coloLightLedConfig = [];
if (coloLightProperties.modelType === "Strip") {
coloLightLedConfig = createClassicLedLayoutSimple(d.hardwareLedCount / 2, d.hardwareLedCount / 4, d.hardwareLedCount / 4, 0, d.hardwareLedCount / 4 * 3, false);
} else {
coloLightLedConfig = createClassicLedLayoutSimple(0, 0, 0, d.hardwareLedCount, 0, true);
}
window.serverConfig.leds = coloLightLedConfig;
//smoothing off
window.serverConfig.smoothing.enable = false;
requestWriteConfig(window.serverConfig, true);
resetWizard();
});
$('#btn_wiz_abort').off().on('click', resetWizard);
}
async function discover_cololights() {
const res = await requestLedDeviceDiscovery('cololight');
if (res && !res.error) {
const r = res.info;
// Process devices returned by discovery
for (const device of r.devices) {
if (device.ip !== "") {
if (getIpInLights(device.ip).length === 0) {
var light = {};
light.ip = device.ip;
light.host = device.hostname;
light.name = device.name;
light.type = device.type;
lights.push(light);
}
}
}
assign_cololight_lights();
}
}
function assign_cololight_lights() {
// If records are left for configuration
if (Object.keys(lights).length > 0) {
$('#wh_topcontainer').toggle(false);
$('#colo_ids_t, #btn_wiz_save').toggle(true);
$('.lidsb').html("");
var options = "";
for (var lightid in lights) {
lights[lightid].id = lightid;
var lightHostname = lights[lightid].host;
var lightIP = lights[lightid].ip;
var val = lightHostname + " (" + lightIP + ")";
options += '<option value="' + lightid + '">' + val + '</option>';
}
var enabled = 'enabled';
$('.lidsb').append(createTableRow(['<select id="colo_select_id" ' + enabled + ' class="colo_sel_watch form-control">'
+ options
+ '</select>', '<button id="wiz_identify_btn" class="btn btn-sm btn-primary">'
+ $.i18n('wiz_identify') + '</button>']));
$('.colo_sel_watch').bind("change", function () {
selectedLightId = $('#colo_select_id').val();
var lightIP = lights[selectedLightId].ip;
$('#wiz_identify_btn').unbind().bind('click', function (event) { identify_cololight_device(lightIP); });
if (!lights[selectedLightId].props) {
getProperties_cololight(lightIP);
}
});
$('.colo_sel_watch').trigger('change');
}
else {
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights','Cololights') + '</p>';
$('#wizp2_body').append(noLightsTxt);
}
}
async function getProperties_cololight(ip) {
let params = { host: ip };
const res = await requestLedDeviceProperties('cololight', params);
if (res && !res.error) {
var coloLightProperties = res.info;
//Store properties along light with given IP-address
var id = getIpInLights(ip)[0].id;
lights[id].props = coloLightProperties;
}
}
async function identify_cololight_device(hostAddress) {
// Take care that new record cannot be save during background process
$('#btn_wiz_save').attr('disabled', true);
let params = { host: hostAddress };
const res = await requestLedDeviceIdentification('cololight', params);
if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false);
}
}
//****************************
// Wizard/Routines RS232-Devices
//****************************
async function discover_providerRs232(rs232Type) {
const res = await requestLedDeviceDiscovery(rs232Type);
// TODO: error case unhandled
// res can be: false (timeout) or res.error (not found)
if (res && !res.error) {
const r = res.info
// Process serialPorts returned by discover
console.log(r);
}
}
//****************************
// Wizard/Routines HID (USB)-Devices
//****************************
async function discover_providerHid(hidType) {
const res = await requestLedDeviceDiscovery(hidType);
// TODO: error case unhandled
// res can be: false (timeout) or res.error (not found)
if (res && !res.error) {
const r = res.info
// Process HID returned by discover
console.log(r);
$('#btn_wiz_save').attr('disabled', false);
}
}

View File

@ -141,8 +141,8 @@ echo "---> or if already used by another service try: ${NET_IP}:8091"
$REBOOTMESSAGE
echo "-----------------------------------------------------------------------------"
echo "Webpage: www.hyperion-project.org"
echo "Wiki: wiki.hyperion-project.org"
echo "Forum: forum.hyperion-project.org"
echo "Forum: www.hyperion-project.org"
echo "Documenation: docs.hyperion-project.org"
echo "-----------------------------------------------------------------------------"

View File

@ -34,7 +34,10 @@ endif()
SET ( CPACK_PACKAGE_NAME "Hyperion" )
SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hyperion is an open source ambient light implementation" )
SET ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" )
SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
# Replease "+", as cmake/rpm has an issue if "+" occurs in CPACK_PACKAGE_VERSION
string(REPLACE "+" "." HYPERION_PACKAGE_VERSION ${HYPERION_VERSION})
SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
SET ( CPACK_PACKAGE_CONTACT "packages@hyperion-project.org")
SET ( CPACK_PACKAGE_VENDOR "hyperion-project")

View File

@ -131,8 +131,8 @@ echo "---> or if already used by another service try: ${NET_IP}:8091"
$REBOOTMESSAGE
echo "-----------------------------------------------------------------------------"
echo "Webpage: www.hyperion-project.org"
echo "Wiki: wiki.hyperion-project.org"
echo "Forum: forum.hyperion-project.org"
echo "Forum: www.hyperion-project.org"
echo "Documenation: docs.hyperion-project.org"
echo "-----------------------------------------------------------------------------"

View File

@ -3,9 +3,14 @@
#include <utils/Logger.h>
#include <utils/settings.h>
#include <utils/version.hpp>
using namespace semver;
// qt includes
#include <QJsonObject>
const int GLOABL_INSTANCE_ID = 255;
class Hyperion;
class SettingsTable;
@ -61,12 +66,17 @@ private:
bool handleConfigUpgrade(QJsonObject& config);
/// Hyperion instance
Hyperion* _hyperion;
bool resolveConfigVersion(QJsonObject& config);
/// Logger instance
Logger* _log;
/// Hyperion instance
Hyperion* _hyperion;
/// Instance number
quint8 _instance;
/// instance of database table interface
SettingsTable* _sTable;
@ -76,5 +86,8 @@ private:
/// the current configuration of this instance
QJsonObject _qconfig;
semver::version _configVersion;
semver::version _previousVersion;
bool _readonlyMode;
};

View File

@ -300,10 +300,21 @@ protected:
/// even if the device is not in enabled state (allowing to have a defined state during device power-off).
/// @note: latch-time is considered between each write
///
/// @param[in] numberOfWrites Write Black given number of times
/// @param[in] numberOfWrites Write Black a given number of times
/// @return Zero on success else negative
///
virtual int writeBlack(int numberOfBlack=1);
virtual int writeBlack(int numberOfWrites = 1);
///
/// @brief Writes a color to the output stream,
/// even if the device is not in enabled state (allowing to have a defined state during device power-off).
/// @note: latch-time is considered between each write
///
/// @param[in] color to be written
/// @param[in] numberOfWrites Write the color a given number of times
/// @return Zero on success else negative
///
virtual int writeColor(const ColorRgb& color, int numberOfWrites = 1);
///
/// @brief Power-/turn on the LED-device.
@ -431,7 +442,7 @@ protected slots:
///
/// @param[in] errorMsg The error message to be logged
///
virtual void setInError( const QString& errorMsg);
virtual void setInError( const QString& errorMsg);
private:

550
include/utils/version.hpp Normal file
View File

@ -0,0 +1,550 @@
#ifndef VERSION_H
#define VERSION_H
/**
* Semver - The Semantic Versioning, https://github.com/euskadi31/semver-cpp
*
* Copyright (c) 2013 Axel Etcheverry, 2021 enhancements & fixes Lord-Grey
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
namespace semver {
enum PRE_RELEASE {
PRE_RELEASE_ALPHA,
PRE_RELEASE_BETA,
PRE_RELEASE_RC,
PRE_RELEASE_NONE
};
typedef enum PRE_RELEASE pre_release_t;
class version
{
private:
std::string m_version;
int m_major;
int m_minor;
int m_patch;
pre_release_t m_pre_release_type;
std::string m_pre_release_id;
std::string m_pre_release;
std::string m_build;
bool m_is_valid;
bool m_is_stable;
enum m_type {
TYPE_MAJOR,
TYPE_MINOR,
TYPE_PATCH,
TYPE_PRE_RELEASE,
TYPE_PRE_RELEASE_ID,
TYPE_BUILD
};
void parse()
{
int type = TYPE_MAJOR;
std::string major, minor, patch;
for (std::size_t i = 0; i < m_version.length(); i++)
{
char chr = m_version[i];
int chr_dec = chr;
switch (type)
{
case TYPE_MAJOR:
if (chr == '.')
{
type = TYPE_MINOR;
continue;
}
if (chr_dec < 48 || chr_dec > 57)
{
m_is_valid = false;
}
// major
major += chr;
break;
case TYPE_MINOR:
if (chr == '.')
{
type = TYPE_PATCH;
continue;
}
if (chr_dec < 48 || chr_dec > 57)
{
m_is_valid = false;
}
minor += chr;
break;
case TYPE_PATCH:
if (chr == '-')
{
type = TYPE_PRE_RELEASE;
continue;
}
if (chr == '+')
{
type = TYPE_BUILD;
continue;
}
if (chr_dec < 48 || chr_dec > 57)
{
m_is_valid = false;
}
patch += chr;
break;
case TYPE_PRE_RELEASE:
if (chr == '.')
{
type = TYPE_PRE_RELEASE_ID;
m_pre_release += chr;
continue;
}
if (chr == '+')
{
type = TYPE_BUILD;
continue;
}
if (
(chr_dec < 48 || chr_dec > 57) && // 0-9
(chr_dec < 65 || chr_dec > 90) && // A-Z
(chr_dec < 97 || chr_dec > 122) && // a-z
(chr_dec != 45) && // -
(chr_dec != 46) // .
)
{
m_is_valid = false;
}
m_pre_release += chr;
break;
case TYPE_PRE_RELEASE_ID:
if (chr == '+')
{
type = TYPE_BUILD;
continue;
}
if (
(chr_dec < 48 || chr_dec > 57) && // 0-9
(chr_dec < 65 || chr_dec > 90) && // A-Z
(chr_dec < 97 || chr_dec > 122) && // a-z
(chr_dec != 45) // -
)
{
m_is_valid = false;
}
m_pre_release += chr;
m_pre_release_id += chr;
break;
case TYPE_BUILD:
if (
(chr_dec < 48 || chr_dec > 57) && // 0-9
(chr_dec < 65 || chr_dec > 90) && // A-Z
(chr_dec < 97 || chr_dec > 122) && // a-z
(chr_dec != 45) // -
)
{
m_is_valid = false;
}
m_build += chr;
break;
}
}
if (m_is_valid)
{
std::istringstream(major) >> m_major;
std::istringstream(minor) >> m_minor;
std::istringstream(patch) >> m_patch;
if (m_pre_release.empty())
{
m_pre_release_type = PRE_RELEASE_NONE;
}
else if (m_pre_release.find("alpha") != std::string::npos)
{
m_pre_release_type = PRE_RELEASE_ALPHA;
}
else if (m_pre_release.find("beta") != std::string::npos)
{
m_pre_release_type = PRE_RELEASE_BETA;
}
else if (m_pre_release.find("rc") != std::string::npos)
{
m_pre_release_type = PRE_RELEASE_RC;
}
if (m_major == 0 && m_minor == 0 && m_patch == 0)
{
m_is_valid = false;
}
if (!m_pre_release_id.empty() && m_pre_release_id[0] == '0')
{
m_is_valid = false;
}
if (m_major == 0)
{
m_is_stable = false;
}
if (m_pre_release_type != PRE_RELEASE_NONE)
{
m_is_stable = false;
}
}
}
public:
/**
* Parse the version string
*/
version(const std::string& version)
{
setVersion(version);
}
version(const version&) = default;
~version() = default;
/**
* Set version
*/
bool setVersion(const std::string& version)
{
m_version = version;
m_major = 0;
m_minor = 0;
m_patch = 0;
m_build = "";
m_pre_release = "";
m_pre_release_id = "";
m_is_stable = true;
if (version.empty())
{
m_is_valid = false;
}
else
{
m_is_valid = true;
parse();
}
return m_is_valid;
}
/**
* Get full version
*/
const std::string& getVersion() const
{
return m_version;
}
/**
* Get the major of the version
*/
const int& getMajor() const
{
return m_major;
}
/**
* Get the minor of the version
*/
const int& getMinor() const
{
return m_minor;
}
/**
* Get the patch of the version
*/
const int& getPatch() const
{
return m_patch;
}
/**
* Get the build of the version
*/
const std::string& getBuild() const
{
return m_build;
}
/**
* Get the release type of the version
*/
const pre_release_t& getPreReleaseType() const
{
return m_pre_release_type;
}
/**
* Get the release identifier of the version
*/
const std::string& getPreReleaseId() const
{
return m_pre_release_id;
}
/**
* Get the release of the version
*/
const std::string& getPreRelease() const
{
return m_pre_release;
}
/**
* Check if the version is stable
*/
const bool& isStable() const
{
return m_is_stable;
}
/**
* Check if the version is valid
*/
const bool& isValid() const
{
return m_is_valid;
}
int compare(version& rgt)
{
if ((*this) == rgt)
{
return 0;
}
if ((*this) > rgt)
{
return 1;
}
return -1;
}
version& operator= (version& rgt)
{
if ((*this) != rgt)
{
this->m_version = rgt.getVersion();
this->m_major = rgt.getMajor();
this->m_minor = rgt.getMinor();
this->m_patch = rgt.getPatch();
this->m_pre_release_type = rgt.getPreReleaseType();
this->m_pre_release_id = rgt.getPreReleaseId();
this->m_pre_release = rgt.getPreRelease();
this->m_build = rgt.getBuild();
this->m_is_valid = rgt.isValid();
this->m_is_stable = rgt.isStable();
}
return *this;
}
friend bool operator== (version &lft, version &rgt)
{
return lft.getVersion().compare(rgt.getVersion()) == 0;
}
friend bool operator!= (version &lft, version &rgt)
{
return !(lft == rgt);
}
friend bool operator> (version &lft, version &rgt)
{
// Major
if (lft.getMajor() < 0 && rgt.getMajor() >= 0)
{
return false;
}
if (lft.getMajor() >= 0 && rgt.getMajor() < 0)
{
return true;
}
if (lft.getMajor() > rgt.getMajor())
{
return true;
}
if (lft.getMajor() < rgt.getMajor())
{
return false;
}
// Minor
if (lft.getMinor() < 0 && rgt.getMinor() >= 0)
{
return false;
}
if (lft.getMinor() >= 0 && rgt.getMinor() < 0)
{
return true;
}
if (lft.getMinor() > rgt.getMinor())
{
return true;
}
if (lft.getMinor() < rgt.getMinor())
{
return false;
}
// Patch
if (lft.getPatch() < 0 && rgt.getPatch() >= 0)
{
return false;
}
if (lft.getPatch() >= 0 && rgt.getPatch() < 0)
{
return true;
}
if (lft.getPatch() > rgt.getPatch())
{
return true;
}
if (lft.getPatch() < rgt.getPatch())
{
return false;
}
// Pre release
if (
(lft.getPreReleaseType() == rgt.getPreReleaseType()) &&
(lft.getPreReleaseId() == rgt.getPreReleaseId())
)
{
return false;
}
if (
(lft.getPreReleaseType() == rgt.getPreReleaseType()) &&
(lft.getPreReleaseId().find_first_not_of("0123456789") == std::string::npos) &&
(rgt.getPreReleaseId().find_first_not_of("0123456789") == std::string::npos)
)
{
if (atoi(lft.getPreReleaseId().c_str()) > atoi(rgt.getPreReleaseId().c_str()))
{
return true;
}
else
{
return false;
}
}
if (
(lft.getPreReleaseType() == rgt.getPreReleaseType()) &&
(lft.getPreReleaseId().compare(rgt.getPreReleaseId()) > 0)
)
{
return true;
}
if (lft.getPreReleaseType() > rgt.getPreReleaseType())
{
return true;
}
return false;
}
friend bool operator>= (version &lft, version &rgt)
{
return (lft > rgt) || (lft == rgt);
}
friend bool operator< (version &lft, version &rgt)
{
return (rgt > lft);
}
friend bool operator<= (version &lft, version &rgt)
{
return (lft < rgt) || (lft == rgt);
}
friend std::ostream& operator<< (std::ostream& out, const version& value)
{
out << value.getVersion();
return out;
}
};
} // end semver namespace
#endif // VERSION_H

View File

@ -83,7 +83,7 @@ void Hyperion::start()
}
// handle hwLedCount
_hwLedCount = qMax(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount()), getLedCount());
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
// Initialize colororder vector
for (const Led& led : _ledString.leds())
@ -217,7 +217,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
}
// handle hwLedCount update
_hwLedCount = qMax(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount()), getLedCount());
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
// change in leds are also reflected in adjustment
delete _raw2ledAdjustment;
@ -231,7 +231,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
QJsonObject dev = config.object();
// handle hwLedCount update
_hwLedCount = qMax(dev["hardwareLedCount"].toInt(getLedCount()), getLedCount());
_hwLedCount = dev["hardwareLedCount"].toInt(getLedCount());
// force ledString update, if device ByteOrder changed
if(_ledDeviceWrapper->getColorOrder() != dev["colorOrder"].toString("rgb"))

View File

@ -4,6 +4,7 @@
// util
#include <utils/JsonUtils.h>
#include <db/SettingsTable.h>
#include "HyperionConfig.h"
// json schema process
#include <utils/jsonschema/QJsonFactory.h>
@ -12,12 +13,23 @@
// write config to filesystem
#include <utils/JsonUtils.h>
#include <utils/version.hpp>
using namespace semver;
// Constants
namespace {
const char DEFAULT_VERSION[] = "2.0.0-alpha.8";
} //End of constants
QJsonObject SettingsManager::schemaJson;
SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonlyMode)
: QObject(parent)
, _log(Logger::getInstance("SETTINGSMGR"))
, _instance(instance)
, _sTable(new SettingsTable(instance, this))
, _configVersion(DEFAULT_VERSION)
, _previousVersion(DEFAULT_VERSION)
, _readonlyMode(readonlyMode)
{
_sTable->setReadonlyMode(_readonlyMode);
@ -38,7 +50,9 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
// get default config
QJsonObject defaultConfig;
if(!JsonUtils::readFile(":/hyperion_default.config", defaultConfig, _log))
{
throw std::runtime_error("Failed to read default config");
}
// transform json to string lists
QStringList keyList = defaultConfig.keys();
@ -64,7 +78,7 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
_sTable->createSettingsRecord(key,val);
}
// need to validate all data in database constuct the entire data object
// need to validate all data in database construct the entire data object
// TODO refactor schemaChecker to accept QJsonArray in validate(); QJsonDocument container? To validate them per entry...
QJsonObject dbConfig;
for(const auto & key : keyList)
@ -76,8 +90,49 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
dbConfig[key] = doc.object();
}
//Check, if database requires migration
bool isNewRelease = false;
// Use instance independent SettingsManager to track migration status
if ( instance == GLOABL_INSTANCE_ID)
{
if ( resolveConfigVersion(dbConfig) )
{
QJsonObject newGeneralConfig = dbConfig["general"].toObject();
semver::version BUILD_VERSION(HYPERION_VERSION);
if ( _configVersion > BUILD_VERSION )
{
Error(_log, "Database version [%s] is greater that current Hyperion version [%s]", _configVersion.getVersion().c_str(), BUILD_VERSION.getVersion().c_str());
// TODO: Remove version checking and Settingsmanager from components' constructor to be able to stop hyperion.
}
else
{
if ( _previousVersion < BUILD_VERSION )
{
if ( _configVersion == BUILD_VERSION )
{
newGeneralConfig["previousVersion"] = BUILD_VERSION.getVersion().c_str();
dbConfig["general"] = newGeneralConfig;
isNewRelease = true;
Info(_log, "Migration completed to version [%s]", BUILD_VERSION.getVersion().c_str());
}
else
{
Info(_log, "Migration from current version [%s] to new version [%s] started", _previousVersion.getVersion().c_str(), BUILD_VERSION.getVersion().c_str());
newGeneralConfig["previousVersion"] = _configVersion.getVersion().c_str();
newGeneralConfig["configVersion"] = BUILD_VERSION.getVersion().c_str();
dbConfig["general"] = newGeneralConfig;
isNewRelease = true;
}
}
}
}
}
// possible data upgrade steps to prevent data loss
if(handleConfigUpgrade(dbConfig))
bool migrated = handleConfigUpgrade(dbConfig);
if ( isNewRelease || migrated )
{
saveSettings(dbConfig, true);
}
@ -193,77 +248,156 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
return rc;
}
bool SettingsManager::resolveConfigVersion(QJsonObject& config)
{
bool isValid = false;
if (config.contains("general"))
{
QJsonObject generalConfig = config["general"].toObject();
QString configVersion = generalConfig["configVersion"].toString();
QString previousVersion = generalConfig["previousVersion"].toString();
if ( !configVersion.isEmpty() )
{
isValid = _configVersion.setVersion(configVersion.toStdString());
}
else
{
_configVersion.setVersion(DEFAULT_VERSION);
isValid = true;
}
if ( !previousVersion.isEmpty() && isValid )
{
isValid = _previousVersion.setVersion(previousVersion.toStdString());
}
else
{
_previousVersion.setVersion(DEFAULT_VERSION);
isValid = true;
}
}
return isValid;
}
bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
{
bool migrated = false;
// LED LAYOUT UPGRADE
// from { hscan: { minimum: 0.2, maximum: 0.3 }, vscan: { minimum: 0.2, maximumn: 0.3 } }
// from { h: { min: 0.2, max: 0.3 }, v: { min: 0.2, max: 0.3 } }
// to { hmin: 0.2, hmax: 0.3, vmin: 0.2, vmax: 0.3}
if(config.contains("leds"))
resolveConfigVersion(config);
//Do only migrate, if configuration is not up to date
if (_previousVersion < _configVersion)
{
const QJsonArray ledarr = config["leds"].toArray();
const QJsonObject led = ledarr[0].toObject();
if(led.contains("hscan") || led.contains("h"))
//Migration steps for versions <= alpha 9
semver::version targetVersion {"2.0.0-alpha.9"};
if (_previousVersion <= targetVersion )
{
const bool whscan = led.contains("hscan");
QJsonArray newLedarr;
Info(_log, "Instance [%u]: Migrate LED Layout from current version [%s] to version [%s] or later", _instance, _previousVersion.getVersion().c_str(), targetVersion.getVersion().c_str());
for(const auto & entry : ledarr)
// LED LAYOUT UPGRADE
// from { hscan: { minimum: 0.2, maximum: 0.3 }, vscan: { minimum: 0.2, maximum: 0.3 } }
// from { h: { min: 0.2, max: 0.3 }, v: { min: 0.2, max: 0.3 } }
// to { hmin: 0.2, hmax: 0.3, vmin: 0.2, vmax: 0.3}
if(config.contains("leds"))
{
const QJsonObject led = entry.toObject();
QJsonObject hscan;
QJsonObject vscan;
QJsonValue hmin;
QJsonValue hmax;
QJsonValue vmin;
QJsonValue vmax;
QJsonObject nL;
const QJsonArray ledarr = config["leds"].toArray();
const QJsonObject led = ledarr[0].toObject();
if(whscan)
if(led.contains("hscan") || led.contains("h"))
{
hscan = led["hscan"].toObject();
vscan = led["vscan"].toObject();
hmin = hscan["minimum"];
hmax = hscan["maximum"];
vmin = vscan["minimum"];
vmax = vscan["maximum"];
const bool whscan = led.contains("hscan");
QJsonArray newLedarr;
for(const auto & entry : ledarr)
{
const QJsonObject led = entry.toObject();
QJsonObject hscan;
QJsonObject vscan;
QJsonValue hmin;
QJsonValue hmax;
QJsonValue vmin;
QJsonValue vmax;
QJsonObject nL;
if(whscan)
{
hscan = led["hscan"].toObject();
vscan = led["vscan"].toObject();
hmin = hscan["minimum"];
hmax = hscan["maximum"];
vmin = vscan["minimum"];
vmax = vscan["maximum"];
}
else
{
hscan = led["h"].toObject();
vscan = led["v"].toObject();
hmin = hscan["min"];
hmax = hscan["max"];
vmin = vscan["min"];
vmax = vscan["max"];
}
// append to led object
nL["hmin"] = hmin;
nL["hmax"] = hmax;
nL["vmin"] = vmin;
nL["vmax"] = vmax;
newLedarr.append(nL);
}
// replace
config["leds"] = newLedarr;
migrated = true;
Info(_log,"Instance [%u]: LED Layout migrated", _instance);
}
else
{
hscan = led["h"].toObject();
vscan = led["v"].toObject();
hmin = hscan["min"];
hmax = hscan["max"];
vmin = vscan["min"];
vmax = vscan["max"];
}
// append to led object
nL["hmin"] = hmin;
nL["hmax"] = hmax;
nL["vmin"] = vmin;
nL["vmax"] = vmax;
newLedarr.append(nL);
}
// replace
config["leds"] = newLedarr;
migrated = true;
Debug(_log,"LED Layout migrated");
}
}
if (config.contains("grabberV4L2"))
{
QJsonObject newGrabberV4L2Config = config["grabberV4L2"].toObject();
if(config.contains("ledConfig"))
{
QJsonObject oldLedConfig = config["ledConfig"].toObject();
if ( !oldLedConfig.contains("classic"))
{
QJsonObject newLedConfig;
newLedConfig.insert("classic", oldLedConfig );
QJsonObject defaultMatrixConfig {{"ledshoriz", 1}
,{"ledsvert", 1}
,{"cabling","snake"}
,{"start","top-left"}
};
newLedConfig.insert("matrix", defaultMatrixConfig );
if (newGrabberV4L2Config.contains("encoding_format"))
{
newGrabberV4L2Config.remove("encoding_format");
config["grabberV4L2"] = newGrabberV4L2Config;
migrated = true;
Debug(_log, "GrabberV4L2 Layout migrated");
config["ledConfig"] = newLedConfig;
migrated = true;
Info(_log,"Instance [%u]: LED-Config migrated", _instance);
}
}
// LED Hardware count is leading for versions after alpha 9
// Setting Hardware LED count to number of LEDs configured via layout, if layout number is greater than number of hardware LEDs
if (config.contains("device"))
{
QJsonObject newDeviceConfig = config["device"].toObject();
if (newDeviceConfig.contains("hardwareLedCount"))
{
int hwLedcount = newDeviceConfig["hardwareLedCount"].toInt();
if (config.contains("leds"))
{
const QJsonArray ledarr = config["leds"].toArray();
int layoutLedCount = ledarr.size();
if (hwLedcount < layoutLedCount )
{
Warning(_log, "Instance [%u]: HwLedCount/Layout mismatch! Setting Hardware LED count to number of LEDs configured via layout", _instance);
hwLedcount = layoutLedCount;
newDeviceConfig["hardwareLedCount"] = hwLedcount;
config["device"] = newDeviceConfig;
migrated = true;
}
}
}
}
}
}
return migrated;

View File

@ -1,50 +1,45 @@
{
"type" : "object",
"title" : "edt_dev_general_heading_title",
"required" : true,
"defaultProperties": ["hardwareLedCount", "colorOrder"],
"properties" :
{
"type" :
{
"type" : "string",
"propertyOrder" : 1
},
"hardwareLedCount" :
{
"type" : "integer",
"title" : "edt_dev_general_hardwareLedCount_title",
"minimum" : 1,
"default" : 1,
"propertyOrder" : 2
},
"colorOrder" :
{
"type" : "string",
"title" : "edt_dev_general_colorOrder_title",
"enum" : ["rgb", "bgr", "rbg", "brg", "gbr", "grb"],
"default" : "rgb",
"required" : true,
"options": {
"enum_titles": [ "edt_conf_enum_rgb", "edt_conf_enum_bgr", "edt_conf_enum_rbg", "edt_conf_enum_brg", "edt_conf_enum_gbr", "edt_conf_enum_grb" ]
},
"access" : "expert",
"propertyOrder" : 3
}
},
"dependencies" :
{
"rewriteTime" :
{
"properties" :
{
"type" :
{
"enum" : ["file", "apa102", "apa104", "ws2801", "lpd6803", "lpd8806", "p9813", "sk6812spi", "sk6822spi", "sk9822", "ws2812spi","ws281x", "piblaster", "adalight", "dmx", "atmo", "hyperionusbasp", "lightpack", "multilightpack", "paintpack", "rawhid", "sedu", "tpm2", "karate"]
}
},
"additionalProperties" : true
}
},
"additionalProperties" : true
"type": "object",
"title": " ",
"defaultProperties": [ "hardwareLedCount", "colorOrder" ],
"properties": {
"type": {
"type": "string",
"propertyOrder": 1
},
"hardwareLedCount": {
"type": "integer",
"title": "edt_dev_general_hardwareLedCount_title",
"minimum": 1,
"default": 1,
"options": {
"infoText": "edt_dev_general_hardwareLedCount_title_info"
},
"propertyOrder": 2
},
"colorOrder": {
"type": "string",
"title": "edt_dev_general_colorOrder_title",
"enum": [ "rgb", "bgr", "rbg", "brg", "gbr", "grb" ],
"default": "rgb",
"required": true,
"options": {
"enum_titles": [ "edt_conf_enum_rgb", "edt_conf_enum_bgr", "edt_conf_enum_rbg", "edt_conf_enum_brg", "edt_conf_enum_gbr", "edt_conf_enum_grb" ],
"infoText": "edt_dev_general_colorOrder_title_info"
},
"access": "expert",
"propertyOrder": 3
}
},
"dependencies": {
"rewriteTime": {
"properties": {
"type": {
"enum": [ "file", "apa102", "apa104", "ws2801", "lpd6803", "lpd8806", "p9813", "sk6812spi", "sk6822spi", "sk9822", "ws2812spi", "ws281x", "piblaster", "adalight", "dmx", "atmo", "hyperionusbasp", "lightpack", "multilightpack", "paintpack", "rawhid", "sedu", "tpm2", "karate" ]
}
},
"additionalProperties": true
}
},
"additionalProperties": true
}

View File

@ -34,6 +34,25 @@
"default" : true,
"required" : true,
"propertyOrder" : 3
},
"configVersion" :
{
"type" : "string",
"title" : "edt_conf_gen_configVersion_title",
"options" : {
"hidden":true
},
"access" : "expert",
"propertyOrder" : 4
},
"previousVersion" :
{
"type" : "string",
"options" : {
"hidden":true
},
"access" : "expert",
"propertyOrder" : 5
}
},
"additionalProperties" : false

View File

@ -135,15 +135,45 @@
},
"cabling": {
"type": "string",
"enum": ["snake", "parallel"]
"enum": [ "snake", "parallel" ]
},
"start": {
"type": "string",
"enum": ["top-left", "top-right", "bottom-left", "bottom-right"]
"enum": [ "top-left", "top-right", "bottom-left", "bottom-right" ]
}
},
"additionalProperties": false
},
"ledBlacklist": {
"type": "array",
"title": "conf_leds_layout_blacklist_rules_title",
"minimum": 1,
"uniqueItems": true,
"items": {
"type": "object",
"title": "conf_leds_layout_blacklist_rule_title",
"required": true,
"properties": {
"start": {
"type": "integer",
"minimum": 0,
"default": 0,
"title": "conf_leds_layout_blacklist_start_title",
"required": true,
"propertyOrder": 1
},
"num": {
"type": "integer",
"minimum": 1,
"default": 1,
"title": "conf_leds_layout_blacklist_num_title",
"required": true,
"propertyOrder": 2
}
}
},
"propertyOrder": 1
}
},
"additionalProperties": true
}
"additionalProperties": true
}

View File

@ -234,20 +234,25 @@ int LedDevice::rewriteLEDs()
return retval;
}
int LedDevice::writeBlack(int numberOfBlack)
int LedDevice::writeBlack(int numberOfWrites)
{
return writeColor(ColorRgb::BLACK, numberOfWrites);
}
int LedDevice::writeColor(const ColorRgb& color, int numberOfWrites)
{
int rc = -1;
for (int i = 0; i < numberOfBlack; i++)
for (int i = 0; i < numberOfWrites; i++)
{
if ( _latchTime_ms > 0 )
if (_latchTime_ms > 0)
{
// Wait latch time before writing black
QEventLoop loop;
QTimer::singleShot(_latchTime_ms, &loop, &QEventLoop::quit);
loop.exec();
}
_lastLedValues = std::vector<ColorRgb>(static_cast<unsigned long>(_ledCount), ColorRgb::BLACK );
_lastLedValues = std::vector<ColorRgb>(static_cast<unsigned long>(_ledCount),color);
rc = write(_lastLedValues);
}
return rc;
@ -411,28 +416,33 @@ void LedDevice::setLatchTime( int latchTime_ms )
void LedDevice::setRewriteTime( int rewriteTime_ms )
{
assert(rewriteTime_ms >= 0);
_refreshTimerInterval_ms = rewriteTime_ms;
if ( _refreshTimerInterval_ms > 0 )
//Check, if refresh timer was not initialised due to getProperties/identify sceanrios
if (_refreshTimer != nullptr)
{
_refreshTimerInterval_ms = rewriteTime_ms;
_isRefreshEnabled = true;
if (_refreshTimerInterval_ms <= _latchTime_ms )
if (_refreshTimerInterval_ms > 0)
{
int new_refresh_timer_interval = _latchTime_ms + 10;
Warning(_log, "latchTime(%d) is bigger/equal rewriteTime(%d), set rewriteTime to %dms", _latchTime_ms, _refreshTimerInterval_ms, new_refresh_timer_interval);
_refreshTimerInterval_ms = new_refresh_timer_interval;
_refreshTimer->setInterval( _refreshTimerInterval_ms );
_isRefreshEnabled = true;
if (_refreshTimerInterval_ms <= _latchTime_ms)
{
int new_refresh_timer_interval = _latchTime_ms + 10;
Warning(_log, "latchTime(%d) is bigger/equal rewriteTime(%d), set rewriteTime to %dms", _latchTime_ms, _refreshTimerInterval_ms, new_refresh_timer_interval);
_refreshTimerInterval_ms = new_refresh_timer_interval;
_refreshTimer->setInterval(_refreshTimerInterval_ms);
}
Debug(_log, "Refresh interval = %dms", _refreshTimerInterval_ms);
_refreshTimer->setInterval(_refreshTimerInterval_ms);
_lastWriteTime = QDateTime::currentDateTime();
}
Debug(_log, "Refresh interval = %dms",_refreshTimerInterval_ms );
_refreshTimer->setInterval( _refreshTimerInterval_ms );
_lastWriteTime = QDateTime::currentDateTime();
Debug(_log, "RewriteTime updated to %dms", _refreshTimerInterval_ms);
}
Debug(_log, "RewriteTime updated to %dms", _refreshTimerInterval_ms);
}
void LedDevice::printLedValues(const std::vector<ColorRgb>& ledValues)

View File

@ -15,6 +15,9 @@ const bool verbose = false;
// Configuration settings
const char CONFIG_ADDRESS[] = "host";
const char CONFIG_RESTORE_STATE[] = "restoreOriginalState";
const char CONFIG_BRIGHTNESS[] = "brightness";
const char CONFIG_BRIGHTNESS_OVERWRITE[] = "overwriteBrightness";
const char CONFIG_SYNC_OVERWRITE[] = "overwriteSync";
// UDP elements
const quint16 STREAM_DEFAULT_PORT = 19446;
@ -32,7 +35,10 @@ const char STATE_VALUE_TRUE[] = "true";
const char STATE_VALUE_FALSE[] = "false";
const char STATE_LIVE[] = "live";
const bool DEFAULT_IS_RESTORE_STATE = false;
const bool DEFAULT_IS_BRIGHTNESS_OVERWRITE = true;
const int BRI_MAX = 255;
const bool DEFAULT_IS_SYNC_OVERWRITE = true;
constexpr std::chrono::milliseconds DEFAULT_IDENTIFY_TIME{ 2000 };
@ -42,6 +48,11 @@ LedDeviceWled::LedDeviceWled(const QJsonObject &deviceConfig)
: ProviderUdp(deviceConfig)
,_restApi(nullptr)
,_apiPort(API_DEFAULT_PORT)
,_isBrightnessOverwrite(DEFAULT_IS_BRIGHTNESS_OVERWRITE)
,_brightness (BRI_MAX)
,_isSyncOverwrite(DEFAULT_IS_SYNC_OVERWRITE)
,_originalStateUdpnSend(false)
,_originalStateUdpnRecv(true)
{
}
@ -70,8 +81,15 @@ bool LedDeviceWled::init(const QJsonObject &deviceConfig)
Debug(_log, "ColorOrder : %s", QSTRING_CSTR( this->getColorOrder() ));
Debug(_log, "LatchTime : %d", this->getLatchTime());
_isRestoreOrigState = _devConfig[CONFIG_RESTORE_STATE].toBool(false);
_isRestoreOrigState = _devConfig[CONFIG_RESTORE_STATE].toBool(DEFAULT_IS_RESTORE_STATE);
_isSyncOverwrite = _devConfig[CONFIG_SYNC_OVERWRITE].toBool(DEFAULT_IS_SYNC_OVERWRITE);
_isBrightnessOverwrite = _devConfig[CONFIG_BRIGHTNESS_OVERWRITE].toBool(DEFAULT_IS_BRIGHTNESS_OVERWRITE);
_brightness = _devConfig[CONFIG_BRIGHTNESS].toInt(BRI_MAX);
Debug(_log, "RestoreOrigState : %d", _isRestoreOrigState);
Debug(_log, "Overwrite Sync. : %d", _isSyncOverwrite);
Debug(_log, "Overwrite Brightn.: %d", _isBrightnessOverwrite);
Debug(_log, "Set Brightness to : %d", _brightness);
//Set hostname as per configuration
QString hostName = deviceConfig[ CONFIG_ADDRESS ].toString();
@ -145,6 +163,13 @@ QString LedDeviceWled::getLorRequest(int lor) const
return QString( "\"lor\":%1" ).arg(lor);
}
QString LedDeviceWled::getUdpnRequest(bool isSendOn, bool isRecvOn) const
{
QString send = isSendOn ? STATE_VALUE_TRUE : STATE_VALUE_FALSE;
QString recv = isRecvOn ? STATE_VALUE_TRUE : STATE_VALUE_FALSE;
return QString( "\"udpn\":{\"send\":%1,\"recv\":%2}" ).arg(send, recv);
}
bool LedDeviceWled::sendStateUpdateRequest(const QString &request)
{
bool rc = true;
@ -166,7 +191,20 @@ bool LedDeviceWled::powerOn()
//Power-on WLED device
_restApi->setPath(API_PATH_STATE);
httpResponse response = _restApi->put(QString("{%1,%2}").arg(getOnOffRequest(true)).arg(getBrightnessRequest(BRI_MAX)));
QString cmd = getOnOffRequest(true);
if ( _isBrightnessOverwrite)
{
cmd += "," + getBrightnessRequest(_brightness);
}
if (_isSyncOverwrite)
{
Debug( _log, "Disable synchronisation with other WLED devices");
cmd += "," + getUdpnRequest(false, false);
}
httpResponse response = _restApi->put(QString("{%1}").arg(cmd));
if ( response.error() )
{
QString errorReason = QString("Power-on request failed with error: '%1'").arg(response.getErrorReason());
@ -191,7 +229,16 @@ bool LedDeviceWled::powerOff()
//Power-off the WLED device physically
_restApi->setPath(API_PATH_STATE);
httpResponse response = _restApi->put(QString("{%1}").arg(getOnOffRequest(false)));
QString cmd = getOnOffRequest(false);
if (_isSyncOverwrite)
{
Debug( _log, "Restore synchronisation with other WLED devices");
cmd += "," + getUdpnRequest(_originalStateUdpnSend, _originalStateUdpnRecv);
}
httpResponse response = _restApi->put(QString("{%1}").arg(cmd));
if ( response.error() )
{
QString errorReason = QString("Power-off request failed with error: '%1'").arg(response.getErrorReason());
@ -206,7 +253,7 @@ bool LedDeviceWled::storeState()
{
bool rc = true;
if ( _isRestoreOrigState )
if ( _isRestoreOrigState || _isSyncOverwrite )
{
_restApi->setPath(API_PATH_STATE);
@ -221,6 +268,13 @@ bool LedDeviceWled::storeState()
{
_originalStateProperties = response.getBody().object();
DebugIf(verbose, _log, "state: [%s]", QString(QJsonDocument(_originalStateProperties).toJson(QJsonDocument::Compact)).toUtf8().constData() );
QJsonObject udpn = _originalStateProperties.value("udpn").toObject();
if (!udpn.isEmpty())
{
_originalStateUdpnSend = udpn["send"].toBool(false);
_originalStateUdpnRecv = udpn["recv"].toBool(true);
}
}
}
@ -233,7 +287,6 @@ bool LedDeviceWled::restoreState()
if ( _isRestoreOrigState )
{
//powerOff();
_restApi->setPath(API_PATH_STATE);
_originalStateProperties[STATE_LIVE] = false;

View File

@ -140,9 +140,11 @@ private:
/// @return Command to switch device on/off
///
QString getOnOffRequest (bool isOn ) const;
QString getBrightnessRequest (int bri ) const;
QString getEffectRequest(int effect, int speed=128) const;
QString getLorRequest(int lor) const;
QString getUdpnRequest(bool send, bool recv) const;
bool sendStateUpdateRequest(const QString &request);
@ -154,6 +156,12 @@ private:
QJsonObject _originalStateProperties;
bool _isBrightnessOverwrite;
int _brightness;
bool _isSyncOverwrite;
bool _originalStateUdpnSend;
bool _originalStateUdpnRecv;
};
#endif // LEDDEVICEWLED_H

View File

@ -1,4 +1,4 @@
#include "LedDeviceYeelight.h"
#include "LedDeviceYeelight.h"
#include <ssdp/SSDPDiscover.h>
#include <utils/QStringUtils.h>
@ -1018,10 +1018,9 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
//Get device specific configuration
bool ok;
if ( deviceConfig[ CONFIG_COLOR_MODEL ].isString() )
{
_outputColorModel = deviceConfig[ CONFIG_COLOR_MODEL ].toString().toInt(&ok,MODEL_RGB);
_outputColorModel = deviceConfig[ CONFIG_COLOR_MODEL ].toString(QString(MODEL_RGB)).toInt();
}
else
{
@ -1030,7 +1029,7 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
if ( deviceConfig[ CONFIG_TRANS_EFFECT ].isString() )
{
_transitionEffect = static_cast<YeelightLight::API_EFFECT>( deviceConfig[ CONFIG_TRANS_EFFECT ].toString().toInt(&ok, YeelightLight::API_EFFECT_SMOOTH) );
_transitionEffect = static_cast<YeelightLight::API_EFFECT>( deviceConfig[ CONFIG_TRANS_EFFECT ].toString(QString(YeelightLight::API_EFFECT_SMOOTH)).toInt() );
}
else
{
@ -1047,7 +1046,7 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
if ( deviceConfig[ CONFIG_DEBUGLEVEL ].isString() )
{
_debuglevel = deviceConfig[ CONFIG_DEBUGLEVEL ].toString().toInt();
_debuglevel = deviceConfig[ CONFIG_DEBUGLEVEL ].toString(QString("0")).toInt();
}
else
{

View File

@ -4,11 +4,22 @@
#include <csignal>
// QT includes
#include <QDir>
#include <QFile>
// Local LedDevice includes
#include "LedDevicePiBlaster.h"
// Constants
namespace {
const bool verbose = false;
// Pi-Blaster discovery service
const char DISCOVERY_DIRECTORY[] = "/dev/";
const char DISCOVERY_FILEPATTERN[] = "pi-blaster";
} //End of constants
LedDevicePiBlaster::LedDevicePiBlaster(const QJsonObject &deviceConfig)
: LedDevice(deviceConfig)
, _fid(nullptr)
@ -184,3 +195,31 @@ int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
return 0;
}
QJsonObject LedDevicePiBlaster::discover(const QJsonObject& /*params*/)
{
QJsonObject devicesDiscovered;
devicesDiscovered.insert("ledDeviceType", _activeDeviceType );
QJsonArray deviceList;
QDir deviceDirectory (DISCOVERY_DIRECTORY);
QStringList deviceFilter(DISCOVERY_FILEPATTERN);
deviceDirectory.setNameFilters(deviceFilter);
deviceDirectory.setSorting(QDir::Name);
QFileInfoList deviceFiles = deviceDirectory.entryInfoList(QDir::System);
QFileInfoList::const_iterator deviceFileIterator;
for (deviceFileIterator = deviceFiles.constBegin(); deviceFileIterator != deviceFiles.constEnd(); ++deviceFileIterator)
{
QJsonObject deviceInfo;
deviceInfo.insert("deviceName", (*deviceFileIterator).fileName());
deviceInfo.insert("systemLocation", (*deviceFileIterator).absoluteFilePath());
deviceList.append(deviceInfo);
}
devicesDiscovered.insert("devices", deviceList);
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
return devicesDiscovered;
}

View File

@ -29,6 +29,12 @@ public:
/// @return LedDevice constructed
static LedDevice* construct(const QJsonObject &deviceConfig);
/// @param[in] params Parameters used to overwrite discovery default behaviour
///
/// @return A JSON structure holding a list of devices found
///
QJsonObject discover(const QJsonObject& params) override;
protected:
///

View File

@ -2,6 +2,7 @@
// LedDevice includes
#include <leddevice/LedDevice.h>
#include "ProviderRs232.h"
#include <utils/WaitTime.h>
// qt includes
#include <QSerialPortInfo>
@ -10,10 +11,16 @@
#include <chrono>
// Constants
constexpr std::chrono::milliseconds WRITE_TIMEOUT{1000}; // device write timeout in ms
constexpr std::chrono::milliseconds OPEN_TIMEOUT{5000}; // device open timeout in ms
const int MAX_WRITE_TIMEOUTS = 5; // Maximum number of allowed timeouts
const int NUM_POWEROFF_WRITE_BLACK = 2; // Number of write "BLACK" during powering off
namespace {
const bool verbose = false;
constexpr std::chrono::milliseconds WRITE_TIMEOUT{ 1000 }; // device write timeout in ms
constexpr std::chrono::milliseconds OPEN_TIMEOUT{ 5000 }; // device open timeout in ms
const int MAX_WRITE_TIMEOUTS = 5; // Maximum number of allowed timeouts
const int NUM_POWEROFF_WRITE_BLACK = 2; // Number of write "BLACK" during powering off
constexpr std::chrono::milliseconds DEFAULT_IDENTIFY_TIME{ 500 };
} //End of constants
ProviderRs232::ProviderRs232(const QJsonObject &deviceConfig)
: LedDevice(deviceConfig)
@ -278,7 +285,7 @@ QJsonObject ProviderRs232::discover(const QJsonObject& /*params*/)
// Discover serial Devices
for (auto &port : QSerialPortInfo::availablePorts() )
{
if ( !port.isNull() && !port.portName().startsWith("ttyS"))
if ( !port.isNull() && port.vendorIdentifier() != 0)
{
QJsonObject portInfo;
portInfo.insert("description", port.description());
@ -294,5 +301,39 @@ QJsonObject ProviderRs232::discover(const QJsonObject& /*params*/)
}
devicesDiscovered.insert("devices", deviceList);
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
return devicesDiscovered;
}
void ProviderRs232::identify(const QJsonObject& params)
{
DebugIf(verbose,_log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData());
QString deviceName = params["output"].toString("");
if (!deviceName.isEmpty())
{
_devConfig = params;
init(_devConfig);
{
if ( open() == 0 )
{
for (int i = 0; i < 2; ++i)
{
if (writeColor(ColorRgb::RED) == 0)
{
wait(DEFAULT_IDENTIFY_TIME);
writeColor(ColorRgb::BLACK);
wait(DEFAULT_IDENTIFY_TIME);
}
else
{
break;
}
}
close();
}
}
}
}

View File

@ -26,6 +26,20 @@ public:
///
~ProviderRs232() override;
///
/// @brief Send an update to the RS232 device to identify it.
///
/// Following parameters are required
/// @code
/// {
/// "deviceConfig" :
/// }
///@endcode
///
/// @param[in] params Parameters to configure device
///
void identify(const QJsonObject& params) override;
protected:
///

View File

@ -14,6 +14,19 @@
#include "ProviderSpi.h"
#include <utils/Logger.h>
// qt includes
#include <QDir>
// Constants
namespace {
const bool verbose = false;
// SPI discovery service
const char DISCOVERY_DIRECTORY[] = "/dev/";
const char DISCOVERY_FILEPATTERN[] = "spidev*";
} //End of constants
ProviderSpi::ProviderSpi(const QJsonObject &deviceConfig)
: LedDevice(deviceConfig)
, _deviceName("/dev/spidev0.0")
@ -148,3 +161,31 @@ int ProviderSpi::writeBytes(unsigned size, const uint8_t * data)
return retVal;
}
QJsonObject ProviderSpi::discover(const QJsonObject& /*params*/)
{
QJsonObject devicesDiscovered;
devicesDiscovered.insert("ledDeviceType", _activeDeviceType );
QJsonArray deviceList;
QDir deviceDirectory (DISCOVERY_DIRECTORY);
QStringList deviceFilter(DISCOVERY_FILEPATTERN);
deviceDirectory.setNameFilters(deviceFilter);
deviceDirectory.setSorting(QDir::Name);
QFileInfoList deviceFiles = deviceDirectory.entryInfoList(QDir::System);
QFileInfoList::const_iterator deviceFileIterator;
for (deviceFileIterator = deviceFiles.constBegin(); deviceFileIterator != deviceFiles.constEnd(); ++deviceFileIterator)
{
QJsonObject deviceInfo;
deviceInfo.insert("deviceName", (*deviceFileIterator).fileName().remove(0,6));
deviceInfo.insert("systemLocation", (*deviceFileIterator).absoluteFilePath());
deviceList.append(deviceInfo);
}
devicesDiscovered.insert("devices", deviceList);
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
return devicesDiscovered;
}

View File

@ -36,6 +36,12 @@ public:
///
int open() override;
/// @param[in] params Parameters used to overwrite discovery default behaviour
///
/// @return A JSON structure holding a list of devices found
///
QJsonObject discover(const QJsonObject& params) override;
public slots:
///
/// Closes the output device.

View File

@ -25,20 +25,24 @@
},
"lightberry_apa102_mode": {
"type": "boolean",
"title":"edt_dev_spec_LBap102Mode_title",
"title": "edt_dev_spec_LBap102Mode_title",
"default": false,
"access" : "advanced",
"propertyOrder" : 4
"required": true,
"access": "advanced",
"propertyOrder": 4
},
"latchTime": {
"type": "integer",
"title":"edt_dev_spec_latchtime_title",
"title": "edt_dev_spec_latchtime_title",
"default": 30,
"append" : "edt_append_ms",
"append": "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access" : "expert",
"propertyOrder" : 5
"access": "expert",
"options": {
"infoText": "edt_dev_spec_latchtime_title_info"
},
"propertyOrder": 5
},
"rewriteTime": {
"type": "integer",

View File

@ -5,8 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"default" : "/dev/spidev0.0",
"propertyOrder" : 1
},
"rate": {

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -1,46 +1,47 @@
{
"type":"object",
"required":true,
"properties":{
"orbIds": {
"type": "string",
"title":"edt_dev_spec_orbIds_title",
"default": "",
"propertyOrder" : 1
},
"useOrbSmoothing": {
"type": "boolean",
"title":"edt_dev_spec_useOrbSmoothing_title",
"default": true,
"access" : "advanced",
"propertyOrder" : 2
},
"output": {
"type": "string",
"title":"edt_dev_spec_multicastGroup_title",
"default" : "239.255.255.250",
"access" : "expert",
"propertyOrder" : 3
},
"port": {
"type": "integer",
"title":"edt_dev_spec_port_title",
"minimum" : 0,
"maximum" : 65535,
"default": 49692,
"access" : "expert",
"propertyOrder" : 4
},
"latchTime": {
"type": "integer",
"title":"edt_dev_spec_latchtime_title",
"default": 30,
"append" : "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access" : "expert",
"propertyOrder" : 5
}
},
"additionalProperties": true
"type": "object",
"required": true,
"properties": {
"orbIds": {
"type": "string",
"title": "edt_dev_spec_orbIds_title",
"minLength": 1,
"default": "",
"propertyOrder": 1
},
"useOrbSmoothing": {
"type": "boolean",
"title": "edt_dev_spec_useOrbSmoothing_title",
"default": true,
"access": "advanced",
"propertyOrder": 2
},
"output": {
"type": "string",
"title": "edt_dev_spec_multicastGroup_title",
"default": "239.255.255.250",
"access": "expert",
"propertyOrder": 3
},
"port": {
"type": "integer",
"title": "edt_dev_spec_port_title",
"minimum": 0,
"maximum": 65535,
"default": 49692,
"access": "expert",
"propertyOrder": 4
},
"latchTime": {
"type": "integer",
"title": "edt_dev_spec_latchtime_title",
"default": 30,
"append": "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access": "expert",
"propertyOrder": 5
}
},
"additionalProperties": true
}

View File

@ -1,22 +1,40 @@
{
"type":"object",
"required":true,
"properties": {
"host" : {
"type": "string",
"title":"edt_dev_spec_targetIpHost_title",
"propertyOrder" : 1
},
"latchTime": {
"type": "integer",
"title":"edt_dev_spec_latchtime_title",
"default": 0,
"append" : "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access" : "expert",
"propertyOrder" : 2
}
},
"additionalProperties": true
"type": "object",
"required": true,
"properties": {
"hostList": {
"type": "string",
"title": "edt_dev_spec_devices_discovered_title",
"enum": [ "NONE" ],
"options": {
"enum_titles": [ "edt_dev_spec_devices_discovery_inprogress" ],
"infoText": "edt_dev_spec_devices_discovered_title_info"
},
"required": true,
"propertyOrder": 1
},
"host": {
"type": "string",
"title": "edt_dev_spec_targetIpHost_title",
"options": {
"infoText": "edt_dev_spec_targetIpHost_title_info"
},
"required": true,
"propertyOrder": 2
},
"latchTime": {
"type": "integer",
"title": "edt_dev_spec_latchtime_title",
"default": 0,
"append": "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access": "expert",
"options": {
"infoText": "edt_dev_spec_latchtime_title_info"
},
"propertyOrder": 3
}
},
"additionalProperties": true
}

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -1,58 +1,78 @@
{
"type":"object",
"required":true,
"properties":{
"host": {
"type": "string",
"title":"edt_dev_spec_targetIpHost_title",
"propertyOrder" : 1
},
"token": {
"type": "string",
"title":"edt_dev_auth_key_title",
"propertyOrder" : 2
},
"title": {
"type" : "object",
"title":"edt_dev_spec_panelorganisation_title",
"access" : "advanced",
"propertyOrder" : 3
},
"panelOrderTopDown": {
"type": "integer",
"title":"edt_dev_spec_order_top_down_title",
"enum" : [0, 1],
"default" : 0,
"options" : {
"enum_titles" : ["edt_conf_enum_top_down", "edt_conf_enum_bottom_up"]
},
"minimum" : 0,
"maximum" : 1,
"access" : "advanced",
"propertyOrder" : 4
},
"panelOrderLeftRight": {
"type": "integer",
"title":"edt_dev_spec_order_left_right_title",
"enum" : [0, 1],
"default" : 0,
"options" : {
"enum_titles" : ["edt_conf_enum_left_right", "edt_conf_enum_right_left"]
},
"minimum" : 0,
"maximum" : 1,
"access" : "advanced",
"propertyOrder" : 5
},
"panelStartPos": {
"type": "integer",
"title":"edt_dev_spec_panel_start_position",
"step": 1,
"minimum" : 0,
"default": 0,
"access" : "advanced",
"propertyOrder" : 6
}
},
"additionalProperties": true
"type": "object",
"required": true,
"properties": {
"hostList": {
"type": "string",
"title": "edt_dev_spec_devices_discovered_title",
"enum": [ "NONE" ],
"options": {
"enum_titles": [ "edt_dev_spec_devices_discovery_inprogress" ],
"infoText": "edt_dev_spec_devices_discovered_title_info"
},
"required": true,
"propertyOrder": 1
},
"host": {
"type": "string",
"title": "edt_dev_spec_targetIpHost_title",
"options": {
"infoText": "edt_dev_spec_targetIpHost_title_info"
},
"required": true,
"propertyOrder": 2
},
"token": {
"type": "string",
"title": "edt_dev_auth_key_title",
"options": {
"infoText": "edt_dev_auth_key_title_info"
},
"propertyOrder": 4
},
"title": {
"type": "object",
"title": "edt_dev_spec_panelorganisation_title",
"access": "advanced",
"propertyOrder": 5
},
"panelOrderTopDown": {
"type": "integer",
"title": "edt_dev_spec_order_top_down_title",
"enum": [ 0, 1 ],
"default": 0,
"required": true,
"options": {
"enum_titles": [ "edt_conf_enum_top_down", "edt_conf_enum_bottom_up" ]
},
"minimum": 0,
"maximum": 1,
"access": "advanced",
"propertyOrder": 6
},
"panelOrderLeftRight": {
"type": "integer",
"title": "edt_dev_spec_order_left_right_title",
"enum": [ 0, 1 ],
"default": 0,
"required": true,
"options": {
"enum_titles": [ "edt_conf_enum_left_right", "edt_conf_enum_right_left" ]
},
"minimum": 0,
"maximum": 1,
"access": "advanced",
"propertyOrder": 7
},
"panelStartPos": {
"type": "integer",
"title": "edt_dev_spec_panel_start_position",
"step": 1,
"minimum": 0,
"default": 0,
"access": "advanced",
"propertyOrder": 8
}
},
"additionalProperties": true
}

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -1,242 +1,243 @@
{
"type":"object",
"required":true,
"properties":{
"output": {
"type": "string",
"title":"edt_dev_spec_targetIp_title",
"default":"",
"propertyOrder" : 1
},
"username": {
"type": "string",
"title":"edt_dev_spec_username_title",
"default": "",
"propertyOrder" : 2
},
"clientkey": {
"type": "string",
"title":"edt_dev_spec_clientKey_title",
"default" : "",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 3
},
"useEntertainmentAPI": {
"type": "boolean",
"title":"edt_dev_spec_useEntertainmentAPI_title",
"default" : false,
"propertyOrder" : 4
},
"transitiontime": {
"type": "number",
"title":"edt_dev_spec_transistionTime_title",
"default" : 1,
"append" : "x100ms",
"options": {
"dependencies": {
"useEntertainmentAPI": false
}
},
"propertyOrder" : 5
},
"switchOffOnBlack": {
"type": "boolean",
"title":"edt_dev_spec_switchOffOnBlack_title",
"default" : false,
"propertyOrder" : 6
},
"restoreOriginalState": {
"type": "boolean",
"title":"edt_dev_spec_restoreOriginalState_title",
"default" : true,
"propertyOrder" : 7
},
"lightIds": {
"type": "array",
"title":"edt_dev_spec_lightid_title",
"minItems": 1,
"uniqueItems" : true,
"items" : {
"type" : "string",
"minimum" : 0,
"title" : "edt_dev_spec_lightid_itemtitle"
},
"options": {
"dependencies": {
"useEntertainmentAPI": false
}
},
"propertyOrder" : 8
},
"groupId": {
"type": "number",
"title":"edt_dev_spec_groupId_title",
"default" : 0,
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 9
},
"blackLightsTimeout": {
"type": "number",
"title":"edt_dev_spec_blackLightsTimeout_title",
"default" : 15000,
"step": 500,
"minimum" : 10000,
"maximum" : 60000,
"access" : "advanced",
"append" : "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 10
},
"brightnessThreshold": {
"type": "number",
"title":"edt_dev_spec_brightnessThreshold_title",
"default" : 0,
"step": 0.005,
"minimum" : 0,
"maximum" : 1.0,
"access" : "advanced",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 11
},
"brightnessFactor": {
"type": "number",
"title":"edt_dev_spec_brightnessFactor_title",
"default" : 1.0,
"step": 0.25,
"minimum" : 0.5,
"maximum" : 10.0,
"access" : "advanced",
"propertyOrder" : 12
},
"brightnessMin": {
"type": "number",
"title":"edt_dev_spec_brightnessMin_title",
"default" : 0,
"step": 0.05,
"minimum" : 0,
"maximum" : 1.0,
"access" : "advanced",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 13
},
"brightnessMax": {
"type": "number",
"title":"edt_dev_spec_brightnessMax_title",
"default" : 1.0,
"step": 0.05,
"minimum" : 0,
"maximum" : 1.0,
"access" : "advanced",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 14
},
"sslReadTimeout": {
"type": "number",
"title":"edt_dev_spec_sslReadTimeout_title",
"default" : 0,
"step": 100,
"minimum" : 0,
"maximum" : 30000,
"access" : "expert",
"append" : "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 15
},
"sslHSTimeoutMin": {
"type": "number",
"title":"edt_dev_spec_sslHSTimeoutMin_title",
"default" : 400,
"step": 100,
"minimum" : 0,
"maximum" : 30000,
"access" : "expert",
"append" : "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 16
},
"sslHSTimeoutMax": {
"type": "number",
"title":"edt_dev_spec_sslHSTimeoutMax_title",
"default" : 1000,
"step": 100,
"minimum" : 0,
"maximum" : 30000,
"access" : "expert",
"append" : "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 17
},
"verbose": {
"type": "boolean",
"title":"edt_dev_spec_verbose_title",
"default" : false,
"access" : "expert",
"propertyOrder" : 18
},
"debugStreamer": {
"type": "boolean",
"title":"edt_dev_spec_debugStreamer_title",
"default" : false,
"access" : "expert",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder" : 19
},
"debugLevel": {
"type": "string",
"title":"edt_dev_spec_debugLevel_title",
"enum" : ["0", "1", "2", "3", "4"],
"default" : "0",
"options" : {
"enum_titles" : ["edt_conf_enum_dl_nodebug", "edt_conf_enum_dl_error", "edt_conf_enum_dl_statechange", "edt_conf_enum_dl_informational", "edt_conf_enum_dl_verbose"],
"dependencies": {
"useEntertainmentAPI": true
}
},
"minimum" : 0,
"maximum" : 4,
"access" : "expert",
"propertyOrder" : 20
}
},
"additionalProperties": true
"type": "object",
"required": true,
"properties": {
"output": {
"type": "string",
"title": "edt_dev_spec_targetIp_title",
"default": "",
"propertyOrder": 1
},
"username": {
"type": "string",
"title": "edt_dev_spec_username_title",
"default": "",
"propertyOrder": 2
},
"clientkey": {
"type": "string",
"title": "edt_dev_spec_clientKey_title",
"default": "",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 3
},
"useEntertainmentAPI": {
"type": "boolean",
"title": "edt_dev_spec_useEntertainmentAPI_title",
"default": false,
"propertyOrder": 4
},
"transitiontime": {
"type": "number",
"title": "edt_dev_spec_transistionTime_title",
"default": 1,
"append": "x100ms",
"options": {
"dependencies": {
"useEntertainmentAPI": false
}
},
"propertyOrder": 5
},
"switchOffOnBlack": {
"type": "boolean",
"title": "edt_dev_spec_switchOffOnBlack_title",
"default": false,
"propertyOrder": 6
},
"restoreOriginalState": {
"type": "boolean",
"title": "edt_dev_spec_restoreOriginalState_title",
"default": true,
"propertyOrder": 7
},
"lightIds": {
"type": "array",
"title": "edt_dev_spec_lightid_title",
"minimum": 1,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1,
"required": true,
"title": "edt_dev_spec_lightid_itemtitle"
},
"options": {
"dependencies": {
"useEntertainmentAPI": false
}
},
"propertyOrder": 8
},
"groupId": {
"type": "number",
"title": "edt_dev_spec_groupId_title",
"default": 0,
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 9
},
"blackLightsTimeout": {
"type": "number",
"title": "edt_dev_spec_blackLightsTimeout_title",
"default": 15000,
"step": 500,
"minimum": 10000,
"maximum": 60000,
"access": "advanced",
"append": "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 10
},
"brightnessThreshold": {
"type": "number",
"title": "edt_dev_spec_brightnessThreshold_title",
"default": 0,
"step": 0.005,
"minimum": 0,
"maximum": 1.0,
"access": "advanced",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 11
},
"brightnessFactor": {
"type": "number",
"title": "edt_dev_spec_brightnessFactor_title",
"default": 1.0,
"step": 0.25,
"minimum": 0.5,
"maximum": 10.0,
"access": "advanced",
"propertyOrder": 12
},
"brightnessMin": {
"type": "number",
"title": "edt_dev_spec_brightnessMin_title",
"default": 0,
"step": 0.05,
"minimum": 0,
"maximum": 1.0,
"access": "advanced",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 13
},
"brightnessMax": {
"type": "number",
"title": "edt_dev_spec_brightnessMax_title",
"default": 1.0,
"step": 0.05,
"minimum": 0,
"maximum": 1.0,
"access": "advanced",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 14
},
"sslReadTimeout": {
"type": "number",
"title": "edt_dev_spec_sslReadTimeout_title",
"default": 0,
"step": 100,
"minimum": 0,
"maximum": 30000,
"access": "expert",
"append": "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 15
},
"sslHSTimeoutMin": {
"type": "number",
"title": "edt_dev_spec_sslHSTimeoutMin_title",
"default": 400,
"step": 100,
"minimum": 0,
"maximum": 30000,
"access": "expert",
"append": "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 16
},
"sslHSTimeoutMax": {
"type": "number",
"title": "edt_dev_spec_sslHSTimeoutMax_title",
"default": 1000,
"step": 100,
"minimum": 0,
"maximum": 30000,
"access": "expert",
"append": "edt_append_ms",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 17
},
"verbose": {
"type": "boolean",
"title": "edt_dev_spec_verbose_title",
"default": false,
"access": "expert",
"propertyOrder": 18
},
"debugStreamer": {
"type": "boolean",
"title": "edt_dev_spec_debugStreamer_title",
"default": false,
"access": "expert",
"options": {
"dependencies": {
"useEntertainmentAPI": true
}
},
"propertyOrder": 19
},
"debugLevel": {
"type": "string",
"title": "edt_dev_spec_debugLevel_title",
"enum": [ "0", "1", "2", "3", "4" ],
"default": "0",
"options": {
"enum_titles": [ "edt_conf_enum_dl_nodebug", "edt_conf_enum_dl_error", "edt_conf_enum_dl_statechange", "edt_conf_enum_dl_informational", "edt_conf_enum_dl_verbose" ],
"dependencies": {
"useEntertainmentAPI": true
}
},
"minimum": 0,
"maximum": 4,
"access": "expert",
"propertyOrder": 20
}
},
"additionalProperties": true
}

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"default" : "/dev/spidev0.0",
"propertyOrder" : 1
},

View File

@ -1,30 +1,84 @@
{
"type":"object",
"required":true,
"properties":{
"host" : {
"type": "string",
"title": "edt_dev_spec_targetIpHost_title",
"required": true,
"propertyOrder": 1
},
"restoreOriginalState": {
"type": "boolean",
"title": "edt_dev_spec_restoreOriginalState_title",
"default": false,
"required": true,
"propertyOrder": 2
},
"latchTime": {
"type": "integer",
"title":"edt_dev_spec_latchtime_title",
"default": 0,
"append" : "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access" : "expert",
"propertyOrder" : 3
}
},
"additionalProperties": true
"type": "object",
"title": "",
"required": true,
"properties": {
"hostList": {
"type": "string",
"title": "edt_dev_spec_devices_discovered_title",
"enum": [ "NONE" ],
"options": {
"enum_titles": [ "edt_dev_spec_devices_discovery_inprogress" ],
"infoText": "edt_dev_spec_devices_discovered_title_info"
},
"required": true,
"propertyOrder": 1
},
"host": {
"type": "string",
"title": "edt_dev_spec_targetIpHost_title",
"options": {
"infoText": "edt_dev_spec_targetIpHost_title_info"
},
"required": true,
"propertyOrder": 2
},
"restoreOriginalState": {
"type": "boolean",
"format": "checkbox",
"title": "edt_dev_spec_restoreOriginalState_title",
"default": false,
"required": true,
"options": {
"infoText": "edt_dev_spec_restoreOriginalState_title_info"
},
"propertyOrder": 3
},
"overwriteSync": {
"type": "boolean",
"format": "checkbox",
"title": "edt_dev_spec_syncOverwrite_title",
"default": true,
"required": true,
"access": "advanced",
"propertyOrder": 4
},
"overwriteBrightness": {
"type": "boolean",
"format": "checkbox",
"title": "edt_dev_spec_brightnessOverwrite_title",
"default": true,
"required": true,
"access": "advanced",
"propertyOrder": 5
},
"brightness": {
"type": "integer",
"title": "edt_dev_spec_brightness_title",
"default": 255,
"minimum": 1,
"maximum": 255,
"options": {
"dependencies": {
"overwriteBrightness": true
}
},
"access": "advanced",
"propertyOrder": 6
},
"latchTime": {
"type": "integer",
"title": "edt_dev_spec_latchtime_title",
"default": 0,
"append": "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access": "expert",
"options": {
"infoText": "edt_dev_spec_latchtime_title_info"
},
"propertyOrder": 7
}
},
"additionalProperties": true
}

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1","/dev/spidev1.0","/dev/spidev1.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -5,7 +5,6 @@
"output": {
"type": "string",
"title":"edt_dev_spec_spipath_title",
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
"propertyOrder" : 1
},
"rate": {

View File

@ -1,180 +1,176 @@
{
"type":"object",
"required":true,
"properties":{
"colorModel": {
"type": "integer",
"title":"Output Type",
"enum" : [0, 1],
"default" : 1,
"options" : {
"enum_titles" : ["edt_conf_enum_hsv", "edt_conf_enum_rgb"]
},
"minimum" : 0,
"maximum" : 1,
"access" : "advanced",
"propertyOrder" : 1
},
"transEffect": {
"type": "integer",
"title":"edt_dev_spec_transeffect_title",
"enum" : [0, 1],
"default" : 0,
"options" : {
"enum_titles" : ["edt_conf_enum_transeffect_smooth", "edt_conf_enum_transeffect_sudden" ]
},
"minimum" : 0,
"maximum" : 1,
"access" : "advanced",
"propertyOrder" : 2
},
"transTime": {
"type": "integer",
"title":"edt_dev_spec_transistionTime_title",
"default": 40,
"append" : "ms",
"minimum": 30,
"maximum": 5000,
"access" : "advanced",
"options": {
"dependencies": {
"transEffect": 0
}
},
"propertyOrder" : 3
},
"extraTimeDarkness": {
"type": "integer",
"title":"edt_dev_spec_transistionTimeExtra_title",
"default" : 0,
"step": 100,
"minimum" : 0,
"maximum" : 8000,
"append" : "ms",
"access" : "advanced",
"propertyOrder" : 4
},
"brightnessMin": {
"type": "integer",
"title":"edt_dev_spec_brightnessMin_title",
"default" : 1,
"step": 1,
"minimum" : 1,
"maximum" : 99,
"append" : "%",
"access" : "advanced",
"propertyOrder" : 5
},
"brightnessSwitchOffOnMinimum": {
"type": "boolean",
"title":"edt_dev_spec_switchOffOnbelowMinBrightness_title",
"default" : true,
"access" : "advanced",
"propertyOrder" : 6
},
"brightnessMax": {
"type": "integer",
"title":"edt_dev_spec_brightnessMax_title",
"default" : 100,
"step": 1,
"minimum" : 0,
"maximum" : 100,
"append" : "%",
"access" : "advanced",
"propertyOrder" : 7
},
"brightnessFactor": {
"type": "number",
"title":"edt_dev_spec_brightnessFactor_title",
"default" : 1.0,
"step": 0.25,
"minimum" : 0.5,
"maximum" : 10.0,
"access" : "expert",
"propertyOrder" : 8
},
"restoreOriginalState": {
"type": "boolean",
"title":"edt_dev_spec_restoreOriginalState_title",
"default" : false,
"propertyOrder" : 9
},
"lights": {
"type": "array",
"title":"edt_dev_spec_lights_title",
"propertyOrder" : 9,
"minimum" : 1,
"uniqueItems" : true,
"items" : {
"type" : "object",
"title" : "edt_dev_spec_lights_itemtitle",
"required" : true,
"properties" :
{
"host" :
{
"type" : "string",
"minimum" : 7,
"title" : "edt_dev_spec_networkDeviceName_title",
"required" : true,
"propertyOrder" : 1
},
"port" :
{
"type" : "integer",
"minimum" : 0,
"maximum" : 65535,
"default":55443,
"title" : "edt_dev_spec_networkDevicePort_title",
"required" : false,
"access" : "expert",
"propertyOrder" : 2
},
"name" :
{
"type" : "string",
"title" : "edt_dev_spec_lights_name",
"minimum" : 0,
"propertyOrder" : 3
}
}
},
"propertyOrder" : 10
},
"quotaWait": {
"type": "integer",
"title":"Wait time (quota)",
"default": 1000,
"append" : "edt_append_ms",
"minimum": 0,
"maximum": 10000,
"step": 100,
"access" : "expert",
"propertyOrder" : 11
},
"latchTime": {
"type": "integer",
"title":"edt_dev_spec_latchtime_title",
"default": 40,
"append" : "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access" : "expert",
"propertyOrder" : 12
},
"debugLevel": {
"type": "integer",
"title":"edt_dev_spec_debugLevel_title",
"enum" : [0, 1, 2, 3],
"default" : 0,
"options" : {
"enum_titles" : ["edt_conf_enum_dl_nodebug", "edt_conf_enum_dl_verbose1", "edt_conf_enum_dl_verbose2", "edt_conf_enum_dl_verbose3"]
},
"minimum" : 0,
"maximum" : 3,
"access" : "expert",
"propertyOrder" : 13
}
},
"additionalProperties": true
"type": "object",
"required": true,
"properties": {
"colorModel": {
"type": "string",
"title": "Output Type",
"enum": [ "0", "1" ],
"default": "1",
"options": {
"enum_titles": [ "edt_conf_enum_hsv", "edt_conf_enum_rgb" ]
},
"minimum": 0,
"maximum": 1,
"access": "advanced",
"propertyOrder": 1
},
"transEffect": {
"type": "string",
"title": "edt_dev_spec_transeffect_title",
"enum": [ "0", "1" ],
"default": "0",
"options": {
"enum_titles": [ "edt_conf_enum_transeffect_smooth", "edt_conf_enum_transeffect_sudden" ]
},
"minimum": 0,
"maximum": 1,
"access": "advanced",
"propertyOrder": 2
},
"transTime": {
"type": "integer",
"title": "edt_dev_spec_transistionTime_title",
"default": 40,
"append": "ms",
"minimum": 30,
"maximum": 5000,
"access": "advanced",
"options": {
"dependencies": {
"transEffect": 0
}
},
"propertyOrder": 3
},
"extraTimeDarkness": {
"type": "integer",
"title": "edt_dev_spec_transistionTimeExtra_title",
"default": 0,
"step": 100,
"minimum": 0,
"maximum": 8000,
"append": "ms",
"access": "advanced",
"propertyOrder": 4
},
"brightnessMin": {
"type": "integer",
"title": "edt_dev_spec_brightnessMin_title",
"default": 1,
"step": 1,
"minimum": 1,
"maximum": 99,
"append": "%",
"access": "advanced",
"propertyOrder": 5
},
"brightnessSwitchOffOnMinimum": {
"type": "boolean",
"title": "edt_dev_spec_switchOffOnbelowMinBrightness_title",
"default": true,
"access": "advanced",
"propertyOrder": 6
},
"brightnessMax": {
"type": "integer",
"title": "edt_dev_spec_brightnessMax_title",
"default": 100,
"step": 1,
"minimum": 0,
"maximum": 100,
"append": "%",
"access": "advanced",
"propertyOrder": 7
},
"brightnessFactor": {
"type": "number",
"title": "edt_dev_spec_brightnessFactor_title",
"default": 1.0,
"step": 0.25,
"minimum": 0.5,
"maximum": 10.0,
"access": "expert",
"propertyOrder": 8
},
"restoreOriginalState": {
"type": "boolean",
"title": "edt_dev_spec_restoreOriginalState_title",
"default": false,
"propertyOrder": 9
},
"lights": {
"type": "array",
"title": "edt_dev_spec_lights_title",
"propertyOrder": 9,
"minimum": 1,
"uniqueItems": true,
"items": {
"type": "object",
"title": "edt_dev_spec_lights_itemtitle",
"required": true,
"properties": {
"host": {
"type": "string",
"minLength": 7,
"title": "edt_dev_spec_networkDeviceName_title",
"required": true,
"propertyOrder": 1
},
"port": {
"type": "integer",
"minimum": 0,
"maximum": 65535,
"default": 55443,
"title": "edt_dev_spec_networkDevicePort_title",
"required": false,
"access": "expert",
"propertyOrder": 2
},
"name": {
"type": "string",
"title": "edt_dev_spec_lights_name",
"minimum": 0,
"propertyOrder": 3
}
}
},
"propertyOrder": 10
},
"quotaWait": {
"type": "integer",
"title": "Wait time (quota)",
"default": 1000,
"append": "edt_append_ms",
"minimum": 0,
"maximum": 10000,
"step": 100,
"access": "expert",
"propertyOrder": 11
},
"latchTime": {
"type": "integer",
"title": "edt_dev_spec_latchtime_title",
"default": 40,
"append": "edt_append_ms",
"minimum": 0,
"maximum": 1000,
"access": "expert",
"propertyOrder": 12
},
"debugLevel": {
"type": "string",
"title": "edt_dev_spec_debugLevel_title",
"enum": [ "0", "1", "2", "3" ],
"default": "0",
"options": {
"enum_titles": [ "edt_conf_enum_dl_nodebug", "edt_conf_enum_dl_verbose1", "edt_conf_enum_dl_verbose2", "edt_conf_enum_dl_verbose3" ]
},
"minimum": 0,
"maximum": 3,
"access": "expert",
"propertyOrder": 13
}
},
"additionalProperties": true
}

View File

@ -96,8 +96,8 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
qRegisterMetaType<QMap<quint8, QJsonObject>>("QMap<quint8,QJsonObject>");
qRegisterMetaType<std::vector<ColorRgb>>("std::vector<ColorRgb>");
// init settings
_settingsManager = new SettingsManager(0, this, readonlyMode);
// init settings, this settingsManager accesses global settings which are independent from instances
_settingsManager = new SettingsManager(GLOABL_INSTANCE_ID, this, readonlyMode);
// set inital log lvl if the loglvl wasn't overwritten by arg
if (!logLvlOverwrite)