var state = "IDLE";
var state_last = "";
var graph = [ 'profile', 'live'];
var points = [];
var profiles = [];
var selected_profile = 0;
var selected_profile_name = "leadfree";
var host = "ws://" + window.location.hostname + ":8080";
var ws_status = new WebSocket(host+"/status");
var ws_control = new WebSocket(host+"/control");
var ws_storage = new WebSocket(host+"/storage");
if(window.webkitRequestAnimationFrame) window.requestAnimationFrame = window.webkitRequestAnimationFrame;
graph.profile =
{
label: "Profile",
data: [],
points: { show: false },
color: "#75890c",
draggable: false
};
graph.live =
{
label: "Live",
data: [],
points: { show: false },
color: "#d8d3c5",
draggable: false
};
function updateProfile(id)
{
selected_profile = id;
job_time = parseInt(profiles[id].data[profiles[id].data.length-1][0]);
var kwh = (3850*job_time/3600/1000).toFixed(2);
var cost = (kwh*0.26).toFixed(2);
var minutes = Math.floor(job_time/60), seconds = job_time-minutes*60;
job_time = minutes+':'+ (seconds < 10 ? "0" : "") + seconds;
$('#sel_prof').html(profiles[id].name);
$('#sel_prof_eta').html(job_time);
$('#sel_prof_cost').html(kwh + ' kWh (EUR: '+ cost +')');
graph.profile.data = profiles[id].data;
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ] , getOptions());
}
function deleteProfile()
{
console.log("Delete profile:" + selected_profile_name);
// FIXME: Add cmd for socket communication to delete stored profile
leaveEditMode();
}
function updateProgress(percentage)
{
if(state=="RUNNING")
{
if(percentage > 100) percentage = 100;
$('#progressBar').css('width', percentage+'%');
if(percentage>5) $('#progressBar').html(parseInt(percentage)+'%');
}
else
{
$('#progressBar').css('width', 0+'%');
$('#progressBar').html('');
}
}
function updateProfileTable()
{
var dps = 0;
var slope = "";
var color = "";
var html = '
Profile Points
';
$('#profile_table').html(html);
//Link table to graph
$(".form-control").change(function(e)
{
var id = $(this)[0].id//e.currentTarget.attributes.id;
var value = parseInt($(this)[0].value);
var fields = id.split("-");
var col = parseInt(fields[1]);
var row = parseInt(fields[2]);
graph.profile.data[row][col] = value;
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ], getOptions());
updateProfileTable();
});
}
function runTask()
{
var cmd =
{
"cmd": "RUN",
"profile": profiles[selected_profile]
}
graph.live.data = [];
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ] , getOptions());
ws_control.send(JSON.stringify(cmd));
}
function runTaskSimulation()
{
var cmd =
{
"cmd": "SIMULATE",
"profile": profiles[selected_profile]
}
graph.live.data = [];
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ] , getOptions());
ws_control.send(JSON.stringify(cmd));
}
function abortTask()
{
var cmd = {"cmd": "STOP"};
ws_control.send(JSON.stringify(cmd));
}
function enterNewMode()
{
state="EDIT"
$('#status').slideUp();
$('#edit').show();
$('#profile_selector').hide();
$('#btn_controls').hide();
$('#form_profile_name').attr('value', '');
$('#form_profile_name').attr('placeholder', 'Please enter a name');
graph.profile.points.show = true;
graph.profile.draggable = true;
graph.profile.data = [];
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ], getOptions());
updateProfileTable();
}
function enterEditMode()
{
state="EDIT"
$('#status').slideUp();
$('#edit').show();
$('#profile_selector').hide();
$('#btn_controls').hide();
$('#form_profile_name').attr('value', profiles[selected_profile].name);
graph.profile.points.show = true;
graph.profile.draggable = true;
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ], getOptions());
updateProfileTable();
}
function leaveEditMode()
{
selected_profile_name = $('#form_profile_name').val();
ws_storage.send('GET');
state="IDLE";
$('#edit').hide();
$('#profile_selector').show();
$('#btn_controls').show();
$('#status').slideDown();
$('#profile_table').slideUp();
graph.profile.points.show = false;
graph.profile.draggable = false;
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ], getOptions());
}
function newPoint()
{
if(graph.profile.data.length > 0)
{
var pointx = parseInt(graph.profile.data[graph.profile.data.length-1][0])+15;
}
else
{
var pointx = 0;
}
graph.profile.data.push([pointx, Math.floor((Math.random()*230)+25)]);
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ], getOptions());
updateProfileTable();
}
function delPoint()
{
graph.profile.data.splice(-1,1)
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ], getOptions());
updateProfileTable();
}
function toggleTable()
{
if($('#profile_table').css('display') == 'none')
{
$('#profile_table').slideDown();
}
else
{
$('#profile_table').slideUp();
}
}
function saveProfile()
{
name = $('#form_profile_name').val();
var rawdata = graph.plot.getData()[0].data
var data = [];
var last = -1;
for(var i=0; i last)
{
data.push([rawdata[i][0], rawdata[i][1]]);
}
else
{
$.bootstrapGrowl(" ERROR 88:
An oven is not a time-machine", {
ele: 'body', // which element to append to
type: 'alert', // (null, 'info', 'error', 'success')
offset: {from: 'top', amount: 250}, // 'top', or 'bottom'
align: 'center', // ('left', 'right', or 'center')
width: 385, // (integer, or 'auto')
delay: 5000,
allow_dismiss: true,
stackup_spacing: 10 // spacing between consecutively stacked growls.
});
return false;
}
last = rawdata[i][0];
}
var profile = { "type": "profile", "data": data, "name": name }
var put = { "cmd": "PUT", "profile": profile }
var put_cmd = JSON.stringify(put);
ws_storage.send(put_cmd);
leaveEditMode();
}
function getOptions()
{
var options =
{
series:
{
lines:
{
show: true
},
points:
{
show: true,
radius: 5,
symbol: "circle"
},
shadowSize: 3
},
xaxis:
{
//tickSize: 30,
min: 0,
tickColor: 'rgba(216, 211, 197, 0.2)',
font:
{
size: 14,
lineHeight: 14, weight: "normal",
family: "Digi",
variant: "small-caps",
color: "rgba(216, 211, 197, 0.85)"
}
},
yaxis:
{
tickSize: 25,
min: 0,
max: 250,
tickDecimals: 0,
draggable: false,
tickColor: 'rgba(216, 211, 197, 0.2)',
font:
{
size: 14,
lineHeight: 14,
weight: "normal",
family: "Digi",
variant: "small-caps",
color: "rgba(216, 211, 197, 0.85)"
}
},
grid:
{
color: 'rgba(216, 211, 197, 0.55)',
borderWidth: 1,
labelMargin: 10,
mouseActiveRadius: 50
},
legend:
{
show: false
}
}
return options;
}
$(document).ready(function()
{
if(!("WebSocket" in window))
{
$('#chatLog, input, button, #examples').fadeOut("fast");
$('Oh no, you need a browser that supports WebSockets. How about Google Chrome?
').appendTo('#container');
}
else
{
// Status Socket ////////////////////////////////
ws_status.onopen = function()
{
console.log("Status Socket has been opened");
$.bootstrapGrowl(" Yay
I'm alive",
{
ele: 'body', // which element to append to
type: 'success', // (null, 'info', 'error', 'success')
offset: {from: 'top', amount: 250}, // 'top', or 'bottom'
align: 'center', // ('left', 'right', or 'center')
width: 385, // (integer, or 'auto')
delay: 2500,
allow_dismiss: true,
stackup_spacing: 10 // spacing between consecutively stacked growls.
});
};
ws_status.onclose = function()
{
$.bootstrapGrowl(" ERROR 1:
Status Websocket not available", {
ele: 'body', // which element to append to
type: 'error', // (null, 'info', 'error', 'success')
offset: {from: 'top', amount: 250}, // 'top', or 'bottom'
align: 'center', // ('left', 'right', or 'center')
width: 385, // (integer, or 'auto')
delay: 5000,
allow_dismiss: true,
stackup_spacing: 10 // spacing between consecutively stacked growls.
});
};
ws_status.onmessage = function(e)
{
x = JSON.parse(e.data);
if (x.type == "backlog")
{
if (x.profile)
{
selected_profile_name = x.profile.name;
}
$.each(x.log, function(i,v) {
graph.live.data.push([v.runtime, v.temperature]);
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ] , getOptions());
});
}
if(state!="EDIT")
{
state = x.state;
if (x.door == "OPEN")
{
}
if (state!=state_last)
{
if(state_last == "RUNNING")
{
$('#target_temp').html('---');
updateProgress(0);
$.bootstrapGrowl(" Run completed", {
ele: 'body', // which element to append to
type: 'success', // (null, 'info', 'error', 'success')
offset: {from: 'top', amount: 250}, // 'top', or 'bottom'
align: 'center', // ('left', 'right', or 'center')
width: 385, // (integer, or 'auto')
delay: 0,
allow_dismiss: true,
stackup_spacing: 10 // spacing between consecutively stacked growls.
});
}
}
if(state=="RUNNING")
{
$("#nav_start").hide();
$("#nav_stop").show();
graph.live.data.push([x.runtime, x.temperature]);
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ] , getOptions());
left = parseInt(x.totaltime-x.runtime);
var minutes = Math.floor(left / 60);
var seconds = left - minutes * 60;
eta = minutes+':'+ (seconds < 10 ? "0" : "") + seconds;
updateProgress(parseFloat(x.runtime)/parseFloat(x.totaltime)*100);
$('#state').html('' + eta + '');
$('#target_temp').html(parseInt(x.target));
}
else
{
$("#nav_start").show();
$("#nav_stop").hide();
$('#state').html(''+state+'
');
}
$('#act_temp').html(parseInt(x.temperature));
if (x.heat > 0.5) { $('#heat').addClass("ds-led-heat-active"); } else { $('#heat').removeClass("ds-led-heat-active"); }
if (x.cool > 0.5) { $('#cool').addClass("ds-led-cool-active"); } else { $('#cool').removeClass("ds-led-cool-active"); }
if (x.air > 0.5) { $('#air').addClass("ds-led-air-active"); } else { $('#air').removeClass("ds-led-air-active"); }
if (x.temperature > 45) { $('#hazard').addClass("ds-led-hazard-active"); } else { $('#hazard').removeClass("ds-led-hazard-active"); }
state_last = state;
}
};
// Control Socket ////////////////////////////////
ws_control.onopen = function()
{
};
ws_control.onmessage = function(e)
{
//Data from Simulation
console.log (e.data);
x = JSON.parse(e.data);
graph.live.data.push([x.runtime, x.temperature]);
graph.plot = $.plot("#graph_container", [ graph.profile, graph.live ] , getOptions());
}
// Storage Socket ///////////////////////////////
ws_storage.onopen = function()
{
ws_storage.send('GET');
};
ws_storage.onmessage = function(e)
{
message = JSON.parse(e.data);
if(message.resp)
{
if(message.resp == "FAIL")
{
if (confirm('Overwrite?'))
{
message.force=true;
console.log("Sending: " + JSON.stringify(message));
ws_storage.send(JSON.stringify(message));
}
else
{
//do nothing
}
}
return;
}
//the message is an array of profiles
//FIXME: this should be better, maybe a {"profiles": ...} container?
profiles = message;
//delete old options in select
$('#e2').find('option').remove().end();
// fill select with new options from websocket
for (var i=0; i'+profile.name+'');
if (profile.name == selected_profile_name)
{
selected_profile = i;
$('#e2').select2('val', i);
updateProfile(i);
}
}
};
$("#e2").select2(
{
placeholder: "Select Profile",
allowClear: false,
minimumResultsForSearch: -1
});
$("#e2").on("change", function(e)
{
updateProfile(e.val);
});
}
});