mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Dynamic Device Selection/Configuration (#1164)
This commit is contained in:
parent
a4d98fd916
commit
7eeb740177
6
.github/workflows/pull-request.yml
vendored
6
.github/workflows/pull-request.yml
vendored
@ -41,7 +41,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
echo -n -PR#${{ github.event.pull_request.number }} >> version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> version
|
||||
|
||||
# Build packages
|
||||
- name: Build packages
|
||||
@ -87,7 +87,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
echo -n "-PR#${{ github.event.pull_request.number }}" >> version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> version
|
||||
|
||||
# Install dependencies
|
||||
- name: Install dependencies
|
||||
@ -136,7 +136,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
echo -n "-PR#${{ github.event.pull_request.number }}" >> version
|
||||
echo -n "+PR${{ github.event.pull_request.number }}" >> version
|
||||
|
||||
- name: Cache Qt
|
||||
uses: actions/cache@v2
|
||||
|
@ -1,3 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hyperion - LED Device Configuration</title>
|
||||
</head>
|
||||
<div class="container-fluid">
|
||||
<h3 class="page-header"><i class="fa fa-lightbulb-o fa-fw"></i><span data-i18n="main_menu_leds_conf_token">LED Hardware</span></h3>
|
||||
<ul id="leds_cfg_nav" class="nav nav-tabs">
|
||||
@ -6,7 +11,6 @@
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div id="menu_controller" class="tab-pane fade in active" style="padding-top:10px">
|
||||
<div class="row">
|
||||
<div class="col-lg-12" id="leddevice_intro"></div>
|
||||
@ -14,15 +18,21 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading form-group">
|
||||
<label for="leddevices" class="panel-title" data-i18n="conf_leds_contr_label_contrtype">Controller type:</label>
|
||||
<select id="leddevices" class="form-control" style="color:black;width:auto;margin-left:10px;display:inline-block" />
|
||||
<select id="leddevices" class="form-control" style="color:black;width:auto;margin-left:10px;display:inline-block"></select>
|
||||
</div>
|
||||
|
||||
<div class="panel-body">
|
||||
<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 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>
|
||||
@ -36,12 +46,12 @@
|
||||
<div class="col-lg-6 col-md-12">
|
||||
<div class="panel-group" id="accordion">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading headcollapse" data-toggle="collapse" data-parent="#accordion" data-target="#collapse1">
|
||||
<div class="panel-heading headcollapse" id="classic_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse1">
|
||||
<h4 class="panel-title">
|
||||
<a><i class="fa fa-television fa-fw"></i><span data-i18n="conf_leds_layout_frame">Classic Layout (LED Frame)</span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse1" class="panel-collapse collapse in">
|
||||
<div id="collapse1" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<table class="table borderless">
|
||||
<tbody>
|
||||
@ -244,7 +254,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="panel-footer" style="text-align:right;">
|
||||
<button id="btn_cl_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
|
||||
@ -252,7 +261,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<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">
|
||||
<a><i class="fa fa-th fa-fw"></i><span data-i18n="conf_leds_layout_matrix">Matrix Configuration (LED wall)</span></a>
|
||||
</h4>
|
||||
@ -290,18 +299,6 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<!--- <tr>
|
||||
<td class="ltd">
|
||||
<label class="ltdlabel" for="ip_ma_order" data-i18n="conf_leds_layout_ma_order">Order</label>
|
||||
</td>
|
||||
<td class="itd">
|
||||
<select class="form-control ledMAconstr" id="ip_ma_order">
|
||||
<option value="horizontal" data-i18n="conf_leds_layout_ma_opthoriz">Horizontal</option>
|
||||
<option value="vertical" data-i18n="conf_leds_layout_ma_optvert">Vertical</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
--->
|
||||
<tr>
|
||||
<td class="ltd">
|
||||
<label class="ltdlabel" for="ip_ma_start" data-i18n="conf_leds_layout_ma_position">Input</label>
|
||||
@ -323,13 +320,28 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="blacklist_panel" class="panel panel-primary">
|
||||
<div class="panel-heading headcollapse" id="blacklist_config_panel" data-toggle="collapse" data-parent="#accordion" data-target="#collapse4">
|
||||
<h4 class="panel-title">
|
||||
<a><i class="fa fa-ban fa-fw"></i><span data-i18n="conf_leds_layout_blacklistleds_title">Blacklist LEDs</span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse4" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div id="editor_container_blacklist_conf"></div>
|
||||
</div>
|
||||
<div class="panel-footer" style="text-align:right;">
|
||||
<button id="btn_bl_save" class="btn btn-primary"><i class="fa fa-fw fa-save"></i><span data-i18n="conf_leds_layout_button_savelay">Save layout</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="texfield_panel" class="panel panel-primary">
|
||||
<div class="panel-heading headcollapse" 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">
|
||||
<a><i class="fa fa-wrench fa-fw"></i><span data-i18n="conf_leds_layout_generatedconf">Generated/Actual LED Configuration</span></a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapse4" class="panel-collapse collapse">
|
||||
<div id="collapse5" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<p id="leds_wl" data-i18n="conf_leds_layout_textf1">This textfield shows by default your current loaded layout and will be overwritten if you generate a new one above. Optional you could perform further edits.</p>
|
||||
<div id="aceedit" style="width:100%;height:500px"></div>
|
||||
@ -363,12 +375,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- row layout -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div> <!-- tab content -->
|
||||
</div>
|
||||
|
||||
<script src="/js/content_leds.js"></script>
|
||||
|
@ -1,15 +1,4 @@
|
||||
{
|
||||
"InfoDialog_access_text": "Depending on settings level you could adjust more options or get access to more features. Recommended is the \"Default\" level.",
|
||||
"InfoDialog_access_title": "Settings level",
|
||||
"InfoDialog_changePassword_success": "Password successfully saved!",
|
||||
"InfoDialog_changePassword_title": "Change Password",
|
||||
"InfoDialog_iswitch_text": "If you run Hyperion more than once in your local network, you could switch between the web configurations. Select the Hyperion instance below and switch!",
|
||||
"InfoDialog_iswitch_title": "Hyperion switcher",
|
||||
"InfoDialog_lang_text": "If you don't like the result of the automatic language detection you could overwrite it here.",
|
||||
"InfoDialog_lang_title": "Language setting",
|
||||
"InfoDialog_nowrite_foottext": "The WebUI will be unlocked automatically after you solved the problem!",
|
||||
"InfoDialog_nowrite_text": "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.",
|
||||
"InfoDialog_nowrite_title": "write permission error!",
|
||||
"about_3rd_party_licenses": "3rd party licenses",
|
||||
"about_3rd_party_licenses_error": "We had trouble collecting 3rd party licenses information from web. <br />Please follow this link to the GitHub Resource.",
|
||||
"about_build": "Build",
|
||||
@ -45,9 +34,19 @@
|
||||
"conf_grabber_v4l_intro": "USB capture is a (capture)device connected via USB which is used to input source pictures for processing.",
|
||||
"conf_helptable_expl": "Explanation",
|
||||
"conf_helptable_option": "Option",
|
||||
"conf_leds_config_error": "Error in LED/LED layout configuration",
|
||||
"conf_leds_config_warning": "Check your LED/LED layout configuration",
|
||||
"conf_leds_contr_label_contrtype": "Controller type:",
|
||||
"conf_leds_device_info_log": "In case your LEDs do not work, check here for errors:",
|
||||
"conf_leds_device_intro": "Hyperion supports a lot of controllers to transmit data to your target device. Select a LED controller out of the sorted list and configure it. We have chosen the best default settings for each device.",
|
||||
"conf_leds_error_hwled_gt_layout": "The hardware LED count ($1) is greater than LEDs configured via layout ($2),<br>$3 {{plural:$1|LED|LEDs}} will stay black if you continue.",
|
||||
"conf_leds_error_hwled_lt_layout": "The hardware LED count ($1) is less than LEDs configured via layout ($2). <br> The number of LEDs configured in the layout must not exceed the available LEDs",
|
||||
"conf_leds_layout_advanced": "Advanced Settings",
|
||||
"conf_leds_layout_blacklist_num_title": "Number of LEDs",
|
||||
"conf_leds_layout_blacklist_rule_title": "Blacklist rule",
|
||||
"conf_leds_layout_blacklist_rules_title": "Blacklist rules",
|
||||
"conf_leds_layout_blacklist_start_title": "Start LED",
|
||||
"conf_leds_layout_blacklistleds_title": "Blacklist LEDs",
|
||||
"conf_leds_layout_btn_checklist": "Show checklist",
|
||||
"conf_leds_layout_button_savelay": "Save Layout",
|
||||
"conf_leds_layout_button_updsim": "Update Preview",
|
||||
@ -113,11 +112,12 @@
|
||||
"conf_leds_layout_textf1": "This text field shows by default your current loaded layout and will be overwritten if you generate a new one with the options above. Optional you could perform further edits.",
|
||||
"conf_leds_nav_label_ledcontroller": "LED Controller",
|
||||
"conf_leds_nav_label_ledlayout": "LED Layout",
|
||||
"conf_leds_note_layout_overwrite": "Note: Overwrite creates a default layout for {{plural:$1| $1 LED| all $1 LEDs}} given by the hardware LED count",
|
||||
"conf_leds_optgroup_network": "Network",
|
||||
"conf_leds_optgroup_other": "Other",
|
||||
"conf_leds_optgroup_RPiGPIO": "RPi GPIO",
|
||||
"conf_leds_optgroup_RPiPWM": "RPi PWM",
|
||||
"conf_leds_optgroup_RPiSPI": "RPi SPI",
|
||||
"conf_leds_optgroup_debug": "Debug",
|
||||
"conf_leds_optgroup_network": "Network",
|
||||
"conf_leds_optgroup_usb": "USB/Serial",
|
||||
"conf_logging_btn_autoscroll": "Auto scrolling",
|
||||
"conf_logging_btn_pbupload": "Upload a report for support requests",
|
||||
@ -215,10 +215,10 @@
|
||||
"edt_conf_color_black_title": "Black",
|
||||
"edt_conf_color_blue_expl": "The calibrated blue value.",
|
||||
"edt_conf_color_blue_title": "Blue",
|
||||
"edt_conf_color_brightnessComp_expl": "Compensates brightness differences between red green blue, cyan magenta yellow and white. 100 means full compensation, 0 no compensation",
|
||||
"edt_conf_color_brightnessComp_title": "Brightness compensation",
|
||||
"edt_conf_color_brightness_expl": "set overall brightness of LEDs",
|
||||
"edt_conf_color_brightness_title": "Brightness",
|
||||
"edt_conf_color_brightnessComp_expl": "Compensates brightness differences between red green blue, cyan magenta yellow and white. 100 means full compensation, 0 no compensation",
|
||||
"edt_conf_color_brightnessComp_title": "Brightness compensation",
|
||||
"edt_conf_color_channelAdjustment_header_expl": "Create color profiles that could be assigned to a specific component. Adjust color, gamma, brightness, compensation and more.",
|
||||
"edt_conf_color_channelAdjustment_header_itemtitle": "Profile",
|
||||
"edt_conf_color_channelAdjustment_header_title": "Color channel adjustments",
|
||||
@ -254,10 +254,6 @@
|
||||
"edt_conf_effp_paths_expl": "You could define more folders that contain effects. The effect configurator will always save inside the first folder.",
|
||||
"edt_conf_effp_paths_itemtitle": "Path",
|
||||
"edt_conf_effp_paths_title": "Effect Path(s)",
|
||||
"edt_conf_enum_NO_CHANGE": "Automatic",
|
||||
"edt_conf_enum_NTSC": "NTSC",
|
||||
"edt_conf_enum_PAL": "PAL",
|
||||
"edt_conf_enum_SECAM": "SECAM",
|
||||
"edt_conf_enum_automatic": "Automatic",
|
||||
"edt_conf_enum_bbclassic": "Classic",
|
||||
"edt_conf_enum_bbdefault": "Default",
|
||||
@ -288,9 +284,14 @@
|
||||
"edt_conf_enum_logverbose": "Verbose",
|
||||
"edt_conf_enum_logwarn": "Warning",
|
||||
"edt_conf_enum_multicolor_mean": "Multicolor",
|
||||
"edt_conf_enum_NO_CHANGE": "Automatic",
|
||||
"edt_conf_enum_NTSC": "NTSC",
|
||||
"edt_conf_enum_PAL": "PAL",
|
||||
"edt_conf_enum_please_select": "Please Select",
|
||||
"edt_conf_enum_rbg": "RBG",
|
||||
"edt_conf_enum_rgb": "RGB",
|
||||
"edt_conf_enum_right_left": "Right to left",
|
||||
"edt_conf_enum_SECAM": "SECAM",
|
||||
"edt_conf_enum_top_down": "Top down",
|
||||
"edt_conf_enum_transeffect_smooth": "Smooth",
|
||||
"edt_conf_enum_transeffect_sudden": "Sudden",
|
||||
@ -322,11 +323,12 @@
|
||||
"edt_conf_fge_type_title": "Type",
|
||||
"edt_conf_fw_flat_expl": "One flatbuffer target per line. Contains IP:PORT (Example: 127.0.0.1:19401)",
|
||||
"edt_conf_fw_flat_itemtitle": "flatbuffer target",
|
||||
"edt_conf_fw_flat_title": "List of flatbuffer clients",
|
||||
"edt_conf_fw_flat_title": "List of flatbuffer targets",
|
||||
"edt_conf_fw_heading_title": "Forwarder",
|
||||
"edt_conf_fw_json_expl": "One json target per line. Contains IP:PORT (Example: 127.0.0.1:19446)",
|
||||
"edt_conf_fw_json_itemtitle": "Json target",
|
||||
"edt_conf_fw_json_title": "List of json clients",
|
||||
"edt_conf_fw_json_title": "List of json targets",
|
||||
"edt_conf_gen_configVersion_title": "Configuration version",
|
||||
"edt_conf_gen_heading_title": "General Settings",
|
||||
"edt_conf_gen_name_expl": "A user defined name which is used to detect Hyperion. (Helpful with more than one Hyperion instance)",
|
||||
"edt_conf_gen_name_title": "Configuration name",
|
||||
@ -354,9 +356,9 @@
|
||||
"edt_conf_net_heading_title": "Network",
|
||||
"edt_conf_net_internetAccessAPI_expl": "Allow access to the Hyperion API/Webinterface from the internet, disable for higher security.",
|
||||
"edt_conf_net_internetAccessAPI_title": "Internet API Access",
|
||||
"edt_conf_net_ip_itemtitle": "IP",
|
||||
"edt_conf_net_ipWhitelist_expl": "You can whitelist IP addresses instead allowing all connections from internet to connect to the Hyperion API/Webinterface.",
|
||||
"edt_conf_net_ipWhitelist_title": "Whitelisted IP's",
|
||||
"edt_conf_net_ip_itemtitle": "IP",
|
||||
"edt_conf_net_localAdminAuth_expl": "When enabled, administration access from your local network needs a password.",
|
||||
"edt_conf_net_localAdminAuth_title": "Local Admin API Authentication",
|
||||
"edt_conf_net_localApiAuth_expl": "When enabled, connections from your home network needs to authenticate themself against Hyperion with a token.",
|
||||
@ -436,25 +438,25 @@
|
||||
"edt_conf_webc_sslport_expl": "Port oft the HTTPS-Webserver",
|
||||
"edt_conf_webc_sslport_title": "HTTPS Port",
|
||||
"edt_dev_auth_key_title": "Authentication Token",
|
||||
"edt_dev_auth_key_title_info": "Authentication Token required to acccess the device",
|
||||
"edt_dev_enum_sub_min_cool_adjust": "Subtract cool white",
|
||||
"edt_dev_enum_sub_min_warm_adjust": "Subtract warm white",
|
||||
"edt_dev_enum_subtract_minimum": "Subtract minimum",
|
||||
"edt_dev_enum_white_off": "White off",
|
||||
"edt_dev_general_colorOrder_title": "RGB byte order",
|
||||
"edt_dev_general_colorOrder_title_info": "The device's color order",
|
||||
"edt_dev_general_hardwareLedCount_title": "Hardware LED count",
|
||||
"edt_dev_general_hardwareLedCount_title_info": "The number of physical LEDs availabe for the given device",
|
||||
"edt_dev_general_heading_title": "General Settings",
|
||||
"edt_dev_general_name_title": "Configuration name",
|
||||
"edt_dev_general_rewriteTime_title": "Refresh time",
|
||||
"edt_dev_spec_FCledToOn_title": "Fadecandy LED set to on",
|
||||
"edt_dev_spec_FCmanualControl_title": "Manual control of fadecandy LED",
|
||||
"edt_dev_spec_FCsetConfig_title": "Set fadecandy configuration",
|
||||
"edt_dev_spec_LBap102Mode_title": "LightBerry APA102 Mode",
|
||||
"edt_dev_spec_PBFiFo_title": "Pi-Blaster FiFo",
|
||||
"edt_dev_spec_baudrate_title": "Baudrate",
|
||||
"edt_dev_spec_blackLightsTimeout_title": "Signal detection timeout on black",
|
||||
"edt_dev_spec_brightness_title": "Brightness",
|
||||
"edt_dev_spec_brightnessFactor_title": "Brightness factor",
|
||||
"edt_dev_spec_brightnessMax_title": "Brightness maximum",
|
||||
"edt_dev_spec_brightnessMin_title": "Brightness minimum",
|
||||
"edt_dev_spec_brightnessOverwrite_title": "Overwrite brightness",
|
||||
"edt_dev_spec_brightnessThreshold_title": "Signal detection brightness minimum",
|
||||
"edt_dev_spec_chanperfixture_title": "Channels per Fixture",
|
||||
"edt_dev_spec_cid_title": "CID",
|
||||
@ -463,8 +465,16 @@
|
||||
"edt_dev_spec_debugLevel_title": "Debug Level",
|
||||
"edt_dev_spec_debugStreamer_title": "Streamer Debug",
|
||||
"edt_dev_spec_delayAfterConnect_title": "Delay after connect",
|
||||
"edt_dev_spec_devices_discovered_none": "No Devices Discovered",
|
||||
"edt_dev_spec_devices_discovered_title": "Devices Discovered",
|
||||
"edt_dev_spec_devices_discovered_title_info": "Select your LED-Device discovered",
|
||||
"edt_dev_spec_devices_discovered_title_info_custom": "Select your LED-Device discovered or configure a custome one",
|
||||
"edt_dev_spec_devices_discovery_inprogress": "Discovery in progress",
|
||||
"edt_dev_spec_dithering_title": "Dithering",
|
||||
"edt_dev_spec_dmaNumber_title": "DMA channel",
|
||||
"edt_dev_spec_FCledToOn_title": "Fadecandy LED set to on",
|
||||
"edt_dev_spec_FCmanualControl_title": "Manual control of fadecandy LED",
|
||||
"edt_dev_spec_FCsetConfig_title": "Set fadecandy configuration",
|
||||
"edt_dev_spec_gamma_title": "Gamma",
|
||||
"edt_dev_spec_globalBrightnessControlMaxLevel_title": "Max Current Level",
|
||||
"edt_dev_spec_globalBrightnessControlThreshold_title": "Adaptive Current Threshold",
|
||||
@ -477,6 +487,8 @@
|
||||
"edt_dev_spec_intervall_title": "Interval",
|
||||
"edt_dev_spec_invert_title": "Invert signal",
|
||||
"edt_dev_spec_latchtime_title": "Latch time",
|
||||
"edt_dev_spec_latchtime_title_info": "Latch time is the time-frame a device requires until the next update can be processed. During that time-frame any updates done via ignored.",
|
||||
"edt_dev_spec_LBap102Mode_title": "LightBerry APA102 Mode",
|
||||
"edt_dev_spec_ledIndex_title": "LED index",
|
||||
"edt_dev_spec_ledType_title": "LED Type",
|
||||
"edt_dev_spec_lightid_itemtitle": "ID",
|
||||
@ -484,8 +496,8 @@
|
||||
"edt_dev_spec_lights_itemtitle": "Light",
|
||||
"edt_dev_spec_lights_name": "Name",
|
||||
"edt_dev_spec_lights_title": "Light(s)",
|
||||
"edt_dev_spec_maxPacket_title": "Max packet",
|
||||
"edt_dev_spec_maximumLedCount_title": "Maximum LED count",
|
||||
"edt_dev_spec_maxPacket_title": "Max packet",
|
||||
"edt_dev_spec_multicastGroup_title": "Multicast group",
|
||||
"edt_dev_spec_networkDeviceName_title": "Network devicename",
|
||||
"edt_dev_spec_networkDevicePort_title": "Port",
|
||||
@ -496,23 +508,27 @@
|
||||
"edt_dev_spec_outputPath_title": "Output path",
|
||||
"edt_dev_spec_panel_start_position": "Start panel [0-max panels]",
|
||||
"edt_dev_spec_panelorganisation_title": "Panel numbering sequence",
|
||||
"edt_dev_spec_PBFiFo_title": "Pi-Blaster FiFo",
|
||||
"edt_dev_spec_pid_title": "PID",
|
||||
"edt_dev_spec_port_title": "Port",
|
||||
"edt_dev_spec_printTimeStamp_title": "Add timestamp",
|
||||
"edt_dev_spec_pwmChannel_title": "PWM channel",
|
||||
"edt_dev_spec_restoreOriginalState_title": "Restore lights' original state when disabled",
|
||||
"edt_dev_spec_restoreOriginalState_title": "Restore lights' state",
|
||||
"edt_dev_spec_restoreOriginalState_title_info": "Restore the device's original state when device is disabled",
|
||||
"edt_dev_spec_serial_title": "Serial number",
|
||||
"edt_dev_spec_spipath_title": "SPI path",
|
||||
"edt_dev_spec_spipath_title": "SPI Device",
|
||||
"edt_dev_spec_sslHSTimeoutMax_title": "Streamer handshake timeout maximum",
|
||||
"edt_dev_spec_sslHSTimeoutMin_title": "Streamer handshake timeout minimum",
|
||||
"edt_dev_spec_sslReadTimeout_title": "Streamer read timeout",
|
||||
"edt_dev_spec_switchOffOnBlack_title": "Switch off on black",
|
||||
"edt_dev_spec_switchOffOnbelowMinBrightness_title": "Switch-off, below minimum",
|
||||
"edt_dev_spec_targetIpHost_title": "Target IP/Hostname",
|
||||
"edt_dev_spec_targetIp_title": "Target IP",
|
||||
"edt_dev_spec_switchOffOnBlack_title": "Switch off on black",
|
||||
"edt_dev_spec_syncOverwrite_title": "Disable synchronisation",
|
||||
"edt_dev_spec_targetIp_title": "Target IP-address",
|
||||
"edt_dev_spec_targetIpHost_title": "Target Hostname/IP-address",
|
||||
"edt_dev_spec_targetIpHost_title_info": "The device's hostname or IP-address",
|
||||
"edt_dev_spec_transeffect_title": "Transition effect",
|
||||
"edt_dev_spec_transistionTimeExtra_title": "Extra time darkness",
|
||||
"edt_dev_spec_transistionTime_title": "Transition time",
|
||||
"edt_dev_spec_transistionTimeExtra_title": "Extra time darkness",
|
||||
"edt_dev_spec_uid_title": "UID",
|
||||
"edt_dev_spec_universe_title": "Universe",
|
||||
"edt_dev_spec_useEntertainmentAPI_title": "Use Hue Entertainment API",
|
||||
@ -538,16 +554,16 @@
|
||||
"edt_eff_collision_header": "color collision",
|
||||
"edt_eff_collision_header_desc": "Two color projectiles are sent from random positions and collide with each other",
|
||||
"edt_eff_color": "Color",
|
||||
"edt_eff_colorHour": "Color hour",
|
||||
"edt_eff_colorMarker": "Marker color",
|
||||
"edt_eff_colorMinute": "Color minute",
|
||||
"edt_eff_colorSecond": "Color second",
|
||||
"edt_eff_colorcount": "Color length",
|
||||
"edt_eff_colorend": "Color end",
|
||||
"edt_eff_colorendtime": "Time to hold start color",
|
||||
"edt_eff_colorevel": "Color level",
|
||||
"edt_eff_colorHour": "Color hour",
|
||||
"edt_eff_colorMarker": "Marker color",
|
||||
"edt_eff_colorMinute": "Color minute",
|
||||
"edt_eff_colorone": "Color one",
|
||||
"edt_eff_colorrandom": "Random color",
|
||||
"edt_eff_colorSecond": "Color second",
|
||||
"edt_eff_colorshift": "Color Shift",
|
||||
"edt_eff_colorstart": "Color start",
|
||||
"edt_eff_colorstarttime": "Time to hold end color",
|
||||
@ -603,13 +619,13 @@
|
||||
"edt_eff_postcolor": "Post color",
|
||||
"edt_eff_rainbowmood_header": "Rainbow Mood",
|
||||
"edt_eff_rainbowmood_header_desc": "All LEDs rainbow mood",
|
||||
"edt_eff_randomCenter": "Random Center",
|
||||
"edt_eff_random_header": "Random",
|
||||
"edt_eff_random_header_desc": "Pixel Dot, dot, dot...",
|
||||
"edt_eff_randomCenter": "Random Center",
|
||||
"edt_eff_repeat": "Repeat",
|
||||
"edt_eff_repeatcount": "Repeat count",
|
||||
"edt_eff_reverseRandomTime": "Reverse every",
|
||||
"edt_eff_reversedirection": "Reverse direction",
|
||||
"edt_eff_reverseRandomTime": "Reverse every",
|
||||
"edt_eff_rotationtime": "Rotation time",
|
||||
"edt_eff_saturation": "Saturation",
|
||||
"edt_eff_showseconds": "Show seconds",
|
||||
@ -647,23 +663,23 @@
|
||||
"edt_msg_button_expand": "Expand",
|
||||
"edt_msg_button_move_down_title": "Move down",
|
||||
"edt_msg_button_move_up_title": "Move up",
|
||||
"edt_msg_error_additionalItems": "No additional items allowed in this array",
|
||||
"edt_msg_error_additional_properties": "No additional properties allowed, but property $1 is set",
|
||||
"edt_msg_error_additionalItems": "No additional items allowed in this array",
|
||||
"edt_msg_error_anyOf": "Value must validate against at least one of the provided schemas",
|
||||
"edt_msg_error_dependency": "Must have property $1",
|
||||
"edt_msg_error_disallow": "Value must not be of type $1",
|
||||
"edt_msg_error_disallow_union": "Value must not be one of the provided disallowed types",
|
||||
"edt_msg_error_enum": "Value must be one of the enumerated values",
|
||||
"edt_msg_error_maximum_excl": "Value must be less than $1",
|
||||
"edt_msg_error_maximum_incl": "Value must be at most $1",
|
||||
"edt_msg_error_maxItems": "Value must have at most $1 items",
|
||||
"edt_msg_error_maxLength": "Value must be at most $1 characters long",
|
||||
"edt_msg_error_maxProperties": "Object must have at most $1 properties",
|
||||
"edt_msg_error_maximum_excl": "Value must be less than $1",
|
||||
"edt_msg_error_maximum_incl": "Value must be at most $1",
|
||||
"edt_msg_error_minimum_excl": "Value must be greater than $1",
|
||||
"edt_msg_error_minimum_incl": "Value must be at least $1",
|
||||
"edt_msg_error_minItems": "Value must have at least $1 items",
|
||||
"edt_msg_error_minLength": "Value must be at least $1 characters long",
|
||||
"edt_msg_error_minProperties": "Object must have at least $1 properties",
|
||||
"edt_msg_error_minimum_excl": "Value must be greater than $1",
|
||||
"edt_msg_error_minimum_incl": "Value must be at least $1",
|
||||
"edt_msg_error_multipleOf": "Value must be a multiple of $1",
|
||||
"edt_msg_error_not": "Value must not validate against the provided schema",
|
||||
"edt_msg_error_notempty": "Value required",
|
||||
@ -698,6 +714,7 @@
|
||||
"general_btn_off": "Off",
|
||||
"general_btn_ok": "OK",
|
||||
"general_btn_on": "On",
|
||||
"general_btn_overwrite": "Overwrite",
|
||||
"general_btn_rename": "Rename",
|
||||
"general_btn_restarthyperion": "Restart Hyperion",
|
||||
"general_btn_save": "Save",
|
||||
@ -745,20 +762,6 @@
|
||||
"general_speech_zh-CN": "Chinese (simplified)",
|
||||
"general_webui_title": "Hyperion - Web Configuration",
|
||||
"general_wiki_moreto": "More information to \"$1\" at our Wiki",
|
||||
"infoDialog_checklist_title": "Checklist!",
|
||||
"infoDialog_effconf_created_text": "The effect \"$1\" has been created successfully!",
|
||||
"infoDialog_effconf_deleted_text": "The effect \"$1\" has been deleted successfully!",
|
||||
"infoDialog_general_error_title": "Error",
|
||||
"infoDialog_general_success_title": "Success",
|
||||
"infoDialog_general_warning_title": "Warning",
|
||||
"infoDialog_import_comperror_text": "Sad! Your browser doesn't support a import. Please try again with another browser.",
|
||||
"infoDialog_import_confirm_text": "Are you sure to import \"$1\"? This process can't be reverted!",
|
||||
"infoDialog_import_confirm_title": "Confirm import",
|
||||
"infoDialog_import_hyperror_text": "The selected configuration file \"$1\" can't be imported. It's not compatible with Hyperion 2.0 and higher!",
|
||||
"infoDialog_import_jsonerror_text": "The selected configuration file \"$1\" is no .json file or it's corrupted. Error message: ($2)",
|
||||
"infoDialog_wizrgb_text": "Your RGB Byte Order is already well adjusted.",
|
||||
"infoDialog_writeconf_error_text": "Saving your configuration failed.",
|
||||
"infoDialog_writeimage_error_text": "The selected file \"$1\" is no image file or it's corrupted! Please select another image file.",
|
||||
"info_404": "The page you requested is not available!",
|
||||
"info_conlost_label_autorecon": "We reconnect again after Hyperion is available.",
|
||||
"info_conlost_label_autorefresh": "This page will be automatically refreshed.",
|
||||
@ -772,6 +775,31 @@
|
||||
"info_restart_contusa": "...with your last steps. Thank you!",
|
||||
"info_restart_rightback": "Hyperion will be right back immediately!",
|
||||
"info_restart_title": "Restarts currently...",
|
||||
"InfoDialog_access_text": "Depending on settings level you could adjust more options or get access to more features. Recommended is the \"Default\" level.",
|
||||
"InfoDialog_access_title": "Settings level",
|
||||
"InfoDialog_changePassword_success": "Password successfully saved!",
|
||||
"InfoDialog_changePassword_title": "Change Password",
|
||||
"infoDialog_checklist_title": "Checklist!",
|
||||
"infoDialog_effconf_created_text": "The effect \"$1\" has been created successfully!",
|
||||
"infoDialog_effconf_deleted_text": "The effect \"$1\" has been deleted successfully!",
|
||||
"infoDialog_general_error_title": "Error",
|
||||
"infoDialog_general_success_title": "Success",
|
||||
"infoDialog_general_warning_title": "Warning",
|
||||
"infoDialog_import_comperror_text": "Sad! Your browser doesn't support a import. Please try again with another browser.",
|
||||
"infoDialog_import_confirm_text": "Are you sure to import \"$1\"? This process can't be reverted!",
|
||||
"infoDialog_import_confirm_title": "Confirm import",
|
||||
"infoDialog_import_hyperror_text": "The selected configuration file \"$1\" can't be imported. It's not compatible with Hyperion 2.0 and higher!",
|
||||
"infoDialog_import_jsonerror_text": "The selected configuration file \"$1\" is no .json file or it's corrupted. Error message: ($2)",
|
||||
"InfoDialog_iswitch_text": "If you run Hyperion more than once in your local network, you could switch between the web configurations. Select the Hyperion instance below and switch!",
|
||||
"InfoDialog_iswitch_title": "Hyperion switcher",
|
||||
"InfoDialog_lang_text": "If you don't like the result of the automatic language detection you could overwrite it here.",
|
||||
"InfoDialog_lang_title": "Language setting",
|
||||
"InfoDialog_nowrite_foottext": "The WebUI will be unlocked automatically after you solved the problem!",
|
||||
"InfoDialog_nowrite_text": "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.",
|
||||
"InfoDialog_nowrite_title": "write permission error!",
|
||||
"infoDialog_wizrgb_text": "Your RGB Byte Order is already well adjusted.",
|
||||
"infoDialog_writeconf_error_text": "Saving your configuration failed.",
|
||||
"infoDialog_writeimage_error_text": "The selected file \"$1\" is no image file or it's corrupted! Please select another image file.",
|
||||
"main_ledsim_btn_togglelednumber": "LED numbers",
|
||||
"main_ledsim_btn_toggleleds": "Show LEDs",
|
||||
"main_ledsim_btn_togglelivevideo": "Live video",
|
||||
|
@ -101,7 +101,7 @@
|
||||
<span class="icon-bar middle-bar"></span>
|
||||
<span class="icon-bar bottom-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="https://www.hyperion-project.org?pk_campaign=WebUI&pk_kwd=mainlogo" target="_blank"><img src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!" height="55"></a>
|
||||
<a class="navbar-brand" href="https://www.hyperion-project.org" target="_blank"><img src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!" height="55"></a>
|
||||
|
||||
</div>
|
||||
<!-- /.navbar-header -->
|
||||
@ -234,7 +234,7 @@
|
||||
<a class="inactive"><i class="fa fa-industry fa-fw"></i><span data-i18n="main_menu_system_token">System</span><span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<li> <a class="inactive mnava" href="#conf_webconfig" id="load_webconfig"><i class="fa fa-wrench fa-fw"></i><span data-i18n="main_menu_webconfig_token">Webconfiguration</span></a> </li>
|
||||
<li> <a class="inactive mnava" href="#conf_logging"><i class="fa fa-reorder fa-fw"></i><span data-i18n="main_menu_logging_token">Log</span></a> </li>
|
||||
<li> <a class="inactive mnava" id="MenuItemLogging" href="#conf_logging"><i class="fa fa-reorder fa-fw"></i><span data-i18n="main_menu_logging_token">Log</span></a> </li>
|
||||
<li> <a class="inactive mnava" href="#update"><i class="fa fa-download fa-fw"></i><span data-i18n="main_menu_update_token">Update</span></a> </li>
|
||||
<li> <a class="inactive mnava" href="#about"><i class="fa fa-info-circle fa-fw"></i><span data-i18n="main_menu_about_token">About</span></a> </li>
|
||||
</ul>
|
||||
|
12
assets/webconfig/js/content_colors.js
Normal file → Executable file
12
assets/webconfig/js/content_colors.js
Normal file → Executable file
@ -4,8 +4,7 @@ $(document).ready( function() {
|
||||
var editor_smoothing = null;
|
||||
var editor_blackborder = null;
|
||||
|
||||
if(window.showOptHelp)
|
||||
{
|
||||
if (window.showOptHelp) {
|
||||
//color
|
||||
$('#conf_cont').append(createRow('conf_cont_color'));
|
||||
$('#conf_cont_color').append(createOptPanel('fa-photo', $.i18n("edt_conf_color_heading_title"), 'editor_container_color', 'btn_submit_color'));
|
||||
@ -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(createHelpTable(window.schema.blackborderdetector.properties, $.i18n("edt_conf_bb_heading_title")));
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
$('#conf_cont').addClass('row');
|
||||
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_color_heading_title"), 'editor_container_color', 'btn_submit_color'));
|
||||
$('#conf_cont').append(createOptPanel('fa-photo', $.i18n("edt_conf_smooth_heading_title"), 'editor_container_smoothing', 'btn_submit_smoothing'));
|
||||
@ -49,7 +47,6 @@ $(document).ready( function() {
|
||||
|
||||
editor_smoothing.on('change', function () {
|
||||
editor_smoothing.validate().length || window.readOnlyMode ? $('#btn_submit_smoothing').attr('disabled', true) : $('#btn_submit_smoothing').attr('disabled', false);
|
||||
|
||||
});
|
||||
|
||||
$('#btn_submit_smoothing').off().on('click', function () {
|
||||
@ -70,11 +67,10 @@ $(document).ready( function() {
|
||||
});
|
||||
|
||||
//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
|
||||
if(window.showOptHelp)
|
||||
{
|
||||
if (window.showOptHelp) {
|
||||
createHint("intro", $.i18n('conf_colors_color_intro'), "editor_container_color");
|
||||
createHint("intro", $.i18n('conf_colors_smoothing_intro'), "editor_container_smoothing");
|
||||
createHint("intro", $.i18n('conf_colors_blackborder_intro'), "editor_container_blackborder");
|
||||
|
33
assets/webconfig/js/content_index.js
Normal file → Executable file
33
assets/webconfig/js/content_index.js
Normal file → Executable file
@ -1,11 +1,9 @@
|
||||
var instNameInit = false
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
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) {
|
||||
handleDarkMode();
|
||||
}
|
||||
@ -15,8 +13,7 @@ $(document).ready(function () {
|
||||
}
|
||||
}
|
||||
|
||||
if(getStorage("darkMode", false) == "on")
|
||||
{
|
||||
if (getStorage("darkMode", false) == "on") {
|
||||
handleDarkMode();
|
||||
}
|
||||
|
||||
@ -62,8 +59,7 @@ $(document).ready(function () {
|
||||
// Update language selection
|
||||
$("#language-select").on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
|
||||
var newLang = availLang[clickedIndex - 1];
|
||||
if (newLang !== storedLang)
|
||||
{
|
||||
if (newLang !== storedLang) {
|
||||
setStorage("langcode", newLang);
|
||||
reload();
|
||||
}
|
||||
@ -155,8 +151,7 @@ $(document).ready(function () {
|
||||
$("#main-nav").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')
|
||||
+ ' <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()">'
|
||||
@ -166,7 +161,6 @@ $(document).ready(function () {
|
||||
//if logged on and pw != default show option to lock ui
|
||||
$("#btn_lock_ui").removeAttr('style')
|
||||
|
||||
|
||||
if (event.response.hasOwnProperty('info'))
|
||||
setStorage("loginToken", event.response.info.token, true);
|
||||
|
||||
@ -313,11 +307,9 @@ $(document).ready(function () {
|
||||
loadContent(e);
|
||||
window.scrollTo(0, 0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function suppressDefaultPwWarning() {
|
||||
|
||||
if (document.getElementById('chk_suppressDefaultPw').checked)
|
||||
setStorage("suppressDefaultPwWarning", "true");
|
||||
else
|
||||
@ -339,9 +331,7 @@ $(document.body).on('hide.bs.modal,hidden.bs.modal', function () {
|
||||
|
||||
//Dark Mode
|
||||
$("#btn_darkmode").off().on("click", function (e) {
|
||||
|
||||
if(getStorage("darkMode", false) != "on")
|
||||
{
|
||||
if (getStorage("darkMode", false) != "on") {
|
||||
handleDarkMode();
|
||||
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
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
225
assets/webconfig/js/ui_utils.js
Normal file → Executable file
@ -53,7 +53,7 @@ function updateSessions() {
|
||||
if (sess && sess.length) {
|
||||
window.wSess = [];
|
||||
for (var i = 0; i < sess.length; i++) {
|
||||
if (sess[i].type == "_hyperiond-http._tcp.") {
|
||||
if (sess[i].type == "_http._tcp." || sess[i].type == "_https._tcp." || sess[i].type == "_hyperiond-http._tcp.") {
|
||||
window.wSess.push(sess[i]);
|
||||
}
|
||||
}
|
||||
@ -183,7 +183,6 @@ function initLanguageSelection() {
|
||||
langText = availLangText[langIdx];
|
||||
}
|
||||
}
|
||||
//console.log("langLocale: ", langLocale, "langText: ", langText);
|
||||
|
||||
$('#language-select').prop('title', langText);
|
||||
$("#language-select").val(langIdx);
|
||||
@ -463,6 +462,170 @@ function createJsonEditor(container, schema, setconfig, usePanel, arrayre) {
|
||||
return editor;
|
||||
}
|
||||
|
||||
function updateJsonEditorSelection(editor, key, addElements, newEnumVals, newTitelVals, newDefaultVal, addSelect, addCustom, addCustomAsFirst, customText) {
|
||||
var orginalProperties = editor.schema.properties[key];
|
||||
|
||||
var newSchema = [];
|
||||
newSchema[key] =
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [],
|
||||
"required": true,
|
||||
"options": { "enum_titles": [], "infoText": "" },
|
||||
"propertyOrder": 1
|
||||
};
|
||||
|
||||
//Add additional elements to overwrite defaults
|
||||
for (var item in addElements) {
|
||||
newSchema[key][item] = addElements[item];
|
||||
}
|
||||
|
||||
if (orginalProperties) {
|
||||
if (orginalProperties["title"]) {
|
||||
newSchema[key]["title"] = orginalProperties["title"];
|
||||
}
|
||||
|
||||
if (orginalProperties["options"] && orginalProperties["options"]["infoText"]) {
|
||||
newSchema[key]["options"]["infoText"] = orginalProperties["options"]["infoText"];
|
||||
}
|
||||
|
||||
if (orginalProperties["propertyOrder"]) {
|
||||
newSchema[key]["propertyOrder"] = orginalProperties["propertyOrder"];
|
||||
}
|
||||
}
|
||||
|
||||
if (addCustom) {
|
||||
|
||||
if (newTitelVals.length === 0) {
|
||||
newTitelVals = [...newEnumVals];
|
||||
}
|
||||
|
||||
if (!!!customText) {
|
||||
customText = "edt_conf_enum_custom";
|
||||
}
|
||||
|
||||
if (addCustomAsFirst) {
|
||||
newEnumVals.unshift("CUSTOM");
|
||||
newTitelVals.unshift(customText);
|
||||
} else {
|
||||
newEnumVals.push("CUSTOM");
|
||||
newTitelVals.push(customText);
|
||||
}
|
||||
|
||||
if (newSchema[key].options.infoText) {
|
||||
var customInfoText = newSchema[key].options.infoText + "_custom";
|
||||
newSchema[key].options.infoText = customInfoText;
|
||||
}
|
||||
}
|
||||
|
||||
if (addSelect) {
|
||||
newEnumVals.unshift("SELECT");
|
||||
newTitelVals.unshift("edt_conf_enum_please_select");
|
||||
newDefaultVal = "SELECT";
|
||||
}
|
||||
|
||||
if (newEnumVals) {
|
||||
newSchema[key]["enum"] = newEnumVals;
|
||||
}
|
||||
|
||||
if (newTitelVals) {
|
||||
newSchema[key]["options"]["enum_titles"] = newTitelVals;
|
||||
}
|
||||
if (newDefaultVal) {
|
||||
newSchema[key]["default"] = newDefaultVal;
|
||||
}
|
||||
|
||||
editor.original_schema.properties[key] = orginalProperties;
|
||||
editor.schema.properties[key] = newSchema[key];
|
||||
|
||||
editor.removeObjectProperty(key);
|
||||
delete editor.cached_editors[key];
|
||||
editor.addObjectProperty(key);
|
||||
}
|
||||
|
||||
function updateJsonEditorMultiSelection(editor, key, addElements, newEnumVals, newTitelVals, newDefaultVal) {
|
||||
var orginalProperties = editor.schema.properties[key];
|
||||
|
||||
var newSchema = [];
|
||||
newSchema[key] =
|
||||
{
|
||||
"type": "array",
|
||||
"format": "select",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [],
|
||||
"options": { "enum_titles": [] },
|
||||
},
|
||||
"options": { "infoText": "" },
|
||||
"default": [],
|
||||
"propertyOrder": 1
|
||||
};
|
||||
|
||||
//Add additional elements to overwrite defaults
|
||||
for (var item in addElements) {
|
||||
newSchema[key][item] = addElements[item];
|
||||
}
|
||||
|
||||
if (orginalProperties) {
|
||||
if (orginalProperties["title"]) {
|
||||
newSchema[key]["title"] = orginalProperties["title"];
|
||||
}
|
||||
|
||||
if (orginalProperties["options"] && orginalProperties["options"]["infoText"]) {
|
||||
newSchema[key]["options"]["infoText"] = orginalProperties["options"]["infoText"];
|
||||
}
|
||||
|
||||
if (orginalProperties["propertyOrder"]) {
|
||||
newSchema[key]["propertyOrder"] = orginalProperties["propertyOrder"];
|
||||
}
|
||||
}
|
||||
|
||||
if (newEnumVals) {
|
||||
newSchema[key]["items"]["enum"] = newEnumVals;
|
||||
}
|
||||
|
||||
if (newTitelVals) {
|
||||
newSchema[key]["items"]["options"]["enum_titles"] = newTitelVals;
|
||||
}
|
||||
|
||||
if (newDefaultVal) {
|
||||
newSchema[key]["default"] = newDefaultVal;
|
||||
}
|
||||
|
||||
editor.original_schema.properties[key] = orginalProperties;
|
||||
editor.schema.properties[key] = newSchema[key];
|
||||
|
||||
editor.removeObjectProperty(key);
|
||||
delete editor.cached_editors[key];
|
||||
editor.addObjectProperty(key);
|
||||
}
|
||||
|
||||
function updateJsonEditorRange(editor, key, minimum, maximum, defaultValue, step) {
|
||||
var orginalProperties = editor.schema.properties[key];
|
||||
var newSchema = [];
|
||||
newSchema[key] = orginalProperties;
|
||||
|
||||
if (minimum) {
|
||||
newSchema[key]["minimum"] = minimum;
|
||||
}
|
||||
if (maximum) {
|
||||
newSchema[key]["maximum"] = maximum;
|
||||
}
|
||||
if (defaultValue) {
|
||||
newSchema[key]["default"] = defaultValue;
|
||||
}
|
||||
if (step) {
|
||||
newSchema[key]["step"] = step;
|
||||
}
|
||||
|
||||
editor.original_schema.properties[key] = orginalProperties;
|
||||
editor.schema.properties[key] = newSchema[key];
|
||||
|
||||
editor.removeObjectProperty(key);
|
||||
delete editor.cached_editors[key];
|
||||
editor.addObjectProperty(key);
|
||||
}
|
||||
|
||||
function buildWL(link, linkt, cl) {
|
||||
var baseLink = "https://docs.hyperion-project.org/";
|
||||
var lang;
|
||||
@ -655,6 +818,48 @@ function createOptPanel(phicon, phead, bodyid, footerid) {
|
||||
return createPanel(phead, "", pfooter, "panel-default", bodyid);
|
||||
}
|
||||
|
||||
function compareTwoValues(key1, key2, order = 'asc') {
|
||||
return function innerSort(a, b) {
|
||||
if (!a.hasOwnProperty(key1) || !b.hasOwnProperty(key1)) {
|
||||
// property key1 doesn't exist on either object
|
||||
return 0;
|
||||
}
|
||||
|
||||
const varA1 = (typeof a[key1] === 'string')
|
||||
? a[key1].toUpperCase() : a[key1];
|
||||
const varB1 = (typeof b[key1] === 'string')
|
||||
? b[key1].toUpperCase() : b[key1];
|
||||
|
||||
let comparison = 0;
|
||||
if (varA1 > varB1) {
|
||||
comparison = 1;
|
||||
} else {
|
||||
if (varA1 < varB1) {
|
||||
comparison = -1;
|
||||
} else {
|
||||
if (!a.hasOwnProperty(key2) || !b.hasOwnProperty(key2)) {
|
||||
// property key2 doesn't exist on either object
|
||||
return 0;
|
||||
}
|
||||
|
||||
const varA2 = (typeof a[key2] === 'string')
|
||||
? a[key2].toUpperCase() : a[key2];
|
||||
const varB2 = (typeof b[key1] === 'string')
|
||||
? b[key2].toUpperCase() : b[key2];
|
||||
|
||||
if (varA2 > varB2) {
|
||||
comparison = 1;
|
||||
} else {
|
||||
comparison = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
(order === 'desc') ? (comparison * -1) : comparison
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function sortProperties(list) {
|
||||
for (var key in list) {
|
||||
list[key].key = key;
|
||||
@ -876,3 +1081,19 @@ function handleDarkMode() {
|
||||
$('#btn_darkmode_icon').removeClass('fa fa-moon-o');
|
||||
$('#btn_darkmode_icon').addClass('fa fa-sun-o');
|
||||
}
|
||||
|
||||
function isAccessLevelCompliant(accessLevel) {
|
||||
var isOK = true;
|
||||
if (accessLevel) {
|
||||
if (accessLevel === 'system') {
|
||||
isOK = false;
|
||||
}
|
||||
else if (accessLevel === 'advanced' && storedAccess === 'default') {
|
||||
isOK = false;
|
||||
}
|
||||
else if (accessLevel === 'expert' && storedAccess !== 'expert') {
|
||||
isOK = false;
|
||||
}
|
||||
}
|
||||
return isOK
|
||||
}
|
||||
|
417
assets/webconfig/js/wizard.js
Normal file → Executable file
417
assets/webconfig/js/wizard.js
Normal file → Executable file
@ -437,7 +437,6 @@ function startWizardCC() {
|
||||
});
|
||||
|
||||
$('#wiz_cc_kodiip').off().on('change', function () {
|
||||
|
||||
kodiAddress = $(this).val().trim();
|
||||
$('#wizp1_body').find("kodiAddress").val(kodiAddress);
|
||||
|
||||
@ -788,8 +787,6 @@ async function discover_hue_bridges() {
|
||||
const r = res.info;
|
||||
|
||||
// Process devices returned by discovery
|
||||
console.log(r);
|
||||
|
||||
if (r.devices.length == 0)
|
||||
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
||||
else {
|
||||
@ -832,7 +829,7 @@ async function identify_hue_device(hostAddress, username, id) {
|
||||
$('#btn_wiz_save').attr('disabled', true);
|
||||
|
||||
let params = { host: hostAddress, user: username, lightId: id };
|
||||
const res = await requestLedDeviceIdentification('philipshue', params);
|
||||
await requestLedDeviceIdentification('philipshue', params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').attr('disabled', false);
|
||||
@ -1187,7 +1184,6 @@ function get_hue_lights() {
|
||||
}
|
||||
|
||||
(cC == 0 || window.readOnlyMode) ? $('#btn_wiz_save').attr("disabled", true) : $('#btn_wiz_save').attr("disabled", false);
|
||||
|
||||
});
|
||||
}
|
||||
$('.hue_sel_watch').trigger('change');
|
||||
@ -1208,108 +1204,6 @@ function abortConnection(UserInterval) {
|
||||
$("#wiz_hue_usrstate").html($.i18n('wiz_hue_failure_connection'));
|
||||
}
|
||||
|
||||
//****************************
|
||||
// Wizard WLED
|
||||
//****************************
|
||||
var lights = null;
|
||||
function startWizardWLED(e) {
|
||||
//create html
|
||||
|
||||
var wled_title = 'wiz_wled_title';
|
||||
var wled_intro1 = 'wiz_wled_intro1';
|
||||
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(wled_title));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(wled_title) + '</h4><p>' + $.i18n(wled_intro1) + '</p>');
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
/*$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
|
||||
|
||||
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
|
||||
|
||||
$('#wizp2_body').append('<div id="hue_ids_t" style="display:none"><p style="font-weight:bold" id="hue_id_headline">'+$.i18n('wiz_wled_desc2')+'</p></div>');
|
||||
|
||||
createTable("lidsh", "lidsb", "hue_ids_t");
|
||||
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lights_title'),$.i18n('wiz_pos'),$.i18n('wiz_identify')], true));
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_save')+'</button><button type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
|
||||
*/
|
||||
//open modal
|
||||
$("#wizard_modal").modal({
|
||||
backdrop: "static",
|
||||
keyboard: false,
|
||||
show: true
|
||||
});
|
||||
|
||||
//listen for continue
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
/* For testing only
|
||||
|
||||
discover_wled();
|
||||
|
||||
var hostAddress = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||
if(hostAddress != "")
|
||||
{
|
||||
getProperties_wled(hostAddress,"info");
|
||||
identify_wled(hostAddress)
|
||||
}
|
||||
|
||||
For testing only */
|
||||
});
|
||||
}
|
||||
|
||||
async function discover_wled() {
|
||||
const res = await requestLedDeviceDiscovery('wled');
|
||||
|
||||
// TODO: error case unhandled
|
||||
// res can be: false (timeout) or res.error (not found)
|
||||
if (res && !res.error) {
|
||||
const r = res.info
|
||||
|
||||
// Process devices returned by discovery
|
||||
console.log(r);
|
||||
|
||||
if (r.devices.length == 0)
|
||||
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
||||
else {
|
||||
for (const device of r.devices) {
|
||||
console.log("Device:", device);
|
||||
|
||||
var ip = device.hostname + ":" + device.port;
|
||||
console.log("Host:", ip);
|
||||
|
||||
//wledIPs.push({internalipaddress : ip});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getProperties_wled(hostAddress, resourceFilter) {
|
||||
let params = { host: hostAddress, filter: resourceFilter };
|
||||
|
||||
const res = await requestLedDeviceProperties('wled', params);
|
||||
|
||||
// TODO: error case unhandled
|
||||
// res can be: false (timeout) or res.error (not found)
|
||||
if (res && !res.error) {
|
||||
const r = res.info
|
||||
|
||||
// Process properties returned
|
||||
console.log(r);
|
||||
}
|
||||
}
|
||||
|
||||
async function identify_wled(hostAddress) {
|
||||
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').attr('disabled', true);
|
||||
|
||||
let params = { host: hostAddress };
|
||||
const res = await requestLedDeviceIdentification('wled', params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').attr('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
//****************************
|
||||
// Wizard Yeelight
|
||||
//****************************
|
||||
@ -1438,8 +1332,17 @@ async function discover_yeelight_lights() {
|
||||
var light = {};
|
||||
light.host = device.hostname;
|
||||
light.port = device.port;
|
||||
|
||||
if (device.txt) {
|
||||
light.name = device.name;
|
||||
light.model = device.txt.md;
|
||||
//Yeelight does not provide correct API port with mDNS response, use default one
|
||||
light.port = 55443;
|
||||
}
|
||||
else {
|
||||
light.name = device.other.name;
|
||||
light.model = device.other.model;
|
||||
}
|
||||
lights.push(light);
|
||||
}
|
||||
}
|
||||
@ -1469,7 +1372,8 @@ async function discover_yeelight_lights() {
|
||||
}
|
||||
|
||||
function assign_yeelight_lights() {
|
||||
var models = ['color', 'color1', 'color2', 'color4', 'stripe', 'strip1'];
|
||||
// Model mappings, see https://www.home-assistant.io/integrations/yeelight/
|
||||
var models = ['color', 'color1', 'YLDP02YL', 'YLDP02YL', 'color2', 'YLDP06YL', 'color4', 'YLDP13YL', 'stripe', 'YLDD04YL', 'strip1', 'YLDD01YL', 'YLDD02YL'];
|
||||
|
||||
// If records are left for configuration
|
||||
if (Object.keys(lights).length > 0) {
|
||||
@ -1555,12 +1459,11 @@ async function getProperties_yeelight(hostname, port) {
|
||||
}
|
||||
|
||||
async function identify_yeelight_device(hostname, port) {
|
||||
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').attr('disabled', true);
|
||||
|
||||
let params = { hostname: hostname, port: port };
|
||||
const res = await requestLedDeviceIdentification("yeelight", params);
|
||||
await requestLedDeviceIdentification("yeelight", params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').attr('disabled', false);
|
||||
@ -1675,13 +1578,11 @@ async function discover_atmoorb_lights(multiCastGroup, multiCastPort) {
|
||||
var light = {};
|
||||
|
||||
var params = {};
|
||||
if (multiCastGroup !== "")
|
||||
{
|
||||
if (multiCastGroup !== "") {
|
||||
params.multiCastGroup = multiCastGroup;
|
||||
}
|
||||
|
||||
if (multiCastPort !== 0)
|
||||
{
|
||||
if (multiCastPort !== 0) {
|
||||
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">'
|
||||
+ 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>']));
|
||||
}
|
||||
|
||||
@ -1799,297 +1700,13 @@ function assign_atmoorb_lights() {
|
||||
}
|
||||
|
||||
async function identify_atmoorb_device(orbId) {
|
||||
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').attr('disabled', true);
|
||||
|
||||
let params = { id: orbId };
|
||||
const res = await requestLedDeviceIdentification("atmoorb", params);
|
||||
await requestLedDeviceIdentification("atmoorb", params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').attr('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
//****************************
|
||||
// Wizard/Routines Nanoleaf
|
||||
//****************************
|
||||
async function discover_nanoleaf() {
|
||||
const res = await requestLedDeviceDiscovery('nanoleaf');
|
||||
|
||||
// TODO: error case unhandled
|
||||
// res can be: false (timeout) or res.error (not found)
|
||||
if (res && !res.error) {
|
||||
const r = res.info
|
||||
|
||||
// Process devices returned by discovery
|
||||
console.log(r);
|
||||
|
||||
if (r.devices.length == 0)
|
||||
$('#wiz_hue_ipstate').html($.i18n('wiz_hue_failure_ip'));
|
||||
else {
|
||||
for (const device of r.devices) {
|
||||
console.log("Device:", device);
|
||||
|
||||
var ip = device.hostname + ":" + device.port;
|
||||
console.log("Host:", ip);
|
||||
|
||||
//nanoleafIPs.push({internalipaddress : ip});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getProperties_nanoleaf(hostAddress, authToken, resourceFilter) {
|
||||
let params = { host: hostAddress, token: authToken, filter: resourceFilter };
|
||||
|
||||
const res = await requestLedDeviceProperties('nanoleaf', params);
|
||||
|
||||
// TODO: error case unhandled
|
||||
// res can be: false (timeout) or res.error (not found)
|
||||
if (res && !res.error) {
|
||||
const r = res.info
|
||||
|
||||
// Process properties returned
|
||||
console.log(r);
|
||||
}
|
||||
}
|
||||
|
||||
async function identify_nanoleaf(hostAddress, authToken) {
|
||||
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').attr('disabled', true);
|
||||
|
||||
let params = { host: hostAddress, token: authToken };
|
||||
const res = await requestLedDeviceIdentification('nanoleaf', params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').attr('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
//****************************
|
||||
// Wizard Cololight
|
||||
//****************************
|
||||
var lights = null;
|
||||
var selectedLightId = null;
|
||||
|
||||
function startWizardCololight(e) {
|
||||
//create html
|
||||
|
||||
var cololight_title = 'wiz_cololight_title';
|
||||
var cololight_intro1 = 'wiz_cololight_intro1';
|
||||
|
||||
$('#wiz_header').html('<i class="fa fa-magic fa-fw"></i>' + $.i18n(cololight_title));
|
||||
$('#wizp1_body').html('<h4 style="font-weight:bold;text-transform:uppercase;">' + $.i18n(cololight_title) + '</h4><p>' + $.i18n(cololight_intro1) + '</p>');
|
||||
$('#wizp1_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_cont"><i class="fa fa-fw fa-check"></i>' + $.i18n('general_btn_continue') + '</button><button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>' + $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
$('#wizp2_body').html('<div id="wh_topcontainer"></div>');
|
||||
|
||||
$('#wh_topcontainer').append('<div class="form-group" id="usrcont" style="display:none"></div>');
|
||||
|
||||
$('#wizp2_body').append('<div id="colo_ids_t" style="display:none"><p style="font-weight:bold" id="colo_id_headline">' + $.i18n('wiz_cololight_desc2') + '</p></div>');
|
||||
|
||||
createTable("lidsh", "lidsb", "colo_ids_t");
|
||||
$('.lidsh').append(createTableRow([$.i18n('edt_dev_spec_lights_title'), $.i18n('wiz_identify')], true));
|
||||
$('#wizp2_footer').html('<button type="button" class="btn btn-primary" id="btn_wiz_save" style="display:none"><i class="fa fa-fw fa-save"></i>'
|
||||
+ $.i18n('general_btn_save') + '</button><buttowindow.serverConfig.device = d;n type="button" class="btn btn-danger" id="btn_wiz_abort"><i class="fa fa-fw fa-close"></i>'
|
||||
+ $.i18n('general_btn_cancel') + '</button>');
|
||||
|
||||
//open modal
|
||||
$("#wizard_modal").modal({
|
||||
backdrop: "static",
|
||||
keyboard: false,
|
||||
show: true
|
||||
});
|
||||
|
||||
//listen for continue
|
||||
$('#btn_wiz_cont').off().on('click', function () {
|
||||
beginWizardCololight();
|
||||
$('#wizp1').toggle(false);
|
||||
$('#wizp2').toggle(true);
|
||||
});
|
||||
}
|
||||
|
||||
function beginWizardCololight() {
|
||||
lights = [];
|
||||
|
||||
discover_cololights();
|
||||
|
||||
$('#btn_wiz_save').off().on("click", function () {
|
||||
//LED device config
|
||||
//Start with a clean configuration
|
||||
var d = {};
|
||||
|
||||
d.type = 'cololight';
|
||||
|
||||
//Cololight does not resolve into stable hostnames (as devices named the same), therefore use IP
|
||||
if (!lights[selectedLightId].ip) {
|
||||
d.host = lights[selectedLightId].host;
|
||||
} else {
|
||||
d.host = lights[selectedLightId].ip;
|
||||
}
|
||||
|
||||
var coloLightProperties = lights[selectedLightId].props.properties;
|
||||
if (Object.keys(coloLightProperties).length === 0) {
|
||||
alert($.i18n('wiz_cololight_noprops'));
|
||||
d.hardwareLedCount = 1;
|
||||
}
|
||||
else {
|
||||
d.hardwareLedCount = coloLightProperties.ledCount;
|
||||
}
|
||||
|
||||
d.colorOrder = conf_editor.getEditor("root.generalOptions.colorOrder").getValue();
|
||||
d.latchTime = parseInt(conf_editor.getEditor("root.specificOptions.latchTime").getValue());;
|
||||
|
||||
window.serverConfig.device = d;
|
||||
|
||||
//LED layout - have initial layout prepared matching the LED-count
|
||||
|
||||
var coloLightLedConfig = [];
|
||||
|
||||
if (coloLightProperties.modelType === "Strip") {
|
||||
coloLightLedConfig = createClassicLedLayoutSimple(d.hardwareLedCount / 2, d.hardwareLedCount / 4, d.hardwareLedCount / 4, 0, d.hardwareLedCount / 4 * 3, false);
|
||||
} else {
|
||||
coloLightLedConfig = createClassicLedLayoutSimple(0, 0, 0, d.hardwareLedCount, 0, true);
|
||||
}
|
||||
|
||||
window.serverConfig.leds = coloLightLedConfig;
|
||||
|
||||
//smoothing off
|
||||
window.serverConfig.smoothing.enable = false;
|
||||
|
||||
requestWriteConfig(window.serverConfig, true);
|
||||
|
||||
resetWizard();
|
||||
});
|
||||
|
||||
$('#btn_wiz_abort').off().on('click', resetWizard);
|
||||
}
|
||||
|
||||
async function discover_cololights() {
|
||||
const res = await requestLedDeviceDiscovery('cololight');
|
||||
|
||||
if (res && !res.error) {
|
||||
const r = res.info;
|
||||
|
||||
// Process devices returned by discovery
|
||||
for (const device of r.devices) {
|
||||
if (device.ip !== "") {
|
||||
if (getIpInLights(device.ip).length === 0) {
|
||||
var light = {};
|
||||
light.ip = device.ip;
|
||||
light.host = device.hostname;
|
||||
light.name = device.name;
|
||||
light.type = device.type;
|
||||
lights.push(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
assign_cololight_lights();
|
||||
}
|
||||
}
|
||||
|
||||
function assign_cololight_lights() {
|
||||
// If records are left for configuration
|
||||
if (Object.keys(lights).length > 0) {
|
||||
$('#wh_topcontainer').toggle(false);
|
||||
$('#colo_ids_t, #btn_wiz_save').toggle(true);
|
||||
|
||||
$('.lidsb').html("");
|
||||
|
||||
var options = "";
|
||||
|
||||
for (var lightid in lights) {
|
||||
lights[lightid].id = lightid;
|
||||
|
||||
var lightHostname = lights[lightid].host;
|
||||
var lightIP = lights[lightid].ip;
|
||||
|
||||
var val = lightHostname + " (" + lightIP + ")";
|
||||
options += '<option value="' + lightid + '">' + val + '</option>';
|
||||
}
|
||||
|
||||
var enabled = 'enabled';
|
||||
|
||||
$('.lidsb').append(createTableRow(['<select id="colo_select_id" ' + enabled + ' class="colo_sel_watch form-control">'
|
||||
+ options
|
||||
+ '</select>', '<button id="wiz_identify_btn" class="btn btn-sm btn-primary">'
|
||||
+ $.i18n('wiz_identify') + '</button>']));
|
||||
|
||||
$('.colo_sel_watch').bind("change", function () {
|
||||
selectedLightId = $('#colo_select_id').val();
|
||||
var lightIP = lights[selectedLightId].ip;
|
||||
|
||||
$('#wiz_identify_btn').unbind().bind('click', function (event) { identify_cololight_device(lightIP); });
|
||||
|
||||
if (!lights[selectedLightId].props) {
|
||||
getProperties_cololight(lightIP);
|
||||
}
|
||||
});
|
||||
$('.colo_sel_watch').trigger('change');
|
||||
}
|
||||
else {
|
||||
var noLightsTxt = '<p style="font-weight:bold;color:red;">' + $.i18n('wiz_noLights','Cololights') + '</p>';
|
||||
$('#wizp2_body').append(noLightsTxt);
|
||||
}
|
||||
}
|
||||
|
||||
async function getProperties_cololight(ip) {
|
||||
let params = { host: ip };
|
||||
|
||||
const res = await requestLedDeviceProperties('cololight', params);
|
||||
|
||||
if (res && !res.error) {
|
||||
var coloLightProperties = res.info;
|
||||
|
||||
//Store properties along light with given IP-address
|
||||
var id = getIpInLights(ip)[0].id;
|
||||
lights[id].props = coloLightProperties;
|
||||
}
|
||||
}
|
||||
|
||||
async function identify_cololight_device(hostAddress) {
|
||||
|
||||
// Take care that new record cannot be save during background process
|
||||
$('#btn_wiz_save').attr('disabled', true);
|
||||
|
||||
let params = { host: hostAddress };
|
||||
const res = await requestLedDeviceIdentification('cololight', params);
|
||||
|
||||
if (!window.readOnlyMode) {
|
||||
$('#btn_wiz_save').attr('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
//****************************
|
||||
// Wizard/Routines RS232-Devices
|
||||
//****************************
|
||||
async function discover_providerRs232(rs232Type) {
|
||||
const res = await requestLedDeviceDiscovery(rs232Type);
|
||||
|
||||
// TODO: error case unhandled
|
||||
// res can be: false (timeout) or res.error (not found)
|
||||
if (res && !res.error) {
|
||||
const r = res.info
|
||||
|
||||
// Process serialPorts returned by discover
|
||||
console.log(r);
|
||||
}
|
||||
}
|
||||
|
||||
//****************************
|
||||
// Wizard/Routines HID (USB)-Devices
|
||||
//****************************
|
||||
async function discover_providerHid(hidType) {
|
||||
const res = await requestLedDeviceDiscovery(hidType);
|
||||
|
||||
// TODO: error case unhandled
|
||||
// res can be: false (timeout) or res.error (not found)
|
||||
if (res && !res.error) {
|
||||
const r = res.info
|
||||
|
||||
// Process HID returned by discover
|
||||
console.log(r);
|
||||
}
|
||||
}
|
||||
|
@ -141,8 +141,8 @@ echo "---> or if already used by another service try: ${NET_IP}:8091"
|
||||
$REBOOTMESSAGE
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
echo "Webpage: www.hyperion-project.org"
|
||||
echo "Wiki: wiki.hyperion-project.org"
|
||||
echo "Forum: forum.hyperion-project.org"
|
||||
echo "Forum: www.hyperion-project.org"
|
||||
echo "Documenation: docs.hyperion-project.org"
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
|
||||
|
||||
|
@ -34,7 +34,10 @@ endif()
|
||||
SET ( CPACK_PACKAGE_NAME "Hyperion" )
|
||||
SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hyperion is an open source ambient light implementation" )
|
||||
SET ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" )
|
||||
SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
# Replease "+", as cmake/rpm has an issue if "+" occurs in CPACK_PACKAGE_VERSION
|
||||
string(REPLACE "+" "." HYPERION_PACKAGE_VERSION ${HYPERION_VERSION})
|
||||
SET ( CPACK_PACKAGE_FILE_NAME "Hyperion-${HYPERION_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
SET ( CPACK_PACKAGE_CONTACT "packages@hyperion-project.org")
|
||||
SET ( CPACK_PACKAGE_VENDOR "hyperion-project")
|
||||
|
@ -131,8 +131,8 @@ echo "---> or if already used by another service try: ${NET_IP}:8091"
|
||||
$REBOOTMESSAGE
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
echo "Webpage: www.hyperion-project.org"
|
||||
echo "Wiki: wiki.hyperion-project.org"
|
||||
echo "Forum: forum.hyperion-project.org"
|
||||
echo "Forum: www.hyperion-project.org"
|
||||
echo "Documenation: docs.hyperion-project.org"
|
||||
echo "-----------------------------------------------------------------------------"
|
||||
|
||||
|
||||
|
@ -3,9 +3,14 @@
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/settings.h>
|
||||
|
||||
#include <utils/version.hpp>
|
||||
using namespace semver;
|
||||
|
||||
// qt includes
|
||||
#include <QJsonObject>
|
||||
|
||||
const int GLOABL_INSTANCE_ID = 255;
|
||||
|
||||
class Hyperion;
|
||||
class SettingsTable;
|
||||
|
||||
@ -61,12 +66,17 @@ private:
|
||||
bool handleConfigUpgrade(QJsonObject& config);
|
||||
|
||||
|
||||
/// Hyperion instance
|
||||
Hyperion* _hyperion;
|
||||
bool resolveConfigVersion(QJsonObject& config);
|
||||
|
||||
/// Logger instance
|
||||
Logger* _log;
|
||||
|
||||
/// Hyperion instance
|
||||
Hyperion* _hyperion;
|
||||
|
||||
/// Instance number
|
||||
quint8 _instance;
|
||||
|
||||
/// instance of database table interface
|
||||
SettingsTable* _sTable;
|
||||
|
||||
@ -76,5 +86,8 @@ private:
|
||||
/// the current configuration of this instance
|
||||
QJsonObject _qconfig;
|
||||
|
||||
semver::version _configVersion;
|
||||
semver::version _previousVersion;
|
||||
|
||||
bool _readonlyMode;
|
||||
};
|
||||
|
@ -300,10 +300,21 @@ protected:
|
||||
/// even if the device is not in enabled state (allowing to have a defined state during device power-off).
|
||||
/// @note: latch-time is considered between each write
|
||||
///
|
||||
/// @param[in] numberOfWrites Write Black given number of times
|
||||
/// @param[in] numberOfWrites Write Black a given number of times
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
virtual int writeBlack(int numberOfBlack=1);
|
||||
virtual int writeBlack(int numberOfWrites = 1);
|
||||
|
||||
///
|
||||
/// @brief Writes a color to the output stream,
|
||||
/// even if the device is not in enabled state (allowing to have a defined state during device power-off).
|
||||
/// @note: latch-time is considered between each write
|
||||
///
|
||||
/// @param[in] color to be written
|
||||
/// @param[in] numberOfWrites Write the color a given number of times
|
||||
/// @return Zero on success else negative
|
||||
///
|
||||
virtual int writeColor(const ColorRgb& color, int numberOfWrites = 1);
|
||||
|
||||
///
|
||||
/// @brief Power-/turn on the LED-device.
|
||||
|
550
include/utils/version.hpp
Normal file
550
include/utils/version.hpp
Normal 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
|
@ -83,7 +83,7 @@ void Hyperion::start()
|
||||
}
|
||||
|
||||
// handle hwLedCount
|
||||
_hwLedCount = qMax(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount()), getLedCount());
|
||||
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
|
||||
|
||||
// Initialize colororder vector
|
||||
for (const Led& led : _ledString.leds())
|
||||
@ -217,7 +217,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
|
||||
}
|
||||
|
||||
// handle hwLedCount update
|
||||
_hwLedCount = qMax(getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount()), getLedCount());
|
||||
_hwLedCount = getSetting(settings::DEVICE).object()["hardwareLedCount"].toInt(getLedCount());
|
||||
|
||||
// change in leds are also reflected in adjustment
|
||||
delete _raw2ledAdjustment;
|
||||
@ -231,7 +231,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
|
||||
QJsonObject dev = config.object();
|
||||
|
||||
// handle hwLedCount update
|
||||
_hwLedCount = qMax(dev["hardwareLedCount"].toInt(getLedCount()), getLedCount());
|
||||
_hwLedCount = dev["hardwareLedCount"].toInt(getLedCount());
|
||||
|
||||
// force ledString update, if device ByteOrder changed
|
||||
if(_ledDeviceWrapper->getColorOrder() != dev["colorOrder"].toString("rgb"))
|
||||
|
@ -4,6 +4,7 @@
|
||||
// util
|
||||
#include <utils/JsonUtils.h>
|
||||
#include <db/SettingsTable.h>
|
||||
#include "HyperionConfig.h"
|
||||
|
||||
// json schema process
|
||||
#include <utils/jsonschema/QJsonFactory.h>
|
||||
@ -12,12 +13,23 @@
|
||||
// write config to filesystem
|
||||
#include <utils/JsonUtils.h>
|
||||
|
||||
#include <utils/version.hpp>
|
||||
using namespace semver;
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
const char DEFAULT_VERSION[] = "2.0.0-alpha.8";
|
||||
} //End of constants
|
||||
|
||||
QJsonObject SettingsManager::schemaJson;
|
||||
|
||||
SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonlyMode)
|
||||
: QObject(parent)
|
||||
, _log(Logger::getInstance("SETTINGSMGR"))
|
||||
, _instance(instance)
|
||||
, _sTable(new SettingsTable(instance, this))
|
||||
, _configVersion(DEFAULT_VERSION)
|
||||
, _previousVersion(DEFAULT_VERSION)
|
||||
, _readonlyMode(readonlyMode)
|
||||
{
|
||||
_sTable->setReadonlyMode(_readonlyMode);
|
||||
@ -38,7 +50,9 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
|
||||
// get default config
|
||||
QJsonObject defaultConfig;
|
||||
if(!JsonUtils::readFile(":/hyperion_default.config", defaultConfig, _log))
|
||||
{
|
||||
throw std::runtime_error("Failed to read default config");
|
||||
}
|
||||
|
||||
// transform json to string lists
|
||||
QStringList keyList = defaultConfig.keys();
|
||||
@ -64,7 +78,7 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
|
||||
_sTable->createSettingsRecord(key,val);
|
||||
}
|
||||
|
||||
// need to validate all data in database constuct the entire data object
|
||||
// need to validate all data in database construct the entire data object
|
||||
// TODO refactor schemaChecker to accept QJsonArray in validate(); QJsonDocument container? To validate them per entry...
|
||||
QJsonObject dbConfig;
|
||||
for(const auto & key : keyList)
|
||||
@ -76,8 +90,49 @@ SettingsManager::SettingsManager(quint8 instance, QObject* parent, bool readonly
|
||||
dbConfig[key] = doc.object();
|
||||
}
|
||||
|
||||
//Check, if database requires migration
|
||||
bool isNewRelease = false;
|
||||
// Use instance independent SettingsManager to track migration status
|
||||
if ( instance == GLOABL_INSTANCE_ID)
|
||||
{
|
||||
if ( resolveConfigVersion(dbConfig) )
|
||||
{
|
||||
QJsonObject newGeneralConfig = dbConfig["general"].toObject();
|
||||
|
||||
semver::version BUILD_VERSION(HYPERION_VERSION);
|
||||
if ( _configVersion > BUILD_VERSION )
|
||||
{
|
||||
Error(_log, "Database version [%s] is greater that current Hyperion version [%s]", _configVersion.getVersion().c_str(), BUILD_VERSION.getVersion().c_str());
|
||||
// TODO: Remove version checking and Settingsmanager from components' constructor to be able to stop hyperion.
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( _previousVersion < BUILD_VERSION )
|
||||
{
|
||||
if ( _configVersion == BUILD_VERSION )
|
||||
{
|
||||
newGeneralConfig["previousVersion"] = BUILD_VERSION.getVersion().c_str();
|
||||
dbConfig["general"] = newGeneralConfig;
|
||||
isNewRelease = true;
|
||||
Info(_log, "Migration completed to version [%s]", BUILD_VERSION.getVersion().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Info(_log, "Migration from current version [%s] to new version [%s] started", _previousVersion.getVersion().c_str(), BUILD_VERSION.getVersion().c_str());
|
||||
|
||||
newGeneralConfig["previousVersion"] = _configVersion.getVersion().c_str();
|
||||
newGeneralConfig["configVersion"] = BUILD_VERSION.getVersion().c_str();
|
||||
dbConfig["general"] = newGeneralConfig;
|
||||
isNewRelease = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// possible data upgrade steps to prevent data loss
|
||||
if(handleConfigUpgrade(dbConfig))
|
||||
bool migrated = handleConfigUpgrade(dbConfig);
|
||||
if ( isNewRelease || migrated )
|
||||
{
|
||||
saveSettings(dbConfig, true);
|
||||
}
|
||||
@ -193,12 +248,55 @@ bool SettingsManager::saveSettings(QJsonObject config, bool correct)
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool SettingsManager::resolveConfigVersion(QJsonObject& config)
|
||||
{
|
||||
bool isValid = false;
|
||||
if (config.contains("general"))
|
||||
{
|
||||
QJsonObject generalConfig = config["general"].toObject();
|
||||
QString configVersion = generalConfig["configVersion"].toString();
|
||||
QString previousVersion = generalConfig["previousVersion"].toString();
|
||||
|
||||
if ( !configVersion.isEmpty() )
|
||||
{
|
||||
isValid = _configVersion.setVersion(configVersion.toStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
_configVersion.setVersion(DEFAULT_VERSION);
|
||||
isValid = true;
|
||||
}
|
||||
|
||||
if ( !previousVersion.isEmpty() && isValid )
|
||||
{
|
||||
isValid = _previousVersion.setVersion(previousVersion.toStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
_previousVersion.setVersion(DEFAULT_VERSION);
|
||||
isValid = true;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
|
||||
{
|
||||
bool migrated = false;
|
||||
|
||||
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
|
||||
// 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 } }
|
||||
// to { hmin: 0.2, hmax: 0.3, vmin: 0.2, vmax: 0.3}
|
||||
if(config.contains("leds"))
|
||||
@ -250,20 +348,56 @@ bool SettingsManager::handleConfigUpgrade(QJsonObject& config)
|
||||
// replace
|
||||
config["leds"] = newLedarr;
|
||||
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"))
|
||||
{
|
||||
newGrabberV4L2Config.remove("encoding_format");
|
||||
config["grabberV4L2"] = newGrabberV4L2Config;
|
||||
config["ledConfig"] = newLedConfig;
|
||||
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;
|
||||
|
@ -1,45 +1,40 @@
|
||||
{
|
||||
"type": "object",
|
||||
"title" : "edt_dev_general_heading_title",
|
||||
"required" : true,
|
||||
"title": " ",
|
||||
"defaultProperties": [ "hardwareLedCount", "colorOrder" ],
|
||||
"properties" :
|
||||
{
|
||||
"type" :
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"propertyOrder": 1
|
||||
},
|
||||
"hardwareLedCount" :
|
||||
{
|
||||
"hardwareLedCount": {
|
||||
"type": "integer",
|
||||
"title": "edt_dev_general_hardwareLedCount_title",
|
||||
"minimum": 1,
|
||||
"default": 1,
|
||||
"options": {
|
||||
"infoText": "edt_dev_general_hardwareLedCount_title_info"
|
||||
},
|
||||
"propertyOrder": 2
|
||||
},
|
||||
"colorOrder" :
|
||||
{
|
||||
"colorOrder": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_general_colorOrder_title",
|
||||
"enum": [ "rgb", "bgr", "rbg", "brg", "gbr", "grb" ],
|
||||
"default": "rgb",
|
||||
"required": true,
|
||||
"options": {
|
||||
"enum_titles": [ "edt_conf_enum_rgb", "edt_conf_enum_bgr", "edt_conf_enum_rbg", "edt_conf_enum_brg", "edt_conf_enum_gbr", "edt_conf_enum_grb" ]
|
||||
"enum_titles": [ "edt_conf_enum_rgb", "edt_conf_enum_bgr", "edt_conf_enum_rbg", "edt_conf_enum_brg", "edt_conf_enum_gbr", "edt_conf_enum_grb" ],
|
||||
"infoText": "edt_dev_general_colorOrder_title_info"
|
||||
},
|
||||
"access": "expert",
|
||||
"propertyOrder": 3
|
||||
}
|
||||
},
|
||||
"dependencies" :
|
||||
{
|
||||
"rewriteTime" :
|
||||
{
|
||||
"properties" :
|
||||
{
|
||||
"type" :
|
||||
{
|
||||
"dependencies": {
|
||||
"rewriteTime": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [ "file", "apa102", "apa104", "ws2801", "lpd6803", "lpd8806", "p9813", "sk6812spi", "sk6822spi", "sk9822", "ws2812spi", "ws281x", "piblaster", "adalight", "dmx", "atmo", "hyperionusbasp", "lightpack", "multilightpack", "paintpack", "rawhid", "sedu", "tpm2", "karate" ]
|
||||
}
|
||||
},
|
||||
|
@ -34,6 +34,25 @@
|
||||
"default" : true,
|
||||
"required" : true,
|
||||
"propertyOrder" : 3
|
||||
},
|
||||
"configVersion" :
|
||||
{
|
||||
"type" : "string",
|
||||
"title" : "edt_conf_gen_configVersion_title",
|
||||
"options" : {
|
||||
"hidden":true
|
||||
},
|
||||
"access" : "expert",
|
||||
"propertyOrder" : 4
|
||||
},
|
||||
"previousVersion" :
|
||||
{
|
||||
"type" : "string",
|
||||
"options" : {
|
||||
"hidden":true
|
||||
},
|
||||
"access" : "expert",
|
||||
"propertyOrder" : 5
|
||||
}
|
||||
},
|
||||
"additionalProperties" : false
|
||||
|
@ -143,6 +143,36 @@
|
||||
}
|
||||
},
|
||||
"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
|
||||
|
@ -234,11 +234,16 @@ int LedDevice::rewriteLEDs()
|
||||
return retval;
|
||||
}
|
||||
|
||||
int LedDevice::writeBlack(int numberOfBlack)
|
||||
int LedDevice::writeBlack(int numberOfWrites)
|
||||
{
|
||||
return writeColor(ColorRgb::BLACK, numberOfWrites);
|
||||
}
|
||||
|
||||
int LedDevice::writeColor(const ColorRgb& color, int numberOfWrites)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
for (int i = 0; i < numberOfBlack; i++)
|
||||
for (int i = 0; i < numberOfWrites; i++)
|
||||
{
|
||||
if (_latchTime_ms > 0)
|
||||
{
|
||||
@ -247,7 +252,7 @@ int LedDevice::writeBlack(int numberOfBlack)
|
||||
QTimer::singleShot(_latchTime_ms, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
}
|
||||
_lastLedValues = std::vector<ColorRgb>(static_cast<unsigned long>(_ledCount), ColorRgb::BLACK );
|
||||
_lastLedValues = std::vector<ColorRgb>(static_cast<unsigned long>(_ledCount),color);
|
||||
rc = write(_lastLedValues);
|
||||
}
|
||||
return rc;
|
||||
@ -411,6 +416,10 @@ void LedDevice::setLatchTime( int latchTime_ms )
|
||||
void LedDevice::setRewriteTime( int rewriteTime_ms )
|
||||
{
|
||||
assert(rewriteTime_ms >= 0);
|
||||
|
||||
//Check, if refresh timer was not initialised due to getProperties/identify sceanrios
|
||||
if (_refreshTimer != nullptr)
|
||||
{
|
||||
_refreshTimerInterval_ms = rewriteTime_ms;
|
||||
|
||||
if (_refreshTimerInterval_ms > 0)
|
||||
@ -434,6 +443,7 @@ void LedDevice::setRewriteTime( int rewriteTime_ms )
|
||||
|
||||
Debug(_log, "RewriteTime updated to %dms", _refreshTimerInterval_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void LedDevice::printLedValues(const std::vector<ColorRgb>& ledValues)
|
||||
{
|
||||
|
@ -15,6 +15,9 @@ const bool verbose = false;
|
||||
// Configuration settings
|
||||
const char CONFIG_ADDRESS[] = "host";
|
||||
const char CONFIG_RESTORE_STATE[] = "restoreOriginalState";
|
||||
const char CONFIG_BRIGHTNESS[] = "brightness";
|
||||
const char CONFIG_BRIGHTNESS_OVERWRITE[] = "overwriteBrightness";
|
||||
const char CONFIG_SYNC_OVERWRITE[] = "overwriteSync";
|
||||
|
||||
// UDP elements
|
||||
const quint16 STREAM_DEFAULT_PORT = 19446;
|
||||
@ -32,7 +35,10 @@ const char STATE_VALUE_TRUE[] = "true";
|
||||
const char STATE_VALUE_FALSE[] = "false";
|
||||
const char STATE_LIVE[] = "live";
|
||||
|
||||
const bool DEFAULT_IS_RESTORE_STATE = false;
|
||||
const bool DEFAULT_IS_BRIGHTNESS_OVERWRITE = true;
|
||||
const int BRI_MAX = 255;
|
||||
const bool DEFAULT_IS_SYNC_OVERWRITE = true;
|
||||
|
||||
constexpr std::chrono::milliseconds DEFAULT_IDENTIFY_TIME{ 2000 };
|
||||
|
||||
@ -42,6 +48,11 @@ LedDeviceWled::LedDeviceWled(const QJsonObject &deviceConfig)
|
||||
: ProviderUdp(deviceConfig)
|
||||
,_restApi(nullptr)
|
||||
,_apiPort(API_DEFAULT_PORT)
|
||||
,_isBrightnessOverwrite(DEFAULT_IS_BRIGHTNESS_OVERWRITE)
|
||||
,_brightness (BRI_MAX)
|
||||
,_isSyncOverwrite(DEFAULT_IS_SYNC_OVERWRITE)
|
||||
,_originalStateUdpnSend(false)
|
||||
,_originalStateUdpnRecv(true)
|
||||
{
|
||||
}
|
||||
|
||||
@ -70,8 +81,15 @@ bool LedDeviceWled::init(const QJsonObject &deviceConfig)
|
||||
Debug(_log, "ColorOrder : %s", QSTRING_CSTR( this->getColorOrder() ));
|
||||
Debug(_log, "LatchTime : %d", this->getLatchTime());
|
||||
|
||||
_isRestoreOrigState = _devConfig[CONFIG_RESTORE_STATE].toBool(false);
|
||||
_isRestoreOrigState = _devConfig[CONFIG_RESTORE_STATE].toBool(DEFAULT_IS_RESTORE_STATE);
|
||||
_isSyncOverwrite = _devConfig[CONFIG_SYNC_OVERWRITE].toBool(DEFAULT_IS_SYNC_OVERWRITE);
|
||||
_isBrightnessOverwrite = _devConfig[CONFIG_BRIGHTNESS_OVERWRITE].toBool(DEFAULT_IS_BRIGHTNESS_OVERWRITE);
|
||||
_brightness = _devConfig[CONFIG_BRIGHTNESS].toInt(BRI_MAX);
|
||||
|
||||
Debug(_log, "RestoreOrigState : %d", _isRestoreOrigState);
|
||||
Debug(_log, "Overwrite Sync. : %d", _isSyncOverwrite);
|
||||
Debug(_log, "Overwrite Brightn.: %d", _isBrightnessOverwrite);
|
||||
Debug(_log, "Set Brightness to : %d", _brightness);
|
||||
|
||||
//Set hostname as per configuration
|
||||
QString hostName = deviceConfig[ CONFIG_ADDRESS ].toString();
|
||||
@ -145,6 +163,13 @@ QString LedDeviceWled::getLorRequest(int lor) const
|
||||
return QString( "\"lor\":%1" ).arg(lor);
|
||||
}
|
||||
|
||||
QString LedDeviceWled::getUdpnRequest(bool isSendOn, bool isRecvOn) const
|
||||
{
|
||||
QString send = isSendOn ? STATE_VALUE_TRUE : STATE_VALUE_FALSE;
|
||||
QString recv = isRecvOn ? STATE_VALUE_TRUE : STATE_VALUE_FALSE;
|
||||
return QString( "\"udpn\":{\"send\":%1,\"recv\":%2}" ).arg(send, recv);
|
||||
}
|
||||
|
||||
bool LedDeviceWled::sendStateUpdateRequest(const QString &request)
|
||||
{
|
||||
bool rc = true;
|
||||
@ -166,7 +191,20 @@ bool LedDeviceWled::powerOn()
|
||||
//Power-on WLED device
|
||||
_restApi->setPath(API_PATH_STATE);
|
||||
|
||||
httpResponse response = _restApi->put(QString("{%1,%2}").arg(getOnOffRequest(true)).arg(getBrightnessRequest(BRI_MAX)));
|
||||
QString cmd = getOnOffRequest(true);
|
||||
|
||||
if ( _isBrightnessOverwrite)
|
||||
{
|
||||
cmd += "," + getBrightnessRequest(_brightness);
|
||||
}
|
||||
|
||||
if (_isSyncOverwrite)
|
||||
{
|
||||
Debug( _log, "Disable synchronisation with other WLED devices");
|
||||
cmd += "," + getUdpnRequest(false, false);
|
||||
}
|
||||
|
||||
httpResponse response = _restApi->put(QString("{%1}").arg(cmd));
|
||||
if ( response.error() )
|
||||
{
|
||||
QString errorReason = QString("Power-on request failed with error: '%1'").arg(response.getErrorReason());
|
||||
@ -191,7 +229,16 @@ bool LedDeviceWled::powerOff()
|
||||
|
||||
//Power-off the WLED device physically
|
||||
_restApi->setPath(API_PATH_STATE);
|
||||
httpResponse response = _restApi->put(QString("{%1}").arg(getOnOffRequest(false)));
|
||||
|
||||
QString cmd = getOnOffRequest(false);
|
||||
|
||||
if (_isSyncOverwrite)
|
||||
{
|
||||
Debug( _log, "Restore synchronisation with other WLED devices");
|
||||
cmd += "," + getUdpnRequest(_originalStateUdpnSend, _originalStateUdpnRecv);
|
||||
}
|
||||
|
||||
httpResponse response = _restApi->put(QString("{%1}").arg(cmd));
|
||||
if ( response.error() )
|
||||
{
|
||||
QString errorReason = QString("Power-off request failed with error: '%1'").arg(response.getErrorReason());
|
||||
@ -206,7 +253,7 @@ bool LedDeviceWled::storeState()
|
||||
{
|
||||
bool rc = true;
|
||||
|
||||
if ( _isRestoreOrigState )
|
||||
if ( _isRestoreOrigState || _isSyncOverwrite )
|
||||
{
|
||||
_restApi->setPath(API_PATH_STATE);
|
||||
|
||||
@ -221,6 +268,13 @@ bool LedDeviceWled::storeState()
|
||||
{
|
||||
_originalStateProperties = response.getBody().object();
|
||||
DebugIf(verbose, _log, "state: [%s]", QString(QJsonDocument(_originalStateProperties).toJson(QJsonDocument::Compact)).toUtf8().constData() );
|
||||
|
||||
QJsonObject udpn = _originalStateProperties.value("udpn").toObject();
|
||||
if (!udpn.isEmpty())
|
||||
{
|
||||
_originalStateUdpnSend = udpn["send"].toBool(false);
|
||||
_originalStateUdpnRecv = udpn["recv"].toBool(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +287,6 @@ bool LedDeviceWled::restoreState()
|
||||
|
||||
if ( _isRestoreOrigState )
|
||||
{
|
||||
//powerOff();
|
||||
_restApi->setPath(API_PATH_STATE);
|
||||
|
||||
_originalStateProperties[STATE_LIVE] = false;
|
||||
|
@ -140,9 +140,11 @@ private:
|
||||
/// @return Command to switch device on/off
|
||||
///
|
||||
QString getOnOffRequest (bool isOn ) const;
|
||||
|
||||
QString getBrightnessRequest (int bri ) const;
|
||||
QString getEffectRequest(int effect, int speed=128) const;
|
||||
QString getLorRequest(int lor) const;
|
||||
QString getUdpnRequest(bool send, bool recv) const;
|
||||
|
||||
bool sendStateUpdateRequest(const QString &request);
|
||||
|
||||
@ -154,6 +156,12 @@ private:
|
||||
|
||||
QJsonObject _originalStateProperties;
|
||||
|
||||
bool _isBrightnessOverwrite;
|
||||
int _brightness;
|
||||
|
||||
bool _isSyncOverwrite;
|
||||
bool _originalStateUdpnSend;
|
||||
bool _originalStateUdpnRecv;
|
||||
};
|
||||
|
||||
#endif // LEDDEVICEWLED_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "LedDeviceYeelight.h"
|
||||
#include "LedDeviceYeelight.h"
|
||||
|
||||
#include <ssdp/SSDPDiscover.h>
|
||||
#include <utils/QStringUtils.h>
|
||||
@ -1018,10 +1018,9 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
|
||||
|
||||
//Get device specific configuration
|
||||
|
||||
bool ok;
|
||||
if ( deviceConfig[ CONFIG_COLOR_MODEL ].isString() )
|
||||
{
|
||||
_outputColorModel = deviceConfig[ CONFIG_COLOR_MODEL ].toString().toInt(&ok,MODEL_RGB);
|
||||
_outputColorModel = deviceConfig[ CONFIG_COLOR_MODEL ].toString(QString(MODEL_RGB)).toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1030,7 +1029,7 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
|
||||
|
||||
if ( deviceConfig[ CONFIG_TRANS_EFFECT ].isString() )
|
||||
{
|
||||
_transitionEffect = static_cast<YeelightLight::API_EFFECT>( deviceConfig[ CONFIG_TRANS_EFFECT ].toString().toInt(&ok, YeelightLight::API_EFFECT_SMOOTH) );
|
||||
_transitionEffect = static_cast<YeelightLight::API_EFFECT>( deviceConfig[ CONFIG_TRANS_EFFECT ].toString(QString(YeelightLight::API_EFFECT_SMOOTH)).toInt() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1047,7 +1046,7 @@ bool LedDeviceYeelight::init(const QJsonObject &deviceConfig)
|
||||
|
||||
if ( deviceConfig[ CONFIG_DEBUGLEVEL ].isString() )
|
||||
{
|
||||
_debuglevel = deviceConfig[ CONFIG_DEBUGLEVEL ].toString().toInt();
|
||||
_debuglevel = deviceConfig[ CONFIG_DEBUGLEVEL ].toString(QString("0")).toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4,11 +4,22 @@
|
||||
#include <csignal>
|
||||
|
||||
// QT includes
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
|
||||
// Local LedDevice includes
|
||||
#include "LedDevicePiBlaster.h"
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
const bool verbose = false;
|
||||
|
||||
// Pi-Blaster discovery service
|
||||
const char DISCOVERY_DIRECTORY[] = "/dev/";
|
||||
const char DISCOVERY_FILEPATTERN[] = "pi-blaster";
|
||||
|
||||
} //End of constants
|
||||
|
||||
LedDevicePiBlaster::LedDevicePiBlaster(const QJsonObject &deviceConfig)
|
||||
: LedDevice(deviceConfig)
|
||||
, _fid(nullptr)
|
||||
@ -184,3 +195,31 @@ int LedDevicePiBlaster::write(const std::vector<ColorRgb> & ledValues)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QJsonObject LedDevicePiBlaster::discover(const QJsonObject& /*params*/)
|
||||
{
|
||||
QJsonObject devicesDiscovered;
|
||||
devicesDiscovered.insert("ledDeviceType", _activeDeviceType );
|
||||
|
||||
QJsonArray deviceList;
|
||||
|
||||
QDir deviceDirectory (DISCOVERY_DIRECTORY);
|
||||
QStringList deviceFilter(DISCOVERY_FILEPATTERN);
|
||||
deviceDirectory.setNameFilters(deviceFilter);
|
||||
deviceDirectory.setSorting(QDir::Name);
|
||||
QFileInfoList deviceFiles = deviceDirectory.entryInfoList(QDir::System);
|
||||
|
||||
QFileInfoList::const_iterator deviceFileIterator;
|
||||
for (deviceFileIterator = deviceFiles.constBegin(); deviceFileIterator != deviceFiles.constEnd(); ++deviceFileIterator)
|
||||
{
|
||||
QJsonObject deviceInfo;
|
||||
deviceInfo.insert("deviceName", (*deviceFileIterator).fileName());
|
||||
deviceInfo.insert("systemLocation", (*deviceFileIterator).absoluteFilePath());
|
||||
deviceList.append(deviceInfo);
|
||||
}
|
||||
devicesDiscovered.insert("devices", deviceList);
|
||||
|
||||
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
|
||||
return devicesDiscovered;
|
||||
}
|
||||
|
@ -29,6 +29,12 @@ public:
|
||||
/// @return LedDevice constructed
|
||||
static LedDevice* construct(const QJsonObject &deviceConfig);
|
||||
|
||||
/// @param[in] params Parameters used to overwrite discovery default behaviour
|
||||
///
|
||||
/// @return A JSON structure holding a list of devices found
|
||||
///
|
||||
QJsonObject discover(const QJsonObject& params) override;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
|
@ -2,6 +2,7 @@
|
||||
// LedDevice includes
|
||||
#include <leddevice/LedDevice.h>
|
||||
#include "ProviderRs232.h"
|
||||
#include <utils/WaitTime.h>
|
||||
|
||||
// qt includes
|
||||
#include <QSerialPortInfo>
|
||||
@ -10,11 +11,17 @@
|
||||
#include <chrono>
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
const bool verbose = false;
|
||||
|
||||
constexpr std::chrono::milliseconds WRITE_TIMEOUT{ 1000 }; // device write timeout in ms
|
||||
constexpr std::chrono::milliseconds OPEN_TIMEOUT{ 5000 }; // device open timeout in ms
|
||||
const int MAX_WRITE_TIMEOUTS = 5; // Maximum number of allowed timeouts
|
||||
const int NUM_POWEROFF_WRITE_BLACK = 2; // Number of write "BLACK" during powering off
|
||||
|
||||
constexpr std::chrono::milliseconds DEFAULT_IDENTIFY_TIME{ 500 };
|
||||
} //End of constants
|
||||
|
||||
ProviderRs232::ProviderRs232(const QJsonObject &deviceConfig)
|
||||
: LedDevice(deviceConfig)
|
||||
, _rs232Port(this)
|
||||
@ -278,7 +285,7 @@ QJsonObject ProviderRs232::discover(const QJsonObject& /*params*/)
|
||||
// Discover serial Devices
|
||||
for (auto &port : QSerialPortInfo::availablePorts() )
|
||||
{
|
||||
if ( !port.isNull() && !port.portName().startsWith("ttyS"))
|
||||
if ( !port.isNull() && port.vendorIdentifier() != 0)
|
||||
{
|
||||
QJsonObject portInfo;
|
||||
portInfo.insert("description", port.description());
|
||||
@ -294,5 +301,39 @@ QJsonObject ProviderRs232::discover(const QJsonObject& /*params*/)
|
||||
}
|
||||
|
||||
devicesDiscovered.insert("devices", deviceList);
|
||||
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
|
||||
return devicesDiscovered;
|
||||
}
|
||||
|
||||
void ProviderRs232::identify(const QJsonObject& params)
|
||||
{
|
||||
DebugIf(verbose,_log, "params: [%s]", QString(QJsonDocument(params).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
|
||||
QString deviceName = params["output"].toString("");
|
||||
if (!deviceName.isEmpty())
|
||||
{
|
||||
_devConfig = params;
|
||||
init(_devConfig);
|
||||
{
|
||||
if ( open() == 0 )
|
||||
{
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (writeColor(ColorRgb::RED) == 0)
|
||||
{
|
||||
wait(DEFAULT_IDENTIFY_TIME);
|
||||
|
||||
writeColor(ColorRgb::BLACK);
|
||||
wait(DEFAULT_IDENTIFY_TIME);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,20 @@ public:
|
||||
///
|
||||
~ProviderRs232() override;
|
||||
|
||||
///
|
||||
/// @brief Send an update to the RS232 device to identify it.
|
||||
///
|
||||
/// Following parameters are required
|
||||
/// @code
|
||||
/// {
|
||||
/// "deviceConfig" :
|
||||
/// }
|
||||
///@endcode
|
||||
///
|
||||
/// @param[in] params Parameters to configure device
|
||||
///
|
||||
void identify(const QJsonObject& params) override;
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
|
@ -14,6 +14,19 @@
|
||||
#include "ProviderSpi.h"
|
||||
#include <utils/Logger.h>
|
||||
|
||||
// qt includes
|
||||
#include <QDir>
|
||||
|
||||
// Constants
|
||||
namespace {
|
||||
const bool verbose = false;
|
||||
|
||||
// SPI discovery service
|
||||
const char DISCOVERY_DIRECTORY[] = "/dev/";
|
||||
const char DISCOVERY_FILEPATTERN[] = "spidev*";
|
||||
|
||||
} //End of constants
|
||||
|
||||
ProviderSpi::ProviderSpi(const QJsonObject &deviceConfig)
|
||||
: LedDevice(deviceConfig)
|
||||
, _deviceName("/dev/spidev0.0")
|
||||
@ -148,3 +161,31 @@ int ProviderSpi::writeBytes(unsigned size, const uint8_t * data)
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
QJsonObject ProviderSpi::discover(const QJsonObject& /*params*/)
|
||||
{
|
||||
QJsonObject devicesDiscovered;
|
||||
devicesDiscovered.insert("ledDeviceType", _activeDeviceType );
|
||||
|
||||
QJsonArray deviceList;
|
||||
|
||||
QDir deviceDirectory (DISCOVERY_DIRECTORY);
|
||||
QStringList deviceFilter(DISCOVERY_FILEPATTERN);
|
||||
deviceDirectory.setNameFilters(deviceFilter);
|
||||
deviceDirectory.setSorting(QDir::Name);
|
||||
QFileInfoList deviceFiles = deviceDirectory.entryInfoList(QDir::System);
|
||||
|
||||
QFileInfoList::const_iterator deviceFileIterator;
|
||||
for (deviceFileIterator = deviceFiles.constBegin(); deviceFileIterator != deviceFiles.constEnd(); ++deviceFileIterator)
|
||||
{
|
||||
QJsonObject deviceInfo;
|
||||
deviceInfo.insert("deviceName", (*deviceFileIterator).fileName().remove(0,6));
|
||||
deviceInfo.insert("systemLocation", (*deviceFileIterator).absoluteFilePath());
|
||||
deviceList.append(deviceInfo);
|
||||
}
|
||||
devicesDiscovered.insert("devices", deviceList);
|
||||
|
||||
DebugIf(verbose,_log, "devicesDiscovered: [%s]", QString(QJsonDocument(devicesDiscovered).toJson(QJsonDocument::Compact)).toUtf8().constData());
|
||||
|
||||
return devicesDiscovered;
|
||||
}
|
||||
|
@ -36,6 +36,12 @@ public:
|
||||
///
|
||||
int open() override;
|
||||
|
||||
/// @param[in] params Parameters used to overwrite discovery default behaviour
|
||||
///
|
||||
/// @return A JSON structure holding a list of devices found
|
||||
///
|
||||
QJsonObject discover(const QJsonObject& params) override;
|
||||
|
||||
public slots:
|
||||
///
|
||||
/// Closes the output device.
|
||||
|
@ -27,6 +27,7 @@
|
||||
"type": "boolean",
|
||||
"title": "edt_dev_spec_LBap102Mode_title",
|
||||
"default": false,
|
||||
"required": true,
|
||||
"access": "advanced",
|
||||
"propertyOrder": 4
|
||||
},
|
||||
@ -38,6 +39,9 @@
|
||||
"minimum": 0,
|
||||
"maximum": 1000,
|
||||
"access": "expert",
|
||||
"options": {
|
||||
"infoText": "edt_dev_spec_latchtime_title_info"
|
||||
},
|
||||
"propertyOrder": 5
|
||||
},
|
||||
"rewriteTime": {
|
||||
|
@ -5,8 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"default" : "/dev/spidev0.0",
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -5,6 +5,7 @@
|
||||
"orbIds": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_orbIds_title",
|
||||
"minLength": 1,
|
||||
"default": "",
|
||||
"propertyOrder": 1
|
||||
},
|
||||
|
@ -2,10 +2,25 @@
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"properties": {
|
||||
"hostList": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_devices_discovered_title",
|
||||
"enum": [ "NONE" ],
|
||||
"options": {
|
||||
"enum_titles": [ "edt_dev_spec_devices_discovery_inprogress" ],
|
||||
"infoText": "edt_dev_spec_devices_discovered_title_info"
|
||||
},
|
||||
"required": true,
|
||||
"propertyOrder": 1
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_targetIpHost_title",
|
||||
"propertyOrder" : 1
|
||||
"options": {
|
||||
"infoText": "edt_dev_spec_targetIpHost_title_info"
|
||||
},
|
||||
"required": true,
|
||||
"propertyOrder": 2
|
||||
},
|
||||
"latchTime": {
|
||||
"type": "integer",
|
||||
@ -15,7 +30,10 @@
|
||||
"minimum": 0,
|
||||
"maximum": 1000,
|
||||
"access": "expert",
|
||||
"propertyOrder" : 2
|
||||
"options": {
|
||||
"infoText": "edt_dev_spec_latchtime_title_info"
|
||||
},
|
||||
"propertyOrder": 3
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -2,47 +2,67 @@
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"properties": {
|
||||
"hostList": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_devices_discovered_title",
|
||||
"enum": [ "NONE" ],
|
||||
"options": {
|
||||
"enum_titles": [ "edt_dev_spec_devices_discovery_inprogress" ],
|
||||
"infoText": "edt_dev_spec_devices_discovered_title_info"
|
||||
},
|
||||
"required": true,
|
||||
"propertyOrder": 1
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_targetIpHost_title",
|
||||
"propertyOrder" : 1
|
||||
"options": {
|
||||
"infoText": "edt_dev_spec_targetIpHost_title_info"
|
||||
},
|
||||
"required": true,
|
||||
"propertyOrder": 2
|
||||
},
|
||||
"token": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_auth_key_title",
|
||||
"propertyOrder" : 2
|
||||
"options": {
|
||||
"infoText": "edt_dev_auth_key_title_info"
|
||||
},
|
||||
"propertyOrder": 4
|
||||
},
|
||||
"title": {
|
||||
"type": "object",
|
||||
"title": "edt_dev_spec_panelorganisation_title",
|
||||
"access": "advanced",
|
||||
"propertyOrder" : 3
|
||||
"propertyOrder": 5
|
||||
},
|
||||
"panelOrderTopDown": {
|
||||
"type": "integer",
|
||||
"title": "edt_dev_spec_order_top_down_title",
|
||||
"enum": [ 0, 1 ],
|
||||
"default": 0,
|
||||
"required": true,
|
||||
"options": {
|
||||
"enum_titles": [ "edt_conf_enum_top_down", "edt_conf_enum_bottom_up" ]
|
||||
},
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"access": "advanced",
|
||||
"propertyOrder" : 4
|
||||
"propertyOrder": 6
|
||||
},
|
||||
"panelOrderLeftRight": {
|
||||
"type": "integer",
|
||||
"title": "edt_dev_spec_order_left_right_title",
|
||||
"enum": [ 0, 1 ],
|
||||
"default": 0,
|
||||
"required": true,
|
||||
"options": {
|
||||
"enum_titles": [ "edt_conf_enum_left_right", "edt_conf_enum_right_left" ]
|
||||
},
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"access": "advanced",
|
||||
"propertyOrder" : 5
|
||||
"propertyOrder": 7
|
||||
},
|
||||
"panelStartPos": {
|
||||
"type": "integer",
|
||||
@ -51,7 +71,7 @@
|
||||
"minimum": 0,
|
||||
"default": 0,
|
||||
"access": "advanced",
|
||||
"propertyOrder" : 6
|
||||
"propertyOrder": 8
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -58,11 +58,12 @@
|
||||
"lightIds": {
|
||||
"type": "array",
|
||||
"title": "edt_dev_spec_lightid_title",
|
||||
"minItems": 1,
|
||||
"minimum": 1,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minimum" : 0,
|
||||
"minLength": 1,
|
||||
"required": true,
|
||||
"title": "edt_dev_spec_lightid_itemtitle"
|
||||
},
|
||||
"options": {
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"default" : "/dev/spidev0.0",
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
|
@ -1,19 +1,70 @@
|
||||
{
|
||||
"type": "object",
|
||||
"title": "",
|
||||
"required": true,
|
||||
"properties": {
|
||||
"host" : {
|
||||
"hostList": {
|
||||
"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,
|
||||
"propertyOrder": 1
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_targetIpHost_title",
|
||||
"options": {
|
||||
"infoText": "edt_dev_spec_targetIpHost_title_info"
|
||||
},
|
||||
"required": true,
|
||||
"propertyOrder": 2
|
||||
},
|
||||
"restoreOriginalState": {
|
||||
"type": "boolean",
|
||||
"format": "checkbox",
|
||||
"title": "edt_dev_spec_restoreOriginalState_title",
|
||||
"default": false,
|
||||
"required": true,
|
||||
"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": {
|
||||
"type": "integer",
|
||||
@ -23,7 +74,10 @@
|
||||
"minimum": 0,
|
||||
"maximum": 1000,
|
||||
"access": "expert",
|
||||
"propertyOrder" : 3
|
||||
"options": {
|
||||
"infoText": "edt_dev_spec_latchtime_title_info"
|
||||
},
|
||||
"propertyOrder": 7
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1","/dev/spidev1.0","/dev/spidev1.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -5,7 +5,6 @@
|
||||
"output": {
|
||||
"type": "string",
|
||||
"title":"edt_dev_spec_spipath_title",
|
||||
"enum" : ["/dev/spidev0.0","/dev/spidev0.1"],
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"rate": {
|
||||
|
@ -3,10 +3,10 @@
|
||||
"required": true,
|
||||
"properties": {
|
||||
"colorModel": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"title": "Output Type",
|
||||
"enum" : [0, 1],
|
||||
"default" : 1,
|
||||
"enum": [ "0", "1" ],
|
||||
"default": "1",
|
||||
"options": {
|
||||
"enum_titles": [ "edt_conf_enum_hsv", "edt_conf_enum_rgb" ]
|
||||
},
|
||||
@ -16,10 +16,10 @@
|
||||
"propertyOrder": 1
|
||||
},
|
||||
"transEffect": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_transeffect_title",
|
||||
"enum" : [0, 1],
|
||||
"default" : 0,
|
||||
"enum": [ "0", "1" ],
|
||||
"default": "0",
|
||||
"options": {
|
||||
"enum_titles": [ "edt_conf_enum_transeffect_smooth", "edt_conf_enum_transeffect_sudden" ]
|
||||
},
|
||||
@ -109,18 +109,15 @@
|
||||
"type": "object",
|
||||
"title": "edt_dev_spec_lights_itemtitle",
|
||||
"required": true,
|
||||
"properties" :
|
||||
{
|
||||
"host" :
|
||||
{
|
||||
"properties": {
|
||||
"host": {
|
||||
"type": "string",
|
||||
"minimum" : 7,
|
||||
"minLength": 7,
|
||||
"title": "edt_dev_spec_networkDeviceName_title",
|
||||
"required": true,
|
||||
"propertyOrder": 1
|
||||
},
|
||||
"port" :
|
||||
{
|
||||
"port": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
@ -130,8 +127,7 @@
|
||||
"access": "expert",
|
||||
"propertyOrder": 2
|
||||
},
|
||||
"name" :
|
||||
{
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_lights_name",
|
||||
"minimum": 0,
|
||||
@ -163,10 +159,10 @@
|
||||
"propertyOrder": 12
|
||||
},
|
||||
"debugLevel": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"title": "edt_dev_spec_debugLevel_title",
|
||||
"enum" : [0, 1, 2, 3],
|
||||
"default" : 0,
|
||||
"enum": [ "0", "1", "2", "3" ],
|
||||
"default": "0",
|
||||
"options": {
|
||||
"enum_titles": [ "edt_conf_enum_dl_nodebug", "edt_conf_enum_dl_verbose1", "edt_conf_enum_dl_verbose2", "edt_conf_enum_dl_verbose3" ]
|
||||
},
|
||||
|
@ -96,8 +96,8 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo
|
||||
qRegisterMetaType<QMap<quint8, QJsonObject>>("QMap<quint8,QJsonObject>");
|
||||
qRegisterMetaType<std::vector<ColorRgb>>("std::vector<ColorRgb>");
|
||||
|
||||
// init settings
|
||||
_settingsManager = new SettingsManager(0, this, readonlyMode);
|
||||
// init settings, this settingsManager accesses global settings which are independent from instances
|
||||
_settingsManager = new SettingsManager(GLOABL_INSTANCE_ID, this, readonlyMode);
|
||||
|
||||
// set inital log lvl if the loglvl wasn't overwritten by arg
|
||||
if (!logLvlOverwrite)
|
||||
|
Loading…
Reference in New Issue
Block a user