mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-04-20 11:02:14 +02:00
The RTW decoder formula encKey - 133 was off by one versus the RTW encoder (which maps command N to encKey N + 132). This caused every non-My RTW command to decode as the wrong button (e.g. Up decoded as My, Down as MyUp). Also adds rawCmd diagnostic field to received frames for protocol debugging.
1119 lines
86 KiB
HTML
1119 lines
86 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta charset="UTF-8">
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-title" content="ESPSomfy RTS App">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
|
|
<link rel="stylesheet" href="main.css?v=3.0.11c" type="text/css" />
|
|
<link rel="stylesheet" href="widgets.css?v=3.0.11c" type="text/css" />
|
|
<link rel="stylesheet" href="icons.css?v=3.0.11c" type="text/css" />
|
|
<link rel="icon" type="image/png" href="favicon.png" />
|
|
|
|
<!-- iPad retina icon -->
|
|
<link href="apple-icon.png"
|
|
sizes="152x152"
|
|
rel="apple-touch-icon-precomposed">
|
|
|
|
<!-- iPad retina icon (iOS < 7) -->
|
|
<link href="apple-icon.png"
|
|
sizes="144x144"
|
|
rel="apple-touch-icon-precomposed">
|
|
|
|
<!-- iPad non-retina icon -->
|
|
<link href="apple-icon.png"
|
|
sizes="76x76"
|
|
rel="apple-touch-icon-precomposed">
|
|
|
|
<!-- iPad non-retina icon (iOS < 7) -->
|
|
<link href="apple-icon.png"
|
|
sizes="72x72"
|
|
rel="apple-touch-icon-precomposed">
|
|
|
|
<!-- iPhone 6 Plus icon -->
|
|
<link href="apple-icon.png"
|
|
sizes="120x120"
|
|
rel="apple-touch-icon-precomposed">
|
|
|
|
<!-- iPhone retina icon (iOS < 7) -->
|
|
<link href="apple-icon.png"
|
|
sizes="114x114"
|
|
rel="apple-touch-icon-precomposed">
|
|
|
|
<!-- iPhone non-retina icon (iOS < 7) -->
|
|
<link href="apple-icon.png"
|
|
sizes="57x57"
|
|
rel="apple-touch-icon-precomposed">
|
|
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 768px) and (device-height: 1024px)
|
|
and (-webkit-device-pixel-ratio: 2)
|
|
and (orientation: portrait)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPad retina landscape startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 768px) and (device-height: 1024px)
|
|
and (-webkit-device-pixel-ratio: 2)
|
|
and (orientation: landscape)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPad non-retina portrait startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 768px) and (device-height: 1024px)
|
|
and (-webkit-device-pixel-ratio: 1)
|
|
and (orientation: portrait)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPad non-retina landscape startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 768px) and (device-height: 1024px)
|
|
and (-webkit-device-pixel-ratio: 1)
|
|
and (orientation: landscape)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPhone 6 Plus portrait startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 414px) and (device-height: 736px)
|
|
and (-webkit-device-pixel-ratio: 3)
|
|
and (orientation: portrait)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPhone 6 Plus landscape startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 414px) and (device-height: 736px)
|
|
and (-webkit-device-pixel-ratio: 3)
|
|
and (orientation: landscape)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPhone 6 startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 375px) and (device-height: 667px)
|
|
and (-webkit-device-pixel-ratio: 2)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPhone 5 startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 320px) and (device-height: 568px)
|
|
and (-webkit-device-pixel-ratio: 2)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPhone < 5 retina startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 320px) and (device-height: 480px)
|
|
and (-webkit-device-pixel-ratio: 2)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
<!-- iPhone < 5 non-retina startup image -->
|
|
<link href="apple-icon.png"
|
|
media="(device-width: 320px) and (device-height: 480px)
|
|
and (-webkit-device-pixel-ratio: 1)"
|
|
rel="apple-touch-startup-image">
|
|
|
|
|
|
<script type="text/javascript" src="index.js?v=3.0.11c"></script>
|
|
</head>
|
|
<body>
|
|
<div id="divContainer" class="container main" data-auth="false">
|
|
<div id="divAuthenticated" style="display:none;">
|
|
<div id="divFirmwareUpdate" class="firmware-message" style="display:none;">Firmware Update Available</div>
|
|
<div id="divRadioError" class="header-message">Radio Not Initialized</div>
|
|
<h1 style="text-align: center;"><img src="icon.png" style="width:50px;float:left;margin-left:1px;margin-top:-10px;" /><span>ESPSomfy RTS</span><span class="button-outline" onclick="ui.toggleConfig();" style="float:right;font-size:1.25rem;display:inline-block;vertical-align:middle;width:38px;height:38px;position:relative;padding-top:4px;"><span style="vertical-align:middle;clear:both;text-align:center;display:inline-block;"><i id="icoConfig" class="icss-gear" style=""></i></span></span></h1>
|
|
<div id="divConfigPnl" style="display:none;">
|
|
<div id="divWiFiStrength" style="margin-top:-10px;text-align:center;font-size:12px;">
|
|
<div style="display:inline-block;vertical-align:middle;">
|
|
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Network:</span><span id="spanNetworkSSID" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">-------------</span></div>
|
|
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Channel:</span><span id="spanNetworkChannel" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">--</span></div>
|
|
</div>
|
|
<div id="divNetworkStrength" class="wifiSignal" style="display:inline-block;vertical-align:middle;">
|
|
</div>
|
|
<div style="position:absolute;display:inline-block;">
|
|
<div style="position:relative;border:solid 1px silver;background-color:cornsilk;padding:2px;font-size:12px;box-shadow: 0 3px 5px rgba(0,0,0,0.19), 0 2px 2px rgba(0,0,0,0.23);float:right;border-radius:4px;margin-left:-4px;"><span id="spanNetworkStrength">---</span><span>dBm</span></div>
|
|
</div>
|
|
</div>
|
|
<div id="divEthernetStatus" style="margin-top:-10px;text-align:center;font-size:12px;display:none;">
|
|
<div style="display:inline-block;vertical-align:middle;">
|
|
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Status:</span><span id="spanEthernetStatus" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">-------------</span></div>
|
|
<div><span style="text-align:right;display:inline-block;width:57px;color:#00bcd4">Speed:</span><span id="spanEthernetSpeed" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">--</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="tab-container"><span class="selected" data-grpid="divSystemSettings">System</span><span data-grpid="divNetworkSettings">Network</span><span data-grpid="divSomfySettings">Somfy</span><span data-grpid="divRadioSettings">Radio</span></div>
|
|
<div id="divSystemSettings" class="tab-content">
|
|
<div class="subtab-container"><span class="selected" data-grpid="divSystemOptions">Options</span><span data-grpid="divSecurityOptions">Security</span><span data-grpid="divFirmware">Firmware</span></div>
|
|
<div id="divSystemOptions" class="subtab-content">
|
|
<div class="field-group">
|
|
<input id="fldHostname" name="hostname" type="text" data-bind="general.hostname" length=32 placeholder="Host Name">
|
|
<label for="fldHostname">Host Name</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<select id="selTimeZone" name="timeZone" placeholder="Time Zone" data-bind="general.posixZone" style="width:100%;"></select>
|
|
<label for="selTimeZone">Time Zone</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldNtptimesever" name="ntptimeserver" type="text" length=32 data-bind="general.ntpServer" placeholder="Time Server">
|
|
<label for="fldNtptimeserver">NTP Time Server</label>
|
|
</div>
|
|
<div class="field-group" style="vertical-align:middle;">
|
|
<input id="cbSsdpBroadcast" name="ssdpBroadcast" type="checkbox" data-bind="general.ssdpBroadcast" style="display:inline-block;" />
|
|
<label for="cbSsdpBroadcast" style="display:inline-block;cursor:pointer;">Broadcast uPnP over SSDP</label>
|
|
</div>
|
|
<div class="field-group" style="margin-top:-12px;">
|
|
<input id="cbCheckForUpdate" type="checkbox" data-bind="general.checkForUpdate" style="display:inline-block;" />
|
|
<label for="cbCheckForUpdate" style="display:inline-block;cursor:pointer;">Auto Check for Updates</label>
|
|
</div>
|
|
<div class="button-container">
|
|
<button id="btnSaveGeneral" type="button" onclick="general.setGeneral();">
|
|
Save
|
|
</button>
|
|
</div>
|
|
<div class="button-container">
|
|
<button id="btnReboot" type="button" onclick="general.rebootDevice();">
|
|
Reboot
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="divSecurityOptions" class="subtab-content" style="display:none;">
|
|
<div>
|
|
<div class="field-group" style="display:inline-block;width:100px;vertical-align:middle;">
|
|
<select data-bind="security.type" onchange="general.onSecurityTypeChanged();" data-datatype="int" style="width:100%;">
|
|
<option value="0" selected>None</option>
|
|
<option value="1">Pin Entry</option>
|
|
<option value="2">Password</option>
|
|
</select>
|
|
<label for="fldPinEntry">Security Type</label>
|
|
</div>
|
|
<div id="divPermissions" class="field-group" style="display:none;vertical-align:middle;float:right;width:auto;">
|
|
<input id="cbSecureConfigOnly" data-bind="security.permissions.configOnly" type="checkbox" style="display:inline-block;" />
|
|
<label for="cbSecureConfigOnly" style="display:inline-block;cursor:pointer;">Secure Config Only</label>
|
|
</div>
|
|
</div>
|
|
<div id="divPinSecurity" style="display:none;">
|
|
<div class="field-group" style="text-align:center;">
|
|
<div id="fldPinEntry" style="display:inline-block;" onkeydown="ui.pinKeyPressed(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="security.pin.d0" onfocus="ui.pinDigitFocus(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="security.pin.d1" onfocus="ui.pinDigitFocus(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="security.pin.d2" onfocus="ui.pinDigitFocus(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="security.pin.d3" onfocus="ui.pinDigitFocus(event);">
|
|
</div>
|
|
<label for="fldPinEntry" style="margin-top:7px;">Enter Pin</label>
|
|
</div>
|
|
</div>
|
|
<div id="divPasswordSecurity" style="display:none;">
|
|
<div class="field-group">
|
|
<input id="fldUsername" name="username" type="text" data-bind="security.username" length=32 placeholder="Username">
|
|
<label for="fldUsername">Username</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldPassword" name="password" type="password" data-bind="security.password" length=32 placeholder="Password">
|
|
<label for="fldPassword">Password</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldReenterPassword" name="password" type="password" data-bind="security.repeatpassword" length=32 placeholder="Re-enter Password">
|
|
<label for="fldRenterPassword">Re-enter Password</label>
|
|
</div>
|
|
</div>
|
|
<div class="button-container">
|
|
<button id="btnLogin" type="button" value="Submit" onclick="general.saveSecurity();">
|
|
Save Security
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="divFirmware" class="subtab-content" style="display:none;padding-top:10px;">
|
|
<div style="display:inline-block">
|
|
<div style="font-size:17px;">
|
|
<span style="text-align:right;display:inline-block;color:#00bcd4;width:127px;margin-top:-27px;">Hardware: </span>
|
|
<span style="padding-left: 4px; display: inline-block;">ESP32<span id="spanHwVersion" style="text-transform:uppercase; text-align:left;width:120px;"></span></span>
|
|
</div>
|
|
<div style="font-size:17px;">
|
|
<span style="text-align:right;display:inline-block;color:#00bcd4;width:127px;margin-top:-27px;">Firmware:</span>
|
|
<span id="spanFwVersion" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">v-.--</span>
|
|
</div>
|
|
<div style="font-size:17px;">
|
|
<span style="text-align:right;display:inline-block;color:#00bcd4;width:127px;">Application:</span>
|
|
<span id="spanAppVersion" style="padding-left:4px;display:inline-block;text-align:left;width:120px;">v-.--</span>
|
|
</div>
|
|
</div>
|
|
<div style="display:inline-block;font-size:12px;padding-top:10px;padding-left:37px;">
|
|
<div style="color: #00bcd4;">Memory (bytes)</div>
|
|
<div style="font-size:12px;display:inline-block;">
|
|
<span style="text-align:right;display:inline-block;color:#00bcd4;">Free: </span>
|
|
<span id="spanFreeMemory" style="text-align:right;width:120px;"></span>
|
|
<span style="text-align:right;display:inline-block;color:#00bcd4;">Max: </span>
|
|
<span id="spanMaxMemory" style="text-align:right;width:120px;"></span>
|
|
<span style="text-align:right;display:inline-block;color:#00bcd4;">Min: </span>
|
|
<span id="spanMinMemory" style="text-align:right;width:120px;"></span>
|
|
<span style="text-align:right;display:inline-block;color:#00bcd4;">Uptime: </span>
|
|
<span id="spanUptime" style="text-align:right;width:120px;"></span>
|
|
</div>
|
|
</div>
|
|
<div class="button-container">
|
|
<button id="btnUpdateGithub" type="button" onclick="firmware.updateGithub();">
|
|
<i class="icss-github-o" style="font-size:1.7em;margin-top:-14px;margin-bottom:-10px;margin-right:7px;"></i><span>Github Update</span>
|
|
</button>
|
|
<button id="btnUpdateFirmware" type="button" onclick="firmware.updateFirmware();">
|
|
Update Firmware
|
|
</button>
|
|
<button id="btnUpdateApplication" type="button" onclick="firmware.updateApplication();">
|
|
Update Application
|
|
</button>
|
|
<button id="btnReloadApplication" type="button" onclick="general.reload();">
|
|
Refresh Cache
|
|
</button>
|
|
<div class="button-container" style="text-align:center;">
|
|
<button id="btnBackup" style="width:47%;display:inline-block;" type="button" onclick="firmware.backup();">
|
|
Backup
|
|
</button>
|
|
<button id="btnRestore" style="width:47%;display:inline-block;" type="button" onclick="firmware.restore();">
|
|
Restore
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divNetworkSettings" style="display:none;">
|
|
<div class="subtab-container"><span class="selected" data-grpid="divNetAdapter">Adapter</span><span data-grpid="divDHCP">DHCP/Static IP</span><span data-grpid="divMQTT">MQTT</span></div>
|
|
<div id="divNetAdapter" class="subtab-content">
|
|
<div class="field-group" style="vertical-align:middle;color:#00bcd4;margin-top:-24px;">
|
|
<input id="cbHardwired" name="hardwired" data-bind="ethernet.hardwired" type="checkbox" style="display:inline-block;" onclick="wifi.useEthernetClicked();" />
|
|
<label for="cbHardwired" style="display:inline-block;cursor:pointer;">Use Ethernet</label>
|
|
<div id="divFallbackWireless" style="display:inline-block;padding-left:7px;">
|
|
<input id="cbFallbackWireless" name="fallbackwireless" data-bind="ethernet.wirelessFallback" type="checkbox" style="display:inline-block;" />
|
|
<label for="cbFallbackWireless" style="display:inline-block;cursor:pointer;">Fallback to Wireless</label>
|
|
</div>
|
|
</div>
|
|
<div class="field-group" style="vertical-align:middle;color:#00bcd4;margin-top:-12px;margin-bottom:18px;">
|
|
<div id="divHiddenSSID" style="display:inline-block;">
|
|
<input id="cbHiddenSSID" data-bind="wifi.hidden" type="checkbox" style="display:inline-block;" onclick="wifi.hiddenSSIDClicked();" />
|
|
<label for="cbHiddenSSID" style="display:inline-block;cursor:pointer;">Use Hidden SSID</label>
|
|
</div>
|
|
<div id="divRoaming" style="display:inline-block;padding-left:7px;">
|
|
<input id="cbRoaming" name="roaming" data-bind="wifi.roaming" type="checkbox" style="display:inline-block;" />
|
|
<label for="cbRoaming" style="display:inline-block;cursor:pointer;">Enable Roaming</label>
|
|
</div>
|
|
|
|
</div>
|
|
<div id="divWiFiMode">
|
|
<form method="post" action="/scan">
|
|
<div id="divAps" data-lastloaded="0" style="border-radius:5px;border:solid 1px #00bcd4;margin-bottom:-10px;"></div>
|
|
<div class="button-container"><button id="btnScanAPs" type="button" onclick="wifi.loadAPs();">Scan</button></div>
|
|
<div class="field-group">
|
|
<input id="fldSsid" name="ssid" type="text" data-bind="wifi.ssid" length=32 placeholder="SSID">
|
|
<label for="fldSsid">Network SSID</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldPassphrase" name="passphrase" type="password" data-bind="wifi.passphrase" length=32 placeholder="Passphrase">
|
|
<label for="fldPassphrase">Passphrase</label>
|
|
</div>
|
|
|
|
</form>
|
|
</div>
|
|
<div id="divEthernetMode" style="display:none;">
|
|
<div class="field-group">
|
|
<select id="selETHBoardType" name="ethBoardType" placeholder="Board Type" data-datatype="int" data-bind="ethernet.boardType" style="width:100%;" onchange="wifi.onETHBoardTypeChanged(this);"></select>
|
|
<label for="selETHBoardType">Board Type</label>
|
|
</div>
|
|
<div id="divETHSettings">
|
|
<div class="field-group" style="width:40%;margin-right:7px;display:inline-block;">
|
|
<select id="selETHPhyType" name="ethphytype" placeholder="PHY Type" data-datatype="int" data-bind="ethernet.phyType" style="width:100%;"></select>
|
|
<label for="selETHPhyType">PHY Chip Type</label>
|
|
</div>
|
|
<div class="field-group" style="width:20%;display:inline-block;margin-right:7px;">
|
|
<select id="selETHAddress" name="address" placeholder="Address" data-datatype="int" data-bind="ethernet.phyAddress" style="width:100%;"></select>
|
|
<label for="selETHAddress">Address</label>
|
|
</div>
|
|
<div class="field-group" style="width:30%;display:inline-block;margin-right:7px;">
|
|
<select id="selETHClkMode" name="clkmode" placeholder="Clock Mode" data-datatype="int" data-bind="ethernet.CLKMode" style="width:100%;"></select>
|
|
<label for="selETHClkMode">Clock Mode</label>
|
|
</div>
|
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;">
|
|
<select id="selETHPWRPin" name="pwr" placeholder="Power Pin" data-datatype="int" data-bind="ethernet.PWRPin" style="width:100%;"></select>
|
|
<label for="selETHPWRPin">Power Pin</label>
|
|
</div>
|
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;">
|
|
<select id="selETHMDCPin" name="mdc" placeholder="MDC Pin" data-datatype="int" data-bind="ethernet.MDCPin" style="width:100%;"></select>
|
|
<label for="selETHPMDCPin">MDC Pin</label>
|
|
</div>
|
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;">
|
|
<select id="selETHMDIOPin" name="mdio" placeholder="MDIO Pin" data-datatype="int" data-bind="ethernet.MDIOPin" style="width:100%;"></select>
|
|
<label for="selETHMDIOPin">MDIO Pin</label>
|
|
</div>
|
|
<hr />
|
|
</div>
|
|
</div>
|
|
<div class="button-container">
|
|
<button id="btnSaveNetwork" type="button" onclick="wifi.saveNetwork();">
|
|
Save Adapter
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="divDHCP" class="subtab-content" style="display:none;">
|
|
<div style="margin-top:-14px;"><span style="color: #00bcd4;">IP Address:</span><span id="spanCurrentIP"></span></div>
|
|
<div class="field-group">
|
|
<input id="cbUseDHCP" name="dhcp" type="checkbox" data-bind="ip.dhcp" style="display:inline-block;" onclick="wifi.onDHCPClicked(this);" checked="checked" />
|
|
<label for="cbUseDHCP" style="display:inline-block;cursor:pointer;">Acquire IP Address automatically (DHCP)</label>
|
|
</div>
|
|
<div id="divStaticIP" style="display:none;">
|
|
<div class="field-group">
|
|
<input id="fldIPAddress" name="staticIP" type="text" data-bind="ip.ip" length=32 placeholder="0.0.0.0">
|
|
<label for="fldIPAddress">Static IP Address</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldSubnetMask" name="subnet" type="text" data-bind="ip.subnet" length=32 placeholder="0.0.0.0">
|
|
<label for="fldSubnetMask">Subnet Mask</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldGateway" name="gateway" type="text" data-bind="ip.gateway" length=32 placeholder="0.0.0.0">
|
|
<label for="fldGateway">Gateway</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldDNS1" name="dns1" type="text" data-bind="ip.dns1" length=32 placeholder="0.0.0.0">
|
|
<label for="fldDNS1">Domain Name Server 1</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldDNS2" name="dns2" type="text" data-bind="ip.dns2" length=32 placeholder="0.0.0.0">
|
|
<label for="fldDNS2">Domain Name Server 2</label>
|
|
</div>
|
|
</div>
|
|
<div style="color:#00bcd4;">* Settings will not take effect until the ESPSomfy RTS device is rebooted</div>
|
|
<div class="button-container">
|
|
<button id="btnSaveIPSettings" type="button" onclick="wifi.saveIPSettings();">
|
|
Save IP Settings
|
|
</button>
|
|
</div>
|
|
|
|
</div>
|
|
<div id="divMQTT" class="subtab-content" style="display:none;">
|
|
<div class="field-group" style="vertical-align:middle;margin-top:-20px;">
|
|
<div class="field-group" style="display:inline-block;width:auto;">
|
|
<input id="cbMqttEnabled" name="mqtt-enabled" type="checkbox" data-bind="mqtt.enabled" style="display:inline-block;" />
|
|
<label for="cbMqttEnabled" style="display:inline-block;cursor:pointer;">Enable MQTT client</label>
|
|
</div>
|
|
<div class="field-group" style="display:inline-block;width:auto;float:right;">
|
|
<input id="cbPubDisco" name="pub-disco" type="checkbox" data-bind="mqtt.pubDisco" style="display:inline-block;margin-left:7px;" onclick="document.getElementById('divDiscoveryTopic').style.display = this.checked ? '' : 'none'" />
|
|
<label for="cbPubDisco" style="display:inline-block;cursor:pointer;">Publish Discovery</label>
|
|
</div>
|
|
</div>
|
|
<div class="field-group1" style="white-space:nowrap;">
|
|
<select name="mqtt-protocol" data-bind="mqtt.protocol" style="width:54px;">
|
|
<option>MQTT</option>
|
|
<option>MQTTS</option>
|
|
</select>
|
|
<span style="">://</span>
|
|
<input name="mqtt-host" type="text" length=64 placeholder="Host" data-bind="mqtt.hostname" style="width:calc(100% - 137px);">
|
|
<span>:</span>
|
|
<input name="mqtt-port" type="text" length=5 placeholder="Port" data-bind="mqtt.port" data-datatype="int" style="width:50px;">
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldMqttUsername" name="mqtt-username" type="text" data-bind="mqtt.username" length=32 placeholder="Username">
|
|
<label for="fldMqttUsername">Username</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldMqttPassword" name="mqtt-password" type="text" length=64 data-bind="mqtt.password" placeholder="Password">
|
|
<label for="fldMqttPassword">Password</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldMqttTopic" name="mqtt-topic" type="text" length=64 data-bind="mqtt.rootTopic" placeholder="Root Topic">
|
|
<label for="fldMqttTopic">Root Topic</label>
|
|
</div>
|
|
<div class="field-group" id="divDiscoveryTopic" style="display:none;">
|
|
<input id="fldDiscoTopic" name="disco-topic" type="text" length=64 data-bind="mqtt.discoTopic" placeholder="Discovery Topic">
|
|
<label for="fldDiscoTopic">Discovery Topic</label>
|
|
</div>
|
|
|
|
<div class="button-container">
|
|
<button id="btnConnectMQTT" type="button" onclick="mqtt.connectMQTT();">Save MQTT Settings</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divSomfySettings" style="display:none;">
|
|
<div class="subtab-container"><span class="selected" data-grpid="divSomfyRooms">Rooms</span><span class="" data-grpid="divSomfyMotors">Shades</span><span data-grpid="divSomfyGroups">Groups</span><span data-grpid="divRepeater">Repeater</span><span class="tabname-virtual-remote" data-grpid="divVirtualRemote"></span></div>
|
|
<div id="divSomfyRooms" class="subtab-content" style="padding-top:10px;">
|
|
<div id="divRoomListContainer">
|
|
<div style="font-size:.8em;">Drag each item to set the order in which they appear in the list.</div>
|
|
<div id="divRoomList" class="edit-roomlist"></div>
|
|
<div class="button-container">
|
|
<button id="btnAddRoom" type="button" onclick="somfy.openEditRoom();">
|
|
Add Room
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="somfyRoom" style="width:100%;display:none;">
|
|
<div style="display:inline-block;float:right;position:relative;"><span id="spanRoomId">*</span>/<span id="spanMaxRooms">16</span></div>
|
|
<div class="field-group" style="padding:0px;">
|
|
<input id="fldRoomName" name="roomName" data-bind="name" type="text" length=20 placeholder="Name">
|
|
<label for="fldRoomName">Name</label>
|
|
</div>
|
|
<div class="button-container" style="margin-top:-10px;padding-left:7px;padding-right:7px;">
|
|
<button id="btnSaveRoom" type="button" onclick="somfy.saveRoom();">
|
|
Save Room
|
|
</button>
|
|
<button id="btnRoomGoBack" type="button" onclick="somfy.showEditRoom(false);">
|
|
Done
|
|
</button>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divSomfyMotors" class="subtab-content" style="padding-top:10px;display:none;">
|
|
<div id="divShadeListContainer">
|
|
<div style="font-size:.8em;">Drag each item to set the order in which they appear in the list.</div>
|
|
<div id="divShadeList" class="edit-motorlist"></div>
|
|
<div class="button-container">
|
|
<button id="btnAddShade" type="button" onclick="somfy.openEditShade();">
|
|
Add Shade
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="somfyShade" style="width:100%;display:none;" data-bitlength="56">
|
|
<div style="display:inline-block;float:right;position:relative;"><span id="spanShadeId">*</span>/<span id="spanMaxShades">5</span></div>
|
|
<div class="field-group" style="padding:0px;">
|
|
<div class="field-group" style="margin-top:-18px;display:inline-block;width:77px;">
|
|
<select id="selShadeProto" name="proto" data-bind="proto" data-datatype="int" style="width:100%;" onchange="somfy.onShadeProtoChanged(this);">
|
|
<option value="0">RTS</option>
|
|
<option value="1">RTW</option>
|
|
<option value="2">RTV</option>
|
|
<option value="8">IO-Relay</option>
|
|
<option value="9">IO-Remote</option>
|
|
</select>
|
|
<label for="selShadeProto">Protocol</label>
|
|
</div>
|
|
<div id="divShadeBitLength" class="field-group" style="margin-top:-18px;width:77px;">
|
|
<select id="selShadeBitLength" name="bitLength" data-bind="bitLength" data-datatype="int" style="width:100%;" onchange="somfy.onShadeBitLengthChanged(this);">
|
|
<option value="56">56-BIT</option>
|
|
<option value="80">80-BIT</option>
|
|
</select>
|
|
<label for="selShadeBitLength">Bit Length</label>
|
|
</div>
|
|
<div id="divGPIOControl" class="field-group">
|
|
<div id="divGPIOUp" class="field-group" style="">
|
|
<select id="selShadeGPIOUp" data-bind="gpioUp" data-datatype="int" style="width:70px;">
|
|
</select>
|
|
<label for="selShadeGPIOUp">UP</label>
|
|
</div>
|
|
<div id="divGPIODown" class="field-group" style="">
|
|
<select id="selShadeGPIODown" data-bind="gpioDown" data-datatype="int" style="width:70px;">
|
|
</select>
|
|
<label for="selShadeGPIODown">Down</label>
|
|
</div>
|
|
<div id="divGPIOMy" class="field-group" style="">
|
|
<select id="selShadeGPIOMy" data-bind="gpioMy" data-datatype="int" style="width:70px;">
|
|
</select>
|
|
<label for="selShadeGPIOMy">My</label>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="field-group" style="width:127px;display:inline-block;margin-top:-10px;float:left;">
|
|
<div class="field-group">
|
|
<div class="field-group" style="margin-top:-10px;">
|
|
<select id="selShadeType" name="shadeType" data-bind="shadeType" data-datatype="int" style="width:100%;" onchange="somfy.onShadeTypeChanged(this);">
|
|
<option value="0">Roller Shade</option>
|
|
<option value="4">Shutter</option>
|
|
<option value="1">Blind</option>
|
|
<option value="2">Drapery (left)</option>
|
|
<option value="7">Drapery (right)</option>
|
|
<option value="8">Drapery (center)</option>
|
|
<option value="3">Awning</option>
|
|
<option value="5">Garage (1-button)</option>
|
|
<option value="6">Garage (3-button)</option>
|
|
<option value="9">Dry Contact</option>
|
|
<option value="10">Dry Contact (2-button)</option>
|
|
<option value="11">Gate (left)</option>
|
|
<option value="12">Gate (center)</option>
|
|
<option value="13">Gate (right)</option>
|
|
<option value="14">Gate (1-button left)</option>
|
|
<option value="15">Gate (1-button center)</option>
|
|
<option value="16">Gate (1-button right)</option>
|
|
|
|
</select>
|
|
<label for="selShadeType">Type</label>
|
|
</div>
|
|
<div id="divShadeAddress" class="field-group" style="margin-top:-15px;">
|
|
<input id="fldShadeAddress" name="shadeAddress" data-bind="remoteAddress" data-datatype="int" type="number" length=5 placeholder="Address" style="width:100%;text-align:right;">
|
|
<label for="fldShadeAddress">Remote Address</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divSomfyButtons" class="shadectl-buttons" style="float:right;margin-top:-18px;position:relative">
|
|
<div style="display:inline-block;margin-right:7px;position:relative;font-size:48px;"><i id="icoShade" class="somfy-shade-icon icss-window-shade" data-shadeid="0" style="--shade-position:0%;vertical-align:middle;"><span class="icss-panel-left"></span><span class="icss-panel-right"></span></i><i class="icss-window-tilt" data-tiltposition="0" style="display:none;"></i></div>
|
|
<div class="button-outline" data-cmd="up" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'up');"><i class="icss-somfy-up"></i></div>
|
|
<div class="button-outline" data-cmd="my" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'my');" style="font-size: 2em; padding: 10px;"><span>my</span></div>
|
|
<div class="button-outline" data-cmd="down" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'down');"><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>
|
|
<div class="button-outline toggle-button" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="toggle" onclick="somfy.sendCommand(parseInt(document.getElementById('spanShadeId').innerText, 10), 'toggle');"><i class="icss-somfy-toggle" style="margin-top:-4px;"></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="field-group" style="padding:0px;">
|
|
<select id="selShadeRoom" data-bind="roomId" data-datatype="int" style="width:100%;"></select>
|
|
<label for="selShadeRoom">Room</label>
|
|
</div>
|
|
<div class="field-group" style="padding:0px;">
|
|
<input id="fldShadeName" name="shadeName" data-bind="name" type="text" length=20 placeholder="Name">
|
|
<label for="fldShadeName">Name</label>
|
|
</div>
|
|
<div id="divLiftSettings" style="margin-top:-10px;">
|
|
<div class="field-group" style="display:inline-block;max-width:127px;margin-right:17px;margin-top:-10px;">
|
|
<input id="fldShadeUpTime" name="shadeUpTime" data-bind="upTime" data-datatype="int" type="number" length=5 placeholder="milliseconds" style="width:100%;text-align:right;" />
|
|
<label for="fldShadeUpTime">Up Time (ms)</label>
|
|
</div>
|
|
<div class="field-group" style="display:inline-block;max-width:127px;">
|
|
<input id="fldShadeDownTime" name="shadeDownTime" type="number" data-bind="downTime" data-datatype="int" length=5 placeholder="milliseconds" style="width:100%;text-align:right;" />
|
|
<label for="fldShadeDownTime">Down Time (ms)</label>
|
|
</div>
|
|
</div>
|
|
<div id="divTiltSettings" style="display:none;margin-top:-10px;">
|
|
<div class="field-group" style="display:inline-block; margin-right:17px;width:127px;vertical-align:middle;">
|
|
<select id="selTiltType" name="tiltType" data-bind="tiltType" data-datatype="int" style="width:100%;" onchange="somfy.onShadeTypeChanged(this);">
|
|
<option value="0">None</option>
|
|
<option value="1">Tilt Motor</option>
|
|
<option value="2">Integrated</option>
|
|
<option value="3">Tilt Only</option>
|
|
<option value="4">Euro Tilt</option>
|
|
</select>
|
|
<label for="selTiltType" style="cursor:pointer;">Tilt Type</label>
|
|
</div>
|
|
<div class="field-group" style="display:inline-block;width:127px;vertical-align:middle;">
|
|
<input id="fldTiltTime" name="shadeTiltTime" type="number" data-bind="tiltTime" data-datatype="int" length=5 placeholder="milliseconds" style="width:100%;text-align:right;" />
|
|
<label for="fldTiltTime">Tilt Time (ms)</label>
|
|
</div>
|
|
</div>
|
|
<div id="divStepSettings">
|
|
<div class="field-group">
|
|
<input id="slidStepSize" name="stepSize" type="range" min="1" max="1000" step="1" data-bind="stepSize" data-datatype="int" style="width:100%;" oninput="somfy.stepSizeChanged(this);" />
|
|
<label for="slidStepSize" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;">
|
|
<span>Step Size (smaller)</span>
|
|
<span style="float:right;display:inline-block;margin-right:7px;">
|
|
<span id="spanStepSize" data-bind="stepSize" data-datatype="int" data-fmttype="number" data-fmtmask="#,##0" style="color:black;"></span><span>(larger)</span>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div id="divLLTrigger" style="margin-top:-10px;">
|
|
<div class="field-group">
|
|
<input id="cbLLTrigger" name="hasLLTrigger" data-bind="gpioLLTrigger" type="checkbox" style="" />
|
|
<label for="cbLLTrigger" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Low Level Trigger</label>
|
|
</div>
|
|
</div>
|
|
<div id="divSunSensor" style="margin-top:-10px;">
|
|
<div class="field-group">
|
|
<input id="cbHasSunsensor" name="hasSunSensor" data-bind="sunSensor" type="checkbox" style="" />
|
|
<label for="cbHasSunsensor" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Has Sun Sensor</label>
|
|
</div>
|
|
</div>
|
|
<div id="divLightSwitch" style="margin-top:-10px;">
|
|
<div class="field-group">
|
|
<input id="cbHasLight" name="hasLight" data-bind="light" type="checkbox" style="" />
|
|
<label for="cbHasLight" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Has Light</label>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top:-10px;" id="divFlipCommands">
|
|
<div class="field-group" style="display:inline-block">
|
|
<input id="cbFlipCommands" name="flipCommands" data-bind="flipCommands" type="checkbox" style="" />
|
|
<label for="cbFlipCommands" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Invert Commands</label>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top:-10px;" id="divFlipPosition">
|
|
<div class="field-group">
|
|
<input id="cbFlipPosition" name="flipPos" data-bind="flipPosition" type="checkbox" style="" />
|
|
<label for="cbFlipPosition" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Invert Position (expressed in % of open)</label>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top:-10px;" id="divSimMy">
|
|
<div class="field-group">
|
|
<input id="cbSimMy" name="simMy" data-bind="simMy" type="checkbox" style="" />
|
|
<label for="cbSimMy" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Simulate Favorite Position</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div classs="field-group" style="display:inline-block;">
|
|
<label for="selRepeatCommnds" style="cursor:pointer;color:#00bcd4;margin-right:4px;">Repeat Commands</label>
|
|
<select id="selRepeatCommands" data-bind="repeats" data-datatype="int" style="width:127px;">
|
|
<option value="0">No Repeats</option>
|
|
<option value="1">1 Time</option>
|
|
<option value="2">2 Times</option>
|
|
<option value="3">3 Times</option>
|
|
<option value="4">4 Times</option>
|
|
<option value="5">5 Times</option>
|
|
<option value="6">6 Times</option>
|
|
<option value="7">7 Times</option>
|
|
<option value="8">8 Times</option>
|
|
<option value="9">9 Times</option>
|
|
<option value="10">10 Times</option>
|
|
<option value="11">11 Times</option>
|
|
<option value="12">12 Times</option>
|
|
<option value="13">13 Times</option>
|
|
<option value="14">14 Times</option>
|
|
<option value="15">15 Times</option>
|
|
<option value="16">16 Times</option>
|
|
<option value="17">17 Times</option>
|
|
<option value="18">18 Times</option>
|
|
<option value="19">19 Times</option>
|
|
<option value="20">20 Times</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div style="margin-top:-10px;">
|
|
<div class="field-group">
|
|
</div>
|
|
</div>
|
|
<div class="button-container" style="text-align:center;">
|
|
<button id="btnPairShade" type="button" onclick="somfy.pairShade(parseInt(document.getElementById('spanShadeId').innerText, 10));" style="display:inline-block;width:47%;">
|
|
Pair Shade
|
|
</button>
|
|
<button id="btnUnpairShade" type="button" onclick="somfy.unpairShade(parseInt(document.getElementById('spanShadeId').innerText, 10));" style="display:inline-block;width:47%;">
|
|
Unpair Shade
|
|
</button>
|
|
<button id="btnSetRollingCode" type="button" onclick="somfy.openSetRollingCode(parseInt(document.getElementById('spanShadeId').innerText, 10));" style="display:inline-block;width:47%;">
|
|
Set Rolling Code
|
|
</button>
|
|
</div>
|
|
<div class="button-container" style="margin-top:-10px;padding-left:7px;padding-right:7px;">
|
|
<button id="btnSaveShade" type="button" onclick="somfy.saveShade();">
|
|
Save Shade
|
|
</button>
|
|
</div>
|
|
<hr />
|
|
<div id="divLinkedRemoteList" style="overflow-y:auto;max-height:177px;padding-top:2px;padding-bottom:2px;"></div>
|
|
<div class="button-container">
|
|
<button id="btnLinkRemote" type="button" onclick="somfy.linkRemote(parseInt(document.getElementById('spanShadeId').innerText, 10));">
|
|
Link Remote
|
|
</button>
|
|
<button id="btnBtnShadeGoBack" type="button" onclick="somfy.showEditShade(false);">
|
|
Done
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divSomfyGroups" class="subtab-content" style="display:none;padding-top:10px;">
|
|
<div id="divGroupListContainer">
|
|
<div style="font-size:.8em;">Drag each item to set the order in which they appear in the list.</div>
|
|
<div id="divGroupList" class="edit-grouplist"></div>
|
|
<div class="button-container">
|
|
<button id="btnAddGroup" type="button" onclick="somfy.openEditGroup();">
|
|
Add Group
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="somfyGroup" style="width:100%;display:none;">
|
|
<div style="display:inline-block;float:right;position:relative;"><span id="spanGroupId">*</span>/<span id="spanMaxGroups">5</span></div>
|
|
<div class="field-group" style="padding:0px;">
|
|
<div class="field-group" style="margin-top:-18px;display:inline-block;width:77px;">
|
|
<select id="selGroupProto" name="proto" data-bind="proto" data-datatype="int" style="width:100%;">
|
|
<option value="0">RTS</option>
|
|
<option value="1">RTW</option>
|
|
<option value="2">RTV</option>
|
|
</select>
|
|
<label for="selGroupProto">Protocol</label>
|
|
</div>
|
|
<div class="field-group" style="margin-top:-18px;display:inline-block;width:77px;">
|
|
<select id="selGroupBitLength" name="bitLength" data-bind="bitLength" data-datatype="int" style="width:100%;">
|
|
<option value="56">56-BIT</option>
|
|
<option value="80">80-BIT</option>
|
|
</select>
|
|
<label for="selGroupBitLength">Bit Length</label>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="field-group" style="width:127px;display:inline-block;margin-top:-10px;float:left;">
|
|
<input id="fldShadeAddress" name="shadeAddress" data-bind="remoteAddress" data-datatype="int" type="number" length=5 placeholder="Address" style="width:100%;text-align:right;">
|
|
<label for="fldShadeAddress">Remote Address</label>
|
|
</div>
|
|
<div>
|
|
<div id="divSomfyGroupButtons" style="float:right;margin-top:-32px;position:relative">
|
|
<div class="button-outline" onclick="somfy.sendGroupCommand(parseInt(document.getElementById('spanGroupId').innerText, 10), 'up');"><i class="icss-somfy-up"></i></div>
|
|
<div class="button-outline" onclick="somfy.sendGroupCommand(parseInt(document.getElementById('spanGroupId').innerText, 10), 'my');" style="font-size: 2em; padding: 10px;"><span>my</span></div>
|
|
<div class="button-outline" onclick="somfy.sendGroupCommand(parseInt(document.getElementById('spanGroupId').innerText, 10), 'down');"><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="field-group" style="padding:0px;">
|
|
<select id="selGroupRoom" data-bind="roomId" data-datatype="int" style="width:100%;"></select>
|
|
<label for="selGroupRoom">Room</label>
|
|
</div>
|
|
<div class="field-group" style="padding:0px;">
|
|
<input id="fldGroupName" name="groupName" data-bind="name" type="text" length=20 placeholder="Name">
|
|
<label for="fldGroupName">Name</label>
|
|
</div>
|
|
<div style="margin-top:-10px;" id="divFlipGrpCommands">
|
|
<div class="field-group" style="display:inline-block">
|
|
<input id="cbFlipGrpCommands" name="flipCommands" data-bind="flipCommands" type="checkbox" style="" />
|
|
<label for="cbFlipGrpCommands" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;display:inline-block;">Invert Commands</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div classs="field-group" style="display:inline-block;">
|
|
<label for="selRepeatCommnds" style="cursor:pointer;color:#00bcd4;margin-right:4px;">Repeat Commands</label>
|
|
<select id="selRepeatCommands" data-bind="repeats" data-datatype="int" style="width:127px;">
|
|
<option value="0">No Repeats</option>
|
|
<option value="1">1 Time</option>
|
|
<option value="2">2 Times</option>
|
|
<option value="3">3 Times</option>
|
|
<option value="4">4 Times</option>
|
|
<option value="5">5 Times</option>
|
|
<option value="6">6 Times</option>
|
|
<option value="7">7 Times</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="button-container" style="margin-top:-10px;padding-left:7px;padding-right:7px;">
|
|
<button id="btnSaveGroup" type="button" onclick="somfy.saveGroup();">
|
|
Save Group
|
|
</button>
|
|
</div>
|
|
<hr />
|
|
<div id="divLinkedShadeList" style="overflow-y:auto;max-height:177px;padding-top:2px;padding-bottom:2px;"></div>
|
|
<div class="button-container">
|
|
<button id="btnLinkShade" type="button" onclick="somfy.linkGroupShade(parseInt(document.getElementById('spanGroupId').innerText, 10));">
|
|
Link Shade
|
|
</button>
|
|
<button id="btnGroupGoBack" type="button" onclick="somfy.showEditGroup(false);">
|
|
Done
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div id="divRepeater" style="display:none;padding-top:10px;" class="subtab-content">
|
|
<div id="divRepeaterListContainer">
|
|
<div style="font-size:.8em;">All repeated remote addresses are listed below.</div>
|
|
<div id="divRepeatList" class="edit-repeaterlist"></div>
|
|
<div class="button-container">
|
|
<button id="btnLinkRepeater" type="button" onclick="somfy.linkRepeatRemote();">
|
|
Scan Remote
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divVirtualRemote" style="display:none;" class="subtab-content" data-bitlength="56">
|
|
<div class="field-group" style="margin-top:-18px;display:inline-block;width:100%;">
|
|
<select id="selVRMotor" style="width:100%;" onchange="document.getElementById('divVirtualRemote').setAttribute('data-bitlength', this.options[this.selectedIndex].getAttribute('data-bitlength'));">
|
|
</select>
|
|
<label for="selVRMotor">Select a Motor or Group</label>
|
|
</div>
|
|
<div class="vr-button vr-updownmy">
|
|
<span>Remote Buttons</span>
|
|
<div>
|
|
<div class="button-outline" data-cmd="up" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><i class="icss-somfy-up"></i></div>
|
|
<div class="button-outline" data-cmd="my" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);" style="font-size: 2em; padding: 10px;"><span>my</span></div>
|
|
<div class="button-outline" data-cmd="down" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-stop vr-80bit">
|
|
<span>Stop</span>
|
|
<div>
|
|
<div class="button-outline toggle-button" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="stop" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><i class="icss-hand" style=""></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-updownmy">
|
|
<span>Toggle Button</span>
|
|
<div>
|
|
<div class="button-outline toggle-button" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="toggle" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><i class="icss-somfy-toggle" style="margin-top:-4px;"></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-updown vr-80bit">
|
|
<span>Step</span>
|
|
<div style="margin-right:7px;width:470px;font-size:.8em;">
|
|
<input id="vrslidStepSize" name="stepSize" type="range" min="1" max="127" step="1" style="width:100%;" data-bind="stepSize" value="1" oninput="document.getElementById('vrspanStepSize').innerText = this.value;" />
|
|
<div>
|
|
<label style="color:#00bcd4;">Step Size:</label><span id="vrspanStepSize">1</span>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="button-outline" style="width:59px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="StepUp" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><span></span><i class="icss-somfy-up" style="margin-top:4px;"></i></div>
|
|
<div class="button-outline" style="width:59px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="StepDown" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><span></span><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-favorite vr-80bit">
|
|
<span>Favorite</span>
|
|
<div>
|
|
<div class="button-outline toggle-button" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="favorite" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><i class="icss-bookmark" style=""></i></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="vr-button vr-updown">
|
|
<span>Up + Down</span>
|
|
<div>
|
|
<div class="button-outline" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="UpDown" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><i class="icss-somfy-up"></i><span> + </span><i class="icss-somfy-down" style="margin-top:-4px;"></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-updownmy">
|
|
<span>Up + My + Down</span>
|
|
<div>
|
|
<div class="button-outline" data-cmd="MyUpDown" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><span style="padding: 10px;">all</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-updown">
|
|
<span>My + Up</span>
|
|
<div>
|
|
<div class="button-outline" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="MyUp" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><span>my</span><span> + </span><i class="icss-somfy-up"></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-updown">
|
|
<span>My + Down</span>
|
|
<div>
|
|
<div class="button-outline" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="MyDown" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><span>my</span><span> + </span><i class="icss-somfy-down"></i></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-updown">
|
|
<span>Prog</span>
|
|
<div>
|
|
<div class="button-outline" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="Prog" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><span>prog</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button vr-updown">
|
|
<span>Sun Flag</span>
|
|
<div>
|
|
<div class="button-outline" style="width: 59px; text-align: center; border-radius: 33%; font-size: 2em; padding: 10px; height: 52px;" data-cmd="SunFlag" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><div class="button-sunflag" data-on="true" style="margin:0px;margin-left:4px;"><i class="icss-sun-c" style="background:white;"></i><i class="icss-sun-o" style="left:0px;color:white;"></i></div></div>
|
|
<div class="button-outline" style="width: 59px; text-align: center; border-radius: 33%; font-size: 2em; padding: 10px; height: 52px;" data-cmd="Flag" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><div class="button-sunflag" data-on="false" style="margin:0px;margin-left:4px;"><i class="icss-sun-c" style="background:transparent;"></i><i class="icss-sun-o" style="left:0px;color:white;"></i></div></div>
|
|
</div>
|
|
</div>
|
|
<div class="vr-button">
|
|
<span>
|
|
<span>Sensor</span>
|
|
<span style="display:inline-block;vertical-align:middle;margin-left:14px;">
|
|
<span style="display:block">
|
|
<input id="cbSunny" type="checkbox" data-bind="sunny" style="display:inline-block;" />
|
|
<label for="cbSunny" style="display:inline-block;cursor:pointer;">Sunny</label>
|
|
</span>
|
|
<span style="display:block">
|
|
<input id="cbWindy" type="checkbox" data-bind="windy" style="display:inline-block;" />
|
|
<label for="cbWindy" style="display:inline-block;cursor:pointer;">Windy</label>
|
|
</span>
|
|
</span>
|
|
</span>
|
|
<div>
|
|
<div class="button-outline" style="width:127px;text-align:center;border-radius:33%;font-size:2em;padding:10px;" data-cmd="Sensor" onmousedown="somfy.sendVRCommand(this);" ontouchstart="somfy.sendVRCommand(this);"><div class="button-sunflag" data-on="false" style="margin:0px;"></div><span>send</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divRadioSettings" style="display:none;">
|
|
<div class="subtab-container"><span class="selected" data-grpid="divTransceiverSettings">Transceiver</span><span data-grpid="divFrameLog">Logs</span></div>
|
|
<div id="divTransceiverSettings" class="subtab-content">
|
|
<div class="field-group" style="display:inline-block;margin-right:7px;width:77px;">
|
|
<label for="selRadioProto">Protocol</label>
|
|
<select id="selRadioProto" name="radioType" data-bind="transceiver.config.proto" data-datatype="int" style="width:77px;">
|
|
<option value="0">RTS</option>
|
|
<option value="1">RTW</option>
|
|
<option value="2">RTV</option>
|
|
</select>
|
|
</div>
|
|
<div class="field-group" style="display:inline-block;width:77px;">
|
|
<label for="selRadioType">Bit Length</label>
|
|
<select id="selRadioType" name="radioType" data-bind="transceiver.config.type" data-datatype="int" style="width:77px;">
|
|
<option value="56">56-BIT</option>
|
|
<option value="80">80-BIT</option>
|
|
</select>
|
|
</div>
|
|
<div class="field-group" style="vertical-align:middle;margin-left:7px;float:right;display:inline-block;width:auto;">
|
|
<input id="cbEnableRadio" name="enableRadio" type="checkbox" data-bind="transceiver.config.enabled" style="display:inline-block;" />
|
|
<label for="cbEnableRadio" style="display:inline-block;cursor:pointer;">Enable Radio</label>
|
|
</div>
|
|
<div class="field-group" style="vertical-align:middle;margin-left:7px;float:right;display:inline-block;width:auto;">
|
|
<input id="cbNoiseDetection" name="noiseDetection" type="checkbox" data-bind="transceiver.config.noiseDetection" style="display:inline-block;" title="When enabled, the RX interrupt is automatically disabled if more than 100 pulses are detected within 10 seconds (RF noise burst). The interrupt is re-enabled after a 100ms cooldown. Enable this if your radio is frequently disrupted by nearby RF interference." />
|
|
<label for="cbNoiseDetection" style="display:inline-block;cursor:pointer;" title="When enabled, the RX interrupt is automatically disabled if more than 100 pulses are detected within 10 seconds (RF noise burst). The interrupt is re-enabled after a 100ms cooldown. Enable this if your radio is frequently disrupted by nearby RF interference.">Noise Detection</label>
|
|
</div>
|
|
<div class="field-group" style="margin-top:-18px;"><label style="font-size:12px;">(default when adding new motors)</label></div>
|
|
<div class="field-group1" style="white-space:nowrap">
|
|
<div class="field-group radioPins">
|
|
<select id="selTransSCKPin" name="transSCK" data-bind="transceiver.config.SCKPin" data-datatype="int"></select>
|
|
<label for="selTransSCKPin">SCLK</label>
|
|
</div>
|
|
<div class="field-group radioPins">
|
|
<select id="selTransCSNPin" name="transCSN" data-bind="transceiver.config.CSNPin" data-datatype="int"></select>
|
|
<label for="selTransCSNPin">CSN</label>
|
|
</div>
|
|
<div class="field-group radioPins">
|
|
<select id="selTransMOSIPin" name="transMOSI" data-bind="transceiver.config.MOSIPin" data-datatype="int"></select>
|
|
<label for="selTransMOSIPin">MOSI</label>
|
|
</div>
|
|
<div class="field-group radioPins">
|
|
<select id="selTransMISOPin" name="transMISO" data-bind="transceiver.config.MISOPin" data-datatype="int"></select>
|
|
<label for="selTransMISOPin">MISO</label>
|
|
</div>
|
|
</div>
|
|
<div class="field-group1" style="margin-top:-20px;">
|
|
<div class="field-group radioPins">
|
|
<select id="selTransTXPin" name="transTX" data-bind="transceiver.config.TXPin" data-datatype="int"></select>
|
|
<label for="selTransTXPin">TX</label>
|
|
</div>
|
|
<div class="field-group radioPins">
|
|
<select id="selTransRXPin" name="transRX" data-bind="transceiver.config.RXPin" data-datatype="int"></select>
|
|
<label for="selTransRXPin">RX</label>
|
|
</div>
|
|
</div>
|
|
<div class="field-group" style="display:inline-block;width:auto;min-width:247px;margin-top:-20px;vertical-align:top;">
|
|
<div class="field-group">
|
|
<input id="slidFrequency" name="frequency" type="range" min="433000" max="434399" step="1" style="width:100%;" data-bind="transceiver.config.frequency" data-datatype="float" data-mult="1000" oninput="somfy.frequencyChanged(this);" />
|
|
<label for="slidFrequency" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;">
|
|
<span>Base Frequency </span>
|
|
<span style="float:right;display:inline-block;margin-right:7px;">
|
|
<span id="spanFrequency" style="color:black;" data-bind="transceiver.config.frequency" data-datatype="float" data-fmttype="number" data-fmtmask="#,###.000"></span><span>MHz</span>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
<div class="field-group" style="margin-top:-10px;">
|
|
<input id="slidRxBandwidth" name="rxBandwidth" type="range" min="5803" max="81250" step="1" style="width:100%;" data-bind="transceiver.config.rxBandwidth" data-setonly="true" data-datatype="float" data-mult="100" oninput="somfy.rxBandwidthChanged(this);" />
|
|
<label for="slidRxBandwidth" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;">
|
|
<span>RX Bandwidth </span>
|
|
<span style="float:right;display:inline-block;margin-right:7px;">
|
|
<span id="spanRxBandwidth" style="color:black;" data-bind="transceiver.config.rxBandwidth" data-datatype="float" data-fmttype="number" data-fmtmask="#,###.00"></span><span>kHz</span>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
<div class="field-group" style="margin-top:-10px;">
|
|
<input id="slidDeviation" name="deviation" type="range" min="158" max="38085" step="1" style="width:100%;" data-bind="transceiver.config.deviation" data-setonly="true" data-datatype="float" data-mult="100" oninput="somfy.deviationChanged(this);" />
|
|
<label for="slidDeviation" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;"><span>Frequency Deviation </span><span style="float: right; display: inline-block; margin-right: 7px;"><span id="spanDeviation" data-bind="transceiver.config.deviation" data-datatype="float" data-fmttype="number" data-fmtmask="#,###.00" style="color:black;"></span><span>kHz</span></span></label>
|
|
</div>
|
|
<div class="field-group" style="margin-top:-10px;">
|
|
<input id="slidTxPower" name="txPower" type="range" min="0" max="10" step="1" style="width:100%;" data-bind="transceiver.config.txPower" data-datatype="index" data-setonly="true" data-values="[-30, -20, -15, -10, -6, 0, 5, 7, 10, 11, 12]" oninput="somfy.txPowerChanged(this);" />
|
|
<label for="slidTxPower" style="display:block;font-size:1em;margin-top:0px;margin-left:7px;"><span>TX Power </span><span style="float: right; display: inline-block; margin-right: 7px;"><span id="spanTxPower" data-bind="transceiver.config.txPower" data-datatype="int" data-fmttype="number" data-fmtmask="#,###" style="color:black;"></span><span>dBm</span></span></label>
|
|
</div>
|
|
</div>
|
|
<div style="display:inline-block;vertical-align:top;padding-left:14px;">
|
|
<div class="field-group" style="">
|
|
<label style="display:block;width:100%;text-align:center;">RSSI: <span id="spanFrameCount" style="color:silver;">0</span></label>
|
|
<span id="spanRssi" name="rssi" style="display:block;font-size:32px;width:100%;text-align:center;">---</span>
|
|
<span style="display: block; color: #00bcd4;width:100%;text-align:center;">dBm</span>
|
|
</div>
|
|
</div>
|
|
<div class="button-container">
|
|
<button id="btnSaveRadio" type="button" onclick="somfy.saveRadio();">
|
|
Save Radio
|
|
</button>
|
|
<button id="btnScanFrequency" type="button" onclick="somfy.scanFrequency(true);">
|
|
Scan Frequency
|
|
</button>
|
|
|
|
</div>
|
|
</div>
|
|
<div id="divFrameLog" class="subtab-content frame-log" style="display:none;margin:0px;padding:0px;">
|
|
<div class="frame-header"><span>Key</span><span>Address</span><span>Command</span><span>Code</span><span>RSSI</span><span>Bits</span><span style="text-align:center;width:77px;">Time</span><span>Raw</span></div>
|
|
<div id="divFrames" class="frame-list"></div>
|
|
<div class="button-container" style="text-align:center">
|
|
<button type="button" class="btnCopyFrame" style="display:inline-block;width:44%;" onclick="somfy.framesToClipboard();">Copy</button>
|
|
<button type="button" class="btnClearFrames" style="display:inline-block;width:44%;" onclick="document.getElementById('divFrames').innerHTML = ''; somfy.frames = [];">Clear</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="divHomePnl" style="position:relative;">
|
|
<hr />
|
|
<div id="divRoomSelector" class="room-selector" style="display:none;" data-roomid="0" onclick="event.stopPropagation(); somfy.openSelectRoom();">
|
|
<i class="icss-bars"></i><span>Home</span>
|
|
<div id="divRoomSelector-list" class="room-selector-list"></div>
|
|
</div>
|
|
<div id="divGroupControls"></div>
|
|
<div id="divShadeControls" style="min-height:130px;"></div>
|
|
</div>
|
|
</div>
|
|
<div id="divUnauthenticated">
|
|
<h1 style="text-align: center;"><img src="icon.png" style="width:127px;margin-left:1px;margin-top:-10px;" /></h1>
|
|
<input id="fldLoginPin" type="hidden" name="pin" />
|
|
<input id="fldLoginType" type="hidden" data-bind="login.type" data-datatype="int" />
|
|
<div id="divLoginPin" style="display:none;">
|
|
<div class="field-group" style="text-align:center;">
|
|
<div id="fldPinEntry" style="display:inline-block;" onkeydown="ui.pinKeyPressed(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="login.pin.d0" onfocus="ui.pinDigitFocus(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="login.pin.d1" onfocus="ui.pinDigitFocus(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="login.pin.d2" onfocus="ui.pinDigitFocus(event);">
|
|
<input class="pin-digit" maxlength="1" data-bind="login.pin.d3" onfocus="ui.pinDigitFocus(event);">
|
|
</div>
|
|
<label for="fldPinEntry" style="margin-top:7px;">Enter Pin</label>
|
|
</div>
|
|
</div>
|
|
<div id="divLoginPassword" style="display:none;" onkeyup="if (event.code === 'Enter') security.login();">
|
|
<div class="field-group">
|
|
<input id="fldLoginUsername" name="username" type="text" data-bind="login.username" length=32 placeholder="Username" />
|
|
<label for="fldLoginUsername">Username</label>
|
|
</div>
|
|
<div class="field-group">
|
|
<input id="fldLoginPassword" name="password" type="password" data-bind="login.password" length=32 placeholder="Password" />
|
|
<label for="fldLoginPassword">Password</label>
|
|
</div>
|
|
</div>
|
|
<div style="text-align:center;"><span id="spanLoginMessage" style="color:red"></span></div>
|
|
<div id="loginButtons" class="button-container" style="display:none;text-align:center;">
|
|
<button id="btnLogin" type="button" onclick="security.login();" style="display:inline-block;width:42%;">Login</button>
|
|
<button id="btnCancelLogin" type="button" onclick="security.cancelLogin();" style="display:none;width:42%;">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script type="text/javascript">
|
|
var mouseDown = false;
|
|
//ui.waitMessage(document.getElementById('divShadeControls'));
|
|
let tabs = document.querySelectorAll('div.tab-container > span');
|
|
tabs.forEach((tab) => {
|
|
tab.addEventListener('click', (evt) => {
|
|
console.log(evt);
|
|
if (evt.srcElement.classList.contains('selected'))
|
|
return;
|
|
else {
|
|
tabs.forEach((tsel) => {
|
|
tsel.classList.remove('selected');
|
|
if (tsel != tab) {
|
|
let grpsel = document.getElementById(tsel.getAttribute('data-grpid'));
|
|
if (typeof grpsel !== 'undefined' && grpsel) grpsel.style.display = 'none';
|
|
}
|
|
});
|
|
tab.classList.add('selected');
|
|
if (tab.getAttribute('data-grpid') !== 'divSomfySettings') {
|
|
somfy.showEditShade(false);
|
|
somfy.showEditGroup(false);
|
|
}
|
|
switch (tab.getAttribute('data-grpid')) {
|
|
case 'divNetworkSettings':
|
|
wifi.loadNetwork();
|
|
break;
|
|
}
|
|
let grp = document.getElementById(tab.getAttribute('data-grpid'));
|
|
if (typeof grp !== 'undefined' && grp) grp.style.display = '';
|
|
}
|
|
|
|
});
|
|
});
|
|
document.querySelectorAll('.subtab-container > span').forEach((tab) => { tab.addEventListener('click', (evt) => { ui.selectTab(evt.srcElement); }) });
|
|
document.addEventListener('mousedown', (event) => {
|
|
mouseDown = true;
|
|
});
|
|
document.addEventListener('mouseup', (event) => {
|
|
mouseDown = false;
|
|
});
|
|
document.addEventListener('mouseleave', (event) => {
|
|
mouseDown = false;
|
|
});
|
|
document.addEventListener('touchend', (event) => {
|
|
mouseDown = false;
|
|
});
|
|
document.addEventListener('touchstart', (event) => {
|
|
mouseDown = true;
|
|
});
|
|
document.addEventListener('touchcancel', (event) => {
|
|
mouseDown = false;
|
|
});
|
|
(async () => { await init(); })();
|
|
/*
|
|
security.init();
|
|
//(async () => { await general.init(); })();
|
|
general.init();
|
|
wifi.init();
|
|
somfy.init();
|
|
mqtt.init();
|
|
firmware.init();
|
|
*/
|
|
/*
|
|
let o = {
|
|
general: { hostname: 'hostname', ntpServer: 'pool.ntp.org', posixZone: '<-10>10', ssdpBroadcast: true }
|
|
|
|
}
|
|
*/
|
|
//ui.toElement(document.getElementById('divContainer'), o);
|
|
//console.log(ui.fromElement(document.getElementById('divContainer')));
|
|
//(async () => { await initSockets(); })();
|
|
</script>
|
|
</body>
|
|
</html>
|