implement hyperion restart via webui (#242)
* first try * implement hyperion restart. core function is good, but needs a beeter structuring- something for next refactoring session ;-) * several fixes (including osx) merge with upstream some refactoring * add some eye candy to webui
This commit is contained in:
parent
a04f34eab7
commit
eeb9b0f7da
|
@ -8,7 +8,7 @@
|
|||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div id='editor_container'></div>
|
||||
<button id='btn_submit'>Submit (console.log)</button>
|
||||
<button id='btn_submit' class="btn btn-danger">Submit - currently will destroy your config!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -61,3 +61,7 @@ table.borderless td,table.borderless th{border: none !important;}
|
|||
top: 0;
|
||||
z-index:99999;
|
||||
}
|
||||
|
||||
#page-content {
|
||||
padding-bottom:50px;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -36,6 +36,11 @@
|
|||
<script src="js/lib/jquery-lang.js" charset="utf-8" type="text/javascript"></script>
|
||||
<script src="js/lib/js.cookie.js"></script>
|
||||
|
||||
<!-- jquery ui -->
|
||||
<link href="css/jquery-ui/jquery-ui.min.css" rel="stylesheet">
|
||||
<link href="css/jquery-ui/jquery-ui.structure.min.css" rel="stylesheet">
|
||||
<link href="css/jquery-ui/jquery-ui.theme.min.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
// Create language switcher instance
|
||||
var lang = new Lang();
|
||||
|
@ -195,7 +200,7 @@
|
|||
</ul>
|
||||
<!-- /.navbar-top-left -->
|
||||
|
||||
<div class="navbar-default sidebar" role="navigation">
|
||||
<div id="main-nav" class="navbar-default sidebar" role="navigation">
|
||||
<div class="sidebar-nav navbar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
<li> <a class="active" id="load_dashboard"><i class="fa fa-dashboard fa-fw"></i><span lang="en" data-lang-token="main_menu_dashboard_token">Dashboard</span></a> </li>
|
||||
|
@ -225,10 +230,10 @@
|
|||
|
||||
<!-- Page Content -->
|
||||
<div id="page-wrapper" style="padding-top:10px">
|
||||
<div id="hyperion_restart_notify" class="alert alert-warning" style="display:none;padding:10px;margin:0">
|
||||
<div id="hyperion_reload_notify" class="alert alert-warning" style="display:none;padding:10px;margin:0">
|
||||
<div class="panel-danger" style="text-align:right">
|
||||
<div style="float:left">Hyperion Configuration is modified. To make it active, restart Hyperion.</div>
|
||||
<button id="btn_hyperion_restart" class="btn btn-danger">Restart Hyperion</button>
|
||||
<button id="btn_hyperion_reload" class="btn btn-danger">Restart Hyperion</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -264,6 +269,7 @@
|
|||
<!-- Custom Theme JavaScript -->
|
||||
<script src="/js/lib/sb-admin-2.js"></script>
|
||||
|
||||
<script src="/js/lib/jquery-ui.min.js"></script>
|
||||
<script src="/js/content_index.js"></script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -50,19 +50,19 @@ $(hyperion).one("cmd-config-getschema", function(event) {
|
|||
schema: {
|
||||
title:'',
|
||||
properties: {
|
||||
/*blackborderdetector,
|
||||
blackborderdetector,
|
||||
color,
|
||||
effects,
|
||||
forwarder,
|
||||
initialEffect,
|
||||
kodiVideoChecker,
|
||||
smoothing,*/
|
||||
logger//,
|
||||
/*jsonServer,
|
||||
smoothing,
|
||||
logger,
|
||||
jsonServer,
|
||||
protoServer,
|
||||
boblightServer,
|
||||
udpListener,
|
||||
webConfig*/
|
||||
webConfig
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -74,10 +74,10 @@ $(hyperion).one("cmd-config-getschema", function(event) {
|
|||
$('#editor_container h3').first().remove();
|
||||
|
||||
//Called everytime a Input Field is changed = No need for save button
|
||||
general_conf_editor.off().on('change',function() {
|
||||
console.log(JSON.stringify(general_conf_editor.getValue()));
|
||||
requestWriteConfig(general_conf_editor.getValue());
|
||||
});
|
||||
// general_conf_editor.off().on('change',function() {
|
||||
// console.log(JSON.stringify(general_conf_editor.getValue()));
|
||||
// requestWriteConfig(general_conf_editor.getValue());
|
||||
// });
|
||||
|
||||
//Alternative Function with submit button to get Values
|
||||
$('btn_submit').off().on('click',function() {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
$(document).ready( function() {
|
||||
$("#main-nav").hide();
|
||||
$("#page-content").hide();
|
||||
$("#loading_overlay").addClass("overlay");
|
||||
loadContentTo("#container_connection_lost","connection_lost");
|
||||
initWebSocket();
|
||||
|
@ -22,9 +24,9 @@ $(document).ready( function() {
|
|||
cleanCurrentVersion = currentVersion.replace(/\./g, '');
|
||||
|
||||
if (parsedServerInfoJSON.info.hyperion[0].config_modified)
|
||||
$("#hyperion_restart_notify").fadeIn("fast");
|
||||
$("#hyperion_reload_notify").fadeIn("fast");
|
||||
else
|
||||
$("#hyperion_restart_notify").fadeOut("fast");
|
||||
$("#hyperion_reload_notify").fadeOut("fast");
|
||||
|
||||
// get active led device
|
||||
var leddevice = parsedServerInfoJSON.info.ledDevices.active;
|
||||
|
@ -59,6 +61,9 @@ $(document).ready( function() {
|
|||
}
|
||||
});
|
||||
$("#loading_overlay").removeClass("overlay");
|
||||
$("#main-nav").show('slide', {direction: 'left'}, 1000);
|
||||
$("#page-content").show('slide', {direction: 'down'}, 2000);
|
||||
|
||||
}); // end cmd-serverinfo
|
||||
|
||||
$(hyperion).one("cmd-config-getschema", function(event) {
|
||||
|
@ -75,6 +80,13 @@ $(document).ready( function() {
|
|||
requestServerInfo();
|
||||
});
|
||||
|
||||
$("#btn_hyperion_reload").on("click", function(){
|
||||
$(hyperion).off();
|
||||
requestServerConfigReload();
|
||||
watchdog = 1;
|
||||
$("#wrapper").fadeOut("slow");
|
||||
cron();
|
||||
});
|
||||
});
|
||||
|
||||
$(function(){
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,6 +1,21 @@
|
|||
|
||||
var ledsCustomCfgInitialized = false;
|
||||
|
||||
function get_hue_lights(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'http://'+$("#ip").val()+'/api/'+$("#user").val()+'/lights',
|
||||
processData: false,
|
||||
contentType: 'application/json',
|
||||
success: function(r) {
|
||||
for(var lightid in r){
|
||||
//console.log(r[lightid].name);
|
||||
$('#hue_lights').append('ID: '+lightid+' Name: '+r[lightid].name+'<br />');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
// ------------------------------------------------------------------
|
||||
|
@ -157,7 +172,7 @@ $(document).ready(function() {
|
|||
if (isCurrentDevice)
|
||||
{
|
||||
specificOptions_val = grabber_conf_editor.getEditor("root.specificOptions").getValue()
|
||||
for(var key in grabber_conf_editor.getEditor("root.specificOptions").getValue()){
|
||||
for(var key in specificOptions_val){
|
||||
values_specific[key] = (key in parsedConfJSON.device) ? parsedConfJSON.device[key] : specificOptions_val[key];
|
||||
};
|
||||
|
||||
|
|
|
@ -155,6 +155,10 @@ function requestServerConfig() {
|
|||
websocket.send('{"command":"config", "tan":'+wsTan+',"subcommand":"getconfig"}');
|
||||
}
|
||||
|
||||
function requestServerConfigReload() {
|
||||
websocket.send('{"command":"config", "tan":'+wsTan+',"subcommand":"reload"}');
|
||||
}
|
||||
|
||||
function requestLedColorsStart() {
|
||||
ledStreamActive=true;
|
||||
websocket.send('{"command":"ledcolors", "tan":'+wsTan+',"subcommand":"ledstream-start"}');
|
||||
|
@ -197,18 +201,3 @@ function requestWriteConfig(config, create, overwrite)
|
|||
var overwrite = (typeof overwrite !== 'undefined') ? overwrite : false;
|
||||
websocket.send('{"command":"config","subcommand":"setconfig", "tan":'+wsTan+', "config":'+JSON.stringify(config)+',"create":'+create+', "overwrite":'+overwrite+'}');
|
||||
}
|
||||
|
||||
function get_hue_lights(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'http://'+$("#ip").val()+'/api/'+$("#user").val()+'/lights',
|
||||
processData: false,
|
||||
contentType: 'application/json',
|
||||
success: function(r) {
|
||||
for(var lightid in r){
|
||||
//console.log(r[lightid].name);
|
||||
$('#hue_lights').append('ID: '+lightid+' Name: '+r[lightid].name+'<br />');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -7,7 +7,7 @@ function bindNavToContent(containerId, fileName, loadNow)
|
|||
});
|
||||
if (loadNow)
|
||||
{
|
||||
$("#page-content").load("/content/"+fileName+".html");
|
||||
$(containerId).trigger("click");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
namespace FileUtils {
|
||||
|
||||
std::string getBaseName( std::string sourceFile);
|
||||
std::string command_exec(const char* cmd);
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#include <string>
|
||||
|
||||
namespace Process {
|
||||
|
||||
void restartHyperion(bool asNewProcess=false);
|
||||
std::string command_exec(const char* cmd);
|
||||
|
||||
};
|
|
@ -657,24 +657,26 @@ unsigned Hyperion::getLedCount() const
|
|||
|
||||
bool Hyperion::configModified()
|
||||
{
|
||||
bool isModified = false;
|
||||
QFile f(_configFile.c_str());
|
||||
if (f.open(QFile::ReadOnly))
|
||||
{
|
||||
QCryptographicHash hash(QCryptographicHash::Sha1);
|
||||
if (hash.addData(&f))
|
||||
if (hash.addData(&f))
|
||||
{
|
||||
if (_configHash.size() == 0)
|
||||
{
|
||||
if (_configHash.size() == 0)
|
||||
{
|
||||
_configHash = hash.result();
|
||||
qDebug(_configHash.toHex());
|
||||
return false;
|
||||
}
|
||||
return _configHash != hash.result();
|
||||
_configHash = hash.result();
|
||||
}
|
||||
else
|
||||
{
|
||||
isModified = _configHash != hash.result();
|
||||
}
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
|
||||
return false;
|
||||
return isModified;
|
||||
}
|
||||
|
||||
void Hyperion::registerPriority(const std::string name, const int priority)
|
||||
|
|
|
@ -1057,7 +1057,15 @@
|
|||
{
|
||||
"paths" :
|
||||
{
|
||||
"type" : "array"
|
||||
"type" : "array",
|
||||
"title" : "List of folders to additional effects",
|
||||
"propertyOrder" : 1
|
||||
},
|
||||
"disable" :
|
||||
{
|
||||
"type" : "array",
|
||||
"title" : "List of disabled effects",
|
||||
"propertyOrder" : 2
|
||||
}
|
||||
},
|
||||
"additionalProperties" : false
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#include <unistd.h>
|
||||
|
||||
// stl includes
|
||||
#include <iostream>
|
||||
|
@ -15,6 +16,7 @@
|
|||
#include <QHostInfo>
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QCoreApplication>
|
||||
|
||||
// hyperion util includes
|
||||
#include <hyperion/ImageProcessorFactory.h>
|
||||
|
@ -27,6 +29,7 @@
|
|||
#include <leddevice/LedDevice.h>
|
||||
#include <HyperionConfig.h>
|
||||
#include <utils/jsonschema/JsonFactory.h>
|
||||
#include <utils/Process.h>
|
||||
|
||||
// project includes
|
||||
#include "JsonClientConnection.h"
|
||||
|
@ -883,6 +886,12 @@ void JsonClientConnection::handleConfigCommand(const Json::Value & message, cons
|
|||
{
|
||||
handleConfigSetCommand(message, full_command, tan);
|
||||
}
|
||||
else if (subcommand == "reload")
|
||||
{
|
||||
// restart hyperion, this code must be put in some own class ...
|
||||
Process::restartHyperion();
|
||||
sendErrorReply("failed to restart hyperion", full_command, tan);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendErrorReply("unknown or missing subcommand", full_command, tan);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"subcommand": {
|
||||
"type" : "string",
|
||||
"required" : true,
|
||||
"enum" : ["getconfig","setconfig","getschema"]
|
||||
"enum" : ["getconfig","setconfig","getschema","reload"]
|
||||
},
|
||||
"tan" : {
|
||||
"type" : "integer"
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
"type" : "array",
|
||||
"propertyOrder" : 9,
|
||||
"default" : [1.0,1.0,1.0],
|
||||
"maxItems" : 3,
|
||||
"minItems" : 3,
|
||||
"format" : "table",
|
||||
"items" : {
|
||||
"type" : "number",
|
||||
"minimum" : 0.0,
|
||||
|
|
|
@ -21,6 +21,8 @@ add_library(hyperion-utils
|
|||
${CURRENT_HEADER_DIR}/Sleep.h
|
||||
${CURRENT_HEADER_DIR}/FileUtils.h
|
||||
${CURRENT_SOURCE_DIR}/FileUtils.cpp
|
||||
${CURRENT_HEADER_DIR}/Process.h
|
||||
${CURRENT_SOURCE_DIR}/Process.cpp
|
||||
|
||||
${CURRENT_HEADER_DIR}/Logger.h
|
||||
${CURRENT_SOURCE_DIR}/Logger.cpp
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
#include <utils/FileUtils.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
namespace FileUtils {
|
||||
|
@ -15,21 +10,5 @@ std::string getBaseName( std::string sourceFile)
|
|||
return fi.fileName().toStdString();
|
||||
}
|
||||
|
||||
std::string command_exec(const char* cmd)
|
||||
{
|
||||
char buffer[128];
|
||||
std::string result = "";
|
||||
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
|
||||
if (pipe)
|
||||
{
|
||||
while (!feof(pipe.get()))
|
||||
{
|
||||
if (fgets(buffer, 128, pipe.get()) != NULL)
|
||||
result += buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
#include <utils/Process.h>
|
||||
#include <utils/Logger.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QStringList>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Process {
|
||||
|
||||
void restartHyperion(bool asNewProcess)
|
||||
{
|
||||
Logger* log = Logger::getInstance("Process");
|
||||
std::cout << std::endl
|
||||
<< " *******************************************" << std::endl
|
||||
<< " * hyperion will restart now *" << std::endl
|
||||
<< " *******************************************" << std::endl << std::endl;
|
||||
|
||||
|
||||
QStringList qargs = QCoreApplication::arguments();
|
||||
int size = qargs.size();
|
||||
char *args[size+1];
|
||||
args[size] = nullptr;
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
int str_size = qargs[i].toLocal8Bit().size();
|
||||
args[i] = new char[str_size+1];
|
||||
strncpy(args[i], qargs[i].toLocal8Bit().constData(),str_size );
|
||||
args[i][str_size] = '\0';
|
||||
}
|
||||
|
||||
execv(args[0],args);
|
||||
Error(log, "error while restarting hyperion");
|
||||
}
|
||||
|
||||
std::string command_exec(const char* cmd)
|
||||
{
|
||||
char buffer[128];
|
||||
std::string result = "";
|
||||
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
|
||||
if (pipe)
|
||||
{
|
||||
while (!feof(pipe.get()))
|
||||
{
|
||||
if (fgets(buffer, 128, pipe.get()) != NULL)
|
||||
result += buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
|
@ -108,7 +108,7 @@ void QJsonSchemaChecker::validate(const QJsonValue & value, const QJsonObject &s
|
|||
; // nothing to do. value is present so always oke
|
||||
else if (attribute == "id")
|
||||
; // references have already been collected
|
||||
else if (attribute == "title" || attribute == "description" || attribute == "default" || attribute == "format"
|
||||
else if (attribute == "title" || attribute == "description" || attribute == "default" || attribute == "format"
|
||||
|| attribute == "defaultProperties" || attribute == "propertyOrder")
|
||||
; // nothing to do.
|
||||
else
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "CgiHandler.h"
|
||||
#include "QtHttpHeader.h"
|
||||
#include <utils/FileUtils.h>
|
||||
#include <utils/Process.h>
|
||||
|
||||
CgiHandler::CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent)
|
||||
: QObject(parent)
|
||||
|
@ -96,7 +97,7 @@ void CgiHandler::cmd_runscript(const QStringList & args, QtHttpReply * reply)
|
|||
|
||||
if (QFile::exists(scriptFilePath) && !interpreter.isEmpty())
|
||||
{
|
||||
QByteArray data = FileUtils::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str();
|
||||
QByteArray data = Process::command_exec(QString(interpreter + " " + scriptFilePath).toUtf8().constData()).c_str();
|
||||
|
||||
reply->addHeader ("Content-Type", "text/plain");
|
||||
reply->appendRawData (data);
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
WebConfig::WebConfig(QObject * parent)
|
||||
: QObject(parent)
|
||||
, _hyperion(Hyperion::getInstance())
|
||||
, _port(WEBCONFIG_DEFAULT_PORT)
|
||||
, _server(nullptr)
|
||||
{
|
||||
_baseUrl = WEBCONFIG_DEFAULT_PATH;
|
||||
const Json::Value &config = _hyperion->getJsonConfig();
|
||||
Logger* log = Logger::getInstance("WEBSERVER");
|
||||
_port = WEBCONFIG_DEFAULT_PORT;
|
||||
_baseUrl = WEBCONFIG_DEFAULT_PATH;
|
||||
const Json::Value &config = _hyperion->getJsonConfig();
|
||||
|
||||
bool webconfigEnable = true;
|
||||
|
||||
|
@ -19,7 +19,7 @@ WebConfig::WebConfig(QObject * parent)
|
|||
{
|
||||
const Json::Value & webconfigConfig = config["webConfig"];
|
||||
webconfigEnable = webconfigConfig.get("enable", true).asBool();
|
||||
_port = webconfigConfig.get("port", WEBCONFIG_DEFAULT_PORT).asUInt();
|
||||
_port = webconfigConfig.get("port", _port).asUInt();
|
||||
_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", _baseUrl.toStdString()).asString() );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue