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:
Patrick McDonagh
2016-03-23 23:05:12 +00:00
6 changed files with 631 additions and 279 deletions

View 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>

View 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>

View 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>

View File

@@ -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;

View File

@@ -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>

View File

@@ -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']: