Compare commits
17 Commits
discharge-
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a443a07e9 | ||
|
|
4a03ac9026 | ||
|
|
a783b061c1 | ||
|
|
8d361778da | ||
|
|
4f34a8b867 | ||
|
|
35311ada74 | ||
|
|
72ae88741b | ||
|
|
7dff9d58eb | ||
|
|
e96e82b31b | ||
|
|
a350e2fb62 | ||
|
|
02aa1de457 | ||
|
|
92bd3367a3 | ||
|
|
049834469c | ||
|
|
91d6877a05 | ||
|
|
e969faf023 | ||
|
|
8f487debe3 | ||
|
|
5f3600507b |
11462
PLC/TransferStation.ACD
Normal file
11462
PLC/TransferStation.ACD
Normal file
File diff suppressed because one or more lines are too long
26621
PLC/TransferStation.L5X
Normal file
26621
PLC/TransferStation.L5X
Normal file
File diff suppressed because it is too large
Load Diff
37622
PLC/TransferSystem_1.L5X
Normal file
37622
PLC/TransferSystem_1.L5X
Normal file
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@
|
||||
<div class="row row-flex">
|
||||
<div class="col-md-4 box-me">
|
||||
<div class="m flowTarget">
|
||||
<h3>Flow Target</h3>
|
||||
<h2>Flow Target</h2>
|
||||
<hr />
|
||||
<br />
|
||||
|
||||
@@ -68,6 +68,36 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 box-me">
|
||||
<div class="m lineBreakSetpoint">
|
||||
<h2>Line Break Flow Multiplier</h2>
|
||||
<hr />
|
||||
<br />
|
||||
|
||||
<div class="entry-top-level" id="lineBreakSetpoint">
|
||||
<form class="form-inline">
|
||||
<div class="form-group">
|
||||
<input class="form-control val_box"
|
||||
type="number"
|
||||
step="any"
|
||||
value="<%=channels['transferstation.line_break_multiplier'].value %>">
|
||||
</div>
|
||||
<a href="#"
|
||||
data-confirm-message="Are you sure you want to do this?"
|
||||
data-refreshpause="1"
|
||||
data-command=""
|
||||
data-staticsend="{'tag': 'par_LineBreakFlowMultiplier', 'val': <%= Math.round(channels['transferstation.line_break_multiplier'].value * 100) / 100 %>}"
|
||||
data-channelId="<%= channels["transferstation.writeplctag"].channelId %>"
|
||||
data-techname="<%=channels["transferstation.writeplctag"].techName %>"
|
||||
data-name="<%= channels["transferstation.writeplctag"].name%>"
|
||||
data-nodechannelcurrentId="<%= channels["transferstation.writeplctag"].nodechannelcurrentId %>"
|
||||
id="<%= channels["transferstation.writeplctag"].channelId %>"
|
||||
class="btn btn-large btn-theme animated setstatic material-icons">send</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -32,7 +32,7 @@
|
||||
<h2>Flow Rate</h2>
|
||||
<p>
|
||||
<% if ([1, 3, 5, 7, 9, 11, 15].indexOf(parseInt(channels['transferstation.ftx1_enabled'].value)) != -1) { %>
|
||||
<%= Math.round(channels["transferstation.ft01_flow"].value * 100) / 100 %> GPM
|
||||
<%= Math.round(channels["transferstation.ft01_flow"].value * 100) / 100 %> BPD
|
||||
<% } else { %>
|
||||
<%= Math.round((channels["transferstation.ft11_flow"].value + channels["transferstation.ft21_flow"].value + channels["transferstation.ft31_flow"].value) * 100) / 100 %> GPM
|
||||
<% }%>
|
||||
@@ -42,9 +42,9 @@
|
||||
id="gauge-ft01_flow"
|
||||
data-chart="solidgauge"
|
||||
data-nodename="transferstation.ft01_flow"
|
||||
data-units="GPM"
|
||||
data-units="BPD"
|
||||
data-min="0"
|
||||
data-max="4000"
|
||||
data-max="75000"
|
||||
data-decimalplaces="2"
|
||||
data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"
|
||||
data-valuefontsize="18px">
|
||||
@@ -159,9 +159,9 @@
|
||||
id="gauge-ft11_flow"
|
||||
data-chart="solidgauge"
|
||||
data-nodename="transferstation.ft11_flow"
|
||||
data-units="GPM"
|
||||
data-units="BPD"
|
||||
data-min="0"
|
||||
data-max="4000"
|
||||
data-max="50000"
|
||||
data-decimalplaces="2"
|
||||
data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"
|
||||
data-valuefontsize="18px">
|
||||
@@ -277,9 +277,9 @@
|
||||
id="gauge-ft21_flow"
|
||||
data-chart="solidgauge"
|
||||
data-nodename="transferstation.ft21_flow"
|
||||
data-units="GPM"
|
||||
data-units="BPD"
|
||||
data-min="0"
|
||||
data-max="4000"
|
||||
data-max="50000"
|
||||
data-decimalplaces="2"
|
||||
data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"
|
||||
data-valuefontsize="18px">
|
||||
@@ -392,9 +392,9 @@
|
||||
id="gauge-ft31_flow"
|
||||
data-chart="solidgauge"
|
||||
data-nodename="transferstation.ft31_flow"
|
||||
data-units="GPM"
|
||||
data-units="BPD"
|
||||
data-min="0"
|
||||
data-max="4000"
|
||||
data-max="50000"
|
||||
data-decimalplaces="2"
|
||||
data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"
|
||||
data-valuefontsize="18px">
|
||||
@@ -3,7 +3,7 @@
|
||||
"driverFileName":"transferstation.py",
|
||||
"deviceName":"transferstation",
|
||||
"driverId":"0140",
|
||||
"releaseVersion":"2",
|
||||
"releaseVersion":"3",
|
||||
"files": {
|
||||
"file1":"transferstation.py",
|
||||
"file2":"Channel.py",
|
||||
|
||||
5768
POCloud/modbusMap.p
5768
POCloud/modbusMap.p
File diff suppressed because it is too large
Load Diff
@@ -74,7 +74,7 @@ class start(threading.Thread, deviceBase):
|
||||
deviceBase.__init__(self, name=name, number=number, mac=mac, Q=Q, mcu=mcu, companyId=companyId, offset=offset, mqtt=mqtt, Nodes=Nodes)
|
||||
|
||||
self.daemon = True
|
||||
self.version = "2"
|
||||
self.version = "3"
|
||||
self.finished = threading.Event()
|
||||
self.forceSend = False
|
||||
threading.Thread.start(self)
|
||||
@@ -89,11 +89,15 @@ class start(threading.Thread, deviceBase):
|
||||
def run(self):
|
||||
"""Actually run the driver."""
|
||||
global persist
|
||||
wait_sec = 10
|
||||
wait_sec = 60
|
||||
for i in range(0, wait_sec):
|
||||
print("transferstation driver will start in {} seconds".format(wait_sec - i))
|
||||
time.sleep(1)
|
||||
print("BOOM! Starting transferstation driver...")
|
||||
# after its booted up assuming that M1 is now reading modbus data
|
||||
# we can replace the reference made to this device name to the M1 driver with this
|
||||
# driver. The 01 in the 0199 below is the device number you referenced in the modbus wizard
|
||||
self.nodes["transferstation_0199"] = self
|
||||
send_loops = 0
|
||||
while True:
|
||||
if self.forceSend:
|
||||
@@ -117,14 +121,14 @@ class start(threading.Thread, deviceBase):
|
||||
else:
|
||||
send_loops += 1
|
||||
|
||||
def transferstation_sync(self, name, value):
|
||||
"""Sync all data from the driver."""
|
||||
self.forceSend = True
|
||||
# self.sendtodb("log", "synced", 0)
|
||||
return True
|
||||
# def transferstation_sync(self, name, value):
|
||||
# """Sync all data from the driver."""
|
||||
# self.forceSend = True
|
||||
# # self.sendtodb("log", "synced", 0)
|
||||
# return True
|
||||
|
||||
def transferstation_writeplctag(self, name, value):
|
||||
"""Write a value to the PLC."""
|
||||
# """Write a value to the PLC."""
|
||||
new_val = json.loads(str(value).replace("'", '"'))
|
||||
tag_n = str(new_val['tag']) # "cmd_Start"
|
||||
val_n = new_val['val']
|
||||
|
||||
11271
TransferStation.ACD
11271
TransferStation.ACD
File diff suppressed because one or more lines are too long
5
docs/_config.yml
Normal file
5
docs/_config.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
markdown: kramdown
|
||||
plugins:
|
||||
- jekyll-mentions
|
||||
|
||||
theme: jekyll-theme-slate
|
||||
82
docs/index.md
Normal file
82
docs/index.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Frac Pit Transfer Station
|
||||
### Developed by @patrickjmcd, @Henry-Pump
|
||||
|
||||
|
||||
# Definitions
|
||||
**Station:** the transfer station, The full system
|
||||
|
||||
**System:** an individual transfer system consisting of a combination of optional level transmitter, charge pump, intake pressure transmitter, optional discharge pressure transmitter, booster pump, and optional system flow transmitter.
|
||||
|
||||
|
||||
# Operation
|
||||
|
||||
## Control Modes
|
||||
### Auto Mode
|
||||
|
||||
In auto mode, the system will react to changing environmental conditions to maintain either a constant Discharge Pressure or a constant Flow Rate.
|
||||
|
||||
### Manual Mode
|
||||
|
||||
In manual mode, each system can be started or stopped at will and commanded to run at specific frequencies
|
||||
|
||||
## Settings
|
||||
|
||||
### Auto Mode Priority
|
||||
|
||||
In auto mode, the Auto Mode Priority is the order in which the specific systems will initiate based on the Get Help Frequency setpoints.
|
||||
|
||||
### Get Help Frequwncy
|
||||
|
||||
In auto mode, the Get Help Frequency is the motor frequency at which the system will activate the next system to assist with maintaining the flow or pressure setpoint.
|
||||
|
||||
### Takeover Frequency
|
||||
|
||||
In auto mode, the Takeover Frequency is the motor frequency at which the current system will shut down to allow the previous system to attempt to regulate the discharge pressure or flow rate the Transfer Station.
|
||||
|
||||
### Use System Flowmeter
|
||||
|
||||
Enables the use of the Overall Flowmeter or the use of a system-specific flowmeter.
|
||||
|
||||
### Use System Level Transmitter
|
||||
|
||||
Enables the use of the Station Level Transmitter of the use of a system-specific level transmitter.
|
||||
|
||||
### Has Booster Pump Discharge Pressure Transmitter
|
||||
|
||||
Enables the use of a system-specific Booster Pump Discharge Transmitter
|
||||
|
||||
|
||||
# Wiring
|
||||
|
||||
| Slot | Channel | Device |
|
||||
|-------- |------------ |-------------------------------- |
|
||||
| 2 | 0 | LT01/LT11 Pond Level |
|
||||
| 2 | 1 | PT11 Intake Pressure |
|
||||
| 2 | 2 | PT12 Discharge Pressure |
|
||||
| 2 | 3 | FT11 System Output |
|
||||
| 3 | 0 | LT21 Pond Level |
|
||||
| 3 | 1 | PT21 Intake Pressure |
|
||||
| 3 | 2 | PT22 Discharge Pressure |
|
||||
| 3 | 3 | FT21 System Output |
|
||||
| 4 | 0 | LT31 Pond Level |
|
||||
| 4 | 1 | PT31 Intake Pressure |
|
||||
| 4 | 2 | PT32 Discharge Pressure |
|
||||
| 4 | 3 | FT31 System Output |
|
||||
|
||||
|
||||
|
||||
# Networking
|
||||
## IP Addresses
|
||||
|
||||
| Device | IP Address |
|
||||
|-------------------------------------- |-------------------- |
|
||||
| PLC (L19) | 192.168.1.10 |
|
||||
| MC11 - System 1 Charge Pump | 192.168.1.11 |
|
||||
| MC21 - System 2 Charge Pump | 192.168.1.12 |
|
||||
| MC31 - System 3 Charge Pump | 192.168.1.13 |
|
||||
| MC12 - System 1 Booster Pump | 192.168.1.14 |
|
||||
| MC22 - System 2 Booster Pump | 192.168.1.15 |
|
||||
| MC32 - System 3 Booster Pump | 192.168.1.16 |
|
||||
| HMI1 | 192.168.1.21 |
|
||||
| HMI2 | 192.168.1.22 |
|
||||
| HMI3 | 192.168.1.23 |
|
||||
38
meshify.py
38
meshify.py
@@ -1,38 +0,0 @@
|
||||
"""Query Meshify for data."""
|
||||
import requests
|
||||
import json
|
||||
from os import getenv
|
||||
from sys import exit
|
||||
|
||||
MESHIFY_BASE_URL = "https://henrypump.meshify.com/api/v3/"
|
||||
MESHIFY_USERNAME = getenv("MESHIFY_USERNAME")
|
||||
MESHIFY_PASSWORD = getenv("MESHIFY_PASSWORD")
|
||||
MESHIFY_AUTH = requests.auth.HTTPBasicAuth(MESHIFY_USERNAME, MESHIFY_PASSWORD)
|
||||
|
||||
if not MESHIFY_USERNAME or not MESHIFY_PASSWORD:
|
||||
print("Be sure to set the meshify username and password as environment variables MESHIFY_USERNAME and MESHIFY_PASSWORD")
|
||||
exit()
|
||||
|
||||
|
||||
def find_by_name(name, list_of_stuff):
|
||||
"""Find an object in a list of stuff by its name parameter."""
|
||||
for x in list_of_stuff:
|
||||
if x['name'] == name:
|
||||
return x
|
||||
return False
|
||||
|
||||
|
||||
def query_meshify_api(endpoint):
|
||||
"""Make a query to the meshify API."""
|
||||
q_url = MESHIFY_BASE_URL + endpoint
|
||||
q_req = requests.get(q_url, auth=MESHIFY_AUTH)
|
||||
return json.loads(q_req.text) if q_req.status_code == 200 else []
|
||||
|
||||
|
||||
def post_meshify_api(endpoint, data):
|
||||
"""Post data to the meshify API."""
|
||||
q_url = MESHIFY_BASE_URL + endpoint
|
||||
q_req = requests.post(q_url, data=json.dumps(data), auth=MESHIFY_AUTH)
|
||||
if q_req.status_code != 200:
|
||||
print(q_req.status_code)
|
||||
return json.loads(q_req.text) if q_req.status_code == 200 else []
|
||||
BIN
meshify.pyc
BIN
meshify.pyc
Binary file not shown.
@@ -1,38 +0,0 @@
|
||||
"""Read a CSV file of channels and post them to Meshify via the API."""
|
||||
|
||||
import csv
|
||||
import meshify
|
||||
import sys
|
||||
|
||||
|
||||
def main(csv_file, devicetype):
|
||||
"""Main function."""
|
||||
csvfile = open(csv_file, 'rU')
|
||||
reader = csv.DictReader(csvfile, dialect=csv.excel)
|
||||
|
||||
channels = []
|
||||
idx = 0
|
||||
for x in reader:
|
||||
channels.append(x)
|
||||
channels[idx]["fromMe"] = False
|
||||
channels[idx]["regex"] = ""
|
||||
channels[idx]["regexErrMsg"] = ""
|
||||
channels[idx]["dataType"] = int(channels[idx]["dataType"])
|
||||
channels[idx]["deviceTypeId"] = int(channels[idx]["deviceTypeId"])
|
||||
channels[idx]["channelType"] = int(channels[idx]["channelType"])
|
||||
channels[idx]["io"] = bool(channels[idx]["io"])
|
||||
idx += 1
|
||||
|
||||
try:
|
||||
this_devicetype = meshify.find_by_name(devicetype, meshify.query_meshify_api("devicetypes"))
|
||||
for c in channels:
|
||||
print(meshify.post_meshify_api("devicetypes/{}/channels".format(this_devicetype['id']), c))
|
||||
except KeyError:
|
||||
print("Could not find key {}".format(devicetype))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) == 3:
|
||||
main(sys.argv[1], sys.argv[2])
|
||||
else:
|
||||
print("Syntax is python postChannels.py <filepath.csv> <devicetype name>")
|
||||
Binary file not shown.
Reference in New Issue
Block a user