Merge pull request #2 in POC/vfd-poc from feature/POC-52-pocloud-notes-page to master
* commit 'd43cb76fe247f31b1eaf94c09253cd74191e51a0': Events, Notes, Fluid Shots, and Well Tests READ page Rewrote SQLite POC driver Cleaned up Overview Screen to make it look cooler add notes, well test, and fluid shot functions to sqlite poc version
This commit is contained in:
93
POCloud/HTML Templates/Fluid_Shots.html
Normal file
93
POCloud/HTML Templates/Fluid_Shots.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<div style='margin-top: 1em;' class='col-xs-12'>
|
||||
<div class="input-daterange input-group" id="datePicker">
|
||||
<input id="fromDate" data-daysofhistory="30" type="text" class="form-control" name="start">
|
||||
<span class="input-group-addon">to</span>
|
||||
<input class="form-control" id="toDate" type="text" name="end">
|
||||
<span class='input-group-btn'>
|
||||
<a href="" id="runPickerBtn" class="btn btn-theme">Run</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-12' style='margin-top: 2em;'>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>Shot ID</th>
|
||||
<th>Date & Time</th>
|
||||
<th>Intake Pressure</th>
|
||||
<th>Fluid Gradient</th>
|
||||
<th>Friction</th>
|
||||
<th>Taken By</th>
|
||||
</thead>
|
||||
|
||||
<tbody id="output">
|
||||
</tbody>
|
||||
</table>
|
||||
<!--<%= JSON.stringify(channels['poc.events'].value) %>-->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var nodeID = <%= node.nodeId %>;
|
||||
var nodeType = '<%= node.nodetypeName %>';
|
||||
var channelID = <%= channels['poc.fluidshots'].channelId %>;
|
||||
console.log({nodeID:nodeID, nodeType:nodeType, channelID: channelID})
|
||||
|
||||
var formatDate = function(str){
|
||||
var c1, c2;
|
||||
c1 = new Date(str);
|
||||
c2 = (c1.getTime() / 1000);
|
||||
c2 = Math.floor(c2);
|
||||
return c2.toString();
|
||||
};
|
||||
|
||||
var updateTable = function(){
|
||||
var apiData, start, end;
|
||||
var $output = $('#output');
|
||||
start = $('#datePicker').find('#fromDate');
|
||||
dateString = start.val().replace(/-/g, "/");
|
||||
start = formatDate(dateString);
|
||||
end = $('#datePicker').find('#toDate');
|
||||
dateString = end.val().replace(/-/g, "/");
|
||||
end = formatDate(dateString);
|
||||
apiData = "&nodelist[0][nodeId]=" + nodeID.toString() + "&nodelist[0][channelId]=" + channelID.toString();
|
||||
apiData += "&start=" + start + "&end=" + end;
|
||||
$.ajax({
|
||||
url: "http://www.pocloud.io/api2/Nodechannels",
|
||||
data: apiData,
|
||||
dataType: "json",
|
||||
type: "GET",
|
||||
success: function(data) {
|
||||
console.log(data);
|
||||
var notes = data.listofstreams[0];
|
||||
for(var i = notes.stream.length-1; i >= 0; i--) {
|
||||
var note = notes.stream[i];
|
||||
var timestamp = note.x;
|
||||
var jsonBlock = note.y;
|
||||
var n = JSON.parse(jsonBlock);
|
||||
var row = "<tr>";
|
||||
row += "<td>" + n.id + "</td>";
|
||||
row += "<td>" + n.shot_datetime + "</td>";
|
||||
row += "<td>" + n.pump_intake_pressure + "</td>";
|
||||
row += "<td>" + n.fluid_gradient + "</td>";
|
||||
row += "<td>" + n.friction + "</td>";
|
||||
row += "<td>" + n.taken_by + "</td>";
|
||||
row += "</tr>"
|
||||
$output.append(row)
|
||||
//$output.append(JSON.stringify(jsonBlock));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('click', '#runPickerBtn', function(e){
|
||||
e.preventDefault();
|
||||
updateTable();
|
||||
});
|
||||
$(document).ready(function(){
|
||||
updateTable();
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
92
POCloud/HTML Templates/Notes.html
Normal file
92
POCloud/HTML Templates/Notes.html
Normal file
@@ -0,0 +1,92 @@
|
||||
<div style='margin-top: 1em;' class='col-xs-12'>
|
||||
<div class="input-daterange input-group" id="datePicker">
|
||||
<input id="fromDate" data-daysofhistory="30" type="text" class="form-control" name="start">
|
||||
<span class="input-group-addon">to</span>
|
||||
<input class="form-control" id="toDate" type="text" name="end">
|
||||
<span class='input-group-btn'>
|
||||
<a href="" id="runPickerBtn" class="btn btn-theme">Run</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-12' style='margin-top: 2em;'>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>Note ID</th>
|
||||
<th>Date & Time</th>
|
||||
<th>Author</th>
|
||||
<th>Type</th>
|
||||
<th>Note</th>
|
||||
<th>Stroke</th>
|
||||
</thead>
|
||||
|
||||
<tbody id="output">
|
||||
</tbody>
|
||||
</table>
|
||||
<!--<%= JSON.stringify(channels['poc.events'].value) %>-->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var nodeID = <%= node.nodeId %>;
|
||||
var nodeType = '<%= node.nodetypeName %>';
|
||||
var channelID = <%= channels['poc.notes'].channelId %>;
|
||||
console.log({nodeID:nodeID, nodeType:nodeType, channelID: channelID})
|
||||
|
||||
var formatDate = function(str){
|
||||
var c1, c2;
|
||||
c1 = new Date(str);
|
||||
c2 = (c1.getTime() / 1000);
|
||||
c2 = Math.floor(c2);
|
||||
return c2.toString();
|
||||
};
|
||||
|
||||
var updateTable = function(){
|
||||
var apiData, start, end;
|
||||
var $output = $('#output');
|
||||
start = $('#datePicker').find('#fromDate');
|
||||
dateString = start.val().replace(/-/g, "/");
|
||||
start = formatDate(dateString);
|
||||
end = $('#datePicker').find('#toDate');
|
||||
dateString = end.val().replace(/-/g, "/");
|
||||
end = formatDate(dateString);
|
||||
apiData = "&nodelist[0][nodeId]=" + nodeID.toString() + "&nodelist[0][channelId]=" + channelID.toString();
|
||||
apiData += "&start=" + start + "&end=" + end;
|
||||
$.ajax({
|
||||
url: "http://www.pocloud.io/api2/Nodechannels",
|
||||
data: apiData,
|
||||
dataType: "json",
|
||||
type: "GET",
|
||||
success: function(data) {
|
||||
var notes = data.listofstreams[0];
|
||||
for(var i = notes.stream.length-1; i >= 0; i--) {
|
||||
var note = notes.stream[i];
|
||||
var timestamp = note.x;
|
||||
var jsonBlock = note.y;
|
||||
var n = JSON.parse(jsonBlock);
|
||||
var row = "<tr>";
|
||||
row += "<td>" + n.id + "</td>";
|
||||
row += "<td>" + n.date_time + "</td>";
|
||||
row += "<td>" + n.author + "</td>";
|
||||
row += "<td>" + n.ntype + "</td>";
|
||||
row += "<td>" + n.note + "</td>";
|
||||
row += "<td>" + n.stroke + "</td>";
|
||||
row += "</tr>"
|
||||
$output.append(row)
|
||||
//$output.append(JSON.stringify(jsonBlock));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('click', '#runPickerBtn', function(e){
|
||||
e.preventDefault();
|
||||
updateTable();
|
||||
});
|
||||
$(document).ready(function(){
|
||||
updateTable();
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
95
POCloud/HTML Templates/Well_Tests.html
Normal file
95
POCloud/HTML Templates/Well_Tests.html
Normal file
@@ -0,0 +1,95 @@
|
||||
<div style='margin-top: 1em;' class='col-xs-12'>
|
||||
<div class="input-daterange input-group" id="datePicker">
|
||||
<input id="fromDate" data-daysofhistory="30" type="text" class="form-control" name="start">
|
||||
<span class="input-group-addon">to</span>
|
||||
<input class="form-control" id="toDate" type="text" name="end">
|
||||
<span class='input-group-btn'>
|
||||
<a href="" id="runPickerBtn" class="btn btn-theme">Run</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-12' style='margin-top: 2em;'>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>Test ID</th>
|
||||
<th>Date & Time</th>
|
||||
<th>Oil (BBL)</th>
|
||||
<th>Water (BBL)</th>
|
||||
<th>Gas (MMCF)</th>
|
||||
<th>K-Factor</th>
|
||||
<th>Hours</th>
|
||||
</thead>
|
||||
|
||||
<tbody id="output">
|
||||
</tbody>
|
||||
</table>
|
||||
<!--<%= JSON.stringify(channels['poc.events'].value) %>-->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
var nodeID = <%= node.nodeId %>;
|
||||
var nodeType = '<%= node.nodetypeName %>';
|
||||
var channelID = <%= channels['poc.welltests'].channelId %>;
|
||||
console.log({nodeID:nodeID, nodeType:nodeType, channelID: channelID})
|
||||
|
||||
var formatDate = function(str){
|
||||
var c1, c2;
|
||||
c1 = new Date(str);
|
||||
c2 = (c1.getTime() / 1000);
|
||||
c2 = Math.floor(c2);
|
||||
return c2.toString();
|
||||
};
|
||||
|
||||
var updateTable = function(){
|
||||
var apiData, start, end;
|
||||
var $output = $('#output');
|
||||
start = $('#datePicker').find('#fromDate');
|
||||
dateString = start.val().replace(/-/g, "/");
|
||||
start = formatDate(dateString);
|
||||
end = $('#datePicker').find('#toDate');
|
||||
dateString = end.val().replace(/-/g, "/");
|
||||
end = formatDate(dateString);
|
||||
apiData = "&nodelist[0][nodeId]=" + nodeID.toString() + "&nodelist[0][channelId]=" + channelID.toString();
|
||||
apiData += "&start=" + start + "&end=" + end;
|
||||
$.ajax({
|
||||
url: "http://www.pocloud.io/api2/Nodechannels",
|
||||
data: apiData,
|
||||
dataType: "json",
|
||||
type: "GET",
|
||||
success: function(data) {
|
||||
console.log(data);
|
||||
var notes = data.listofstreams[0];
|
||||
for(var i = notes.stream.length-1; i >= 0; i--) {
|
||||
var note = notes.stream[i];
|
||||
var timestamp = note.x;
|
||||
var jsonBlock = note.y;
|
||||
var n = JSON.parse(jsonBlock);
|
||||
var row = "<tr>";
|
||||
row += "<td>" + n.id + "</td>";
|
||||
row += "<td>" + n.test_date + "</td>";
|
||||
row += "<td>" + n.test_volume_oil + "</td>";
|
||||
row += "<td>" + n.test_volume_water + "</td>";
|
||||
row += "<td>" + n.test_volume_gas + "</td>";
|
||||
row += "<td>" + n.k_factor + "</td>";
|
||||
row += "<td>" + n.test_hours + "</td>";
|
||||
row += "</tr>"
|
||||
$output.append(row)
|
||||
//$output.append(JSON.stringify(jsonBlock));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('click', '#runPickerBtn', function(e){
|
||||
e.preventDefault();
|
||||
updateTable();
|
||||
});
|
||||
$(document).ready(function(){
|
||||
updateTable();
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
@@ -56,13 +56,13 @@
|
||||
apiData = "&nodelist[0][nodeId]=" + nodeID.toString() + "&nodelist[0][channelId]=" + channelID.toString();
|
||||
apiData += "&start=" + start + "&end=" + end;
|
||||
$.ajax({
|
||||
url: "http://henrypump.meshify.com/api2/Nodechannels",
|
||||
url: "http://www.pocloud.io/api2/Nodechannels",
|
||||
data: apiData,
|
||||
dataType: "json",
|
||||
type: "GET",
|
||||
success: function(data) {
|
||||
var events = data.listofstreams[0];
|
||||
for(var i = events.stream.length-1; i > 0; i--) {
|
||||
for(var i = events.stream.length-1; i >= 0; i--) {
|
||||
var event = events.stream[i];
|
||||
var timestamp = event.x;
|
||||
var jsonBlock = event.y;
|
||||
|
||||
@@ -1,41 +1,107 @@
|
||||
<div class="text-center"><h1>TODAY'S TOTALS</h1></div>
|
||||
<div class='row overview'>
|
||||
<div class="text-center"><h1>LATEST STROKE</h1></div>
|
||||
<div class='row row-flex box-me'>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Pump Fill</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge-fillage_percent" data-chart="solidgauge" data-nodename="poc.fillage_percent" data-units="%" data-min="0" data-max="100" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B" data-valuefontsize="18px"></div>
|
||||
<span data-timeupdate="fillage_percent"><%= channels["poc.fillage_percent"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-8'>
|
||||
<div style="height:300px" id="chart-fillage_percent" data-chart="chart" data-nodename1="poc.fillage_percent" data-datalabel1="Fill" data-daysofhistory="2" data-chartlabel="" data-ylabel="" data-xlabel="Date" data-units="%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='row row-flex box-me'>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Fluid Level</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge-fluid_above_pump" data-chart="solidgauge" data-nodename="poc.fluid_above_pump" data-units="ft." data-min="0" data-max="10000" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B" data-valuefontsize="18px"></div>
|
||||
<span data-timeupdate="fluid_above_pump"><%= channels["poc.fluid_above_pump"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-8'>
|
||||
<div style="height:300px" id="chart-fluid_above_pump" data-chart="chart" data-nodename1="poc.fluid_above_pump" data-datalabel1="Fluid Level" data-daysofhistory="2" data-chartlabel="" data-ylabel="" data-xlabel="Date" data-units="ft."></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='row row-flex box-me'>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Stroke Speed</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge-SPM" data-chart="solidgauge" data-nodename="poc.SPM" data-units="SPM" data-min="0" data-max="12" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B" data-valuefontsize="18px"></div>
|
||||
<span data-timeupdate="SPM"><%= channels["poc.SPM"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-8'>
|
||||
<div style="height:300px" id="chart-SPM" data-chart="chart" data-nodename1="poc.SPM" data-datalabel1="Speed" data-daysofhistory="2" data-chartlabel="" data-ylabel="" data-xlabel="Date" data-units="SPM"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='row row-flex box-me'>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Pump HP</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge-pump_hp" data-chart="solidgauge" data-nodename="poc.pump_hp" data-units="HP" data-min="0" data-max="10" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B" data-valuefontsize="18px"></div>
|
||||
<span data-timeupdate="pump_hp"><%= channels["poc.pump_hp"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-8'>
|
||||
<div style="height:300px" id="chart-pump_hp" data-chart="chart" data-nodename1="poc.pump_hp" data-datalabel1="HP" data-daysofhistory="2" data-chartlabel="" data-ylabel="" data-xlabel="Date" data-units="HP"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='row row-flex box-me'>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Fluid Load</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge-downhole_fluid_load" data-chart="solidgauge" data-nodename="poc.downhole_fluid_load" data-units="lbs." data-min="0" data-max="10000" data-colors="0.1:#DF5353,0.5:#55BF3B,0.9:#DF5353" data-valuefontsize="18px"></div>
|
||||
<span data-timeupdate="pump_hp"><%= channels["poc.downhole_fluid_load"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-8'>
|
||||
<div style="height:300px" id="chart-downhole_fluid_load" data-chart="chart" data-nodename1="poc.downhole_fluid_load" data-datalabel1="Fluid Load" data-daysofhistory="2" data-chartlabel="" data-ylabel="" data-xlabel="Date" data-units="lbs."></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center"><h1>TODAY'S TOTALS</h1></div>
|
||||
<div class='row row-flex'>
|
||||
<div class='col-xs-4 text-center box-me'>
|
||||
<h2>Percent Run</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge1" data-chart="solidgauge" data-nodename="poc.dt_percent_run" data-units="%" data-min="0" data-max="100" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="dt_percent_run"><%= channels["poc.dt_percent_run"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<div class='col-xs-4 text-center box-me'>
|
||||
<h2>Average Speed</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge2" data-chart="solidgauge" data-nodename="poc.dt_average_spm" data-units="SPM" data-min="0" data-max="20" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B" data-decimals="2"></div>
|
||||
<span data-timeupdate="dt_average_spm"><%= channels["poc.dt_average_spm"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<div class='col-xs-4 text-center box-me'>
|
||||
<h2>Calculated Production</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge3" data-chart="solidgauge" data-nodename="poc.dt_calculated_production" data-units="BBL" data-min="0" data-max="1000" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="dt_calculated_production"><%= channels["poc.dt_calculated_production"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<div class='col-xs-4 text-center box-me'>
|
||||
<h2>Projected Production</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge4" data-chart="solidgauge" data-nodename="poc.dt_projected_production" data-units="HP" data-min="0" data-max="1000" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="dt_projected_production"><%= channels["poc.dt_projected_production"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<div class='col-xs-4 text-center box-me'>
|
||||
<h2>Pump Intake Pressure</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge5" data-chart="solidgauge" data-nodename="poc.dt_pump_intake_pressure" data-units="PSI" data-min="0" data-max="2000" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="dt_pump_intake_pressure"><%= channels["poc.dt_pump_intake_pressure"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<div class='col-xs-4 text-center box-me'>
|
||||
<h2>Energy Consumed</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge6" data-chart="solidgauge" data-nodename="poc.dt_kWh" data-units="kWh" data-min="0" data-max="200" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
@@ -45,129 +111,56 @@
|
||||
</div>
|
||||
|
||||
|
||||
<!-- TOTALS -->
|
||||
<div class="text-center"><h1>LATEST STROKE</h1></div>
|
||||
<div class='row overview'>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Pump Fillage</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge7" data-chart="solidgauge" data-nodename="poc.fillage_percent" data-units="%" data-min="0" data-max="100" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="fillage_percent"><%= channels["poc.fillage_percent"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Fluid Above Pump</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge8" data-chart="solidgauge" data-nodename="poc.fluid_above_pump" data-units="ft." data-min="0" data-max="5000" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="fluid_above_pump"><%= channels["poc.fluid_above_pump"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Speed</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge9" data-chart="solidgauge" data-nodename="poc.SPM" data-units="SPM" data-min="0" data-max="20" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="SPM"><%= channels["poc.SPM"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Polished Rod HP</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge10" data-chart="solidgauge" data-nodename="poc.polished_rod_hp" data-units="HP" data-min="0" data-max="50" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="polished_rod_hp"><%= channels["poc.polished_rod_hp"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Pump HP</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge11" data-chart="solidgauge" data-nodename="poc.pump_hp" data-units="HP" data-min="0" data-max="50" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="pump_hp"><%= channels["poc.pump_hp"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4 text-center'>
|
||||
<h2>Downhole Fluid Load</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10" style="height: 170px; background: transparent; margin: 0 auto;" id="gauge12" data-chart="solidgauge" data-nodename="poc.downhole_fluid_load" data-units="lbs." data-min="0" data-max="10000" data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"></div>
|
||||
<span data-timeupdate="downhole_fluid_load"><%= channels["poc.downhole_fluid_load"].timestamp %></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="col-xs-12" style="padding: 1em 0;">
|
||||
<div class="progress" style="margin:1em 5%">
|
||||
<div class="progress-bar progress-bar-striped active" id="surface_stroke_length" role="progressbar" aria-valuenow="<%= channels["poc.surface_stroke_length"].value %>" aria-valuemin="0" aria-valuemax="100" style="width: <%= channels["poc.surface_stroke_length"].value %>%;">
|
||||
Surface Stroke Length: <%= channels["poc.surface_stroke_length"].value %> in.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress" style="margin:1em 5%">
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_gross_stroke" role="progressbar" aria-valuenow="<%= channels["poc.downhole_gross_stroke"].value %>" aria-valuemin="0" aria-valuemax="100" style="width: <%= channels["poc.downhole_gross_stroke"].value %>%;">
|
||||
Downhole Gross Stroke: <%= channels["poc.downhole_gross_stroke"].value %> in.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress" style="margin:1em 5%">
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_adjusted_gross_stroke" role="progressbar" aria-valuenow="<%= channels["poc.downhole_adjusted_gross_stroke"].value %>" aria-valuemin="0" aria-valuemax="100" style="width: <%= channels["poc.downhole_adjusted_gross_stroke"].value %>%;">
|
||||
Downhole Adjusted Gross Stroke: <%= channels["poc.downhole_adjusted_gross_stroke"].value %> in.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress" style="margin:1em 5%">
|
||||
<div class="progress-bar progress-bar-striped active" id="downhole_net_stroke" role="progressbar" aria-valuenow="<%= channels["poc.downhole_net_stroke"].value %>" aria-valuemin="0" aria-valuemax="100" style="width: <%= channels["poc.downhole_net_stroke"].value %>%;">
|
||||
Downhole Net Stroke: <%= channels["poc.downhole_net_stroke"].value %> in.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<table style="margin-top: 1.5em;" class="table table-striped">
|
||||
<thead>
|
||||
<tr><th>Measurement</th><th>Value</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- <tr><td>Well Name</td><td><span data-valueupdate="well_name"><%= channels["poc.well_name"].value %></span></td></tr>
|
||||
<tr><td>Fillage Percent</td><td><span data-valueupdate="fillage_percent"><%= channels["poc.fillage_percent"].value %> %</span></td></tr> -->
|
||||
<tr><td>Fluid Gradient</td><td><span data-valueupdate="fluid_gradient"><%= channels["poc.fluid_gradient"].value %> lbs/ft</span></td></tr>
|
||||
<tr><td>dt</td><td><span data-valueupdate="dt"><%= channels["poc.dt"].value %> sec</span></td></tr>
|
||||
<tr><td>Tubing Head Pressure</td><td><span data-valueupdate="tubing_head_pressure"><%= channels["poc.tubing_head_pressure"].value %> PSI</span></td></tr>
|
||||
<tr><td>Stuffing Box Friction</td><td><span data-valueupdate="stuffing_box_friction"><%= channels["poc.stuffing_box_friction"].value %> lbs.</span></td></tr>
|
||||
|
||||
<tr><td>Surface Stroke Length</td><td><span data-valueupdate="surface_stroke_length"><%= channels["poc.surface_stroke_length"].value %> in.</span></td></tr>
|
||||
<tr><td>Surface Min. Load</td><td><span data-valueupdate="surface_min_load"><%= channels["poc.surface_min_load"].value %> lbs.</span></td></tr>
|
||||
<tr><td>Surface Max. Load</td><td><span data-valueupdate="surface_max_load"><%= channels["poc.surface_max_load"].value %> lbs.</span></td></tr>
|
||||
|
||||
<tr><td>Downhole Gross Stroke</td><td><span data-valueupdate="downhole_gross_stroke"><%= channels["poc.downhole_gross_stroke"].value %> in.</span></td></tr>
|
||||
<tr><td>Tubing Movement</td><td><span data-valueupdate="tubing_movement"><%= channels["poc.tubing_movement"].value %> in.</span></td></tr>
|
||||
<tr><td>Downhole Adjusted Gross Stroke</td><td><span data-valueupdate="downhole_adjusted_gross_stroke"><%= channels["poc.downhole_adjusted_gross_stroke"].value %> in.</span></td></tr>
|
||||
<tr><td>Downhole Net Stroke</td><td><span data-valueupdate="downhole_net_stroke"><%= channels["poc.downhole_net_stroke"].value %> in.</span></td></tr>
|
||||
<tr><td>Downhole Fluid Load</td><td><span data-valueupdate="downhole_fluid_load"><%= channels["poc.downhole_fluid_load"].value %> lbs.</span></td></tr>
|
||||
|
||||
<tr><td>Polished Rod HP</td><td><span data-valueupdate="polished_rod_hp"><%= channels["poc.polished_rod_hp"].value %> HP</span></td></tr>
|
||||
<tr><td>Pump HP</td><td><span data-valueupdate="pump_hp"><%= channels["poc.pump_hp"].value %> HP</span></td></tr>
|
||||
<tr><td>Fluid Level</td><td><span data-valueupdate="fluid_above_pump"><%= channels["poc.fluid_above_pump"].value %> ft.</span></td></tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<style>
|
||||
.overview .col-xs-4 {
|
||||
.box-me {
|
||||
position: relative;
|
||||
padding: 0.5em;
|
||||
padding-bottom: 1.5em;
|
||||
border: 1px solid #eee;
|
||||
/*margin: 1em 0;*/
|
||||
}
|
||||
.overview .gauge-box {
|
||||
}
|
||||
.box-me .gauge-box {
|
||||
margin-top: -0.25em;
|
||||
}
|
||||
.overview h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.pad15 {
|
||||
margin: 15px 15px;
|
||||
}
|
||||
|
||||
.box-me h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
.dynamic-chart-form {
|
||||
background-color: whiteSmoke;
|
||||
padding: 1em 0.5em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.row-flex {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.row-flex > [class*='col-'] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#systemStatusTimelineContainer h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -15,6 +15,7 @@ import pickle
|
||||
import re
|
||||
from device_base import deviceBase
|
||||
from datetime import datetime
|
||||
import traceback
|
||||
|
||||
import requests
|
||||
try:
|
||||
@@ -24,85 +25,109 @@ except:
|
||||
import calendar
|
||||
|
||||
|
||||
def min_max_check(val, min, max):
|
||||
if val < min:
|
||||
return min
|
||||
elif val > max:
|
||||
return max
|
||||
else:
|
||||
return val
|
||||
class Channel():
|
||||
def __init__(self, mesh_name, data_type, chg_threshold, guarantee_sec):
|
||||
self.mesh_name = mesh_name
|
||||
self.data_type = data_type
|
||||
self.last_value = None
|
||||
self.value = None
|
||||
self.last_send_time = 0
|
||||
self.chg_threshold = chg_threshold
|
||||
self.guarantee_sec = guarantee_sec
|
||||
|
||||
def checkSend(self, newVal, force):
|
||||
v = self.data_type(newVal)
|
||||
if self.data_type == bool or self.data_type == str:
|
||||
if (self.last_send_time == 0) or (self.value is None) or not (self.value == v) or ((self.guarantee_sec > 0) and ((time.time() - self.last_send_time) > self.guarantee_sec)) or (force):
|
||||
self.last_value = self.value
|
||||
self.value = v
|
||||
self.last_send_time = time.time()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if (self.last_send_time == 0) or (self.value is None) or (abs(self.value - v) > self.chg_threshold) or ((self.guarantee_sec > 0) and ((time.time() - self.last_send_time) > self.guarantee_sec)) or (force):
|
||||
self.last_value = self.value
|
||||
self.value = v
|
||||
self.last_send_time = time.time()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
go_channels = {
|
||||
"percent_run": {"meshifyName": "go_percent_run", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"kWh": {"meshifyName": "go_kwh", "last_value": "", "last_send_time": 0, "data_type": " float", "change_amount": 0},
|
||||
"electricity_cost": {"meshifyName": "go_electricity_cost", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"peak_load": {"meshifyName": "go_peak_load", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"min_load": {"meshifyName": "go_min_load", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"average_SPM": {"meshifyName": "go_average_spm", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"production_calculated": {"meshifyName": "go_production_calculated", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"full_card_production": {"meshifyName": "go_full_card_production", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"polished_rod_HP": {"meshifyName": "go_polished_rod_hp", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"lifting_cost": {"meshifyName": "go_lifting_cost", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"fluid_above_pump": {"meshifyName": "go_fluid_above_pump", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"pump_intake_pressure": {"meshifyName": "go_pump_intake_pressure", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"kWh_regen": {"meshifyName": "go_kwh_regen", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
"inflow_rate": {"meshifyName": "go_inflow_rate", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
}
|
||||
'electricity_cost': Channel('go_electricity_cost', float, 0.0, 0),
|
||||
'percent_run': Channel('go_percent_run', float, 0.0, 0),
|
||||
'average_SPM': Channel('go_average_spm', float, 0.0, 0),
|
||||
'peak_load': Channel('go_peak_load', float, 0.0, 0),
|
||||
'polished_rod_HP': Channel('go_polished_rod_hp', float, 0.0, 0),
|
||||
'lifting_cost': Channel('go_lifting_cost', float, 0.0, 0),
|
||||
'full_card_production': Channel('go_full_card_production', float, 0.0, 0),
|
||||
'fluid_above_pump': Channel('go_fluid_above_pump', float, 0.0, 0),
|
||||
'production_calculated': Channel('go_production_calculated', float, 0.0, 0),
|
||||
'kWh': Channel('go_kwh', float, 0.0, 3600),
|
||||
'inflow_rate': Channel('go_inflow_rate', float, 0.0, 0),
|
||||
'kWh_regen': Channel('go_kwh_regen', float, 0.0, 0),
|
||||
'pump_intake_pressure': Channel('go_pump_intake_pressure', float, 0.0, 0),
|
||||
'min_load': Channel('go_min_load', float, 0.0, 0),
|
||||
}
|
||||
|
||||
stroke_data_min_upload_time = 300 # seconds
|
||||
card_channels = {
|
||||
"card_id": Channel("card_history", int, 0, 0),
|
||||
"card_type": Channel("cardtype", str, 0, 0),
|
||||
"card": Channel(None, str, 0, 600)
|
||||
}
|
||||
|
||||
channels = {
|
||||
"status": {"last_value": "", "data_type": "str", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": 0},
|
||||
"card_history": {"last_value": "", "data_type": "str", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": 0},
|
||||
"well_name": {"last_value": "", "data_type": "str", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"tubing_head_pressure": {"last_value": "", "data_type": "float", "change_amount": 5, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"fluid_gradient": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"stuffing_box_friction": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"dt": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"downhole_gross_stroke": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"downhole_adjusted_gross_stroke": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"downhole_net_stroke": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"downhole_fluid_load": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"surface_max_load": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"surface_min_load": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"tubing_movement": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"surface_stroke_length": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"fillage_percent": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"polished_rod_hp": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"pump_hp": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"SPM": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"fluid_above_pump": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"pump_intake_pressure": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"stroke_production": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"drive_torque_mode": {"last_value": "", "data_type": "int", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"torque_reference": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"speed_reference": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"downhole_min_position": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
"downhole_max_position": {"last_value": "", "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": stroke_data_min_upload_time},
|
||||
}
|
||||
status = Channel('status', str, 0, 0)
|
||||
|
||||
tag_channels = {
|
||||
'polished_rod_hp': Channel('polished_rod_hp', float, 1.0, 3600),
|
||||
'drive_torque_mode': Channel('drive_torque_mode', int, 1.0, 3600),
|
||||
'downhole_gross_stroke': Channel('downhole_gross_stroke', float, 1.0, 3600),
|
||||
'fluid_gradient': Channel('fluid_gradient', float, 0.01, 3600),
|
||||
'tubing_head_pressure': Channel('tubing_head_pressure', float, 10.0, 3600),
|
||||
'surface_min_load': Channel('surface_min_load', float, 500.0, 3600),
|
||||
'downhole_fluid_load': Channel('downhole_fluid_load', float, 500.0, 3600),
|
||||
'downhole_max_position': Channel('downhole_max_position', float, 1.0, 3600),
|
||||
'downhole_net_stroke': Channel('downhole_net_stroke', float, 1.0, 3600),
|
||||
'fillage_percent': Channel('fillage_percent', float, 5.0, 3600),
|
||||
'pump_hp': Channel('pump_hp', float, 1.0, 3600),
|
||||
'spm': Channel('SPM', float, 0.5, 3600),
|
||||
'pump_intake_pressure': Channel('pump_intake_pressure', float, 200.0, 3600),
|
||||
'speed_reference': Channel('speed_reference', float, 50.0, 3600),
|
||||
'downhole_min_position': Channel('downhole_min_position', float, 1.0, 3600),
|
||||
'tubing_movement': Channel('tubing_movement', float, 1.0, 3600),
|
||||
'surface_max_load': Channel('surface_max_load', float, 500.0, 3600),
|
||||
'stuffing_box_friction': Channel('stuffing_box_friction', float, 50.0, 3600),
|
||||
'dt': Channel('dt', float, 0.001, 3600),
|
||||
'fluid_level': Channel('fluid_above_pump', float, 100.0, 3600),
|
||||
'torque_reference': Channel('torque_reference', float, 5.0, 3600),
|
||||
'surface_stroke_length': Channel('surface_stroke_length', float, 1.0, 3600),
|
||||
'downhole_adjusted_gross_stroke': Channel('downhole_adjusted_gross_stroke', float, 1.0, 3600),
|
||||
'stroke_production': Channel('stroke_production', float, 0.001, 3600),
|
||||
}
|
||||
|
||||
total_min_upload_time = 300 # seconds
|
||||
dt_channels = { # Current Daily Totals
|
||||
"Average_SPM": {"meshify_channel": "dt_average_spm", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Downhole_Net_Stroke": {"meshify_channel": "dt_downhole_net_stroke", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Electricity_Cost": {"meshify_channel": "dt_electricity_cost", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Fluid_Level": {"meshify_channel": "dt_fluid_level", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Full_Card_Production": {"meshify_channel": "dt_full_card_production", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Inflow_Rate": {"meshify_channel": "dt_inflow_rate", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"kWh": {"meshify_channel": "dt_kWh", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"kWh_Regen": {"meshify_channel": "dt_kWh_regen", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Lifting_Cost": {"meshify_channel": "dt_lifting_cost", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Peak_Load": {"meshify_channel": "dt_peak_load", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Min_Load": {"meshify_channel": "dt_min_load", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Percent_Run": {"meshify_channel": "dt_percent_run", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Polished_Rod_HP": {"meshify_channel": "dt_polished_rod_hp", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Calculated_Production": {"meshify_channel": "dt_calculated_production", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Projected_Production": {"meshify_channel": "dt_projected_production", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Pump_HP": {"meshify_channel": "dt_pump_hp", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Pump_Intake_Presure": {"meshify_channel": "dt_pump_intake_pressure", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Surface_Stroke_Length": {"meshify_channel": "dt_surface_stroke_length", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
"Tubing_Movement": {"meshify_channel": "dt_tubing_movement", "last_value": 0, "data_type": "float", "change_amount": 0, "last_time_uploaded": 0, "min_time_between_uploads": total_min_upload_time},
|
||||
'Electricity_Cost': Channel('dt_electricity_cost', float, 1.0, 3600),
|
||||
'Downhole_Net_Stroke': Channel('dt_downhole_net_stroke', float, 2.0, 3600),
|
||||
'Tubing_Movement': Channel('dt_tubing_movement', float, 1.0, 3600),
|
||||
'Average_SPM': Channel('dt_average_spm', float, 0.50, 3600),
|
||||
'Peak_Load': Channel('dt_peak_load', float, 500.0, 3600),
|
||||
'kWh': Channel('dt_kWh', float, 5.0, 3600),
|
||||
'Pump_HP': Channel('dt_pump_hp', float, 0.5, 3600),
|
||||
'Percent_Run': Channel('dt_percent_run', float, 5.0, 3600),
|
||||
'Projected_Production': Channel('dt_projected_production', float, 5.0, 3600),
|
||||
'Pump_Intake_Presure': Channel('dt_pump_intake_pressure', float, 100.0, 3600),
|
||||
'Inflow_Rate': Channel('dt_inflow_rate', float, 1.0, 3600),
|
||||
'Calculated_Production': Channel('dt_calculated_production', float, 5.0, 3600),
|
||||
'Fluid_Level': Channel('dt_fluid_level', float, 100.0, 3600),
|
||||
'Lifting_Cost': Channel('dt_lifting_cost', float, 1.0, 3600),
|
||||
'Polished_Rod_HP': Channel('dt_polished_rod_hp', float, 1.0, 3600),
|
||||
'kWh_Regen': Channel('dt_kWh_regen', float, 1.0, 3600),
|
||||
'Surface_Stroke_Length': Channel('dt_surface_stroke_length', float, 1.0, 3600),
|
||||
'Full_Card_Production': Channel('dt_full_card_production', float, 10.0, 3600),
|
||||
'Min_Load': Channel('dt_min_load', float, 500.0, 3600),
|
||||
}
|
||||
|
||||
|
||||
@@ -134,6 +159,36 @@ class start(threading.Thread, deviceBase):
|
||||
print "couldn't load enent ID's from pickle"
|
||||
self.eventIds = []
|
||||
|
||||
# load stored Well Test ID's
|
||||
try:
|
||||
with open('welltestIDs.p', 'rb') as handle:
|
||||
self.welltestIDs = pickle.load(handle)
|
||||
|
||||
print "found pickled welltestIDs dictionary: {0}".format(self.welltestIDs)
|
||||
except:
|
||||
print "couldn't load well test ID's from pickle"
|
||||
self.welltestIDs = []
|
||||
|
||||
# load stored Fluid Shot ID's
|
||||
try:
|
||||
with open('fluidshotIDs.p', 'rb') as handle:
|
||||
self.fluidshotIDs = pickle.load(handle)
|
||||
|
||||
print "found pickled fluidshotIDs dictionary: {0}".format(self.fluidshotIDs)
|
||||
except:
|
||||
print "couldn't load fluid shot ID's from pickle"
|
||||
self.fluidshotIDs = []
|
||||
|
||||
# load stored note ID's
|
||||
try:
|
||||
with open('noteIDs.p', 'rb') as handle:
|
||||
self.noteIDs = pickle.load(handle)
|
||||
|
||||
print "found pickled noteID dictionary: {0}".format(self.noteIDs)
|
||||
except:
|
||||
print "couldn't load note ID's from pickle"
|
||||
self.noteIDs = []
|
||||
|
||||
# load stored wellconfig's
|
||||
try:
|
||||
with open('wellSetup.p', 'rb') as handle:
|
||||
@@ -158,27 +213,44 @@ class start(threading.Thread, deviceBase):
|
||||
checkBackupSkipped = 1
|
||||
while True:
|
||||
try:
|
||||
runLoopStatus = "checkEvents"
|
||||
self.checkEvents()
|
||||
if self.forceSend:
|
||||
print("!!!!!!!!!!!!!!! FORCE SEND !!!!!!!!!!!!!!!")
|
||||
|
||||
runLoopStatus = "checkStatus"
|
||||
self.checkStatus()
|
||||
|
||||
runLoopStatus = "checkEvents"
|
||||
self.checkEvents()
|
||||
|
||||
runLoopStatus = "checkNotes"
|
||||
self.checkNotes()
|
||||
|
||||
runLoopStatus = "checkWellTests"
|
||||
self.checkWellTests()
|
||||
|
||||
runLoopStatus = "checkFluidShots"
|
||||
self.checkFluidShots()
|
||||
|
||||
runLoopStatus = "checkDailyTotals"
|
||||
self.checkDailyTotals()
|
||||
|
||||
runLoopStatus = "checkGaugeOffData"
|
||||
self.checkGaugeOffData()
|
||||
|
||||
runLoopStatus = "checkStoredValues"
|
||||
self.checkStoredValues(self.forceSend)
|
||||
|
||||
runLoopStatus = "getDataLoggerStatus()"
|
||||
self.getDataLoggerStatus()
|
||||
|
||||
if self.statusChanged:
|
||||
runLoopStatus = "getLatestXCards"
|
||||
self.getLatestXCards(5)
|
||||
else:
|
||||
runLoopStatus = "checkLatestCard"
|
||||
self.checkLatestCard()
|
||||
# if self.statusChanged:
|
||||
# runLoopStatus = "getLatestXCards"
|
||||
# self.getLatestXCards(5)
|
||||
# else:
|
||||
# runLoopStatus = "checkLatestCard"
|
||||
# self.checkLatestCard()
|
||||
runLoopStatus = "checkLatestCard"
|
||||
self.checkLatestCard()
|
||||
|
||||
if self.forceSend or (checkBackupSkipped > checkBackupEvery):
|
||||
runLoopStatus = "checkBackup"
|
||||
@@ -192,6 +264,7 @@ class start(threading.Thread, deviceBase):
|
||||
except Exception, e:
|
||||
sleep_timer = 20
|
||||
print "Error during {0} of run loop: {1}\nWill try again in {2} seconds...".format(runLoopStatus, e, sleep_timer)
|
||||
traceback.print_exc()
|
||||
time.sleep(sleep_timer)
|
||||
|
||||
def checkBackup(self):
|
||||
@@ -219,7 +292,50 @@ class start(threading.Thread, deviceBase):
|
||||
with open('eventIds.p', 'wb') as handle:
|
||||
pickle.dump(self.eventIds, handle)
|
||||
|
||||
def checkNotes(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/notes/get").text)
|
||||
notes = data["notes"]
|
||||
for note in notes:
|
||||
if int(note["id"]) not in self.noteIDs:
|
||||
timestamp = calendar.timegm(time.strptime(note["date_time"], '%Y-%m-%d %H:%M:%S'))
|
||||
# we have a new note
|
||||
self.sendtodbJSON("notes", json.dumps(note), timestamp)
|
||||
self.noteIDs.append(int(note["id"]))
|
||||
if len(self.noteIDs) > 50:
|
||||
del self.noteIDs[0]
|
||||
with open('noteIDs.p', 'wb') as handle:
|
||||
pickle.dump(self.noteIDs, handle)
|
||||
|
||||
def checkFluidShots(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/fluid_shot/get").text)
|
||||
fluid_shots = data["fluid_shots"]
|
||||
for shot in fluid_shots:
|
||||
if int(shot["id"]) not in self.fluidshotIDs:
|
||||
timestamp = calendar.timegm(time.strptime(shot["shot_datetime"], '%Y-%m-%d %H:%M:%S'))
|
||||
# we have a new note
|
||||
self.sendtodbJSON("fluidshots", json.dumps(shot), timestamp)
|
||||
self.fluidshotIDs.append(int(shot["id"]))
|
||||
if len(self.fluidshotIDs) > 50:
|
||||
del self.fluidshotIDs[0]
|
||||
with open('fluidshotIDs.p', 'wb') as handle:
|
||||
pickle.dump(self.fluidshotIDs, handle)
|
||||
|
||||
def checkWellTests(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/well_test/get").text)
|
||||
well_tests = data["well_tests"]
|
||||
for test in well_tests:
|
||||
if int(test["id"]) not in self.welltestIDs:
|
||||
timestamp = calendar.timegm(time.strptime(test["test_date"], '%Y-%m-%d %H:%M:%S'))
|
||||
# we have a new note
|
||||
self.sendtodbJSON("welltests", json.dumps(test), timestamp)
|
||||
self.welltestIDs.append(int(test["id"]))
|
||||
if len(self.welltestIDs) > 50:
|
||||
del self.welltestIDs[0]
|
||||
with open('welltestIDs.p', 'wb') as handle:
|
||||
pickle.dump(self.welltestIDs, handle)
|
||||
|
||||
def checkStatus(self):
|
||||
global status
|
||||
statusMap = {
|
||||
0: 'Stopped',
|
||||
1: 'Running',
|
||||
@@ -235,47 +351,40 @@ class start(threading.Thread, deviceBase):
|
||||
if st_response.status_code == 200:
|
||||
data = json.loads(st_response.text)
|
||||
date = data["ISOdate"]
|
||||
status = statusMap[int(data["status"])]
|
||||
status_read = statusMap[int(data["status"])]
|
||||
|
||||
if channels["status"]["last_value"] != status:
|
||||
if status.last_value != status_read:
|
||||
self.statusChanged = True
|
||||
print "Status has changed from {0} to {1} @ {2}".format(channels["status"]["last_value"], status, time.time())
|
||||
print "Status has changed from {0} to {1} @ {2}".format(status.last_value, status_read, time.time())
|
||||
else:
|
||||
self.statusChanged = False
|
||||
|
||||
if self.statusChanged or self.forceSend:
|
||||
self.status = status
|
||||
self.status = status_read
|
||||
reg = "(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d{3})Z"
|
||||
fd = re.search(reg, date)
|
||||
dt = datetime(int(fd.group(1)), int(fd.group(2)), int(fd.group(3)), int(fd.group(4)), int(fd.group(5)), int(fd.group(6)), int(fd.group(7)))
|
||||
# timestamp = int(time.mktime(time.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')))
|
||||
timestamp = calendar.timegm(dt.timetuple())
|
||||
self.sendtodb("status", status, timestamp)
|
||||
channels["status"]["last_value"] = status
|
||||
self.sendtodb("status", status_read, timestamp)
|
||||
status.last_value = status_read
|
||||
|
||||
def checkDailyTotals(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/totals").text)
|
||||
total = data["totals"]
|
||||
if total['status'] == "success":
|
||||
if data['status'] == "OK":
|
||||
totals = data["totals"]
|
||||
timestamp = 0
|
||||
for val in total['values']:
|
||||
# if dt_channels.has_key(val['name']):
|
||||
for val in totals:
|
||||
if val['name'] in dt_channels:
|
||||
if ((time.time() - int(dt_channels[val['name']]['last_time_uploaded'])) > int(dt_channels[val['name']]['min_time_between_uploads'])):
|
||||
if (float(val['value']) >= (float(dt_channels[val['name']]["last_value"]) + float(dt_channels[val['name']]["change_amount"]))) or (float(val['value']) <= (float(dt_channels[val['name']]["last_value"]) - float(dt_channels[val['name']]["change_amount"]))):
|
||||
print("[dailyTotal] {0}: {1}".format(val['name'], val['value']))
|
||||
self.sendtodb(dt_channels[val['name']]["meshify_channel"], float(val['value']), timestamp)
|
||||
dt_channels[val['name']]["last_value"] = float(val['value'])
|
||||
dt_channels[val['name']]["last_time_uploaded"] = time.time()
|
||||
if dt_channels[val['name']].checkSend(val['value'], False):
|
||||
self.sendtodb(dt_channels[val['name']].mesh_name, dt_channels[val['name']].value, timestamp)
|
||||
else:
|
||||
print("checkDailyTotalsError: {0}".format(total.message))
|
||||
print("checkDailyTotalsError: {0}".format(data.message))
|
||||
|
||||
def checkGaugeOffData(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/history").text)
|
||||
day = data["hist"]
|
||||
date = day['gauge_date']
|
||||
# print day["gauge_date"]
|
||||
# timestamp = time.mktime(time.strptime(day["gauge_date"], '%Y-%m-%dT%H:%M:%S.%fZ'))
|
||||
|
||||
reg = "(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})"
|
||||
fd = re.search(reg, date)
|
||||
@@ -283,31 +392,19 @@ class start(threading.Thread, deviceBase):
|
||||
# timestamp = int(time.mktime(time.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')))
|
||||
timestamp = calendar.timegm(dt.timetuple())
|
||||
for entry in day:
|
||||
# if go_channels.has_key(entry):
|
||||
if entry in go_channels:
|
||||
# "percent_run": {"meshifyName": "go_percent_run", "last_value": "", "last_send_time": 0, "data_type": "float", "change_amount": 0},
|
||||
if go_channels[entry]["last_value"] != day[entry]:
|
||||
print entry, day[entry]
|
||||
print go_channels[entry]["meshifyName"], day[entry], timestamp
|
||||
self.sendtodb(go_channels[entry]["meshifyName"], day[entry], timestamp)
|
||||
go_channels[entry]["last_value"] = day[entry]
|
||||
if go_channels[entry].checkSend(day[entry], False):
|
||||
self.sendtodb(go_channels[entry].mesh_name, day[entry], timestamp)
|
||||
|
||||
def checkLatestCard(self):
|
||||
latest = requests.get(self.device_address + "/json/latest")
|
||||
latest = json.loads(latest.text)
|
||||
folder = str(latest["folder"])
|
||||
file = latest["file"].replace(".csv", "")
|
||||
latest = json.loads(requests.get(self.device_address + "/json/latestcard").text)
|
||||
|
||||
# check the card to see if its new
|
||||
# 1. if its new send the folder/file_name to the card_history channel
|
||||
# 2. if its new and its been 10 minutes since you last sent an entire card, then send up all of the data
|
||||
|
||||
if channels["card_history"]["last_value"] != (folder + "/" + file):
|
||||
# we have a new card
|
||||
# get the data for this event
|
||||
data = json.loads(requests.get(self.device_address + "/json/" + folder + "/" + file).text)
|
||||
dateTime = str(data["card_data"]["Stroke_Time"])
|
||||
# timestamp = time.mktime(time.strptime(dateTime, '%Y-%m-%dT%H:%M:%S.%fZ'))
|
||||
if card_channels['card_id'].checkSend(latest['card_data']['Card_ID'], self.forceSend):
|
||||
dateTime = str(latest["card_data"]["Stroke_Time"])
|
||||
|
||||
reg = "(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})"
|
||||
fd = re.search(reg, dateTime)
|
||||
@@ -317,18 +414,17 @@ class start(threading.Thread, deviceBase):
|
||||
|
||||
print "New card detected @ {0}".format(datetime.strftime(datetime.fromtimestamp(timestamp), "%Y-%m-%d %H:%M:%S.%f"))
|
||||
# set the last value = to current value and upload your data
|
||||
channels["card_history"]["last_value"] = (folder + "/" + file)
|
||||
self.sendtodb("card_history", (folder + "/" + file), timestamp)
|
||||
self.sendtodb("card_history", card_channels['card_id'].value, timestamp)
|
||||
|
||||
# check the last time the card was updated
|
||||
if (time.time() - int(channels["card_history"]["last_time_uploaded"])) > self.cardLoopTimer or self.statusChanged or self.forceSend:
|
||||
if (time.time() - card_channels['card'].last_send_time) > self.cardLoopTimer or self.statusChanged or self.forceSend:
|
||||
# its been 10 minutes, send the full upload
|
||||
print "Either status has changed or last stored card is too old."
|
||||
channels["card_history"]["last_time_uploaded"] = time.time()
|
||||
self.process_card(data, timestamp, card_timestamp, sendCards=True)
|
||||
card_channels["card"].last_send_time = time.time()
|
||||
self.process_card(latest, timestamp, card_timestamp, sendCards=True)
|
||||
return
|
||||
else:
|
||||
self.process_card(data, timestamp, card_timestamp, sendCards=False)
|
||||
self.process_card(latest, timestamp, card_timestamp, sendCards=False)
|
||||
|
||||
def process_card(self, data, data_timestamp, card_timestamp, sendCards=False):
|
||||
|
||||
@@ -339,39 +435,13 @@ class start(threading.Thread, deviceBase):
|
||||
# NOTE: the initial vaue of "" is given to all channels in the channels object,
|
||||
# so to avoid comparing a string to a float, and to make sure on startup we send all of the values, the first time through we send everything that has a "" as its last value
|
||||
|
||||
# We don't want to store any data on starting, just the cards
|
||||
if self.status != 'Starting':
|
||||
for channel in data["card_data"]:
|
||||
# if channels.has_key(channel):
|
||||
if channel in channels:
|
||||
if channels[channel]["data_type"] == "str":
|
||||
if (data["card_data"][channel] != channels[channel]["last_value"] and ((time.time() - int(channels[channel]["last_time_uploaded"])) > int(channels[channel]["min_time_between_uploads"]))) or sendCards:
|
||||
print "new value for: ", channel
|
||||
print data["card_data"][channel]
|
||||
self.sendtodb(channel, str(data["card_data"][channel]), int(data_timestamp))
|
||||
channels[channel]["last_value"] = data["card_data"][channel]
|
||||
channels[channel]["last_time_uploaded"] = time.time()
|
||||
if channels[channel]["data_type"] == "float" or channels[channel]["data_type"] == "int":
|
||||
if channels[channel]["last_value"] == "":
|
||||
# print "first time getting data"
|
||||
print "new value for: ", channel
|
||||
print data["card_data"][channel]
|
||||
self.sendtodb(channel, str(data["card_data"][channel]), int(data_timestamp))
|
||||
channels[channel]["last_value"] = data["card_data"][channel]
|
||||
channels[channel]["last_time_uploaded"] = time.time()
|
||||
if (abs(float(data["card_data"][channel]) - float(channels[channel]["last_value"])) > channels[channel]["change_amount"] and ((time.time() - int(channels[channel]["last_time_uploaded"])) > int(channels[channel]["min_time_between_uploads"]))) or sendCards:
|
||||
# print "first time getting data"
|
||||
print "new value for: ", channel
|
||||
print data["card_data"][channel]
|
||||
self.sendtodb(channel, str(data["card_data"][channel]), int(data_timestamp))
|
||||
channels[channel]["last_value"] = data["card_data"][channel]
|
||||
channels[channel]["last_time_uploaded"] = time.time()
|
||||
|
||||
if sendCards:
|
||||
s_p = data["card_data"]["Surface_Position"]
|
||||
s_l = data["card_data"]["Surface_Load"]
|
||||
d_p = data["card_data"]["Downhole_Position"]
|
||||
d_l = data["card_data"]["Downhole_Load"]
|
||||
self.sendtodb("cardtype", str(data['card_data']['Card_Type']), int(data_timestamp))
|
||||
|
||||
s_p = data['card_data']["Surface_Position"]
|
||||
s_l = data['card_data']["Surface_Load"]
|
||||
d_p = data['card_data']["Downhole_Position"]
|
||||
d_l = data['card_data']["Downhole_Load"]
|
||||
newSc = "["
|
||||
newDc = "["
|
||||
|
||||
@@ -400,6 +470,15 @@ class start(threading.Thread, deviceBase):
|
||||
self.sendtodb("sc", newSc, card_timestamp)
|
||||
self.sendtodb("dc", newDc, card_timestamp)
|
||||
|
||||
def checkStoredValues(self, forceSend):
|
||||
data = json.loads(requests.get(self.device_address + "/json/tagvalues").text)
|
||||
if data['status'] == "OK":
|
||||
vals = data['vals']
|
||||
for val in vals:
|
||||
if val['name'] in tag_channels:
|
||||
if tag_channels[val['name']].checkSend(val['val'], forceSend):
|
||||
self.sendtodbJSON(tag_channels[val['name']].mesh_name, tag_channels[val['name']].value, 0)
|
||||
|
||||
def getLatestXCards(self, numCards):
|
||||
data = json.loads(requests.get(self.device_address + "/json/latest/" + str(int(numCards))).text)
|
||||
for card in data['cards']:
|
||||
|
||||
Reference in New Issue
Block a user