root@pOpenHAB:~# curl "http://192.168.1.51:2323/?cmd=screenOff&password=\[1234\]"
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Fully Remote Admin</title>
<link rel="shortcut icon" type="image/x-icon" href="fully-favicon.ico">
<style>
* { margin: 0; padding: 0; }
body { font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; text-align:left; box-sizing:border-box; overflow-x:hidden; min-height:100%; }
h1 { font-size: 1.35em; margin-bottom: 0.7em; }
h2 { font-size: 1em; }
img.header { max-width:100%; }
img.screenshot, #imgholder { max-width:100%; border:2px solid #666666; margin-top:0.2em; margin-bottom:0.4em; text-align:center; }
#imgholder { display:none; min-width:100%; min-height:195px;}
form, input, select, textarea, p, div, label { font-size: 1.0em; }
p {margin-bottom: 1em;}
p.buttonline { margin-top:0.4em; line-height: 1.8em; font-size: 1.0em;}
.scale80 { font-size: 0.8em !important; }
.scale90 { font-size: 0.9em !important; }
.scale110 { font-size: 1.1em !important; }
.small, .key { font-size: 0.7em !important; }
.key { display: none; }
a, a:visited {color: #304ffe; text-decoration:none;}
.disabled { color: #808080; }
.width20 { width:20em !important; }
.nowrap { white-space: nowrap !important;}
p.error, p.success, p.saving { line-height:1.5em; margin-top:0.5em; }
p.error, p.success { margin-left:-1.8em; margin-right:-1.8em; padding-left:1.8em; padding-right:1.8em; }
.table-cell p.error, .table-cell p.success, .table-value p.error, .table-value p.success { margin-left: -0.5em; margin-right: -0.5em; padding-left:1.2em; padding-right:1.2em; }
p.error { color: #FFFFFF; background:#FF0000; border-top:2px solid #880000;border-bottom:2px solid #880000;}
p.success { color: #FFFFFF; background:#00CC00; border-top:2px solid #007700;border-bottom:2px solid #007700;}
p.right { text-align:right; }
table.table { width:100%; background-color:#eee; border:1px solid #666666; border-spacing:0.2em; margin-bottom:0.5em; }
table.smaller { font-size: 0.9em; }
table.spaceafter { margin-bottom:1.5em;}
tr.table-row { }
td.table-cell { background-color:#ddd; padding:0.3em; margin:0.1em; vertical-align:top; }
td.table-ocell { background-color:#ddd; padding:0.3em; margin:0.1em; vertical-align:top; overflow-wrap:anywhere; }
td.table-head { background-color:#bbb; padding:0.3em; vertical-align:top; font-weight: bold;}
td.table-value { background-color:#ccc; padding:0.3em; vertical-align:top; text-align:right; overflow-wrap:anywhere; }
a.prefCategory {
font-weight: bold;
}
.editArea {
margin-top: 0.4em;
margin-bottom: 0.4em;
display: none;
}
.smallicon {
height: 0.8em;
width: 0.8em;
}
.button {
color: #ffffff !important;
background: #37474f !important;
font-size: 1.0em;
font-weight: bold;
border: 1px solid #808080;
height: 2em;
padding-left: 1em !important;
padding-right: 1em !important;
text-decoration:none;
cursor: pointer;
white-space: nowrap;
}
.button:hover {
color: #ffffff;
background: #6a6a6a;
}
a.button {
font-size: 0.9em;
padding-left: 0.5em;
padding-right: 0.5em;
padding-top: 0.2em;
padding-bottom: 0.2em;
}
a.disabled {
opacity: 0.4;
pointer-events: none;
cursor: default;
}
a.button+a {
margin-left: 1em;
}
p.formexpl {
font-size: 1.0em;
vertical-align: top;
text-align: left;
}
p.formline {
font-size: 1.0em;
vertical-align: top;
text-align: left;
line-height: 2.5em;
}
p.narrow {
line-height: 1.8em !important;
}
p.formline input, p.formline select {
height: 2em;
border: 1px solid #37474f;
padding-left: 0.2em;
box-sizing: border-box;
vertical-align: middle;
}
p.formline label {
padding-left: 0.3em;
box-sizing: border-box;
vertical-align: middle;
}
p.formline input[type=file] {
border: 0px;
padding-top: 0.2em;
}
p.formline textarea {
min-height: 2em;
border: 1px solid #37474f;
padding-left: 0.2em;
box-sizing: border-box;
}
/* Make nice select arrow in Firefox etc. */
select {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: url(dropdown-icon.png) right / 20px no-repeat #fff;
padding-right: 20px;
-webkit-border-radius: 0px;
}
select::-ms-expand {
display: none; /* hide the default arrow in ie10 and ie11 */
}
.content {
width: 100%;
min-height:100%;
max-width:44em;
margin: 0 auto;
box-sizing:border-box;
padding: 5.5em 1.8em 1.8em;
background: #ffffff;
box-shadow: 0 0 1.2em rgba(0,0,0,0.5);
position:absolute;
top: 0;
left: 0;
}
@media (min-width:55em) {
.banner {
margin: 0 auto;
padding: 5.5em 0.8em 0.8em;
background: #ffffff;
position:absolute;
top: 0;
left: 44em;
}
}
@media (max-width:55em) {
.banner {
display:none;
}
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: rgba(0,0,0,0.5);
z-index: 1;
}
#hamburger-checkbox {
display: none;
}
label.hamburger {
position: fixed;
width: 3.8em;
height: 3.8em;
cursor: pointer;
text-transform: uppercase;
font-weight: 700;
z-index: 999;
}
label.hamburger span {
display: block;
top: 8px;
width: 1.5em;
height: 0.3em;
background-color: #ffffff;
position: relative;
/*position: absolute;*/
top: 1.6em;
left: 1.1em;
-webkit-transition-duration: 0;
-moz-transition-duration: 0;
-ms-transition-duration: 0;
-o-transition-duration: 0;
transition-duration: 0;
-webkit-transition-delay: 0.2s;
-moz-transition-delay: 0.2s;
-ms-transition-delay: 0.2s;
-o-transition-delay: 0.2s;
transition-delay: 0.2s;
}
label.hamburger span::after, label.hamburger span::before {
display: block;
content: '';
position: absolute;
width: 1.5em;
height: 0.3em;
background-color: #ffffff;
-webkit-transition-property: margin, -webkit-transform;
-webkit-transition-duration: 0.2s;
-moz-transition-duration: 0.2s;
-ms-transition-duration: 0.2s;
-o-transition-duration: 0.2s;
transition-duration: 0.2s;
-webkit-transition-delay: 0.2s, 0;
-moz-transition-delay: 0.2s, 0;
-ms-transition-delay: 0.2s, 0;
-o-transition-delay: 0.2s, 0;
transition-delay: 0.2s, 0;
}
label.hamburger span::before {
margin-top: -0.5em;
}
label.hamburger span::after {
margin-top: 0.5em;
}
#hamburger-checkbox:checked ~ label.hamburger span {
background-color: transparent;
}
#hamburger-checkbox:checked ~ label.hamburger span::before,
#hamburger-checkbox:checked ~ label.hamburger span::after {
margin-top: 0px;
-webkit-transition-delay: 0, 0.2s;
-moz-transition-delay: 0, 0.2s;
-ms-transition-delay: 0, 0.2s;
-o-transition-delay: 0, 0.2s;
transition-delay: 0, 0.2s;
}
#hamburger-checkbox:checked ~ label.hamburger span::before {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
#hamburger-checkbox:checked ~ label.hamburger span::after {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
#hamburger-checkbox:checked ~ nav.off-canvas-menu {
-ms-transform: translateX(0);
-webkit-transform: translateX(0);
transform: translateX(0);
transition: 0.5s;
}
#hamburger-checkbox:checked ~ .content {
-ms-transform: translateX(11em);
-webkit-transform: translateX(11em);
transform: translateX(11em);
transition: 0.5s;
}
#hamburger-checkbox:checked ~ .overlay {
height: 100%;
opacity: 1;
}
nav li,
label.hamburger {
transition: 0.2s;
}
nav li:hover,
label.hamburger:hover,
#hamburger-checkbox:checked ~ label.hamburger {
background: #207ce5 !important;
}
.hidden {
display: none;
}
.main-menu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 3.8em;
background: #37474f;
box-shadow: 0 0 10px rgba(0,0,0,0.9);
z-index: 3;
}
.main-menu header {
font-size: 1.35em;
font-weight: bold;
margin-left: 4em;
margin-top: 0.8em;
white-space: nowrap;
}
.main-menu header a {
text-decoration:none;
color: #ffffff;
}
.main-menu header a:visited {
color: #ffffff;
}
.main-menu ul.nav-icons {
float: right;
}
.main-menu li {
float: left;
line-height: 3.8em;
list-style: none;
transition: 0.3s;
}
.main-menu li a {
display: inline-block;
}
.main-menu li i {
width: 3.8em;
font-size: 1em;
color: #ffffff;
text-align: center;
text-decoration: none;
vertical-align: middle;
}
.off-canvas-menu {
position: fixed;
top: 0;
left: 0;
width: 11em;
height: 100%;
background: #37474f;
font-size: 1em;
-ms-transform: translateX(-11em);
-webkit-transform: translateX(-11em);
transform: translateX(-100%);
box-shadow: 0 0 10px rgba(0,0,0,0.9);
transition: 0.5s;
z-index: 2;
}
.off-canvas-menu input[type=checkbox] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
display: block;
cursor: pointer;
}
.off-canvas-menu ul {
margin: 0;
padding: 0;
}
.off-canvas-menu > ul {
margin-top: 3.8em;
}
.off-canvas-menu a {
display: block;
padding: 1.0em 1.2em;
color: #fff;
text-decoration: none;
}
.off-canvas-menu li {
position: relative;
float: left;
width: 100%;
list-style: none;
color: #ffffff;
transition: 0.5s;
border-top: 1px solid #555;
}
.off-canvas-menu > ul > li:last-child {
border-bottom: 1px solid #555;
}
.off-canvas-menu ul li:first-child {
border-top: none;
}
.off-canvas-menu ul > li.sub > a:after {
position: relative;
float: right;
content: '+';
font-size: 1.5em;
font-weight: 700;
color: #ffffff;
vertical-align: middle;
transition: 0.5s;
}
.off-canvas-menu .submenu {
max-height: 0;
overflow: hidden;
transition: max-height 0.5s ease-in-out;
border-top: none;
}
.off-canvas-menu input[type=checkbox]:checked ~ .submenu {
border-top: 1px solid #555;
max-height: 999px;
}
.off-canvas-menu input[type=checkbox]:checked ~ a:after {
transform: rotate(45deg);
}
.off-canvas-menu .submenu li {
background: #333;
}
.off-canvas-menu .submenu li a {
padding-left: 30px;
}
.off-canvas-menu .submenu li li a {
padding-left: 35px;
}
.off-canvas-menu .submenu li li li a {
padding-left: 40px;
}
.off-canvas-menu .submenu li.sub {
list-style: none;
}
</style>
<link rel="stylesheet" href="jquery.toast.min.css" />
<link rel="stylesheet" href="switch-input.css" />
<script src="jquery.min.js"></script>
<script src="jquery.toast.min.js"></script>
<script>
function closeWindow() {
if(window.opener != null || window.history.length == 1)
window.close();
else
alert('Please just close this tab in your browser!');
}
function htmlEncode(value){
return $('<div/>').text(value).html().replace(/\n/g,"<br>");
}
function htmlDecode(value){
return $('<div/>').html(value).text();
}
var imageUrl = null;
function toggleImage(url) {
if (!$("#imgholder").is(":visible") || $("#imgholder").attr('src').indexOf(url)<0) {
$("#imgholder").show();
$("#imgholder").off('load');
imageUrl = url;
$("#imgholder").attr('src', 'fully-loading.png');
$("#imgholder").on('load', function () {
$("#imgholder").attr('src', imageUrl + "&time="+new Date().getTime());
$("#imgholder").off('load');
$("#startrefreshbutton").show();
});
}
else {
$("#imgholder").hide();
$("#imgholder").off('load');
$("#startrefreshbutton").hide();
imageUrl = null;
}
}
function startAutoRefresh() {
$("#startrefreshbutton").hide();
if (imageUrl!=null) {
$("#imgholder").attr('src', imageUrl + "&time="+new Date().getTime());
$("#imgholder").on('load', function () {
$("#imgholder").off('load');
setTimeout('startAutoRefresh()', 100); // refresh after the next 100ms
});
}
}
function savePref(key) {
if (!window.jQuery) {
setTimeout(function() { submitForm(key); }, 200);
return;
}
var form = $("#form-"+key);
var editArea = $("#edit-"+key);
var editButton = $("#edit-button-"+key);
var value = $("#value-"+key);
var newValue = "", oldValue = "";
if (form.find('input[name="value"]').attr('type')=='radio') {
newValue = form.find('input[name="value"]:checked').attr('customValue');
oldValue = htmlDecode(value.html());
}
else if (form.find('textarea[name="value"]').length) {
if (form.find('textarea[name="value"]').attr('type')=='json')
oldValue = newValue = "(JSON)";
else {
newValue = form.find('textarea[name="value"]').val();
oldValue = htmlDecode(value.html());
}
}
else if (form.find('input[name="value"]').attr('type')=='password')
oldValue = newValue = "*****";
else {
newValue = form.find('input[name="value"]').val();
oldValue = htmlDecode(value.html());
}
console.log(" Form data: "+form.serialize());
console.log(" New value: "+newValue);
editArea.hide();
value.html(htmlEncode(newValue));
editButton.addClass("disabled");
$.ajax({
dataType: "json",
url: "?type=json",
method: "POST",
data: form.serialize()})
.done(function( json ) {
console.log( "JSON Status: " + json.status+", "+json.statustext );
if (json.status == "OK") {
editButton.removeClass("disabled");
$.toast({
heading: 'Success',
text: json.statustext,
showHideTransition: 'slide',
icon: 'success'
})
}
else if (json.status == "Error") {
value.html(htmlEncode(oldValue));
editButton.removeClass("disabled");
$.toast({
heading: 'Error',
text: json.statustext,
showHideTransition: 'slide',
icon: 'error'
})
}
else {
value.html(htmlEncode(oldValue));
editButton.removeClass("disabled");
$.toast({
heading: 'Error',
text: 'Device communication error',
showHideTransition: 'slide',
icon: 'error'
})
}
})
.fail(function( jqxhr, textStatus, error ) {
console.log(" Request Failed: " + textStatus + ", " + error);
console.log(" Response: "+ jqxhr.responseText);
value.html(htmlEncode(oldValue));
editButton.removeClass("disabled");
$.toast({
heading: 'Error',
text: 'Device communication error',
showHideTransition: 'slide',
icon: 'error'
})
});
}
function saveSwitchPref(input) {
var newValue = ($(input).is(':checked')) ? 'true' : 'false';
var oldValue = !($(input).is(':checked'));
var sid = $(input).attr('id');
console.log('Attr ' + sid + ' changed to ' + newValue + " from " + oldValue );
$(input).prop("disabled",true);
var formData = {
'cmd' : "setBooleanSetting",
'key' : sid,
'value' : newValue
};
$.ajax({
dataType: "json",
url: "?type=json",
method: "POST",
data: formData})
.done(function( json ) {
console.log( "JSON Status: " + json.status+", "+json.statustext );
if (json.status == "OK") {
$.toast({
heading: 'Success',
text: json.statustext,
showHideTransition: 'slide',
icon: 'success'
})
$(input).prop("disabled",false);
}
else if (json.status == "Error") {
$.toast({
heading: 'Error',
text: json.statustext,
showHideTransition: 'slide',
icon: 'error'
})
$(input).prop("checked",oldValue);
$(input).prop("disabled",false);
}
else {
$.toast({
heading: 'Error',
text: 'Device communication error',
showHideTransition: 'slide',
icon: 'error'
})
$(input).prop("checked",oldValue);
$(input).prop("disabled",false);
}
})
.fail(function( jqxhr, textStatus, error ) {
console.log(" Request Failed: " + textStatus + ", " + error);
console.log(" Response: "+ jqxhr.responseText);
$.toast({
heading: 'Error',
text: 'Device communication error',
showHideTransition: 'slide',
icon: 'error'
})
$(input).prop("checked",oldValue);
$(input).prop("disabled",false);
});
}
// Show additional input fields for the fast admin selector
// Select elements by name or in some cases by id provided in addFields attribute on the selector
function showAddFields() {
var form = $("#fastAdminForm");
var actionSelector = $("#actionSelector");
$(".addFields").hide();
$(".addFields").attr("disabled",true)
if ($("#actionSelector option:selected").attr('addFields')) {
var addFields = $("#actionSelector option:selected").attr('addFields').split(",");
for (index = 0; index < addFields.length; ++index) {
form.find('input[name="'+addFields[index]+'"]').show();
form.find('input[name="'+addFields[index]+'"]').attr("disabled",false)
form.find('select[name="'+addFields[index]+'"]').show();
form.find('select[name="'+addFields[index]+'"]').attr("disabled",false)
form.find('select[id="'+addFields[index]+'"]').show();
form.find('select[id="'+addFields[index]+'"]').attr("disabled",false)
form.find('span[name="'+addFields[index]+'"]').css('display', 'inline-block');
form.find('span[name="'+addFields[index]+'"]').attr("disabled",false)
}
}
}
function submitFastAdmin() {
// Check if command is selected
var command = $("#actionSelector").val();
if (command=="") {
console.log("No command selected");
return;
}
// This command should only toggle the embedded image
if ($("#actionSelector option:selected").attr('toggleImage')) {
toggleImage('?cmd='+command);
return;
}
// Show confirmation box
var confirmText = $("#actionSelector option:selected").attr('confirm');
if (confirmText && !confirm(confirmText)) return;
$("#fastAdminForm").submit();
}
function pollWebConsole(startTime){
$.ajax({
type: "GET",
url: "?cmd=getWebConsoleEvents&type=json&startTime="+startTime,
dataType: "json",
async: true,
cache: false,
timeout: 45000,
success: function(data){
// console.log("startTime: "+startTime);
console.log(data);
if (data.status == 'OK') {
for(let i = 0; i < data.events.length; i++) {
var dt = new Date(data.events[i].timestamp);
dt = new Date(dt.getTime() - dt.getTimezoneOffset() * 60000);
$('#console').append(dt.toISOString().match(/\d{2}:\d{2}:\d{2}\.\d{3}/) + ' -- ');
$('#console').append(htmlEncode(data.events[i].message) + "<br/><br/>\n");
}
$('html, body').animate({ scrollTop: $('#console')[0].scrollHeight }, 300);
setTimeout(function () { pollWebConsole(data.lastTime); }, 200);
}
else if (data.status == 'Error') {
$('#console').append(data.statustext + "<br/><br/>\n");
$('html, body').animate({ scrollTop: $('#console')[0].scrollHeight }, 300);
setTimeout(function () { pollWebConsole(startTime); }, 20000);
}
else
setTimeout(function () { pollWebConsole(startTime); }, 200);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
console.log("error: " + textStatus + " (" + errorThrown + ")");
setTimeout(function () { pollWebConsole(startTime); }, 10000);
}
});
};
</script>
</head>
<body>
<input type="checkbox" id="hamburger-checkbox">
<label for="hamburger-checkbox" class="hamburger"><span></span></label>
<div class="overlay"></div>
<div class="banner">
<a href="?cmd=home"><img class="header" src="fully-header-web-90.png" /></a>
</div><nav class='main-menu'><header><a href='?cmd=home'>Fully Remote Admin </a></header></nav><nav class='off-canvas-menu'><ul>
<li><a href='?cmd=home' title='Login'>Login</a></li>
</ul></nav>
<div class='content'>
<h1>Please login</h1>
<p class='error'>Please login first</p>
<form action='?' method='post'>
<p class='formline scale110'>Password: <input type='password' name='password'>
<input type='submit' name='submit' value='OK' class='button'>
<input type='hidden' name='return' value='/?cmd=screenOff&password=[1337]'><input type='hidden' name='cmd' value='login'></p></form>
</div></body></html>