2017-03-02 09:35:26 +00:00
|
|
|
"use strict";
|
2017-03-02 12:39:59 +00:00
|
|
|
FW_version["console.js"] = "$Id$";
|
2017-03-02 09:35:26 +00:00
|
|
|
|
2012-02-26 13:36:53 +00:00
|
|
|
var consConn;
|
2019-07-28 18:22:09 +00:00
|
|
|
var debug;
|
2012-02-26 13:36:53 +00:00
|
|
|
|
2017-03-03 08:26:40 +00:00
|
|
|
var consFilter, oldFilter, consFType="";
|
2015-10-26 18:49:54 +00:00
|
|
|
var consLastIndex = 0;
|
2015-12-21 10:33:45 +00:00
|
|
|
var withLog = 0;
|
2016-04-07 18:58:11 +00:00
|
|
|
var mustScroll = 1;
|
|
|
|
|
2019-07-28 18:22:09 +00:00
|
|
|
log("Event monitor is starting!");
|
2014-08-10 13:52:25 +00:00
|
|
|
|
2017-03-01 17:08:25 +00:00
|
|
|
function
|
|
|
|
cons_closeConn()
|
|
|
|
{
|
|
|
|
if(!consConn)
|
|
|
|
return;
|
|
|
|
if(typeof consConn.close == "function")
|
|
|
|
consConn.close();
|
|
|
|
else if(typeof consConn.abort == "function")
|
|
|
|
consConn.abort();
|
|
|
|
consConn = undefined;
|
|
|
|
}
|
|
|
|
|
2012-02-26 13:36:53 +00:00
|
|
|
function
|
2017-01-04 21:31:55 +00:00
|
|
|
consUpdate(evt)
|
2012-02-26 13:36:53 +00:00
|
|
|
{
|
2017-01-04 21:31:55 +00:00
|
|
|
var errstr = "Connection lost, trying a reconnect every 5 seconds.";
|
|
|
|
var new_content = "";
|
2014-02-12 09:10:01 +00:00
|
|
|
|
2017-05-01 13:14:52 +00:00
|
|
|
if((typeof WebSocket == "function" || typeof WebSocket == "object") && evt &&
|
|
|
|
evt.target instanceof WebSocket) {
|
2017-01-04 21:31:55 +00:00
|
|
|
if(evt.type == 'close') {
|
|
|
|
FW_errmsg(errstr, 4900);
|
2017-03-01 17:08:25 +00:00
|
|
|
cons_closeConn();
|
2017-01-04 21:31:55 +00:00
|
|
|
setTimeout(consFill, 5000);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
new_content = evt.data;
|
|
|
|
consLastIndex = 0;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if(consConn.readyState == 4) {
|
|
|
|
FW_errmsg(errstr, 4900);
|
|
|
|
setTimeout(consFill, 5000);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(consConn.readyState != 3)
|
|
|
|
return;
|
|
|
|
|
|
|
|
var len = consConn.responseText.length;
|
|
|
|
if (consLastIndex == len) // No new data
|
|
|
|
return;
|
|
|
|
|
|
|
|
new_content = consConn.responseText.substring(consLastIndex, len);
|
|
|
|
consLastIndex = len;
|
|
|
|
}
|
2017-01-16 09:01:48 +00:00
|
|
|
if(new_content == undefined || new_content.length == 0)
|
|
|
|
return;
|
2021-05-10 07:55:41 +00:00
|
|
|
if(new_content.length < 120)
|
|
|
|
log("console Rcvd: "+new_content);
|
|
|
|
else
|
|
|
|
log("console Rcvd: "+new_content.substr(0,120)+
|
|
|
|
"..., truncated, original length "+new_content.length);
|
2019-11-10 15:09:48 +00:00
|
|
|
|
|
|
|
// Extract the FHEM-Log, to avoid escaping its formatting (Forum #104842)
|
|
|
|
var logContent = "";
|
2019-07-30 14:12:40 +00:00
|
|
|
var rTab = {'<':'<', '>':'>',' ':' '};
|
2019-11-10 15:09:48 +00:00
|
|
|
new_content = new_content.replace(/(<div class='fhemlog'>)(.*?)(<\/div>)/g,
|
|
|
|
function(all, div1, msg, div2) {
|
|
|
|
logContent += div1+msg.replace(/[<> ]/g, function(a){return rTab[a]})+div2;
|
|
|
|
return "";
|
|
|
|
});
|
|
|
|
|
2019-08-04 13:02:12 +00:00
|
|
|
var isTa = $("#console").is("textarea"); // 102773
|
2021-05-10 07:55:41 +00:00
|
|
|
var ncA = new_content.split(/<br>[\r\n]/);
|
|
|
|
for(var i1=0; i1<ncA.length; i1++)
|
|
|
|
ncA[i1] = ncA[i1].replace(/[<> ]/g, function(a){return rTab[a]});
|
2021-05-11 07:35:39 +00:00
|
|
|
$("#console").append(logContent+ncA.join(isTa?"\n":"<br>"));
|
2016-04-07 18:58:11 +00:00
|
|
|
|
|
|
|
if(mustScroll)
|
|
|
|
$("#console").scrollTop($("#console")[0].scrollHeight);
|
2012-02-26 13:36:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function
|
|
|
|
consFill()
|
|
|
|
{
|
2014-02-12 09:10:01 +00:00
|
|
|
FW_errmsg("");
|
2014-09-24 07:48:32 +00:00
|
|
|
|
2017-03-01 17:08:25 +00:00
|
|
|
if(FW_pollConn)
|
|
|
|
FW_closeConn();
|
2017-01-04 21:31:55 +00:00
|
|
|
|
|
|
|
var query = "?XHR=1"+
|
2017-07-08 12:06:55 +00:00
|
|
|
"&inform=type=raw;withLog="+withLog+";filter="+
|
|
|
|
encodeURIComponent(consFilter)+consFType+
|
2014-01-05 22:19:11 +00:00
|
|
|
"×tamp="+new Date().getTime();
|
2014-08-10 13:52:25 +00:00
|
|
|
query = addcsrf(query);
|
2017-01-04 21:31:55 +00:00
|
|
|
|
2017-03-01 16:01:41 +00:00
|
|
|
var loc = (""+location).replace(/\?.*/,"");
|
2017-01-04 21:31:55 +00:00
|
|
|
if($("body").attr("longpoll") == "websocket") {
|
2019-01-18 22:09:42 +00:00
|
|
|
if(consConn) {
|
|
|
|
consConn.onclose =
|
|
|
|
consConn.onerror =
|
|
|
|
consConn.onmessage = undefined;
|
2017-01-04 21:31:55 +00:00
|
|
|
consConn.close();
|
2019-01-18 22:09:42 +00:00
|
|
|
}
|
2017-03-01 16:01:41 +00:00
|
|
|
consConn = new WebSocket(loc.replace(/[&?].*/,'')
|
|
|
|
.replace(/^http/i, "ws")+query);
|
2017-01-04 21:31:55 +00:00
|
|
|
consConn.onclose =
|
|
|
|
consConn.onerror =
|
|
|
|
consConn.onmessage = consUpdate;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if(consConn) {
|
|
|
|
consConn.onreadystatechange = undefined;
|
|
|
|
consConn.abort();
|
|
|
|
}
|
|
|
|
consConn = new XMLHttpRequest();
|
2017-03-01 16:01:41 +00:00
|
|
|
consConn.open("GET", loc+query, true);
|
2017-01-04 21:31:55 +00:00
|
|
|
consConn.onreadystatechange = consUpdate;
|
|
|
|
consConn.send(null);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-10-26 18:49:54 +00:00
|
|
|
consLastIndex = 0;
|
|
|
|
if(oldFilter != consFilter) // only clear, when filter changes
|
|
|
|
$("#console").html("");
|
|
|
|
|
|
|
|
oldFilter = consFilter;
|
2012-02-26 13:36:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function
|
|
|
|
consStart()
|
|
|
|
{
|
2014-09-24 07:48:32 +00:00
|
|
|
var el = document.getElementById("console");
|
|
|
|
|
2015-03-29 14:43:22 +00:00
|
|
|
consFilter = $("a#eventFilter").html();
|
2014-09-24 07:48:32 +00:00
|
|
|
if(consFilter == undefined)
|
|
|
|
consFilter = ".*";
|
2015-10-26 18:49:54 +00:00
|
|
|
oldFilter = consFilter;
|
2016-01-17 11:03:44 +00:00
|
|
|
withLog = ($("#eventWithLog").is(':checked') ? 1 : 0);
|
2015-12-21 10:33:45 +00:00
|
|
|
setTimeout(consFill, 1000);
|
2015-03-26 13:53:13 +00:00
|
|
|
|
2015-12-21 10:33:45 +00:00
|
|
|
$("#eventReset").click(function(evt){ // Event Monitor Reset
|
2015-10-26 18:49:54 +00:00
|
|
|
log("Console resetted by user");
|
|
|
|
$("#console").html("");
|
|
|
|
});
|
|
|
|
|
2015-12-21 10:33:45 +00:00
|
|
|
$("#eventFilter").click(function(evt){ // Event-Filter Dialog
|
2015-03-26 13:53:13 +00:00
|
|
|
$('body').append(
|
|
|
|
'<div id="evtfilterdlg">'+
|
2017-03-03 08:26:40 +00:00
|
|
|
'<div>Filter (Regexp):</div><br>'+
|
|
|
|
'<div><input id="filtertext" value="'+consFilter+'"></div><br>'+
|
|
|
|
'<div>'+
|
|
|
|
'<input id="f" type="radio" name="x"> Match the whole line</br>'+
|
|
|
|
'<input id="n" type="radio" name="x"> Notify-Type: deviceName:event'+
|
|
|
|
'</div>'+
|
2015-03-26 13:53:13 +00:00
|
|
|
'</div>');
|
2017-03-03 08:26:40 +00:00
|
|
|
$("#evtfilterdlg input#"+(consFType=="" ? "f" : "n")).prop("checked",true);
|
2015-03-26 13:53:13 +00:00
|
|
|
|
2017-03-03 08:26:40 +00:00
|
|
|
$('#evtfilterdlg').dialog({ modal:true, width:'auto',
|
2015-06-27 05:42:11 +00:00
|
|
|
position:{ my: "left top", at: "right bottom",
|
|
|
|
of: this, collision: "flipfit" },
|
2015-03-26 13:53:13 +00:00
|
|
|
close:function(){$('#evtfilterdlg').remove();},
|
|
|
|
buttons:[
|
|
|
|
{ text:"Cancel", click:function(){ $(this).dialog('close'); }},
|
|
|
|
{ text:"OK", click:function(){
|
|
|
|
var val = $("#filtertext").val().trim();
|
2015-10-28 07:22:39 +00:00
|
|
|
try {
|
|
|
|
new RegExp(val ? val : ".*");
|
|
|
|
} catch(e) {
|
|
|
|
return FW_okDialog(e);
|
|
|
|
}
|
2015-03-26 13:53:13 +00:00
|
|
|
consFilter = val ? val : ".*";
|
2017-03-03 08:26:40 +00:00
|
|
|
consFType= ($("#evtfilterdlg input#n").is(":checked")) ?
|
|
|
|
";filterType=notify" : "";
|
2015-03-26 13:53:13 +00:00
|
|
|
$(this).dialog('close');
|
|
|
|
$("a#eventFilter").html(consFilter);
|
|
|
|
consFill();
|
|
|
|
}}]
|
|
|
|
});
|
|
|
|
});
|
2015-12-21 10:33:45 +00:00
|
|
|
|
|
|
|
$("#eventWithLog").change(function(evt){ // Event-Filter Dialog
|
|
|
|
withLog = ($("#eventWithLog").is(':checked') ? 1 : 0);
|
|
|
|
consFill();
|
|
|
|
});
|
2016-04-07 18:58:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
$("#console").scroll(function() { // autoscroll check
|
2016-07-20 07:47:33 +00:00
|
|
|
|
2017-01-23 13:55:25 +00:00
|
|
|
if($("#console")[0].scrollHeight - $("#console").scrollTop() <=
|
|
|
|
$("#console").outerHeight() + 2) {
|
|
|
|
if(!mustScroll) {
|
|
|
|
mustScroll = 1;
|
|
|
|
log("Console autoscroll restarted");
|
|
|
|
}
|
|
|
|
} else {
|
2016-04-07 18:58:11 +00:00
|
|
|
if(mustScroll) {
|
|
|
|
mustScroll = 0;
|
|
|
|
log("Console autoscroll stopped");
|
|
|
|
}
|
2017-01-23 13:55:25 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
consAddRegexpPart();
|
2012-02-26 13:36:53 +00:00
|
|
|
}
|
|
|
|
|
2017-01-23 13:55:25 +00:00
|
|
|
function
|
|
|
|
consAddRegexpPart()
|
|
|
|
{
|
|
|
|
$("<button style='margin-left:1em' id='addRegexpPart'>"+
|
2017-02-18 16:08:50 +00:00
|
|
|
"Create/Modify Device</button>").insertAfter("button#eventReset");
|
|
|
|
|
|
|
|
var knownTypes = {
|
|
|
|
"notify": { modify: "set modDev addRegexpPart evtDev event",
|
|
|
|
createArg: "evtDev:event {}" },
|
|
|
|
"FileLog":{ modify: "set modDev addRegexpPart evtDev event",
|
|
|
|
createArg: "./log/modDev.log evtDev:event" },
|
|
|
|
"watchdog":{createArg: "evtDev:event 00:15 SAME {}" },
|
2017-03-12 17:26:41 +00:00
|
|
|
"sequence":{createArg: "evtDev:event 00:15 evtDev:event" },
|
2019-01-24 12:56:44 +00:00
|
|
|
"average":{createArg: "evtDev:event" },
|
2017-03-12 17:26:41 +00:00
|
|
|
"DOIF":{createArg: "([evtDev:\"^event$\"]) ()" }
|
2017-02-18 16:08:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
var modDev, devList, devHash = {};
|
|
|
|
var creates = [];
|
|
|
|
for(var t in knownTypes)
|
|
|
|
if(knownTypes[t].createArg)
|
|
|
|
creates.push(t);
|
2017-01-23 13:55:25 +00:00
|
|
|
|
|
|
|
$("button#addRegexpPart").click(function(){
|
|
|
|
// get selection, build regexp from event
|
|
|
|
var txt = window.getSelection().toString();
|
|
|
|
var hlp = "Please highlight exactly one complete event line";
|
|
|
|
if(!txt)
|
|
|
|
return FW_okDialog(hlp);
|
|
|
|
var re=/^....-..-..\s..:..:..(\....)?\s([^\s]+)\s([^\s]+)\s(.*)([\r\n]*)?$/;
|
|
|
|
var ret = txt.match(re);
|
|
|
|
if(!ret)
|
|
|
|
return FW_okDialog(hlp);
|
|
|
|
|
2017-02-18 16:08:50 +00:00
|
|
|
var evtDev=ret[3];
|
|
|
|
var evt1 = ret[4].replace(/\s/g, ".")
|
|
|
|
.replace(/[\^\$\[\]\(\)\\]/g, function(s){return"\\"+s});
|
2019-12-25 20:15:03 +00:00
|
|
|
var evt2 = evt1.replace(/\b-?\d*\.?\d+\b/g,'.*')
|
|
|
|
.replace(/\.+\*(\.+\*)*/g,'.*');
|
2017-02-18 16:08:50 +00:00
|
|
|
|
|
|
|
// build the dialog
|
2017-01-23 13:55:25 +00:00
|
|
|
var txt = '<style type="text/css">\n'+
|
|
|
|
'div.evt label { display:block; margin-left:2em; }\n'+
|
|
|
|
'div.evt input { float:left; }\n'+
|
|
|
|
'</style>\n';
|
2017-02-18 16:08:50 +00:00
|
|
|
|
|
|
|
var inputPrf="<input type='radio' name="
|
|
|
|
txt += inputPrf+"'defmod' id='def' checked/><label>Create</label>"+
|
|
|
|
inputPrf+"'defmod' id='mod'/><label>Modify</label><br><br>"
|
|
|
|
txt += "<select id='modDev' style='display:none'></select>";
|
|
|
|
txt += "<select id='newType'><option>"+
|
|
|
|
creates.sort().join("</option><option>")+
|
|
|
|
"</select><br><br>";
|
|
|
|
|
|
|
|
if(evt1 != evt2) {
|
|
|
|
txt += "<div class='evt'>"+inputPrf+"'evtType' id='rdEx' checked/>"+
|
|
|
|
"<label>with exactly this event</div><br>";
|
|
|
|
txt += "<div class='evt'>"+inputPrf+"'evtType' id='rdNum'/>"+
|
|
|
|
"<label>with any number matching</label></div><br>";
|
|
|
|
}
|
|
|
|
txt += "<div class='evt' id='cmd'> </txt>";
|
|
|
|
|
|
|
|
$('body').append('<div id="evtCoM" style="display:none">'+txt+'</div>');
|
|
|
|
$('#evtCoM').dialog(
|
2017-01-23 17:17:20 +00:00
|
|
|
{ modal:true, closeOnEscape:true, width:"auto",
|
2017-02-18 16:08:50 +00:00
|
|
|
close:function(){ $('#evtCoM').remove(); },
|
2017-01-23 13:55:25 +00:00
|
|
|
buttons:[
|
|
|
|
{ text:"Cancel", click:function(){ $(this).dialog('close'); }},
|
|
|
|
{ text:"OK", click:function(){
|
2017-02-18 16:08:50 +00:00
|
|
|
FW_cmd(FW_root+"?cmd="+$("#evtCoM #cmd").html()+"&XHR=1");
|
2017-01-23 13:55:25 +00:00
|
|
|
$(this).dialog('close');
|
2017-02-18 16:08:50 +00:00
|
|
|
location = FW_root+'?detail='+modDev;
|
|
|
|
}}],
|
|
|
|
open:function(){
|
|
|
|
$("#evtCoM #newType").val("notify");
|
|
|
|
$("#evtCoM input,#evtCoM select").change(optChanged);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function
|
|
|
|
optChanged()
|
|
|
|
{
|
|
|
|
var event = evt1;
|
|
|
|
if(evt1 != evt2 && $("#evtCoM #rdNum").is(":checked"))
|
|
|
|
event = evt2;
|
|
|
|
var cmd;
|
|
|
|
|
|
|
|
if($("#evtCoM #def").is(":checked")) { // define
|
|
|
|
$("#evtCoM #newType").show();
|
|
|
|
$("#evtCoM #modDev").hide();
|
|
|
|
var type = $("#evtCoM #newType").val(), num=1;
|
|
|
|
var nRe = new RegExp(evtDev+"_"+type+"_(\\d+)");
|
|
|
|
for(var i1=0; i1<devList.length; i1++) {
|
|
|
|
var m = nRe.exec(devList[i1].Name);
|
|
|
|
if(m && m[1] >= num)
|
|
|
|
num = parseInt(m[1])+1;
|
|
|
|
}
|
|
|
|
modDev = evtDev+"_"+type+"_"+num;
|
|
|
|
cmd = "define "+modDev+" "+type+" "+knownTypes[type].createArg;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
$("#evtCoM #newType").hide();
|
|
|
|
$("#evtCoM #modDev").show();
|
|
|
|
modDev = $("#evtCoM #modDev").val();
|
|
|
|
cmd = knownTypes[devHash[modDev].Internals.TYPE].modify;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
$("#evtCoM #cmd").text(cmd
|
|
|
|
.replace(/modDev/g,modDev)
|
|
|
|
.replace(/evtDev/g,evtDev)
|
|
|
|
.replace(/event/g,event));
|
|
|
|
}
|
|
|
|
|
|
|
|
FW_cmd(FW_root+"?cmd=jsonlist2 .* TYPE&XHR=1", function(data){
|
|
|
|
devList = JSON.parse(data).Results;
|
|
|
|
for(var i1=0; i1<devList.length; i1++) {
|
|
|
|
var dev = devList[i1], type = dev.Internals.TYPE;
|
|
|
|
if(knownTypes[type] && knownTypes[type].modify)
|
|
|
|
$("select#modDev").append('<option>'+dev.Name+'</option>');
|
|
|
|
devHash[dev.Name] = dev;
|
2017-01-23 13:55:25 +00:00
|
|
|
}
|
2017-02-18 16:08:50 +00:00
|
|
|
optChanged();
|
2017-01-23 13:55:25 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-02-26 13:36:53 +00:00
|
|
|
window.onload = consStart;
|