diff --git a/Makefile b/Makefile index 65ee15c..4609711 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ CC := g++ -INC := -I include -I include/wiringPi -I /usr/local/include +INC := -I ./include -I ./include/mraa -I /usr/local/include -I/usr/local/Cellar/nlohmann_json/2.1.1/include CFLAGS := -c --std=c++11 -Wall $(shell pkg-config --cflags --libs libmongocxx) -LIB := -L /usr/local/lib -lmongocxx -lbsoncxx -lmraa +LIB := -L /usr/local/lib -lmongocxx -lbsoncxx SRCDIR := src diff --git a/POCpp.xcodeproj/project.pbxproj b/POCpp.xcodeproj/project.pbxproj index a30d013..d7d2825 100644 --- a/POCpp.xcodeproj/project.pbxproj +++ b/POCpp.xcodeproj/project.pbxproj @@ -333,6 +333,7 @@ C568AEC81F13D1F800524D66 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; DEVELOPMENT_TEAM = JNP6SX52H9; HEADER_SEARCH_PATHS = ""; LIBRARY_SEARCH_PATHS = ( @@ -340,13 +341,14 @@ "$(PROJECT_DIR)/include/mraa", ); PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "/usr/local/include/libmongoc-1.0/** /usr/local/include/mongocxx/v_noabi/** /usr/local/include/bsoncxx/v_noabi/** /usr/local/include/libbson-1.0/** ./include ./include/mraa"; + USER_HEADER_SEARCH_PATHS = "./include ./include/mraa /usr/local/include/mongocxx/v_noabi /usr/local/include /usr/local/include/libmongoc-1.0 /usr/local/include/bsoncxx/v_noabi /usr/local/include/libbson-1.0 /usr/local/Cellar/nlohmann_json/2.1.1/include"; }; name = Debug; }; C568AEC91F13D1F800524D66 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; DEVELOPMENT_TEAM = JNP6SX52H9; HEADER_SEARCH_PATHS = ""; LIBRARY_SEARCH_PATHS = ( @@ -354,7 +356,7 @@ "$(PROJECT_DIR)/include/mraa", ); PRODUCT_NAME = "$(TARGET_NAME)"; - USER_HEADER_SEARCH_PATHS = "/usr/local/include/libmongoc-1.0/** /usr/local/include/mongocxx/v_noabi/** /usr/local/include/bsoncxx/v_noabi/** /usr/local/include/libbson-1.0/** ./include ./include/mraa"; + USER_HEADER_SEARCH_PATHS = "./include ./include/mraa /usr/local/include/mongocxx/v_noabi /usr/local/include /usr/local/include/libmongoc-1.0 /usr/local/include/bsoncxx/v_noabi /usr/local/include/libbson-1.0 /usr/local/Cellar/nlohmann_json/2.1.1/include"; }; name = Release; }; diff --git a/POCpp.xcodeproj/project.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate b/POCpp.xcodeproj/project.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate index 13357af..1b898c0 100644 Binary files a/POCpp.xcodeproj/project.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate and b/POCpp.xcodeproj/project.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/src/AnalogIn.cpp b/src/AnalogIn.cpp index 584de3d..f553530 100644 --- a/src/AnalogIn.cpp +++ b/src/AnalogIn.cpp @@ -85,6 +85,11 @@ double AnalogIn::read(MuxSetup *mux){ } +void AnalogIn::setRawScaling(int rawMin, int rawMax){ + this->rawMin = rawMin; + this->rawMax = rawMax; +} + AnalogIn::~AnalogIn() { // TODO Auto-generated destructor stub } diff --git a/src/AnalogIn.h b/src/AnalogIn.h index 5424563..646f4dd 100644 --- a/src/AnalogIn.h +++ b/src/AnalogIn.h @@ -22,6 +22,7 @@ public: double setValue(int value); double read(MuxSetup *mux); double readSim(double simRaw); + void setRawScaling(int rawMin, int rawMax); virtual ~AnalogIn(); private: diff --git a/src/Database.cpp b/src/Database.cpp index a9c591a..381e5e3 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -395,6 +395,48 @@ long Database::newRunStatus(std::string runStatus, std::string initiator){ return runStatusCollection.count({}); } +long Database::storeSetpoint(std::string setpointName, double setpointValue){ + + bsoncxx::types::b_date timestamp = bsoncxx::types::b_date {std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch())}; + + + bsoncxx::builder::stream::document spBuilder, filterBuilder; + + filterBuilder << "name" << setpointName; + + spBuilder << "name" << setpointName; + spBuilder << "value" << setpointValue; + spBuilder << "lastStored" << timestamp; + spBuilder << "storedBy" << "poc"; + + mongocxx::options::update updOptions; + updOptions.upsert(true); + + setpointCollection.update_one(filterBuilder.view(), spBuilder.view(), updOptions); + + return setpointCollection.count({}); + +} + +double Database::getSetpoint(std::string setpointName){ + double setpointValue = -__DBL_MAX__; + std::string storedBy = "NONE"; + bsoncxx::builder::stream::document filterBuilder; + filterBuilder << "name" << setpointName; + + mongocxx::cursor spCursor = setpointCollection.find(filterBuilder.view()); + for (auto&& doc : spCursor) { + try { + setpointValue = doc["value"].get_double(); + storedBy = doc["storedBy"].get_utf8().value.to_string(); + std::cout << "Setpoint retrieved from database: [" << setpointName << " = " << setpointValue << " stored by " << storedBy << "]"; + } catch (std::exception) { + std::cout << "Could not find a value for " << setpointName << " in the database."; + } + } + + return setpointValue; +} // FUNCTION TESTS diff --git a/src/Database.h b/src/Database.h index 731fb5e..c02177e 100644 --- a/src/Database.h +++ b/src/Database.h @@ -63,6 +63,9 @@ public: long newFluidShot(FluidShot inp); double getLatestFrictionEstimate(); long newRunStatus(std::string runStatus, std::string initiator); + long storeSetpoint(std::string setpointName, double setpointValue); + double getSetpoint(std::string setpointName); + }; diff --git a/src/Well.cpp b/src/Well.cpp index 5271a82..cf246b4 100644 --- a/src/Well.cpp +++ b/src/Well.cpp @@ -31,15 +31,844 @@ Well::Well(): surfaceStrokeLength("Surface Stroke Length"), tubingMovement("Tubing Movement"), pumpFillPercent("Pump Fill Percent"){ - + + initializeSetpoints(); } int Well::calibrateInclinometer(){ std::cout << "Calibrating inclinometer..." << std::endl; - long now = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()).count(); + long now = std::chrono::duration_cast< std::chrono::seconds >(std::chrono::system_clock::now().time_since_epoch()).count(); + long start = now; + int maxRaw = -__INT_MAX__; + int minRaw = __INT_MAX__; - + while (now - start > 30){ + inclinometer.read(&ioMux); + if (inclinometer.getRawValue() > maxRaw){ + maxRaw = inclinometer.getRawValue(); + } + + if (inclinometer.getRawValue() < minRaw){ + minRaw = inclinometer.getRawValue(); + } + + now = std::chrono::duration_cast< std::chrono::seconds >(std::chrono::system_clock::now().time_since_epoch()).count(); + + } + + std::cout << "Inclinometer Min: " << minRaw << ", Inclinometer Max: " << maxRaw; + inclinometer.setRawScaling(minRaw, maxRaw); + return 1; }; + +void Well::setRunMode(int runMode) { + this->runMode = runMode; +} + +std::string Well::getRunModeString(){ + switch (runMode){ + case RUNMODE_POC: + return "POC"; + case RUNMODE_MANUAL: + return "MANUAL"; + case RUNMODE_TIMER: + return "TIMER"; + default: + return "UNKNOWN"; + } +} + +void Well::initializeSetpoints(){ + double dbPumpOffFillPercentSetpoint = db.getSetpoint("pumpOffFillPercentSetpoint"); + if (dbPumpOffFillPercentSetpoint == -__DBL_MAX__){ + pumpOffFillPercentSetpoint = 65.0; // DEFAULT VALUE + db.storeSetpoint("pumpOffFillPercentSetpoint", pumpOffFillPercentSetpoint); + } else { + pumpOffFillPercentSetpoint = dbPumpOffFillPercentSetpoint; + } + + double dbPumpOffStrokes = db.getSetpoint("pumpOffStrokesSetpoint"); + if (dbPumpOffStrokes == -__DBL_MAX__){ + pumpOffStrokesSetpoint = 5; // DEFAULT VALUE + std::cout << "Using default value of " << pumpOffStrokesSetpoint << " for pumpOffStrokesSetpoint."; + db.storeSetpoint("pumpOffStrokesSetpoint", (double) pumpOffStrokesSetpoint); + } else { + pumpOffStrokesSetpoint = (int) dbPumpOffStrokes; + } + + double dbPumpOffDowntimeMinutesSetpoint = db.getSetpoint("pumpOffDowntimeMinutesSetpoint"); + if (dbPumpOffDowntimeMinutesSetpoint == -__DBL_MAX__){ + pumpOffDowntimeMinutesSetpoint = 30; // DEFAULT VALUE + std::cout << "Using default value of " << pumpOffDowntimeMinutesSetpoint << " for pumpOffDowntimeMinutesSetpoint."; + db.storeSetpoint("pumpOffDowntimeMinutesSetpoint", (double) pumpOffDowntimeMinutesSetpoint); + } else { + pumpOffDowntimeMinutesSetpoint = (long) dbPumpOffDowntimeMinutesSetpoint; + } + + double dbTimerRunMinutesSetpoint = db.getSetpoint("timerRunMinutesSetpoint"); + if (dbTimerRunMinutesSetpoint == -__DBL_MAX__){ + timerRunMinutesSetpoint = 45; // DEFAULT VALUE + std::cout << "Using default value of " << timerRunMinutesSetpoint << " for timerRunMinutesSetpoint."; + db.storeSetpoint("timerRunMinutesSetpoint", (double) timerRunMinutesSetpoint); + } else { + timerRunMinutesSetpoint = (long) dbTimerRunMinutesSetpoint; + } + + double dbTimerOffMinutesSetpoint = db.getSetpoint("timerOffMinutesSetpoint"); + if (dbTimerOffMinutesSetpoint == -__DBL_MAX__){ + timerOffMinutesSetpoint = 15; // DEFAULT VALUE + std::cout << "Using default value of " << timerOffMinutesSetpoint << " for timerOffMinutesSetpoint."; + db.storeSetpoint("timerOffMinutesSetpoint", (double) timerOffMinutesSetpoint); + } else { + timerOffMinutesSetpoint = (long) dbTimerOffMinutesSetpoint; + } + + double dbFluidOilRatio = db.getSetpoint("fluidOilRatio"); + if (dbFluidOilRatio == -__DBL_MAX__){ + fluidOilRatio = 0.5; // DEFAULT VALUE + std::cout << "Using default value of " << fluidOilRatio << " for fluidOilRatio."; + db.storeSetpoint("fluidOilRatio", (double) fluidOilRatio); + } else { + fluidOilRatio = dbFluidOilRatio; + } + + double dbFluidWaterRatio = db.getSetpoint("fluidWaterRatio"); + if (dbFluidWaterRatio == -__DBL_MAX__){ + fluidWaterRatio = 0.5; // DEFAULT VALUE + std::cout << "Using default value of " << fluidWaterRatio << " for fluidWaterRatio."; + db.storeSetpoint("fluidWaterRatio", (double) fluidWaterRatio); + } else { + fluidWaterRatio = dbFluidWaterRatio; + } + + double dbFluidGasRatio = db.getSetpoint("fluidGasRatio"); + if (dbFluidGasRatio == -__DBL_MAX__){ + fluidGasRatio = 2; // DEFAULT VALUE + std::cout << "Using default value of " << fluidGasRatio << " for fluidGasRatio."; + db.storeSetpoint("fluidGasRatio", (double) fluidGasRatio); + } else { + fluidGasRatio = dbFluidGasRatio; + } + + double dbRunMode = db.getSetpoint("runMode"); + if (dbRunMode == -__DBL_MAX__){ + runMode = RUNMODE_MANUAL; // DEFAULT VALUE + std::cout << "Using default value of " << runMode << " for runMode."; + db.storeSetpoint("runMode", (double) runMode); + } else { + setRunMode((int) dbRunMode); + std::cout << "Run Mode set to " << getRunModeString(); + } +} + +void Well::initializeMeasurements(){ + if (strokeSpeed.getUnits() == "") { + strokeSpeed.setUnits("SPM"); + strokeSpeed.setSendDelta(0.5); + strokeSpeed.setSendTimeDelta(600); + strokeSpeed.setUseAverage(true); + strokeSpeed.setUseTotal(false); + } + + if (downholeGrossStroke.getUnits() == "") { + downholeGrossStroke.setUnits("in."); + downholeGrossStroke.setSendDelta(0.5); + downholeGrossStroke.setSendTimeDelta(600); + downholeGrossStroke.setUseAverage(true); + downholeGrossStroke.setUseTotal(false); + } + + if (downholeNetStroke.getUnits() == "") { + downholeNetStroke.setUnits("in."); + downholeNetStroke.setSendDelta(0.5); + downholeNetStroke.setSendTimeDelta(600); + downholeNetStroke.setUseAverage(true); + downholeNetStroke.setUseTotal(false); + } + + if (fluidLevel.getUnits() == "") { + fluidLevel.setUnits("ft."); + fluidLevel.setSendDelta(10.0); + fluidLevel.setSendTimeDelta(600); + fluidLevel.setUseAverage(true); + fluidLevel.setUseTotal(false); + } + + if (fluidLoad.getUnits() == "") { + fluidLoad.setUnits("lbs."); + fluidLoad.setSendDelta(20.0); + fluidLoad.setSendTimeDelta(600); + fluidLoad.setUseAverage(true); + fluidLoad.setUseTotal(false); + } + + if (inflowRate.getUnits() == "") { + inflowRate.setUnits("BBL/day"); + inflowRate.setSendDelta(0.5); + inflowRate.setSendTimeDelta(600); + inflowRate.setUseAverage(true); + inflowRate.setUseTotal(false); + } + + if (peakPolishedRodLoad.getUnits() == "") { + peakPolishedRodLoad.setUnits("lbs."); + peakPolishedRodLoad.setSendDelta(50); + peakPolishedRodLoad.setSendTimeDelta(600); + peakPolishedRodLoad.setUseAverage(true); + peakPolishedRodLoad.setUseTotal(false); + } + + if (minPolishedRodLoad.getUnits() == "") { + minPolishedRodLoad.setUnits("lbs."); + minPolishedRodLoad.setSendDelta(50.0); + minPolishedRodLoad.setSendTimeDelta(600); + minPolishedRodLoad.setUseAverage(true); + minPolishedRodLoad.setUseTotal(false); + } + + if (percentRun.getUnits() == "") { + percentRun.setUnits("%"); + percentRun.setSendDelta(0.5); + percentRun.setSendTimeDelta(600); + percentRun.setUseAverage(false); + percentRun.setUseTotal(false); + } + + if (polishedRodHP.getUnits() == "") { + polishedRodHP.setUnits("HP"); + polishedRodHP.setSendDelta(0.25); + polishedRodHP.setSendTimeDelta(600); + polishedRodHP.setUseAverage(true); + polishedRodHP.setUseTotal(false); + } + + if (pumpHP.getUnits() == "") { + pumpHP.setUnits("HP"); + pumpHP.setSendDelta(0.25); + pumpHP.setSendTimeDelta(600); + pumpHP.setUseAverage(true); + pumpHP.setUseTotal(false); + } + + if (fluidProduced.getUnits() == "") { + fluidProduced.setUnits("BBL"); + fluidProduced.setSendDelta(1.0); + fluidProduced.setSendTimeDelta(600); + fluidProduced.setUseAverage(true); + fluidProduced.setUseTotal(true); + } + + if (fluidProducedAdjusted.getUnits() == "") { + fluidProducedAdjusted.setUnits("BBL"); + fluidProducedAdjusted.setSendDelta(1.0); + fluidProducedAdjusted.setSendTimeDelta(600); + fluidProducedAdjusted.setUseAverage(true); + fluidProducedAdjusted.setUseTotal(true); + } + + if (oilProduced.getUnits() == "") { + oilProduced.setUnits("BBL"); + oilProduced.setSendDelta(0.5); + oilProduced.setSendTimeDelta(600); + oilProduced.setUseAverage(true); + oilProduced.setUseTotal(true); + } + + if (waterProduced.getUnits() == "") { + waterProduced.setUnits("BBL"); + waterProduced.setSendDelta(1.0); + waterProduced.setSendTimeDelta(600); + waterProduced.setUseAverage(true); + waterProduced.setUseTotal(true); + } + + if (gasProduced.getUnits() == "") { + gasProduced.setUnits("MCF"); + gasProduced.setSendDelta(1.0); + gasProduced.setSendTimeDelta(600); + gasProduced.setUseAverage(true); + gasProduced.setUseTotal(true); + } + + if (pumpIntakePressure.getUnits() == "") { + pumpIntakePressure.setUnits("PSI"); + pumpIntakePressure.setSendDelta(5.0); + pumpIntakePressure.setSendTimeDelta(600); + pumpIntakePressure.setUseAverage(true); + pumpIntakePressure.setUseTotal(false); + } + + if (surfaceStrokeLength.getUnits() == "") { + surfaceStrokeLength.setUnits("in."); + surfaceStrokeLength.setSendDelta(0.5); + surfaceStrokeLength.setSendTimeDelta(600); + surfaceStrokeLength.setUseAverage(true); + surfaceStrokeLength.setUseTotal(false); + } + + if (tubingMovement.getUnits() == "") { + tubingMovement.setUnits("in."); + tubingMovement.setSendDelta(0.5); + tubingMovement.setSendTimeDelta(600); + tubingMovement.setUseAverage(true); + tubingMovement.setUseTotal(false); + } + + if (pumpFillPercent.getUnits() == "") { + pumpFillPercent.setUnits("%"); + pumpFillPercent.setSendDelta(1.0); + pumpFillPercent.setSendTimeDelta(600); + pumpFillPercent.setUseAverage(true); + pumpFillPercent.setUseTotal(false); + } +} + +double Well::getDt() { + return dt; +} + +void Well::setDt(double dt) { + this->dt = dt; +} + +double Well::getTubingHeadPressure() { + return tubingHeadPressure; +} + +void Well::setTubingHeadPressure(double tubingHeadPressure) { + this->tubingHeadPressure = tubingHeadPressure; +} + +double Well::getFluidGradient() { + return fluidGradient; +} + +void Well::setFluidGradient(double fluidGradient) { + this->fluidGradient = fluidGradient; +} + +double Well::getSbfriction() { + return stuffingBoxFriction; +} + +void Well::setSbfriction(double stuffingBoxFriction) { + this->stuffingBoxFriction = stuffingBoxFriction; +} + +int Well::getNumTapers() { + return numTapers; +} + +void Well::setNumTapers(int numTapers) { + this->numTapers = numTapers; +} + +double Well::getTubingAnchorDepth() { + return tubingAnchorDepth; +} + +void Well::setTubingAnchorDepth(double tubingAnchorDepth) { + this->tubingAnchorDepth = tubingAnchorDepth; +} + +double Well::getPumpDiameter() { + return pumpDiameter; +} + +void Well::setPumpDiameter(double pumpDiameter) { + this->pumpDiameter = pumpDiameter; + this->pumpArea = pow(pumpDiameter, 2) * M_PI; +} + +double Well::getTubingInnerDiameter() { + return tubingInnerDiameter; +} + +void Well::setTubingInnerDiameter(double tubingInnerDiameter) { + this->tubingInnerDiameter = tubingInnerDiameter; + this->tubingCrossSectionalArea = (M_PI / 4) * (pow(this->tubingOuterDiameter, 2) - pow(this->tubingInnerDiameter,2)); +} + +double Well::getTubingOuterDiameter() { + return tubingOuterDiameter; +} + +void Well::setTubingOuterDiameter(double tubingOuterDiameter){ + this->tubingOuterDiameter = tubingOuterDiameter; + this->tubingCrossSectionalArea = (M_PI / 4) * (pow(this->tubingOuterDiameter, 2) - pow(tubingInnerDiameter,2)); + +} + +void Well::setDampingFactor(int i, double c) { + this->c[i] = c; +} + +double Well::getDampingFactor(int i){ return c[i]; } + +void Well::setRodLength(int i, double rodLength) { + this->rodLength[i] = rodLength; +} + +double Well::getRodLength(int i){ return rodLength[i]; } + +void Well::setRodDiameter(int i, double rodDiameter) { + this->rodDiameter[i] = rodDiameter; +} + +double Well::getRodDiameter(int i){ return rodDiameter[i]; } + +void Well::setRodYM(int i, std::string material) { + std::transform(material.begin(), material.end(), material.begin(), ::tolower); + if (material == "steel"){ + rodYM[i] = YM_STEEL; + } else if (material == "fiberglass"){ + rodYM[i] = YM_FIBERGLASS; + } +} + +double Well::getRodYM(int i){ return rodYM[i]; } + +std::string Well::getRodMaterial(int i){ + if(rodYM[i] == YM_STEEL) + return "steel"; + if(rodYM[i] == YM_FIBERGLASS) + return "fiberglass"; + return "unknown"; +} + +double Well::getFrictionEstimate() { + return frictionEstimate; +} + +void Well::setFrictionEstimate(double frictionEstimate) { + this->frictionEstimate = frictionEstimate; +} + +double Well::getRodDepthTotal() { + return rodDepthTotal; +} + +double Well::getPumpArea() { + return pumpArea; +} + +double Well::getTubingCrossSectionalArea() { + return tubingCrossSectionalArea; +} + +double Well::getStructuralRating() { + return structuralRating; +} + +void Well::setStructuralRating(double structuralRating) { + this->structuralRating = structuralRating; +} + +void Well::setWellName(std::string wellName) { + this->wellName = wellName; +} + +std::string Well::getWellName() { + return wellName; +} + +bool Well::isPermissiveOK() { + return permissiveOK; +} + +int Well::getRunStatus() { + return runStatus; +} + +std::string Well::getRunStatusString(){ + switch(runStatus){ + case RUNSTATUS_STOPPED: + return "Stopped"; + case RUNSTATUS_STARTING: + return "Starting"; + case RUNSTATUS_RUNNING: + return "Running"; + case RUNSTATUS_PUMPEDOFF: + return "Pumped-Off"; + case RUNSTATUS_FAULTED: + return "Faulted"; + case RUNSTATUS_LOCKEDOUT: + return "Locked Out"; + default: + return "Unknown"; + } +} + +int Well::getRunMode() { + return runMode; +} + +void Well::setRunModeString(std::string runModeString){ + if (runModeString == "POC"){ + runMode = RUNMODE_POC; + std::cout << "Run Mode has been set to POC" << std::endl; + } else if (runModeString == "MANUAL"){ + std::cout << "Run Mode has been set to MANUAL" << std::endl; + runMode = RUNMODE_MANUAL; + } else if (runModeString == "TIMER"){ + std::cout << "Run Mode has been set to TIMER" << std::endl; + runMode = RUNMODE_TIMER; + } +} + +double Well::getCurrentSurfacePosition() { + return currentSurfacePosition; +} + +double Well::getCurrentSurfaceLoad() { + return currentSurfaceLoad; +} + +double Well::getCurrentDownholePosition() { + return currentDownholePosition; +} + +double Well::getCurrentDownholeLoad() { + return currentDownholeLoad; +} + +long Well::getStartupStrokes() { + return startupStrokes; +} + +void Well::setStartupStrokes(long startupStrokes) { + this->startupStrokes = startupStrokes; +} + +long Well::getStrokesSinceStart() { + return strokesSinceStart; +} + +long Well::getStrokesToday() { + return strokesToday; +} + +long Well::getStrokesLifetime() { + return strokesLifetime; +} + +int Well::getDirection() { + return direction; +} + +void Well::setFluidOilRatio(double fluidOilRatio) { + this->fluidOilRatio = fluidOilRatio; +} + +void Well::setFluidWaterRatio(double fluidWaterRatio) { + this->fluidWaterRatio = fluidWaterRatio; +} + +void Well::setFluidGasRatio(double fluidGasRatio) { + this->fluidGasRatio = fluidGasRatio; +} + +double Well::getFluidOilRatio() { + return fluidOilRatio; +} + +double Well::getFluidWaterRatio() { + return fluidWaterRatio; +} + +double Well::getFluidGasRatio() { + return fluidGasRatio; +} + +double Well::getkFactor() { + return kFactor; +} + +void Well::setkFactor(double kFactor) { + this->kFactor = kFactor; +} + +int Well::getLowFillageStrokes() { + return lowFillageStrokes; +} + +std::chrono::milliseconds Well::getPumpedOffTime() { + return pumpedOffTime; +} + +long Well::getMinutesSincePumpOff() { + return minutesSincePumpOff; +} + +double Well::getPumpOffFillPercentSetpoint() { + return pumpOffFillPercentSetpoint; +} + +void Well::setPumpOffFillPercentSetpoint(double pumpOffFillPercentSetpoint) { + this->pumpOffFillPercentSetpoint = pumpOffFillPercentSetpoint; +} + +int Well::getPumpOffStrokesSetpoint() { + return pumpOffStrokesSetpoint; +} + +void Well::setPumpOffStrokesSetpoint(int pumpOffStrokesSetpoint) { + this->pumpOffStrokesSetpoint = pumpOffStrokesSetpoint; +} + +long Well::getPumpOffDowntimeMinutesSetpoint() { + return pumpOffDowntimeMinutesSetpoint; +} + +void Well::setPumpOffDowntimeMinutesSetpoint(long pumpOffDowntimeMinutesSetpoint) { + this->pumpOffDowntimeMinutesSetpoint = pumpOffDowntimeMinutesSetpoint; +} + +void Well::setupFluidRatio(double oilRatio, double waterRatio, double gasRatio){ + fluidOilRatio = oilRatio; + fluidWaterRatio = waterRatio; + fluidGasRatio = gasRatio; +} + +long Well::getTimerRunMinutesSetpoint() { + return timerRunMinutesSetpoint; +} + +void Well::setTimerRunMinutesSetpoint(long timerRunMinutesSetpoint) { + this->timerRunMinutesSetpoint = timerRunMinutesSetpoint; +} + +long Well::getTimerOffMinutesSetpoint() { + return timerOffMinutesSetpoint; +} + +void Well::setTimerOffMinutesSetpoint(long timerOffMinutesSetpoint) { + this->timerOffMinutesSetpoint = timerOffMinutesSetpoint; +} + +// WELL COMMAND FUNCTIONS +void Well::start(std::string initiator){ + if (runStatus == RUNSTATUS_STOPPED && permissiveOK){ + std::cout << "Starting " << wellName << " from " << initiator << "..." << std::endl; + runStatus = RUNSTATUS_STARTING; + strokesSinceStart = 0; + pumpStartTime = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); + db.newRunStatus(getRunStatusString(), initiator); + calibrateInclinometer(); + } +} + +void Well::stop(std::string initiator){ + if (runStatus == RUNSTATUS_STARTING || runStatus == RUNSTATUS_RUNNING || runStatus == RUNSTATUS_PUMPEDOFF){ + std::cout << "Stopping " << wellName << " from " << initiator << "..." << std::endl; + runStatus = RUNSTATUS_STOPPED; + db.newRunStatus(getRunStatusString(), initiator); + } +} + +void Well::restart(std::string initiator){ + if (runStatus == RUNSTATUS_PUMPEDOFF && permissiveOK){ + std::cout << "Restarting after pump-off from " << initiator << "..." << std::endl; + runStatus = RUNSTATUS_STARTING; + strokesSinceStart = 0; + pumpStartTime = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); + db.newRunStatus(getRunStatusString(), initiator); + } +} + +void Well::pumpOff(std::string initiator){ + if (runStatus == RUNSTATUS_RUNNING){ + std::cout << "Pumping off from " << initiator << "..." << std::endl; + if (runMode == RUNMODE_POC) { + std::cout << "Restarting in " << pumpOffDowntimeMinutesSetpoint << " minutes." << std::endl; + pumpedOffTime = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); + } else if (runMode == RUNMODE_TIMER){ + std::cout << "Restarting in " << timerOffMinutesSetpoint << " minutes." << std::endl; + timerStopTime = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); + } + runStatus = RUNSTATUS_PUMPEDOFF; + db.newRunStatus(getRunStatusString(), initiator); + } +} + +void Well::checkSafeties(){ + permissiveOK = true; +} + +// WELL CALCULATION FUNCTIONS +double lookupRodWeightPerFoot(double i_ym, double i_diam) { + double wtPerFt; + if (i_ym == YM_STEEL) { + if (i_diam <= 2 && i_diam > 1.75) { + wtPerFt = 10.7; + } else if (i_diam <= 1.75 && i_diam > 1.65) { + wtPerFt = 8.2; + } else if (i_diam <= 1.65 && i_diam > 1.5) { + wtPerFt = 7; + } else if (i_diam <= 1.5 && i_diam > 1.375) { + wtPerFt = 6; + } else if (i_diam <= 1.375 && i_diam > 1.125) { + wtPerFt = 5; + } else if (i_diam <= 1.125 && i_diam > 1) { + wtPerFt = 3.676; + } else if (i_diam <= 1 && i_diam > 0.875) { + wtPerFt = 2.904; + } else if (i_diam <= 0.875 && i_diam > 0.75) { + wtPerFt = 2.224; + } else if (i_diam <= 0.75 && i_diam > 0.625) { + wtPerFt = 1.634; + } else if (i_diam <= 0.625 && i_diam > 0.5) { + wtPerFt = 1.13; + } else if (i_diam <= 0.5) { + wtPerFt = 0.72; + } else { + wtPerFt = 0; + } + } else if (i_ym == YM_FIBERGLASS) { + if (i_diam <= 1.25 && i_diam > 1.125) { + wtPerFt = 1.2879; + } else if (i_diam <= 1.125 && i_diam > 1) { + wtPerFt = 1.09; + } else if (i_diam <= 1 && i_diam > 0.875) { + wtPerFt = 0.8188; + } else if (i_diam <= 0.875 && i_diam > 0.75) { + wtPerFt = 0.6108; + } else if (i_diam <= 0.75) { + wtPerFt = 0.484; + } else { + wtPerFt = 0; + } + } else { + wtPerFt = 0; + } + return wtPerFt; +}; + + +void Well::getWellSetup(){ + std::string jsonFilename = "wellSetup.json"; + std::ifstream i(jsonFilename); + json jsonData; + i >> jsonData; + + try { + wellName = jsonData["wellName"]; + dt = jsonData["dt"]; + setPumpDiameter(jsonData["pumpDiameter"]); + fluidGradient = jsonData["fluidGradient"]; + setTubingInnerDiameter(jsonData["tubingID"]); + setTubingOuterDiameter(jsonData["tubingOD"]); + tubingAnchorDepth = jsonData["] + + } + + + + + + try { + + Object newTubingAnchorDepth = well.get("tubingAnchorDepth"); + if (newTubingAnchorDepth != null) tubingAnchorDepth = (Double) newTubingAnchorDepth; + + Object newStructuralRating = well.get("structuralRating"); + if (newStructuralRating != null) structuralRating = (Double) newStructuralRating; + + Object newStuffingBoxFriction = well.get("stuffingBoxFriction"); + if (newStuffingBoxFriction != null) setSbfriction((Double) newStuffingBoxFriction); + + Object newTubingHeadPressure = well.get("tubingOD"); + if (newTubingHeadPressure != null) setTubingOD((Double) newTubingHeadPressure); + + JSONArray tapers = (JSONArray) well.get("tapers"); + numTapers = tapers.size(); + for (int i = 0; i < numTapers; i++){ + int currentTaperNum = i + 1; + JSONObject taperObj = (JSONObject) tapers.get(i); + + Object newLength = taperObj.get("length"); + if (newLength != null) setRodLength(currentTaperNum, (Double) newLength); + + Object newDiameter = taperObj.get("diameter"); + if (newDiameter != null) setRodDiameter(currentTaperNum, (Double) newDiameter); + + Object newMaterial = taperObj.get("material"); + if (newMaterial != null) setRodYM(currentTaperNum, (String) newMaterial); + + Object newDampingFactor = taperObj.get("dampingFactor"); + if (newDampingFactor != null) setDampingFactor(currentTaperNum, (Double) newDampingFactor); + } + + Path fromFile = Paths.get(jsonFilename); + Path toFile = Paths.get(jsonFilename + ".bak"); + try { + Files.move(fromFile, toFile); + } catch (FileAlreadyExistsException e) { + Files.delete(toFile); + Files.move(fromFile, toFile); + } + updateTapers(true); + + } catch (FileNotFoundException e) { + System.out.println("No configuration file found. Pulling latest value from database."); + Document newConfigDoc = db.getLatestWellConfiguration(); + + Object newWellName = newConfigDoc.get("wellName"); + if (newWellName != null) wellName = (String) newWellName; + + Object newDeltaT = newConfigDoc.get("deltaT"); + if (newDeltaT != null) dt = (Double) newDeltaT; + + Object newPumpDiameter = newConfigDoc.get("pumpDiameter"); + if (newPumpDiameter != null) setPumpDiameter((Double) newPumpDiameter); + + Object newFluidGradient = newConfigDoc.get("fluidGradient"); + if (newFluidGradient != null) fluidGradient = (Double) newFluidGradient; + + Object newTubingID = newConfigDoc.get("tubingID"); + if (newTubingID != null) setTubingID((Double) newTubingID); + + Object newTubingOD = newConfigDoc.get("tubingOD"); + if (newTubingOD != null) setTubingOD((Double) newTubingOD); + + Object newTubingAnchorDepth = newConfigDoc.get("tubingAnchorDepth"); + if (newTubingAnchorDepth != null) tubingAnchorDepth = (Double) newTubingAnchorDepth; + + Object newStructuralRating = newConfigDoc.get("structuralRating"); + if (newStructuralRating != null) structuralRating = (Double) newStructuralRating; + + Object newStuffingBoxFriction = newConfigDoc.get("stuffingBoxFriction"); + if (newStuffingBoxFriction != null) setSbfriction((Double) newStuffingBoxFriction); + + Object newTubingHeadPressure = newConfigDoc.get("tubingOD"); + if (newTubingHeadPressure != null) setTubingOD((Double) newTubingHeadPressure); + + ArrayList tapers = (ArrayList) newConfigDoc.get("tapers"); + numTapers = tapers.size(); + for (int i = 0; i < numTapers; i++) { + int currentTaperNum = i + 1; + Document taperObj = tapers.get(i); + + Object newLength = taperObj.get("length"); + if (newLength != null) setRodLength(currentTaperNum, (Double) newLength); + + Object newDiameter = taperObj.get("diameter"); + if (newDiameter != null) setRodDiameter(currentTaperNum, (Double) newDiameter); + + Object newMaterial = taperObj.get("material"); + if (newMaterial != null) setRodYM(currentTaperNum, (String) newMaterial); + + Object newDampingFactor = taperObj.get("dampingFactor"); + if (newDampingFactor != null) setDampingFactor(currentTaperNum, (Double) newDampingFactor); + } + updateTapers(false); + } catch (IOException | ParseException e) { + e.printStackTrace(); + System.exit(3); + } + + +} diff --git a/src/Well.h b/src/Well.h index e2a0705..265efd2 100644 --- a/src/Well.h +++ b/src/Well.h @@ -12,12 +12,18 @@ #include #include +#include + +#include "json.hpp" +using json = nlohmann::json; #include "AnalogIn.h" #include "Card.h" #include "Measurement.h" #include "Database.h" + + const static double YM_STEEL = 30.5; const static double YM_FIBERGLASS = 7.2; @@ -184,9 +190,108 @@ private: long minutesSinceTimerStart_last = 0; + void initializeMeasurements(); + + public: Well(); int calibrateInclinometer(); + void initializeSetpoints(); + void setRunMode(int runMode); + std::string getRunModeString(); + double getDt(); + void setDt(double dt); + double getTubingHeadPressure(); + void setTubingHeadPressure(double tubingHeadPressure); + double getFluidGradient(); + void setFluidGradient(double fluidGradient); + double getSbfriction(); + void setSbfriction(double sbfriction); + int getNumTapers(); + void setNumTapers(int numTapers); + double getTubingAnchorDepth(); + void setTubingAnchorDepth(double tubingAnchorDepth); + double getPumpDiameter(); + void setPumpDiameter(double pumpDiameter); + double getTubingInnerDiameter(); + void setTubingInnerDiameter(double tubingInnerDiameter); + double getTubingOuterDiameter(); + void setTubingOuterDiameter(double tubingOuterDiameter); + void setDampingFactor(int i, double c); + double getDampingFactor(int i); + void setRodLength(int i, double rodLength); + double getRodLength(int i); + void setRodDiameter(int i, double rodDiameter); + double getRodDiameter(int i); + void setRodYM(int i, std::string material); + double getRodYM(int i); + std::string getRodMaterial(int i); + double getFrictionEstimate(); + void setFrictionEstimate(double frictionEstimate); + double getRodDepthTotal(); + double getPumpArea(); + double getTubingCrossSectionalArea(); + double getStructuralRating(); + void setStructuralRating(double structuralRating); + void setWellName(std::string wellName); + std::string getWellName(); + bool isPermissiveOK(); + int getRunStatus(); + std::string getRunStatusString(); + int getRunMode(); + void setRunModeString(std::string runModeString); + double getCurrentSurfacePosition(); + double getCurrentSurfaceLoad(); + double getCurrentDownholePosition(); + double getCurrentDownholeLoad(); + long getStartupStrokes(); + void setStartupStrokes(long startupStrokes); + long getStrokesSinceStart(); + long getStrokesToday(); + long getStrokesLifetime(); + int getDirection(); + void setFluidOilRatio(double fluidOilRatio); + void setFluidWaterRatio(double fluidWaterRatio); + void setFluidGasRatio(double fluidGasRatio); + double getFluidOilRatio(); + double getFluidWaterRatio(); + double getFluidGasRatio(); + double getkFactor(); + void setkFactor(double kFactor); + int getLowFillageStrokes(); + std::chrono::milliseconds getPumpedOffTime(); + long getMinutesSincePumpOff(); + double getPumpOffFillPercentSetpoint(); + void setPumpOffFillPercentSetpoint(double pumpOffFillPercentSetpoint); + int getPumpOffStrokesSetpoint(); + void setPumpOffStrokesSetpoint(int pumpOffStrokesSetpoint); + long getPumpOffDowntimeMinutesSetpoint(); + void setPumpOffDowntimeMinutesSetpoint(long pumpOffDowntimeMinutesSetpoint); + void setupFluidRatio(double oilRatio, double waterRatio, double gasRatio); + long getTimerRunMinutesSetpoint(); + void setTimerRunMinutesSetpoint(long timerRunMinutesSetpoint); + long getTimerOffMinutesSetpoint(); + void setTimerOffMinutesSetpoint(long timerOffMinutesSetpoint); + + // WELL COMMAND FUNCTIONS + void start(std::string initiator); + void stop(std::string initiator); + void restart(std::string initiator); + void pumpOff(std::string initiator); + void checkSafeties(); + void getWellSetup(); + + + + + + + + + + + + }; #endif /* Well_h */