2016-08-20 16:36:01 +02:00
2016-08-30 23:25:27 +02:00
// global vars
2017-01-17 21:53:35 +01:00
var webPrio = 1 ;
2017-02-28 17:53:41 +01:00
var webOrigin = "Web Configuration" ;
2017-02-08 14:36:28 +01:00
var showOptHelp ;
2017-03-18 00:05:04 +01:00
var currentVersion ;
2016-08-30 23:25:27 +02:00
var latestVersion ;
2017-02-08 14:36:28 +01:00
var serverInfo = { } ;
2016-09-05 17:26:29 +02:00
var parsedUpdateJSON = { } ;
2017-02-08 14:36:28 +01:00
var serverSchema = { } ;
var serverConfig = { } ;
var schema ;
2017-03-18 00:05:04 +01:00
var sysInfo = { } ;
2017-02-08 14:36:28 +01:00
var jsonPort = 19444 ;
2016-09-03 15:54:33 +02:00
var websocket = null ;
var hyperion = { } ;
var wsTan = 1 ;
2016-12-18 19:00:14 +01:00
var ledStreamActive = false ;
var imageStreamActive = false ;
var loggingStreamActive = false ;
2016-11-26 22:46:16 +01:00
var loggingHandlerInstalled = false ;
2016-09-07 20:10:37 +02:00
var watchdog = 0 ;
2016-12-18 19:00:14 +01:00
var debugMessagesActive = true ;
2017-03-24 10:17:36 +01:00
var wSess = [ ] ;
2016-12-21 18:24:03 +01:00
function initRestart ( )
{
$ ( hyperion ) . off ( ) ;
requestServerConfigReload ( ) ;
2017-01-15 10:32:09 +01:00
watchdog = 10 ;
2017-01-17 21:53:35 +01:00
connectionLostDetection ( 'restart' ) ;
2016-12-21 18:24:03 +01:00
}
2017-01-17 21:53:35 +01:00
function connectionLostDetection ( type )
2017-01-15 10:32:09 +01:00
{
2017-04-03 05:19:05 +02:00
if ( watchdog > 2 )
2016-09-06 10:14:54 +02:00
{
var interval _id = window . setInterval ( "" , 9999 ) ; // Get a reference to the last
for ( var i = 1 ; i < interval _id ; i ++ )
window . clearInterval ( i ) ;
2017-01-17 21:53:35 +01:00
if ( type == 'restart' )
{
2017-09-04 23:12:59 +02:00
$ ( "body" ) . html ( $ ( "#container_restart" ) . html ( ) ) ;
// setTimeout delay for probably slower systems, some browser don't execute THIS action
setTimeout ( restartAction , 250 ) ;
2017-01-17 21:53:35 +01:00
}
else
{
$ ( "body" ) . html ( $ ( "#container_connection_lost" ) . html ( ) ) ;
connectionLostAction ( ) ;
}
2016-09-06 10:14:54 +02:00
}
2017-01-15 10:32:09 +01:00
else
{
$ . get ( "/cgi/cfg_jsonserver" , function ( ) { watchdog = 0 } ) . fail ( function ( ) { watchdog ++ ; } ) ;
}
2016-09-03 15:54:33 +02:00
}
2016-08-31 00:22:17 +02:00
2017-01-15 10:32:09 +01:00
setInterval ( connectionLostDetection , 3000 ) ;
2016-12-21 18:24:03 +01:00
2016-09-03 15:54:33 +02:00
// init websocket to hyperion and bind socket events to jquery events of $(hyperion) object
function initWebSocket ( )
{
if ( "WebSocket" in window )
{
if ( websocket == null )
{
$ . ajax ( { url : "/cgi/cfg_jsonserver" } ) . done ( function ( data ) {
2017-02-08 14:36:28 +01:00
jsonPort = data . substr ( 1 ) ;
2016-09-03 15:54:33 +02:00
websocket = new WebSocket ( 'ws://' + document . location . hostname + data ) ;
2016-08-31 00:22:17 +02:00
2016-09-03 15:54:33 +02:00
websocket . onopen = function ( event ) {
$ ( hyperion ) . trigger ( { type : "open" } ) ;
2017-03-18 00:05:04 +01:00
2016-09-06 10:14:54 +02:00
$ ( hyperion ) . on ( "cmd-serverinfo" , function ( event ) {
2016-09-07 20:10:37 +02:00
watchdog = 0 ;
2016-09-06 10:14:54 +02:00
} ) ;
2016-09-03 15:54:33 +02:00
} ;
2016-08-30 23:25:27 +02:00
2016-09-03 15:54:33 +02:00
websocket . onclose = function ( event ) {
// See http://tools.ietf.org/html/rfc6455#section-7.4.1
var reason ;
switch ( event . code )
{
case 1000 : reason = "Normal closure, meaning that the purpose for which the connection was established has been fulfilled." ; break ;
case 1001 : reason = "An endpoint is \"going away\", such as a server going down or a browser having navigated away from a page." ; break ;
case 1002 : reason = "An endpoint is terminating the connection due to a protocol error" ; break ;
case 1003 : reason = "An endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it receives a binary message)." ; break ;
case 1004 : reason = "Reserved. The specific meaning might be defined in the future." ; break ;
case 1005 : reason = "No status code was actually present." ; break ;
case 1006 : reason = "The connection was closed abnormally, e.g., without sending or receiving a Close control frame" ; break ;
case 1007 : reason = "An endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message (e.g., non-UTF-8 [http://tools.ietf.org/html/rfc3629] data within a text message)." ; break ;
case 1008 : reason = "An endpoint is terminating the connection because it has received a message that \"violates its policy\". This reason is given either if there is no other sutible reason, or if there is a need to hide specific details about the policy." ; break ;
case 1009 : reason = "An endpoint is terminating the connection because it has received a message that is too big for it to process." ; break ;
case 1010 : reason = "An endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the server didn't return them in the response message of the WebSocket handshake. <br /> Specifically, the extensions that are needed are: " + event . reason ; break ;
case 1011 : reason = "A server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request." ; break ;
case 1015 : reason = "The connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified)." ; break ;
default : reason = "Unknown reason" ;
}
2017-09-16 09:08:21 +02:00
console . log ( "[websocket::onclose] " + reason )
2016-09-03 15:54:33 +02:00
$ ( hyperion ) . trigger ( { type : "close" , reason : reason } ) ;
2017-02-08 14:36:28 +01:00
watchdog = 10 ;
connectionLostDetection ( ) ;
2016-09-03 15:54:33 +02:00
} ;
2016-08-30 23:25:27 +02:00
2016-09-03 15:54:33 +02:00
websocket . onmessage = function ( event ) {
try
{
response = JSON . parse ( event . data ) ;
success = response . success ;
cmd = response . command ;
if ( success )
{
$ ( hyperion ) . trigger ( { type : "cmd-" + cmd , response : response } ) ;
}
else
{
error = response . hasOwnProperty ( "error" ) ? response . error : "unknown" ;
$ ( hyperion ) . trigger ( { type : "error" , reason : error } ) ;
console . log ( "[websocket::onmessage] " + error )
}
}
catch ( exception _error )
{
$ ( hyperion ) . trigger ( { type : "error" , reason : exception _error } ) ;
console . log ( "[websocket::onmessage] " + exception _error )
}
} ;
2016-08-30 23:25:27 +02:00
2016-09-03 15:54:33 +02:00
websocket . onerror = function ( error ) {
$ ( hyperion ) . trigger ( { type : "error" , reason : error } ) ;
console . log ( "[websocket::onerror] " + error )
} ;
} ) ;
}
}
else
{
$ ( hyperion ) . trigger ( "error" ) ;
alert ( "Websocket is not supported by your browser" ) ;
return ;
}
}
2016-08-31 00:22:17 +02:00
2016-12-05 11:10:44 +01:00
function sendToHyperion ( command , subcommand , msg )
{
if ( typeof subcommand != 'undefined' && subcommand . length > 0 )
subcommand = ',"subcommand":"' + subcommand + '"' ;
else
subcommand = "" ;
2016-09-06 10:14:54 +02:00
2016-12-05 11:10:44 +01:00
if ( typeof msg != 'undefined' && msg . length > 0 )
msg = "," + msg ;
else
msg = "" ;
websocket . send ( encode _utf8 ( '{"command":"' + command + '", "tan":' + wsTan + subcommand + msg + '}' ) ) ;
}
2016-09-06 10:14:54 +02:00
2016-09-03 15:54:33 +02:00
// -----------------------------------------------------------
// wrapped server commands
2016-08-31 00:22:17 +02:00
2016-09-06 10:14:54 +02:00
// also used for watchdog
2016-12-05 23:16:14 +01:00
function requestServerInfo ( )
{
2016-12-05 11:10:44 +01:00
sendToHyperion ( "serverinfo" ) ;
2016-09-03 15:54:33 +02:00
}
2016-08-30 23:25:27 +02:00
2017-03-04 22:17:42 +01:00
function requestSysInfo ( )
{
sendToHyperion ( "sysinfo" ) ;
}
2016-12-05 23:16:14 +01:00
function requestServerConfigSchema ( )
{
2016-12-05 11:10:44 +01:00
sendToHyperion ( "config" , "getschema" ) ;
2016-09-03 15:54:33 +02:00
}
2016-12-05 23:16:14 +01:00
function requestServerConfig ( )
{
2016-12-05 11:10:44 +01:00
sendToHyperion ( "config" , "getconfig" ) ;
2016-09-05 17:26:29 +02:00
}
2016-12-05 23:16:14 +01:00
function requestServerConfigReload ( )
{
2016-12-05 11:10:44 +01:00
sendToHyperion ( "config" , "reload" ) ;
2016-09-15 20:42:58 +02:00
}
2016-12-05 23:16:14 +01:00
function requestLedColorsStart ( )
{
2016-09-07 20:10:37 +02:00
ledStreamActive = true ;
2016-12-05 11:10:44 +01:00
sendToHyperion ( "ledcolors" , "ledstream-start" ) ;
2016-09-05 17:26:29 +02:00
}
2016-12-05 23:16:14 +01:00
function requestLedColorsStop ( )
{
2016-09-07 20:10:37 +02:00
ledStreamActive = false ;
2016-12-05 11:10:44 +01:00
sendToHyperion ( "ledcolors" , "ledstream-stop" ) ;
2016-09-06 10:14:54 +02:00
}
2016-12-18 19:00:14 +01:00
function requestLedImageStart ( )
{
imageStreamActive = true ;
sendToHyperion ( "ledcolors" , "imagestream-start" ) ;
}
function requestLedImageStop ( )
{
imageStreamActive = false ;
sendToHyperion ( "ledcolors" , "imagestream-stop" ) ;
}
2017-01-17 21:53:35 +01:00
function requestPriorityClear ( prio )
2016-12-05 23:16:14 +01:00
{
2017-01-17 21:53:35 +01:00
if ( typeof prio !== 'number' )
prio = webPrio ;
sendToHyperion ( "clear" , "" , '"priority":' + prio + '' ) ;
2016-09-03 15:54:33 +02:00
}
2017-03-24 10:17:36 +01:00
function requestClearAll ( )
{
sendToHyperion ( "clearall" ) ;
}
2017-02-28 17:53:41 +01:00
function requestPlayEffect ( effectName , duration )
2017-09-04 23:12:59 +02:00
{
2017-03-02 11:52:27 +01:00
sendToHyperion ( "effect" , "" , '"effect":{"name":"' + effectName + '"},"priority":' + webPrio + ',"duration":' + validateDuration ( duration ) + ',"origin":"' + webOrigin + '"' ) ;
2017-02-28 17:53:41 +01:00
}
function requestSetColor ( r , g , b , duration )
2017-09-04 23:12:59 +02:00
{
2017-03-02 11:52:27 +01:00
sendToHyperion ( "color" , "" , '"color":[' + r + ',' + g + ',' + b + '], "priority":' + webPrio + ',"duration":' + validateDuration ( duration ) + ',"origin":"' + webOrigin + '"' ) ;
2016-09-03 15:54:33 +02:00
}
2017-02-28 17:53:41 +01:00
function requestSetImage ( data , width , height , duration )
2017-09-04 23:12:59 +02:00
{
2017-03-02 11:52:27 +01:00
sendToHyperion ( "image" , "" , '"imagedata":"' + data + '", "imagewidth":' + width + ',"imageheight":' + height + ', "priority":' + webPrio + ',"duration":' + validateDuration ( duration ) + '' ) ;
2016-09-03 15:54:33 +02:00
}
2016-12-05 23:16:14 +01:00
function requestSetComponentState ( comp , state )
{
2016-12-05 11:10:44 +01:00
state _str = state ? "true" : "false" ;
sendToHyperion ( "componentstate" , "" , '"componentstate":{"component":"' + comp + '","state":' + state _str + '}' ) ;
2016-09-03 15:54:33 +02:00
}
2016-09-09 10:15:35 +02:00
function requestSetSource ( prio )
2016-09-03 15:54:33 +02:00
{
if ( prio == "auto" )
2016-12-05 11:10:44 +01:00
sendToHyperion ( "sourceselect" , "" , '"auto":true' ) ;
2016-09-03 15:54:33 +02:00
else
2016-12-05 11:10:44 +01:00
sendToHyperion ( "sourceselect" , "" , '"priority":' + prio ) ;
2016-09-03 15:54:33 +02:00
}
2016-08-31 00:22:17 +02:00
2017-01-17 21:53:35 +01:00
function requestWriteConfig ( config , full )
2016-09-09 10:15:35 +02:00
{
2017-01-17 21:53:35 +01:00
if ( full === true )
2017-02-08 14:36:28 +01:00
serverConfig = config ;
2017-01-17 21:53:35 +01:00
else
{
jQuery . each ( config , function ( i , val ) {
2017-02-08 14:36:28 +01:00
serverConfig [ i ] = val ;
2017-01-17 21:53:35 +01:00
} ) ;
}
2016-12-05 11:10:44 +01:00
2017-09-16 09:08:21 +02:00
sendToHyperion ( "config" , "setconfig" , '"config":' + JSON . stringify ( serverConfig ) ) ;
2016-09-09 10:15:35 +02:00
}
2016-10-30 17:54:38 +01:00
function requestWriteEffect ( effectName , effectPy , effectArgs )
{
var cutArgs = effectArgs . slice ( 1 , - 1 ) ;
2016-12-05 11:10:44 +01:00
sendToHyperion ( "create-effect" , "" , '"name":"' + effectName + '", "script":"' + effectPy + '", ' + cutArgs ) ;
2016-10-30 22:59:45 +01:00
}
2016-12-05 23:16:14 +01:00
function requestTestEffect ( effectName , effectPy , effectArgs )
{
2017-10-12 11:55:03 +02:00
sendToHyperion ( "effect" , "" , '"effect":{"name":"' + effectName + '", "args":' + effectArgs + '}, "priority":' + webPrio + ', "origin":"' + webOrigin + '", "pythonScript":"' + effectPy + '"' ) ;
2016-10-30 22:59:45 +01:00
}
2016-11-18 18:39:27 +01:00
2016-12-05 11:10:44 +01:00
function requestDeleteEffect ( effectName )
{
sendToHyperion ( "delete-effect" , "" , '"name":"' + effectName + '"' ) ;
2016-11-18 18:39:27 +01:00
}
2016-11-26 22:46:16 +01:00
2016-12-05 11:10:44 +01:00
function requestLoggingStart ( )
{
2016-11-26 22:46:16 +01:00
loggingStreamActive = true ;
2016-12-05 11:10:44 +01:00
sendToHyperion ( "logging" , "start" ) ;
2016-11-26 22:46:16 +01:00
}
2016-12-05 11:10:44 +01:00
function requestLoggingStop ( )
{
2016-11-26 22:46:16 +01:00
loggingStreamActive = false ;
2016-12-05 11:10:44 +01:00
sendToHyperion ( "logging" , "stop" ) ;
2016-11-26 22:46:16 +01:00
}
2016-12-21 18:24:03 +01:00
function requestMappingType ( type )
{
sendToHyperion ( "processing" , "" , '"mappingType": "' + type + '"' ) ;
}
2017-09-04 23:12:59 +02:00
function requestVideoMode ( newMode )
{
sendToHyperion ( "videomode" , "" , '"videoMode": "' + newMode + '"' ) ;
}
2017-02-08 14:36:28 +01:00
function requestAdjustment ( type , value , complete )
{
if ( complete === true )
sendToHyperion ( "adjustment" , "" , '"adjustment": ' + type + '' ) ;
2017-09-04 23:12:59 +02:00
else
2017-02-08 14:36:28 +01:00
sendToHyperion ( "adjustment" , "" , '"adjustment": {"' + type + '": ' + value + '}' ) ;
}