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 shell: bash
run: | run: |
tr -d '\n' < version > temp && mv temp version 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 # Build packages
- name: Build packages - name: Build packages
@ -87,7 +87,7 @@ jobs:
shell: bash shell: bash
run: | run: |
tr -d '\n' < version > temp && mv temp version 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 # Install dependencies
- name: Install dependencies - name: Install dependencies
@ -136,7 +136,7 @@ jobs:
shell: bash shell: bash
run: | run: |
tr -d '\n' < version > temp && mv temp version 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 - name: Cache Qt
uses: actions/cache@v2 uses: actions/cache@v2

View File

@ -1,3 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<title>Hyperion - LED Device Configuration</title>
</head>
<div class="container-fluid"> <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> <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"> <ul id="leds_cfg_nav" class="nav nav-tabs">
@ -6,7 +11,6 @@
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div id="menu_controller" class="tab-pane fade in active" style="padding-top:10px"> <div id="menu_controller" class="tab-pane fade in active" style="padding-top:10px">
<div class="row"> <div class="row">
<div class="col-lg-12" id="leddevice_intro"></div> <div class="col-lg-12" id="leddevice_intro"></div>
@ -14,15 +18,21 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading form-group"> <div class="panel-heading form-group">
<label for="leddevices" class="panel-title" data-i18n="conf_leds_contr_label_contrtype">Controller type:</label> <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 id="leddevices" class="form-control" style="color:black;width:auto;margin-left:10px;display:inline-block"></select>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<div id="btn_wiz_holder"></div> <div id="btn_wiz_holder"></div>
<div id="ledDeviceOptions"> <div id='editor_container'></div> </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>
<div class="panel-footer" style="text-align:right"> <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> <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>
@ -36,12 +46,12 @@
<div class="col-lg-6 col-md-12"> <div class="col-lg-6 col-md-12">
<div class="panel-group" id="accordion"> <div class="panel-group" id="accordion">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading headcollapse" data-toggle="collapse" data-parent="#accordion" data-target="#collapse1"> <div class="panel-heading headcollapse" id="classic_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse1">
<h4 class="panel-title"> <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> <a><i class="fa fa-television fa-fw"></i><span data-i18n="conf_leds_layout_frame">Classic Layout (LED Frame)</span></a>
</h4> </h4>
</div> </div>
<div id="collapse1" class="panel-collapse collapse in"> <div id="collapse1" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
<table class="table borderless"> <table class="table borderless">
<tbody> <tbody>
@ -244,7 +254,6 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="panel-footer" style="text-align:right;"> <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> <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>
@ -252,7 +261,7 @@
</div> </div>
</div> </div>
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading headcollapse" data-toggle="collapse" data-parent="#accordion" data-target="#collapse2"> <div class="panel-heading headcollapse" id="matrix_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse2">
<h4 class="panel-title"> <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> <a><i class="fa fa-th fa-fw"></i><span data-i18n="conf_leds_layout_matrix">Matrix Configuration (LED wall)</span></a>
</h4> </h4>
@ -290,18 +299,6 @@
</select> </select>
</td> </td>
</tr> </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> <tr>
<td class="ltd"> <td class="ltd">
<label class="ltdlabel" for="ip_ma_start" data-i18n="conf_leds_layout_ma_position">Input</label> <label class="ltdlabel" for="ip_ma_start" data-i18n="conf_leds_layout_ma_position">Input</label>
@ -323,13 +320,28 @@
</div> </div>
</div> </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 id="texfield_panel" class="panel panel-primary">
<div class="panel-heading headcollapse" data-toggle="collapse" data-parent="#accordion" data-target="#collapse4"> <div class="panel-heading headcollapse" id="current_config_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse5">
<h4 class="panel-title"> <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> <a><i class="fa fa-wrench fa-fw"></i><span data-i18n="conf_leds_layout_generatedconf">Generated/Actual LED Configuration</span></a>
</h4> </h4>
</div> </div>
<div id="collapse4" class="panel-collapse collapse"> <div id="collapse5" class="panel-collapse collapse in">
<div class="panel-body"> <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> <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 id="aceedit" style="width:100%;height:500px"></div>
@ -363,12 +375,8 @@
</div> </div>
</div> </div>
</div> </div>
</div> <!-- row layout -->
</div> </div>
</div> </div>
</div> <!-- tab content -->
</div> </div>
<script src="/js/content_leds.js"></script> <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": "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_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", "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_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_expl": "Explanation",
"conf_helptable_option": "Option", "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_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_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_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_btn_checklist": "Show checklist",
"conf_leds_layout_button_savelay": "Save Layout", "conf_leds_layout_button_savelay": "Save Layout",
"conf_leds_layout_button_updsim": "Update Preview", "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_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_ledcontroller": "LED Controller",
"conf_leds_nav_label_ledlayout": "LED Layout", "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_RPiGPIO": "RPi GPIO",
"conf_leds_optgroup_RPiPWM": "RPi PWM", "conf_leds_optgroup_RPiPWM": "RPi PWM",
"conf_leds_optgroup_RPiSPI": "RPi SPI", "conf_leds_optgroup_RPiSPI": "RPi SPI",
"conf_leds_optgroup_debug": "Debug",
"conf_leds_optgroup_network": "Network",
"conf_leds_optgroup_usb": "USB/Serial", "conf_leds_optgroup_usb": "USB/Serial",
"conf_logging_btn_autoscroll": "Auto scrolling", "conf_logging_btn_autoscroll": "Auto scrolling",
"conf_logging_btn_pbupload": "Upload a report for support requests", "conf_logging_btn_pbupload": "Upload a report for support requests",
@ -215,10 +215,10 @@
"edt_conf_color_black_title": "Black", "edt_conf_color_black_title": "Black",
"edt_conf_color_blue_expl": "The calibrated blue value.", "edt_conf_color_blue_expl": "The calibrated blue value.",
"edt_conf_color_blue_title": "Blue", "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_expl": "set overall brightness of LEDs",
"edt_conf_color_brightness_title": "Brightness", "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_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_itemtitle": "Profile",
"edt_conf_color_channelAdjustment_header_title": "Color channel adjustments", "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_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_itemtitle": "Path",
"edt_conf_effp_paths_title": "Effect Path(s)", "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_automatic": "Automatic",
"edt_conf_enum_bbclassic": "Classic", "edt_conf_enum_bbclassic": "Classic",
"edt_conf_enum_bbdefault": "Default", "edt_conf_enum_bbdefault": "Default",
@ -288,9 +284,14 @@
"edt_conf_enum_logverbose": "Verbose", "edt_conf_enum_logverbose": "Verbose",
"edt_conf_enum_logwarn": "Warning", "edt_conf_enum_logwarn": "Warning",
"edt_conf_enum_multicolor_mean": "Multicolor", "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_rbg": "RBG",
"edt_conf_enum_rgb": "RGB", "edt_conf_enum_rgb": "RGB",
"edt_conf_enum_right_left": "Right to left", "edt_conf_enum_right_left": "Right to left",
"edt_conf_enum_SECAM": "SECAM",
"edt_conf_enum_top_down": "Top down", "edt_conf_enum_top_down": "Top down",
"edt_conf_enum_transeffect_smooth": "Smooth", "edt_conf_enum_transeffect_smooth": "Smooth",
"edt_conf_enum_transeffect_sudden": "Sudden", "edt_conf_enum_transeffect_sudden": "Sudden",
@ -322,11 +323,12 @@
"edt_conf_fge_type_title": "Type", "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_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_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_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_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_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_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_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", "edt_conf_gen_name_title": "Configuration name",
@ -354,9 +356,9 @@
"edt_conf_net_heading_title": "Network", "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_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_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_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_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_expl": "When enabled, administration access from your local network needs a password.",
"edt_conf_net_localAdminAuth_title": "Local Admin API Authentication", "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.", "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_expl": "Port oft the HTTPS-Webserver",
"edt_conf_webc_sslport_title": "HTTPS Port", "edt_conf_webc_sslport_title": "HTTPS Port",
"edt_dev_auth_key_title": "Authentication Token", "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_cool_adjust": "Subtract cool white",
"edt_dev_enum_sub_min_warm_adjust": "Subtract warm white", "edt_dev_enum_sub_min_warm_adjust": "Subtract warm white",
"edt_dev_enum_subtract_minimum": "Subtract minimum", "edt_dev_enum_subtract_minimum": "Subtract minimum",
"edt_dev_enum_white_off": "White off", "edt_dev_enum_white_off": "White off",
"edt_dev_general_colorOrder_title": "RGB byte order", "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": "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_heading_title": "General Settings",
"edt_dev_general_name_title": "Configuration name", "edt_dev_general_name_title": "Configuration name",
"edt_dev_general_rewriteTime_title": "Refresh time", "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_baudrate_title": "Baudrate",
"edt_dev_spec_blackLightsTimeout_title": "Signal detection timeout on black", "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_brightnessFactor_title": "Brightness factor",
"edt_dev_spec_brightnessMax_title": "Brightness maximum", "edt_dev_spec_brightnessMax_title": "Brightness maximum",
"edt_dev_spec_brightnessMin_title": "Brightness minimum", "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_brightnessThreshold_title": "Signal detection brightness minimum",
"edt_dev_spec_chanperfixture_title": "Channels per Fixture", "edt_dev_spec_chanperfixture_title": "Channels per Fixture",
"edt_dev_spec_cid_title": "CID", "edt_dev_spec_cid_title": "CID",
@ -463,8 +465,16 @@
"edt_dev_spec_debugLevel_title": "Debug Level", "edt_dev_spec_debugLevel_title": "Debug Level",
"edt_dev_spec_debugStreamer_title": "Streamer Debug", "edt_dev_spec_debugStreamer_title": "Streamer Debug",
"edt_dev_spec_delayAfterConnect_title": "Delay after connect", "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_dithering_title": "Dithering",
"edt_dev_spec_dmaNumber_title": "DMA channel", "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_gamma_title": "Gamma",
"edt_dev_spec_globalBrightnessControlMaxLevel_title": "Max Current Level", "edt_dev_spec_globalBrightnessControlMaxLevel_title": "Max Current Level",
"edt_dev_spec_globalBrightnessControlThreshold_title": "Adaptive Current Threshold", "edt_dev_spec_globalBrightnessControlThreshold_title": "Adaptive Current Threshold",
@ -477,6 +487,8 @@
"edt_dev_spec_intervall_title": "Interval", "edt_dev_spec_intervall_title": "Interval",
"edt_dev_spec_invert_title": "Invert signal", "edt_dev_spec_invert_title": "Invert signal",
"edt_dev_spec_latchtime_title": "Latch time", "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_ledIndex_title": "LED index",
"edt_dev_spec_ledType_title": "LED Type", "edt_dev_spec_ledType_title": "LED Type",
"edt_dev_spec_lightid_itemtitle": "ID", "edt_dev_spec_lightid_itemtitle": "ID",
@ -484,8 +496,8 @@
"edt_dev_spec_lights_itemtitle": "Light", "edt_dev_spec_lights_itemtitle": "Light",
"edt_dev_spec_lights_name": "Name", "edt_dev_spec_lights_name": "Name",
"edt_dev_spec_lights_title": "Light(s)", "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_maximumLedCount_title": "Maximum LED count",
"edt_dev_spec_maxPacket_title": "Max packet",
"edt_dev_spec_multicastGroup_title": "Multicast group", "edt_dev_spec_multicastGroup_title": "Multicast group",
"edt_dev_spec_networkDeviceName_title": "Network devicename", "edt_dev_spec_networkDeviceName_title": "Network devicename",
"edt_dev_spec_networkDevicePort_title": "Port", "edt_dev_spec_networkDevicePort_title": "Port",
@ -496,23 +508,27 @@
"edt_dev_spec_outputPath_title": "Output path", "edt_dev_spec_outputPath_title": "Output path",
"edt_dev_spec_panel_start_position": "Start panel [0-max panels]", "edt_dev_spec_panel_start_position": "Start panel [0-max panels]",
"edt_dev_spec_panelorganisation_title": "Panel numbering sequence", "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_pid_title": "PID",
"edt_dev_spec_port_title": "Port", "edt_dev_spec_port_title": "Port",
"edt_dev_spec_printTimeStamp_title": "Add timestamp", "edt_dev_spec_printTimeStamp_title": "Add timestamp",
"edt_dev_spec_pwmChannel_title": "PWM channel", "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_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_sslHSTimeoutMax_title": "Streamer handshake timeout maximum",
"edt_dev_spec_sslHSTimeoutMin_title": "Streamer handshake timeout minimum", "edt_dev_spec_sslHSTimeoutMin_title": "Streamer handshake timeout minimum",
"edt_dev_spec_sslReadTimeout_title": "Streamer read timeout", "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_switchOffOnbelowMinBrightness_title": "Switch-off, below minimum",
"edt_dev_spec_targetIpHost_title": "Target IP/Hostname", "edt_dev_spec_switchOffOnBlack_title": "Switch off on black",
"edt_dev_spec_targetIp_title": "Target IP", "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_transeffect_title": "Transition effect",
"edt_dev_spec_transistionTimeExtra_title": "Extra time darkness",
"edt_dev_spec_transistionTime_title": "Transition time", "edt_dev_spec_transistionTime_title": "Transition time",
"edt_dev_spec_transistionTimeExtra_title": "Extra time darkness",
"edt_dev_spec_uid_title": "UID", "edt_dev_spec_uid_title": "UID",
"edt_dev_spec_universe_title": "Universe", "edt_dev_spec_universe_title": "Universe",
"edt_dev_spec_useEntertainmentAPI_title": "Use Hue Entertainment API", "edt_dev_spec_useEntertainmentAPI_title": "Use Hue Entertainment API",
@ -538,16 +554,16 @@
"edt_eff_collision_header": "color collision", "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_collision_header_desc": "Two color projectiles are sent from random positions and collide with each other",
"edt_eff_color": "Color", "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_colorcount": "Color length",
"edt_eff_colorend": "Color end", "edt_eff_colorend": "Color end",
"edt_eff_colorendtime": "Time to hold start color", "edt_eff_colorendtime": "Time to hold start color",
"edt_eff_colorevel": "Color level", "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_colorone": "Color one",
"edt_eff_colorrandom": "Random color", "edt_eff_colorrandom": "Random color",
"edt_eff_colorSecond": "Color second",
"edt_eff_colorshift": "Color Shift", "edt_eff_colorshift": "Color Shift",
"edt_eff_colorstart": "Color start", "edt_eff_colorstart": "Color start",
"edt_eff_colorstarttime": "Time to hold end color", "edt_eff_colorstarttime": "Time to hold end color",
@ -603,13 +619,13 @@
"edt_eff_postcolor": "Post color", "edt_eff_postcolor": "Post color",
"edt_eff_rainbowmood_header": "Rainbow Mood", "edt_eff_rainbowmood_header": "Rainbow Mood",
"edt_eff_rainbowmood_header_desc": "All LEDs 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": "Random",
"edt_eff_random_header_desc": "Pixel Dot, dot, dot...", "edt_eff_random_header_desc": "Pixel Dot, dot, dot...",
"edt_eff_randomCenter": "Random Center",
"edt_eff_repeat": "Repeat", "edt_eff_repeat": "Repeat",
"edt_eff_repeatcount": "Repeat count", "edt_eff_repeatcount": "Repeat count",
"edt_eff_reverseRandomTime": "Reverse every",
"edt_eff_reversedirection": "Reverse direction", "edt_eff_reversedirection": "Reverse direction",
"edt_eff_reverseRandomTime": "Reverse every",
"edt_eff_rotationtime": "Rotation time", "edt_eff_rotationtime": "Rotation time",
"edt_eff_saturation": "Saturation", "edt_eff_saturation": "Saturation",
"edt_eff_showseconds": "Show seconds", "edt_eff_showseconds": "Show seconds",
@ -647,23 +663,23 @@
"edt_msg_button_expand": "Expand", "edt_msg_button_expand": "Expand",
"edt_msg_button_move_down_title": "Move down", "edt_msg_button_move_down_title": "Move down",
"edt_msg_button_move_up_title": "Move up", "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_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_anyOf": "Value must validate against at least one of the provided schemas",
"edt_msg_error_dependency": "Must have property $1", "edt_msg_error_dependency": "Must have property $1",
"edt_msg_error_disallow": "Value must not be of type $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_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_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_maxItems": "Value must have at most $1 items",
"edt_msg_error_maxLength": "Value must be at most $1 characters long", "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_maxProperties": "Object must have at most $1 properties",
"edt_msg_error_maximum_excl": "Value must be less than $1", "edt_msg_error_minimum_excl": "Value must be greater than $1",
"edt_msg_error_maximum_incl": "Value must be at most $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_minItems": "Value must have at least $1 items",
"edt_msg_error_minLength": "Value must be at least $1 characters long", "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_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_multipleOf": "Value must be a multiple of $1",
"edt_msg_error_not": "Value must not validate against the provided schema", "edt_msg_error_not": "Value must not validate against the provided schema",
"edt_msg_error_notempty": "Value required", "edt_msg_error_notempty": "Value required",
@ -698,6 +714,7 @@
"general_btn_off": "Off", "general_btn_off": "Off",
"general_btn_ok": "OK", "general_btn_ok": "OK",
"general_btn_on": "On", "general_btn_on": "On",
"general_btn_overwrite": "Overwrite",
"general_btn_rename": "Rename", "general_btn_rename": "Rename",
"general_btn_restarthyperion": "Restart Hyperion", "general_btn_restarthyperion": "Restart Hyperion",
"general_btn_save": "Save", "general_btn_save": "Save",
@ -745,20 +762,6 @@
"general_speech_zh-CN": "Chinese (simplified)", "general_speech_zh-CN": "Chinese (simplified)",
"general_webui_title": "Hyperion - Web Configuration", "general_webui_title": "Hyperion - Web Configuration",
"general_wiki_moreto": "More information to \"$1\" at our Wiki", "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_404": "The page you requested is not available!",
"info_conlost_label_autorecon": "We reconnect again after Hyperion is available.", "info_conlost_label_autorecon": "We reconnect again after Hyperion is available.",
"info_conlost_label_autorefresh": "This page will be automatically refreshed.", "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_contusa": "...with your last steps. Thank you!",
"info_restart_rightback": "Hyperion will be right back immediately!", "info_restart_rightback": "Hyperion will be right back immediately!",
"info_restart_title": "Restarts currently...", "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_togglelednumber": "LED numbers",
"main_ledsim_btn_toggleleds": "Show LEDs", "main_ledsim_btn_toggleleds": "Show LEDs",
"main_ledsim_btn_togglelivevideo": "Live video", "main_ledsim_btn_togglelivevideo": "Live video",

View File

@ -101,7 +101,7 @@
<span class="icon-bar middle-bar"></span> <span class="icon-bar middle-bar"></span>
<span class="icon-bar bottom-bar"></span> <span class="icon-bar bottom-bar"></span>
</button> </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> </div>
<!-- /.navbar-header --> <!-- /.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> <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"> <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_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="#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> <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> </ul>

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

@ -4,8 +4,7 @@ $(document).ready( function() {
var editor_smoothing = null; var editor_smoothing = null;
var editor_blackborder = null; var editor_blackborder = null;
if(window.showOptHelp) if (window.showOptHelp) {
{
//color //color
$('#conf_cont').append(createRow('conf_cont_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(createOptPanel('fa-photo', $.i18n("edt_conf_color_heading_title"), 'editor_container_color', 'btn_submit_color'));
@ -21,8 +20,7 @@ $(document).ready( function() {
$('#conf_cont_blackborder').append(createOptPanel('fa-photo', $.i18n("edt_conf_bb_heading_title"), 'editor_container_blackborder', 'btn_submit_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"))); $('#conf_cont_blackborder').append(createHelpTable(window.schema.blackborderdetector.properties, $.i18n("edt_conf_bb_heading_title")));
} }
else else {
{
$('#conf_cont').addClass('row'); $('#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_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_smooth_heading_title"), 'editor_container_smoothing', 'btn_submit_smoothing'));
@ -49,7 +47,6 @@ $(document).ready( function() {
editor_smoothing.on('change', function () { editor_smoothing.on('change', function () {
editor_smoothing.validate().length || window.readOnlyMode ? $('#btn_submit_smoothing').attr('disabled', true) : $('#btn_submit_smoothing').attr('disabled', false); 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 () { $('#btn_submit_smoothing').off().on('click', function () {
@ -70,11 +67,10 @@ $(document).ready( function() {
}); });
//wiki links //wiki links
$('#editor_container_blackborder').append(buildWL("user/moretopics/bbmode","edt_conf_bb_mode_title",true)); $('#editor_container_blackborder').append(buildWL("user/advanced/Advanced.html#blackbar-detection", "edt_conf_bb_mode_title", true));
//create introduction //create introduction
if(window.showOptHelp) if (window.showOptHelp) {
{
createHint("intro", $.i18n('conf_colors_color_intro'), "editor_container_color"); 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_smoothing_intro'), "editor_container_smoothing");
createHint("intro", $.i18n('conf_colors_blackborder_intro'), "editor_container_blackborder"); createHint("intro", $.i18n('conf_colors_blackborder_intro'), "editor_container_blackborder");

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

@ -1,11 +1,9 @@
var instNameInit = false var instNameInit = false
$(document).ready(function () { $(document).ready(function () {
var darkModeOverwrite = getStorage("darkModeOverwrite", true); var darkModeOverwrite = getStorage("darkModeOverwrite", true);
if(darkModeOverwrite == "false" || darkModeOverwrite == null) if (darkModeOverwrite == "false" || darkModeOverwrite == null) {
{
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
handleDarkMode(); handleDarkMode();
} }
@ -15,8 +13,7 @@ $(document).ready(function () {
} }
} }
if(getStorage("darkMode", false) == "on") if (getStorage("darkMode", false) == "on") {
{
handleDarkMode(); handleDarkMode();
} }
@ -62,8 +59,7 @@ $(document).ready(function () {
// Update language selection // Update language selection
$("#language-select").on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) { $("#language-select").on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
var newLang = availLang[clickedIndex - 1]; var newLang = availLang[clickedIndex - 1];
if (newLang !== storedLang) if (newLang !== storedLang) {
{
setStorage("langcode", newLang); setStorage("langcode", newLang);
reload(); reload();
} }
@ -155,8 +151,7 @@ $(document).ready(function () {
$("#main-nav").removeAttr('style') $("#main-nav").removeAttr('style')
$("#top-navbar").removeAttr('style') $("#top-navbar").removeAttr('style')
if (window.defaultPasswordIsSet === true && getStorage("suppressDefaultPwWarning") !== "true" ) if (window.defaultPasswordIsSet === true && getStorage("suppressDefaultPwWarning") !== "true") {
{
var supprPwWarnCheckbox = '<div class="text-right">' + $.i18n('dashboard_message_do_not_show_again') var supprPwWarnCheckbox = '<div class="text-right">' + $.i18n('dashboard_message_do_not_show_again')
+ ' <input id="chk_suppressDefaultPw" type="checkbox" onChange="suppressDefaultPwWarning()"> </div>' + ' <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()">' showNotification('warning', $.i18n('dashboard_message_default_password'), $.i18n('dashboard_message_default_password_t'), '<a style="cursor:pointer" onClick="changePassword()">'
@ -166,7 +161,6 @@ $(document).ready(function () {
//if logged on and pw != default show option to lock ui //if logged on and pw != default show option to lock ui
$("#btn_lock_ui").removeAttr('style') $("#btn_lock_ui").removeAttr('style')
if (event.response.hasOwnProperty('info')) if (event.response.hasOwnProperty('info'))
setStorage("loginToken", event.response.info.token, true); setStorage("loginToken", event.response.info.token, true);
@ -313,11 +307,9 @@ $(document).ready(function () {
loadContent(e); loadContent(e);
window.scrollTo(0, 0); window.scrollTo(0, 0);
}); });
}); });
function suppressDefaultPwWarning() { function suppressDefaultPwWarning() {
if (document.getElementById('chk_suppressDefaultPw').checked) if (document.getElementById('chk_suppressDefaultPw').checked)
setStorage("suppressDefaultPwWarning", "true"); setStorage("suppressDefaultPwWarning", "true");
else else
@ -339,9 +331,7 @@ $(document.body).on('hide.bs.modal,hidden.bs.modal', function () {
//Dark Mode //Dark Mode
$("#btn_darkmode").off().on("click", function (e) { $("#btn_darkmode").off().on("click", function (e) {
if (getStorage("darkMode", false) != "on") {
if(getStorage("darkMode", false) != "on")
{
handleDarkMode(); handleDarkMode();
setStorage("darkModeOverwrite", true, true); setStorage("darkModeOverwrite", true, true);
} }
@ -352,3 +342,16 @@ $("#btn_darkmode").off().on("click",function(e){
} }
}); });
// 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;
};

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

File diff suppressed because it is too large Load Diff

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

@ -53,7 +53,7 @@ function updateSessions() {
if (sess && sess.length) { if (sess && sess.length) {
window.wSess = []; window.wSess = [];
for (var i = 0; i < sess.length; i++) { 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]); window.wSess.push(sess[i]);
} }
} }
@ -183,7 +183,6 @@ function initLanguageSelection() {
langText = availLangText[langIdx]; langText = availLangText[langIdx];
} }
} }
//console.log("langLocale: ", langLocale, "langText: ", langText);
$('#language-select').prop('title', langText); $('#language-select').prop('title', langText);
$("#language-select").val(langIdx); $("#language-select").val(langIdx);
@ -463,6 +462,170 @@ function createJsonEditor(container, schema, setconfig, usePanel, arrayre) {
return editor; 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) { function buildWL(link, linkt, cl) {
var baseLink = "https://docs.hyperion-project.org/"; var baseLink = "https://docs.hyperion-project.org/";
var lang; var lang;
@ -655,6 +818,48 @@ function createOptPanel(phicon, phead, bodyid, footerid) {
return createPanel(phead, "", pfooter, "panel-default", bodyid); 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) { function sortProperties(list) {
for (var key in list) { for (var key in list) {
list[key].key = key; list[key].key = key;
@ -876,3 +1081,19 @@ function handleDarkMode() {
$('#btn_darkmode_icon').removeClass('fa fa-moon-o'); $('#btn_darkmode_icon').removeClass('fa fa-moon-o');
$('#btn_darkmode_icon').addClass('fa fa-sun-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
}

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

@ -437,7 +437,6 @@ function startWizardCC() {
}); });
$('#wiz_cc_kodiip').off().on('change', function () { $('#wiz_cc_kodiip').off().on('change', function () {
kodiAddress = $(this).val().trim(); kodiAddress = $(this).val().trim();
$('#wizp1_body').find("kodiAddress").val(kodiAddress); $('#wizp1_body').find("kodiAddress").val(kodiAddress);
@ -788,8 +787,6 @@ async function discover_hue_bridges() {
const r = res.info; const r = res.info;
// Process devices returned by discovery // Process devices returned by discovery
console.log(r);
if (r.devices.length == 0) if (r.devices.length == 0)
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip')); $('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
else { else {
@ -832,7 +829,7 @@ async function identify_hue_device(hostAddress, username, id) {
$('#btn_wiz_save').attr('disabled', true); $('#btn_wiz_save').attr('disabled', true);
let params = { host: hostAddress, user: username, lightId: id }; let params = { host: hostAddress, user: username, lightId: id };
const res = await requestLedDeviceIdentification('philipshue', params); await requestLedDeviceIdentification('philipshue', params);
if (!window.readOnlyMode) { if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false); $('#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); (cC == 0 || window.readOnlyMode) ? $('#btn_wiz_save').attr("disabled", true) : $('#btn_wiz_save').attr("disabled", false);
}); });
} }
$('.hue_sel_watch').trigger('change'); $('.hue_sel_watch').trigger('change');
@ -1208,108 +1204,6 @@ function abortConnection(UserInterval) {
$("#wiz_hue_usrstate").html($.i18n('wiz_hue_failure_connection')); $("#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 // Wizard Yeelight
//**************************** //****************************
@ -1438,8 +1332,17 @@ async function discover_yeelight_lights() {
var light = {}; var light = {};
light.host = device.hostname; light.host = device.hostname;
light.port = device.port; light.port = device.port;
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.name = device.other.name;
light.model = device.other.model; light.model = device.other.model;
}
lights.push(light); lights.push(light);
} }
} }
@ -1469,7 +1372,8 @@ async function discover_yeelight_lights() {
} }
function assign_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 records are left for configuration
if (Object.keys(lights).length > 0) { if (Object.keys(lights).length > 0) {
@ -1555,12 +1459,11 @@ async function getProperties_yeelight(hostname, port) {
} }
async function identify_yeelight_device(hostname, port) { async function identify_yeelight_device(hostname, port) {
// Take care that new record cannot be save during background process // Take care that new record cannot be save during background process
$('#btn_wiz_save').attr('disabled', true); $('#btn_wiz_save').attr('disabled', true);
let params = { hostname: hostname, port: port }; let params = { hostname: hostname, port: port };
const res = await requestLedDeviceIdentification("yeelight", params); await requestLedDeviceIdentification("yeelight", params);
if (!window.readOnlyMode) { if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false); $('#btn_wiz_save').attr('disabled', false);
@ -1675,13 +1578,11 @@ async function discover_atmoorb_lights(multiCastGroup, multiCastPort) {
var light = {}; var light = {};
var params = {}; var params = {};
if (multiCastGroup !== "") if (multiCastGroup !== "") {
{
params.multiCastGroup = multiCastGroup; params.multiCastGroup = multiCastGroup;
} }
if (multiCastPort !== 0) if (multiCastPort !== 0) {
{
params.multiCastPort = multiCastPort; params.multiCastPort = multiCastPort;
} }
@ -1774,7 +1675,7 @@ function assign_atmoorb_lights() {
$('.lidsb').append(createTableRow([orbId + lightAnnotation, '<select id="orb_' + lightid + '" ' + enabled + ' class="orb_sel_watch form-control">' $('.lidsb').append(createTableRow([orbId + lightAnnotation, '<select id="orb_' + lightid + '" ' + enabled + ' class="orb_sel_watch form-control">'
+ options + 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>'])); + $.i18n('wiz_identify_light', orbId) + '</button>']));
} }
@ -1799,297 +1700,13 @@ function assign_atmoorb_lights() {
} }
async function identify_atmoorb_device(orbId) { async function identify_atmoorb_device(orbId) {
// Take care that new record cannot be save during background process // Take care that new record cannot be save during background process
$('#btn_wiz_save').attr('disabled', true); $('#btn_wiz_save').attr('disabled', true);
let params = { id: orbId }; let params = { id: orbId };
const res = await requestLedDeviceIdentification("atmoorb", params); await requestLedDeviceIdentification("atmoorb", params);
if (!window.readOnlyMode) { if (!window.readOnlyMode) {
$('#btn_wiz_save').attr('disabled', false); $('#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);
}
}

View File

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

View File

@ -34,7 +34,10 @@ endif()
SET ( CPACK_PACKAGE_NAME "Hyperion" ) SET ( CPACK_PACKAGE_NAME "Hyperion" )
SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hyperion is an open source ambient light implementation" ) 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_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_CONTACT "packages@hyperion-project.org")
SET ( CPACK_PACKAGE_VENDOR "hyperion-project") 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 $REBOOTMESSAGE
echo "-----------------------------------------------------------------------------" echo "-----------------------------------------------------------------------------"
echo "Webpage: www.hyperion-project.org" echo "Webpage: www.hyperion-project.org"
echo "Wiki: wiki.hyperion-project.org" echo "Forum: www.hyperion-project.org"
echo "Forum: forum.hyperion-project.org" echo "Documenation: docs.hyperion-project.org"
echo "-----------------------------------------------------------------------------" echo "-----------------------------------------------------------------------------"

View File

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

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

View File

@ -4,6 +4,7 @@
// util // util
#include <utils/JsonUtils.h> #include <utils/JsonUtils.h>
#include <db/SettingsTable.h> #include <db/SettingsTable.h>
#include "HyperionConfig.h"
// json schema process // json schema process
#include <utils/jsonschema/QJsonFactory.h> #include <utils/jsonschema/QJsonFactory.h>
@ -12,12 +13,23 @@
// write config to filesystem // write config to filesystem
#include <utils/JsonUtils.h> #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; QJsonObject SettingsManager::schemaJson;
SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonlyMode) SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonlyMode)
: QObject(parent) : QObject(parent)
, _log(Logger::getInstance("SETTINGSMGR")) , _log(Logger::getInstance("SETTINGSMGR"))
, _instance(instance)
, _sTable(new SettingsTable(instance, this)) , _sTable(new SettingsTable(instance, this))
, _configVersion(DEFAULT_VERSION)
, _previousVersion(DEFAULT_VERSION)
, _readonlyMode(readonlyMode) , _readonlyMode(readonlyMode)
{ {
_sTable->setReadonlyMode(_readonlyMode); _sTable->setReadonlyMode(_readonlyMode);
@ -38,7 +50,9 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
// get default config // get default config
QJsonObject defaultConfig; QJsonObject defaultConfig;
if(!JsonUtils::readFile(":/hyperion_default.config", defaultConfig, _log)) if(!JsonUtils::readFile(":/hyperion_default.config", defaultConfig, _log))
{
throw std::runtime_error("Failed to read default config"); throw std::runtime_error("Failed to read default config");
}
// transform json to string lists // transform json to string lists
QStringList keyList = defaultConfig.keys(); QStringList keyList = defaultConfig.keys();
@ -64,7 +78,7 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
_sTable->createSettingsRecord(key,val); _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... // TODO refactor schemaChecker to accept QJsonArray in validate(); QJsonDocument container? To validate them per entry...
QJsonObject dbConfig; QJsonObject dbConfig;
for(const auto & key : keyList) for(const auto & key : keyList)
@ -76,8 +90,49 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
dbConfig[key] = doc.object(); 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 // possible data upgrade steps to prevent data loss
if(handleConfigUpgrade(dbConfig)) bool migrated = handleConfigUpgrade(dbConfig);
if ( isNewRelease || migrated )
{ {
saveSettings(dbConfig, true); saveSettings(dbConfig, true);
} }
@ -193,12 +248,55 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
return rc; 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 SettingsManager::handleConfigUpgrade(QJsonObject& config)
{ {
bool migrated = false; bool migrated = false;
resolveConfigVersion(config);
//Do only migrate, if configuration is not up to date
if (_previousVersion < _configVersion)
{
//Migration steps for versions <= alpha 9
semver::version targetVersion {"2.0.0-alpha.9"};
if (_previousVersion <= targetVersion )
{
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());
// LED LAYOUT UPGRADE // LED LAYOUT UPGRADE
// from { hscan: { minimum: 0.2, maximum: 0.3 }, vscan: { minimum: 0.2, maximumn: 0.3 } } // 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 } } // 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} // to { hmin: 0.2, hmax: 0.3, vmin: 0.2, vmax: 0.3}
if(config.contains("leds")) if(config.contains("leds"))
@ -250,20 +348,56 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
// replace // replace
config["leds"] = newLedarr; config["leds"] = newLedarr;
migrated = true; migrated = true;
Debug(_log,"LED Layout migrated"); Info(_log,"Instance [%u]: LED Layout migrated", _instance);
} }
} }
if (config.contains("grabberV4L2")) if(config.contains("ledConfig"))
{ {
QJsonObject newGrabberV4L2Config = config["grabberV4L2"].toObject(); 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")) config["ledConfig"] = newLedConfig;
{
newGrabberV4L2Config.remove("encoding_format");
config["grabberV4L2"] = newGrabberV4L2Config;
migrated = true; migrated = true;
Debug(_log, "GrabberV4L2 Layout migrated"); 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; return migrated;

View File

@ -1,45 +1,40 @@
{ {
"type": "object", "type": "object",
"title" : "edt_dev_general_heading_title", "title": " ",
"required" : true,
"defaultProperties": [ "hardwareLedCount", "colorOrder" ], "defaultProperties": [ "hardwareLedCount", "colorOrder" ],
"properties" : "properties": {
{ "type": {
"type" :
{
"type": "string", "type": "string",
"propertyOrder": 1 "propertyOrder": 1
}, },
"hardwareLedCount" : "hardwareLedCount": {
{
"type": "integer", "type": "integer",
"title": "edt_dev_general_hardwareLedCount_title", "title": "edt_dev_general_hardwareLedCount_title",
"minimum": 1, "minimum": 1,
"default": 1, "default": 1,
"options": {
"infoText": "edt_dev_general_hardwareLedCount_title_info"
},
"propertyOrder": 2 "propertyOrder": 2
}, },
"colorOrder" : "colorOrder": {
{
"type": "string", "type": "string",
"title": "edt_dev_general_colorOrder_title", "title": "edt_dev_general_colorOrder_title",
"enum": [ "rgb", "bgr", "rbg", "brg", "gbr", "grb" ], "enum": [ "rgb", "bgr", "rbg", "brg", "gbr", "grb" ],
"default": "rgb", "default": "rgb",
"required": true, "required": true,
"options": { "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" ] "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", "access": "expert",
"propertyOrder": 3 "propertyOrder": 3
} }
}, },
"dependencies" : "dependencies": {
{ "rewriteTime": {
"rewriteTime" : "properties": {
{ "type": {
"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" ] "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" ]
} }
}, },

View File

@ -34,6 +34,25 @@
"default" : true, "default" : true,
"required" : true, "required" : true,
"propertyOrder" : 3 "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 "additionalProperties" : false

View File

@ -143,6 +143,36 @@
} }
}, },
"additionalProperties": false "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,11 +234,16 @@ int LedDevice::rewriteLEDs()
return retval; 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; 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)
{ {
@ -247,7 +252,7 @@ int LedDevice::writeBlack(int numberOfBlack)
QTimer::singleShot(_latchTime_ms, &loop, &QEventLoop::quit); QTimer::singleShot(_latchTime_ms, &loop, &QEventLoop::quit);
loop.exec(); 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); rc = write(_lastLedValues);
} }
return rc; return rc;
@ -411,6 +416,10 @@ void LedDevice::setLatchTime( int latchTime_ms )
void LedDevice::setRewriteTime( int rewriteTime_ms ) void LedDevice::setRewriteTime( int rewriteTime_ms )
{ {
assert(rewriteTime_ms >= 0); assert(rewriteTime_ms >= 0);
//Check, if refresh timer was not initialised due to getProperties/identify sceanrios
if (_refreshTimer != nullptr)
{
_refreshTimerInterval_ms = rewriteTime_ms; _refreshTimerInterval_ms = rewriteTime_ms;
if (_refreshTimerInterval_ms > 0) if (_refreshTimerInterval_ms > 0)
@ -434,6 +443,7 @@ void LedDevice::setRewriteTime( int rewriteTime_ms )
Debug(_log, "RewriteTime updated to %dms", _refreshTimerInterval_ms); Debug(_log, "RewriteTime updated to %dms", _refreshTimerInterval_ms);
} }
}
void LedDevice::printLedValues(const std::vector<ColorRgb>& ledValues) void LedDevice::printLedValues(const std::vector<ColorRgb>& ledValues)
{ {

View File

@ -15,6 +15,9 @@ const bool verbose = false;
// Configuration settings // Configuration settings
const char CONFIG_ADDRESS[] = "host"; const char CONFIG_ADDRESS[] = "host";
const char CONFIG_RESTORE_STATE[] = "restoreOriginalState"; 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 // UDP elements
const quint16 STREAM_DEFAULT_PORT = 19446; 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_VALUE_FALSE[] = "false";
const char STATE_LIVE[] = "live"; 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 int BRI_MAX = 255;
const bool DEFAULT_IS_SYNC_OVERWRITE = true;
constexpr std::chrono::milliseconds DEFAULT_IDENTIFY_TIME{ 2000 }; constexpr std::chrono::milliseconds DEFAULT_IDENTIFY_TIME{ 2000 };
@ -42,6 +48,11 @@ LedDeviceWled::LedDeviceWled(const QJsonObject &deviceConfig)
: ProviderUdp(deviceConfig) : ProviderUdp(deviceConfig)
,_restApi(nullptr) ,_restApi(nullptr)
,_apiPort(API_DEFAULT_PORT) ,_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, "ColorOrder : %s", QSTRING_CSTR( this->getColorOrder() ));
Debug(_log, "LatchTime : %d", this->getLatchTime()); 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, "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 //Set hostname as per configuration
QString hostName = deviceConfig[ CONFIG_ADDRESS ].toString(); QString hostName = deviceConfig[ CONFIG_ADDRESS ].toString();
@ -145,6 +163,13 @@ QString LedDeviceWled::getLorRequest(int lor) const
return QString( "\"lor\":%1" ).arg(lor); 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 LedDeviceWled::sendStateUpdateRequest(const QString &request)
{ {
bool rc = true; bool rc = true;
@ -166,7 +191,20 @@ bool LedDeviceWled::powerOn()
//Power-on WLED device //Power-on WLED device
_restApi->setPath(API_PATH_STATE); _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() ) if ( response.error() )
{ {
QString errorReason = QString("Power-on request failed with error: '%1'").arg(response.getErrorReason()); 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 //Power-off the WLED device physically
_restApi->setPath(API_PATH_STATE); _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() ) if ( response.error() )
{ {
QString errorReason = QString("Power-off request failed with error: '%1'").arg(response.getErrorReason()); QString errorReason = QString("Power-off request failed with error: '%1'").arg(response.getErrorReason());
@ -206,7 +253,7 @@ bool LedDeviceWled::storeState()
{ {
bool rc = true; bool rc = true;
if ( _isRestoreOrigState ) if ( _isRestoreOrigState || _isSyncOverwrite )
{ {
_restApi->setPath(API_PATH_STATE); _restApi->setPath(API_PATH_STATE);
@ -221,6 +268,13 @@ bool LedDeviceWled::storeState()
{ {
_originalStateProperties = response.getBody().object(); _originalStateProperties = response.getBody().object();
DebugIf(verbose, _log, "state: [%s]", QString(QJsonDocument(_originalStateProperties).toJson(QJsonDocument::Compact)).toUtf8().constData() ); 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 ) if ( _isRestoreOrigState )
{ {
//powerOff();
_restApi->setPath(API_PATH_STATE); _restApi->setPath(API_PATH_STATE);
_originalStateProperties[STATE_LIVE] = false; _originalStateProperties[STATE_LIVE] = false;

View File

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

View File

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

View File

@ -4,11 +4,22 @@
#include <csignal> #include <csignal>
// QT includes // QT includes
#include <QDir>
#include <QFile> #include <QFile>
// Local LedDevice includes // Local LedDevice includes
#include "LedDevicePiBlaster.h" #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) LedDevicePiBlaster::LedDevicePiBlaster(const QJsonObject &deviceConfig)
: LedDevice(deviceConfig) : LedDevice(deviceConfig)
, _fid(nullptr) , _fid(nullptr)
@ -184,3 +195,31 @@ int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
return 0; 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 /// @return LedDevice constructed
static LedDevice* construct(const QJsonObject &deviceConfig); 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: protected:
/// ///

View File

@ -2,6 +2,7 @@
// LedDevice includes // LedDevice includes
#include <leddevice/LedDevice.h> #include <leddevice/LedDevice.h>
#include "ProviderRs232.h" #include "ProviderRs232.h"
#include <utils/WaitTime.h>
// qt includes // qt includes
#include <QSerialPortInfo> #include <QSerialPortInfo>
@ -10,11 +11,17 @@
#include <chrono> #include <chrono>
// Constants // Constants
namespace {
const bool verbose = false;
constexpr std::chrono::milliseconds WRITE_TIMEOUT{ 1000 }; // device write timeout in ms constexpr std::chrono::milliseconds WRITE_TIMEOUT{ 1000 }; // device write timeout in ms
constexpr std::chrono::milliseconds OPEN_TIMEOUT{ 5000 }; // device open 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 MAX_WRITE_TIMEOUTS = 5; // Maximum number of allowed timeouts
const int NUM_POWEROFF_WRITE_BLACK = 2; // Number of write "BLACK" during powering off 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) ProviderRs232::ProviderRs232(const QJsonObject &deviceConfig)
: LedDevice(deviceConfig) : LedDevice(deviceConfig)
, _rs232Port(this) , _rs232Port(this)
@ -278,7 +285,7 @@ QJsonObject ProviderRs232::discover(const QJsonObject& /*params*/)
// Discover serial Devices // Discover serial Devices
for (auto &port : QSerialPortInfo::availablePorts() ) for (auto &port : QSerialPortInfo::availablePorts() )
{ {
if ( !port.isNull() && !port.portName().startsWith("ttyS")) if ( !port.isNull() && port.vendorIdentifier() != 0)
{ {
QJsonObject portInfo; QJsonObject portInfo;
portInfo.insert("description", port.description()); portInfo.insert("description", port.description());
@ -294,5 +301,39 @@ QJsonObject ProviderRs232::discover(const QJsonObject& /*params*/)
} }
devicesDiscovered.insert("devices", deviceList); devicesDiscovered.insert("devices", deviceList);
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
return devicesDiscovered; 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; ~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: protected:
/// ///

View File

@ -14,6 +14,19 @@
#include "ProviderSpi.h" #include "ProviderSpi.h"
#include <utils/Logger.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) ProviderSpi::ProviderSpi(const QJsonObject &deviceConfig)
: LedDevice(deviceConfig) : LedDevice(deviceConfig)
, _deviceName("/dev/spidev0.0") , _deviceName("/dev/spidev0.0")
@ -148,3 +161,31 @@ int ProviderSpi::writeBytes(unsigned size, const uint8_t * data)
return retVal; 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; 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: public slots:
/// ///
/// Closes the output device. /// Closes the output device.

View File

@ -27,6 +27,7 @@
"type": "boolean", "type": "boolean",
"title": "edt_dev_spec_LBap102Mode_title", "title": "edt_dev_spec_LBap102Mode_title",
"default": false, "default": false,
"required": true,
"access": "advanced", "access": "advanced",
"propertyOrder": 4 "propertyOrder": 4
}, },
@ -38,6 +39,9 @@
"minimum": 0, "minimum": 0,
"maximum": 1000, "maximum": 1000,
"access": "expert", "access": "expert",
"options": {
"infoText": "edt_dev_spec_latchtime_title_info"
},
"propertyOrder": 5 "propertyOrder": 5
}, },
"rewriteTime": { "rewriteTime": {

View File

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

View File

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

View File

@ -5,6 +5,7 @@
"orbIds": { "orbIds": {
"type": "string", "type": "string",
"title": "edt_dev_spec_orbIds_title", "title": "edt_dev_spec_orbIds_title",
"minLength": 1,
"default": "", "default": "",
"propertyOrder": 1 "propertyOrder": 1
}, },

View File

@ -2,10 +2,25 @@
"type": "object", "type": "object",
"required": true, "required": true,
"properties": { "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": { "host": {
"type": "string", "type": "string",
"title": "edt_dev_spec_targetIpHost_title", "title": "edt_dev_spec_targetIpHost_title",
"propertyOrder" : 1 "options": {
"infoText": "edt_dev_spec_targetIpHost_title_info"
},
"required": true,
"propertyOrder": 2
}, },
"latchTime": { "latchTime": {
"type": "integer", "type": "integer",
@ -15,7 +30,10 @@
"minimum": 0, "minimum": 0,
"maximum": 1000, "maximum": 1000,
"access": "expert", "access": "expert",
"propertyOrder" : 2 "options": {
"infoText": "edt_dev_spec_latchtime_title_info"
},
"propertyOrder": 3
} }
}, },
"additionalProperties": true "additionalProperties": true

View File

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

View File

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

View File

@ -2,47 +2,67 @@
"type": "object", "type": "object",
"required": true, "required": true,
"properties": { "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": { "host": {
"type": "string", "type": "string",
"title": "edt_dev_spec_targetIpHost_title", "title": "edt_dev_spec_targetIpHost_title",
"propertyOrder" : 1 "options": {
"infoText": "edt_dev_spec_targetIpHost_title_info"
},
"required": true,
"propertyOrder": 2
}, },
"token": { "token": {
"type": "string", "type": "string",
"title": "edt_dev_auth_key_title", "title": "edt_dev_auth_key_title",
"propertyOrder" : 2 "options": {
"infoText": "edt_dev_auth_key_title_info"
},
"propertyOrder": 4
}, },
"title": { "title": {
"type": "object", "type": "object",
"title": "edt_dev_spec_panelorganisation_title", "title": "edt_dev_spec_panelorganisation_title",
"access": "advanced", "access": "advanced",
"propertyOrder" : 3 "propertyOrder": 5
}, },
"panelOrderTopDown": { "panelOrderTopDown": {
"type": "integer", "type": "integer",
"title": "edt_dev_spec_order_top_down_title", "title": "edt_dev_spec_order_top_down_title",
"enum": [ 0, 1 ], "enum": [ 0, 1 ],
"default": 0, "default": 0,
"required": true,
"options": { "options": {
"enum_titles": [ "edt_conf_enum_top_down", "edt_conf_enum_bottom_up" ] "enum_titles": [ "edt_conf_enum_top_down", "edt_conf_enum_bottom_up" ]
}, },
"minimum": 0, "minimum": 0,
"maximum": 1, "maximum": 1,
"access": "advanced", "access": "advanced",
"propertyOrder" : 4 "propertyOrder": 6
}, },
"panelOrderLeftRight": { "panelOrderLeftRight": {
"type": "integer", "type": "integer",
"title": "edt_dev_spec_order_left_right_title", "title": "edt_dev_spec_order_left_right_title",
"enum": [ 0, 1 ], "enum": [ 0, 1 ],
"default": 0, "default": 0,
"required": true,
"options": { "options": {
"enum_titles": [ "edt_conf_enum_left_right", "edt_conf_enum_right_left" ] "enum_titles": [ "edt_conf_enum_left_right", "edt_conf_enum_right_left" ]
}, },
"minimum": 0, "minimum": 0,
"maximum": 1, "maximum": 1,
"access": "advanced", "access": "advanced",
"propertyOrder" : 5 "propertyOrder": 7
}, },
"panelStartPos": { "panelStartPos": {
"type": "integer", "type": "integer",
@ -51,7 +71,7 @@
"minimum": 0, "minimum": 0,
"default": 0, "default": 0,
"access": "advanced", "access": "advanced",
"propertyOrder" : 6 "propertyOrder": 8
} }
}, },
"additionalProperties": true "additionalProperties": true

View File

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

View File

@ -58,11 +58,12 @@
"lightIds": { "lightIds": {
"type": "array", "type": "array",
"title": "edt_dev_spec_lightid_title", "title": "edt_dev_spec_lightid_title",
"minItems": 1, "minimum": 1,
"uniqueItems": true, "uniqueItems": true,
"items": { "items": {
"type": "string", "type": "string",
"minimum" : 0, "minLength": 1,
"required": true,
"title": "edt_dev_spec_lightid_itemtitle" "title": "edt_dev_spec_lightid_itemtitle"
}, },
"options": { "options": {

View File

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

View File

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

View File

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

View File

@ -1,19 +1,70 @@
{ {
"type": "object", "type": "object",
"title": "",
"required": true, "required": true,
"properties": { "properties": {
"host" : { "hostList": {
"type": "string", "type": "string",
"title": "edt_dev_spec_targetIpHost_title", "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, "required": true,
"propertyOrder": 1 "propertyOrder": 1
}, },
"host": {
"type": "string",
"title": "edt_dev_spec_targetIpHost_title",
"options": {
"infoText": "edt_dev_spec_targetIpHost_title_info"
},
"required": true,
"propertyOrder": 2
},
"restoreOriginalState": { "restoreOriginalState": {
"type": "boolean", "type": "boolean",
"format": "checkbox",
"title": "edt_dev_spec_restoreOriginalState_title", "title": "edt_dev_spec_restoreOriginalState_title",
"default": false, "default": false,
"required": true, "required": true,
"propertyOrder": 2 "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": { "latchTime": {
"type": "integer", "type": "integer",
@ -23,7 +74,10 @@
"minimum": 0, "minimum": 0,
"maximum": 1000, "maximum": 1000,
"access": "expert", "access": "expert",
"propertyOrder" : 3 "options": {
"infoText": "edt_dev_spec_latchtime_title_info"
},
"propertyOrder": 7
} }
}, },
"additionalProperties": true "additionalProperties": true

View File

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

View File

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

View File

@ -3,10 +3,10 @@
"required": true, "required": true,
"properties": { "properties": {
"colorModel": { "colorModel": {
"type": "integer", "type": "string",
"title": "Output Type", "title": "Output Type",
"enum" : [0, 1], "enum": [ "0", "1" ],
"default" : 1, "default": "1",
"options": { "options": {
"enum_titles": [ "edt_conf_enum_hsv", "edt_conf_enum_rgb" ] "enum_titles": [ "edt_conf_enum_hsv", "edt_conf_enum_rgb" ]
}, },
@ -16,10 +16,10 @@
"propertyOrder": 1 "propertyOrder": 1
}, },
"transEffect": { "transEffect": {
"type": "integer", "type": "string",
"title": "edt_dev_spec_transeffect_title", "title": "edt_dev_spec_transeffect_title",
"enum" : [0, 1], "enum": [ "0", "1" ],
"default" : 0, "default": "0",
"options": { "options": {
"enum_titles": [ "edt_conf_enum_transeffect_smooth", "edt_conf_enum_transeffect_sudden" ] "enum_titles": [ "edt_conf_enum_transeffect_smooth", "edt_conf_enum_transeffect_sudden" ]
}, },
@ -109,18 +109,15 @@
"type": "object", "type": "object",
"title": "edt_dev_spec_lights_itemtitle", "title": "edt_dev_spec_lights_itemtitle",
"required": true, "required": true,
"properties" : "properties": {
{ "host": {
"host" :
{
"type": "string", "type": "string",
"minimum" : 7, "minLength": 7,
"title": "edt_dev_spec_networkDeviceName_title", "title": "edt_dev_spec_networkDeviceName_title",
"required": true, "required": true,
"propertyOrder": 1 "propertyOrder": 1
}, },
"port" : "port": {
{
"type": "integer", "type": "integer",
"minimum": 0, "minimum": 0,
"maximum": 65535, "maximum": 65535,
@ -130,8 +127,7 @@
"access": "expert", "access": "expert",
"propertyOrder": 2 "propertyOrder": 2
}, },
"name" : "name": {
{
"type": "string", "type": "string",
"title": "edt_dev_spec_lights_name", "title": "edt_dev_spec_lights_name",
"minimum": 0, "minimum": 0,
@ -163,10 +159,10 @@
"propertyOrder": 12 "propertyOrder": 12
}, },
"debugLevel": { "debugLevel": {
"type": "integer", "type": "string",
"title": "edt_dev_spec_debugLevel_title", "title": "edt_dev_spec_debugLevel_title",
"enum" : [0, 1, 2, 3], "enum": [ "0", "1", "2", "3" ],
"default" : 0, "default": "0",
"options": { "options": {
"enum_titles": [ "edt_conf_enum_dl_nodebug", "edt_conf_enum_dl_verbose1", "edt_conf_enum_dl_verbose2", "edt_conf_enum_dl_verbose3" ] "enum_titles": [ "edt_conf_enum_dl_nodebug", "edt_conf_enum_dl_verbose1", "edt_conf_enum_dl_verbose2", "edt_conf_enum_dl_verbose3" ]
}, },

View File

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