From 1df78af2326ca0894adc9ede5a098e6e767c9e2e Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Mon, 29 Jun 2026 15:47:04 -0700 Subject: [PATCH 01/26] remove scripting api's marked as unused to ensure removed api's still allow the application to compile, the gradle build and github actions were added for the CI/CD check --- .github/dependabot.yml | 14 + .github/workflows/build.yml | 34 + build.gradle | 4 +- .../regi-headless.deps-conventions.gradle | 18 - gradle/libs.versions.toml | 52 +- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 48462 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 19 +- gradlew.bat | 58 +- regi-headless/build.gradle | 20 +- .../rowcps/headless/HeadlessMessageTaker.java | 4 +- .../headless/HeadlessRegiDomainFactory.java | 156 +-- .../usace/rowcps/headless/LoggingOptions.java | 2 +- .../rowcps/headless/PythonEvaluator.java | 13 - .../java/usace/rowcps/headless/RegiCLI.java | 17 +- .../headless/SimpleFactoryRegistry.java | 10 - .../ScriptableExportAssociations.java | 34 - .../ScriptableExportAssociationsFactory.java | 50 - .../ScriptableExportTSAssociationsImpl.java | 151 --- .../ScriptableGateSettingsImpl.java | 2 +- .../poolpercent/PoolPercentCalcFactory.java | 41 - .../ScriptablePoolPercentImpl.java | 106 -- .../HeadlessBasinPieAnnotationLayer.java | 79 -- .../status/LocationGroupFactory.java | 235 ---- .../status/ScriptableStatusGraphicImpl.java | 1151 ----------------- .../status/SimpleTemplateEngine.java | 54 - .../calculator/status/StatusCalcFactory.java | 41 - .../exportdb/ExportSigStagesCalcFactory.java | 51 - .../ScriptableExportSigStagesImpl.java | 116 -- .../exportdb/ScriptableExportSigstages.java | 21 - .../importdb/ImportSigStagesCalcFactory.java | 50 - .../ScriptableImportSigStagesImpl.java | 95 -- .../importdb/ScriptableImportSigstages.java | 17 - .../RetrieveSigStagesCalcFactory.java | 49 - .../retrieve/RetrieveSigStagesImpl.java | 488 ------- .../sigstages/retrieve/RetrieveSigstages.java | 27 - .../sigstages/retrieve/SigstageLocation.java | 70 - .../sigstages/retrieve/xmlmodel/Action.java | 98 -- .../retrieve/xmlmodel/AltRating.java | 111 -- .../sigstages/retrieve/xmlmodel/Bankfull.java | 98 -- .../sigstages/retrieve/xmlmodel/Datum.java | 268 ---- .../retrieve/xmlmodel/Disclaimers.java | 152 --- .../sigstages/retrieve/xmlmodel/Flood.java | 98 -- .../sigstages/retrieve/xmlmodel/Forecast.java | 140 -- .../sigstages/retrieve/xmlmodel/Low.java | 98 -- .../sigstages/retrieve/xmlmodel/Major.java | 98 -- .../sigstages/retrieve/xmlmodel/Moderate.java | 98 -- .../retrieve/xmlmodel/ObjectFactory.java | 252 ---- .../sigstages/retrieve/xmlmodel/Observed.java | 78 -- .../sigstages/retrieve/xmlmodel/Primary.java | 122 -- .../sigstages/retrieve/xmlmodel/Quality.java | 101 -- .../sigstages/retrieve/xmlmodel/Rating.java | 111 -- .../sigstages/retrieve/xmlmodel/Record.java | 98 -- .../retrieve/xmlmodel/Secondary.java | 122 -- .../sigstages/retrieve/xmlmodel/Sigflows.java | 239 ---- .../sigstages/retrieve/xmlmodel/Sigstage.java | 61 - .../retrieve/xmlmodel/Sigstages.java | 239 ---- .../sigstages/retrieve/xmlmodel/Site.java | 385 ------ .../sigstages/retrieve/xmlmodel/Standing.java | 159 --- .../sigstages/retrieve/xmlmodel/Valid.java | 103 -- .../retrieve/xmlmodel/Zerodatum.java | 90 -- .../usace/rowcps/headless/TestHeadless.java | 5 +- ...lyHeadlessInflowCurrentDayControlTest.java | 7 +- .../inflow/HeadlessInflowOptionsTest.java | 6 +- .../InflowComputationStorageOptionTest.java | 7 +- 65 files changed, 200 insertions(+), 6597 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build.yml delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f9bbc2e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 + +updates: + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8fca131 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,34 @@ +name: Gradle CI + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + build: + name: Build and test + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 21 + cache: gradle + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + + - name: Build and test + run: ./gradlew clean build \ No newline at end of file diff --git a/build.gradle b/build.gradle index 33d99e9..84613dc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { - id "com.palantir.git-version" version "3.0.0" - id "org.sonarqube" version "4.0.0.2929" + id "com.palantir.git-version" version "5.0.0" + id "org.sonarqube" version "7.3.1.8318" } def versionLabel(gitInfo) { diff --git a/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle b/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle index 9e8db3d..9f129f3 100644 --- a/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle +++ b/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle @@ -1,24 +1,6 @@ - -def checkForNexusCredentials() { - if(!project.hasProperty('nexusUser')) { - println ('Please set the nexusUser property in the GRADLE_USER_HOME ($userHome/.gradle/gradle.properties) file or via -PnexusUser= .') - } - if(!project.hasProperty('nexusPassword')) { - println ('Please set the nexusPassword property in the GRADLE_USER_HOME ($userHome/.gradle/gradle.properties) file or via -PnexusPassword= .') - } -} - repositories { maven { url 'https://www.hec.usace.army.mil/nexus/repository/maven-public' } - maven { - url 'https://www.hec.usace.army.mil/nexus/repository/hec-internal' - credentials { - checkForNexusCredentials() - username "$nexusUser" - password "$nexusPassword" - } - } mavenCentral() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c8dacb..fd6e634 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,14 +1,12 @@ [versions] # HEC Dependencies -service-annotations = "1.2.2" -win-java-heclib = "7-IE-win-x64" -solaris-java-heclib = "7-IE-Solaris64" -hec-core = "6.1-SNAPSHOT" # required for PasswordFileEditor +service-annotations = "2.1.0" +hec-server-suite = "8.4.5" # REGI Dependencies -regi-tools = "3.4.3" -regi = "3.4.4" +regi-tools = "9.1.1" +regi = "3.5.0-alpha001" # Third Party jython-standalone = "2.7.2" @@ -20,15 +18,16 @@ solaris-jre = "1.8.0_202-Solaris-SPARC" jython-starter = "2.2.4.0" # Test -junit4 = "4.13.2" -junit = "5.9.3" +junit = "6.1.0" [libraries] # HEC Dependencies service-annotations = { module = "mil.army.usace.hec:service-annotations", version.ref = "service-annotations" } -hec-core = { module="mil.army.usace.hec:hec-core", version.ref = "hec-core" } -win-java-heclib = {module="mil.army.usace.hec:javaHeclib", version.ref = "win-java-heclib"} -solaris-java-heclib = {module="mil.army.usace.hec:javaHeclib", version.ref = "solaris-java-heclib"} +serversuite = { module = "mil.army.usace.hec:hec-server-suite", version.ref = "hec-server-suite" } +serversuite-cda = { module = "mil.army.usace.hec:cda-server-suite", version.ref = "hec-server-suite" } +serversuite-jdbc = { module = "mil.army.usace.hec:jdbc-server-suite", version.ref = "hec-server-suite" } +hec-db-cda = { module = "mil.army.usace.hec:hec-db-cda", version = "14.1.0" } +hec-cwms-ratings-cda = { module = "mil.army.usace.hec:hec-cwms-ratings-io-cda", version = "4.2.2"} # REGI Dependencies regi-basinpie-ui = {module = "mil.army.wmist.regi:basin-pie-ui", version.ref = "regi"} @@ -42,46 +41,27 @@ regi-tools-regi-core = {module = "mil.army.wmist.regi-tools:regi-core", version. regi-tools-regi-data = {module = "mil.army.wmist.regi-tools:regi-data", version.ref = "regi-tools"} regi-tools-regi-dao = {module = "mil.army.wmist.regi-tools:regi-dao", version.ref = "regi-tools"} regi-tools-regi-cwms = {module = "mil.army.wmist.regi-tools:regi-cwms", version.ref = "regi-tools"} -# Required for reservoir status graphics -regi-tools-regi-cache-ui = {module = "mil.army.wmist.regi-tools:regi-cache-ui", version.ref = "regi-tools"} # Third Party jython-standalone = {module = "org.python:jython-standalone", version.ref = "jython-standalone"} args4j = {module = "args4j:args4j", version.ref = "args4j"} - -# Natives -windows_jre = { module = "com.oracle:oracle-jre", version.ref = "windows-jre" } -solaris_jre = { module = "com.oracle:jre", version.ref = "solaris-jre" } -jython-starter = { module = 'mil.army.usace.hec.javastarter:javastarter-Jython', version.ref = "jython-starter"} +otel = {module = "io.opentelemetry:opentelemetry-api", version="1.58.0"} # Test -junit4 = { module = "junit:junit", version.ref = "junit4" } junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } -junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit" } +junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } [bundles] -regi = [ - "regi-basinpie-ui", - "regi-computation", - "regi-decisionsupport-ui", - "regi-mappanel-ui", - "regi-ui"] +regi = ["regi-computation"] regi-tools = [ "regi-tools-regi-core", - "regi-tools-regi-cache-ui", "regi-tools-regi-cwms", "regi-tools-regi-dao", "regi-tools-regi-data" ] -hec = [ - "hec-core" -] -sys = [ - "args4j", - "jython-standalone" -] +serversuite = ["serversuite", "serversuite-cda", "serversuite-jdbc", "hec-db-cda"] -junit-api = ["junit-jupiter-api", "junit-jupiter-params", "junit4"] -junit-engine = ["junit-jupiter-engine", "junit-vintage-engine"] \ No newline at end of file +junit-api = ["junit-jupiter-api", "junit-jupiter-params"] +junit-engine = ["junit-jupiter-engine", "junit-platform-launcher"] \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..b1b8ef56b44f16b14dc800fa8103a6d89abb526f 100644 GIT binary patch delta 39897 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

Igj3NXa_|8<`c7r$X{#UWi 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[sex+d!zoXF=a?l-EdR8AUn8#-&A&o?v{ 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

yb%-OYcg6{P)b3;TV;9l88> zH7}mIwVJI>bGwUSXd1>bE7+mmCfKsNAfs{*q1f=$vJWmoDyVo4@x5=l%f2_Eq_{ z{BA6Js?P81xnJ+Xu|K?JgY)GVk*>Fsr|fExbxKT|W$*%csmL8}?)re2w_jwsE`7CN zdPumP^?|RoN!Cfca|6w7KV${y>(%{QC4POM?n_UHOT0=##V`Jg9k>(0B!2eaU70Mt zR_Bj~Kk^qU%DtC5{3lRH=IEn9ovj}pRK|3*D1BUMf2j5N#|^E=>ixJAf5l`cF5W+t zE&7nVj!oLav-`W<{Ked=|I9Uc#VNmXqrm11&+BKkv2%B~|2=<6BT!*VkaYd(wl9gW@ou&?~8$?-q>F2_DbRq&+0i&=i9=| zdF(fiTw-3{@Wxg4o$^k@66Wr|;<`1Z;`=82S1JzNrmR#H6|rl1Sd0Ao6(8e!b~+jU zH$OY&u!P=SMU}(zzr0t~{`$rC{Gh@7qW+yD1 z>Cus2cGvZ8(shp?dRd2+PwOw3=9{*7@~X_qg7bXZJaR2t55Ktr99pgi)i>(|ZaoMF zUV(X(XY%^>k({|3?Q9)@3!d#K3vO_d@z#A`qXg_^6#%gz1MmbGIM~fMS#XogMhG zY)}+k69p@36H}S&uvtI``QA=j6oqAyK!p)9@Jkkf)}fkoNC9k;tPyT2 zH7bK8`Zu#pR@|&F1HK6j=5)0^cRA1fKfSYEeB?@*l_yQ)N ziRXYO8ljjNrVUoSUq=e85Pl62(DC*t3e$AK3NP!agB2pK_dpMMe*>UGCE)c%{9uKM zv-;5$#+puU-0CO;I$}N;=(aULtb=0ZS4*G*rAgaVW#DISV?^O<>&cGW{AA!qHv>Ir zhhm7B{p9ZLkuu;zgn>550Tt+@DDZWhyl|)JWYHa_GVtS4fz~*pC~|TJD~j96F}Zn% zy$s@zNCpNI6orr7;0k~5Fp>eCUj#Y6h=D;7MPaTNRH3>I{2U#i`%t4&I|Qsq!C4a= zmhfX&fS%ArF-;^4sL(?Ov9W-GK?_AeU<6Qs^kjuy+>sXmHasH+)(LC#1^~+; yR9`KhG /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..a51ec4f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,16 +13,18 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -43,13 +45,13 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -57,36 +59,24 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% -:mainEnd -if "%OS%"=="Windows_NT" endlocal +@rem Execute gradlew +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index e528b8c..26da9f7 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -4,21 +4,35 @@ plugins { } dependencies { - implementation(libs.bundles.hec) + implementation(libs.bundles.serversuite) implementation(libs.jython.standalone) implementation(libs.args4j) implementation(libs.bundles.regi) implementation(libs.bundles.regi) {artifact {extension = "jar"}} implementation(libs.bundles.regi.tools) implementation(libs.bundles.regi.tools) {artifact {extension = "jar"} } - + implementation(libs.otel) + runtimeOnly(libs.hec.cwms.ratings.cda) testImplementation(libs.bundles.junit.api) testRuntimeOnly(libs.bundles.junit.engine) } +configurations.configureEach { + exclude group: 'mil.army.usace.hec', module: 'hec-cwmsvue' + exclude group: 'mil.army.usace.hec', module: 'hec-gt-crs' + exclude group: 'org.openjfx', module: '*' + exclude group: 'mil.army.usace.hec.swingx', module: '*' + exclude group: 'org.swinglabs', module: '*' + exclude group: 'org.jfree', module: '*' +} + jar { manifest { attributes('Implementation-Version': project.version) } -} \ No newline at end of file +} + +test { + useJUnitPlatform() +} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java index 4369a50..8ec109e 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java @@ -37,13 +37,13 @@ public void addMessage(String string, Message msg) logger.log(Level.INFO, "{0} {1}", new String[]{string, msg.toString()}); } -// @Override + @Override public void addMessage(String string, String string1, boolean showProgress) { logger.log(Level.INFO, "{0} {1}", new String[]{string, string1}); } -// @Override + @Override public void addMessage(String string, Message msg, boolean showProgress) { logger.log(Level.INFO, "{0} {1}", new String[]{string, msg.toString()}); diff --git a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java index f631bf0..494dd94 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java @@ -1,29 +1,30 @@ package usace.rowcps.headless; -import com.rma.io.FileManager; -import com.rma.io.FileManagerImpl; import com.rma.io.RmaFile; -import com.rma.model.Manager; import com.rma.model.Project; +import hec.db.DataAccessFactory; import hec.db.DbConnectionException; +import hec.db.DbIoException; import hec.db.DbPluginNotFoundException; -import hec.db.InvalidDbConnectionException; -import hec.io.Identifier; +import hec.db.cwms.CwmsSecurityDao; import hec.lang.LoginException; +import hec.serversuite.ServerSuite; import hec.serversuite.ServerSuiteUtil; -import hec.serversuite.data.DirectOracleAuthenticationSource; -import java.io.File; -import java.util.List; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.logging.Level; import java.util.logging.Logger; +import mil.army.usace.hec.serversuite.cda.CdaAuthenticationSource; +import mil.army.usace.hec.serversuite.cda.CwmsApiKeyAuthExtension; import rma.services.ServiceLookup; import rma.services.tz.TimeZoneDisplayService; +import usace.rowcps.regi.executor.ManagerIdType; import usace.rowcps.regi.factories.RegiDomainFactory; import usace.rowcps.regi.interfaces.model.ManagerIdProvider; import usace.rowcps.regi.model.DatabaseConnectionManager; import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.executor.ManagerIdType; - import usace.rowcps.regi.model.RegiDomain; /** @@ -34,121 +35,72 @@ public class HeadlessRegiDomainFactory { private static final Logger logger = Logger.getLogger(HeadlessRegiDomainFactory.class.getName()); + private final ManagerIdProvider idProvider = buildNewProvider(); - public void setPluginsDirFromClasspath() - { - String cp = System.getProperties().getProperty("java.class.path"); - String[] split = cp.split(File.pathSeparator); - final String dbiClientjar = "dbiClient-v3.1.1.jar"; - for (String cpentry : split) { - if (cpentry.endsWith(dbiClientjar)) { - String pluginDir = cpentry.split(dbiClientjar)[0]; - logger.log(Level.INFO, "Setting plugin dir to: {0}", pluginDir); - System.setProperty("PLUGINS", pluginDir); - } - } - } + public RegiDomain createDomain() throws DbConnectionException, + DbPluginNotFoundException, IOException { - public RegiDomain createDomain(CLIOptions options, ManagerId managerId) throws DbConnectionException, - DbPluginNotFoundException, InvalidDbConnectionException - { - RegiDomain regiDomain = null; - - setPluginsDirFromClasspath(); - File rowcpsPojectDir = options.getRowcpsProjectDir(); - - String rowcpsProjectName = options.getRowcpsProjectName(); - logger.log(Level.INFO, "Creating project dir: "+ (rowcpsPojectDir == null ? "null" : rowcpsPojectDir), rowcpsProjectName == null ? "null" : rowcpsProjectName); - File projectDir = new File(rowcpsPojectDir, rowcpsProjectName); - - if (projectDir == null) { - String missingProjDirMessage - = "A Rowcps Project Dir is required and must be specified on the command line or in a properties file."; - throw new IllegalArgumentException(missingProjDirMessage); - } else { - if (!projectDir.exists()) { - // If we are being run headlessly I'm not sure how much hand-holding and sanity checking we have to do. - projectDir.mkdirs(); - if (!projectDir.exists()) { - throw new IllegalArgumentException("The directory " + projectDir.getAbsolutePath() + - " did not exist and could not be created."); - } - } - - String testProjDir = projectDir.getAbsolutePath(); - FileManager fileManager = FileManagerImpl.getFileManager(); - final String projectFilePath = testProjDir + "/" + options.getRowcpsProjectName() + ".prj"; - - RmaFile prjFile; - if (!fileManager.fileExists(projectFilePath)) { - final Identifier identifier = new Identifier(projectFilePath); - Identifier prjId = fileManager.createFile(identifier); - prjFile = fileManager.getFile(prjId.getPath()); - } else { - prjFile = fileManager.getFile(projectFilePath); - } + Path projectDir = Paths.get("regi-projects", "regi-cli"); + logger.log(Level.INFO, "Creating project dir: "+ projectDir); + Files.createDirectories(projectDir); - logger.log(Level.INFO, "Temp project file: " + prjFile.getAbsolutePath()); + Path projectFile = projectDir.resolve("regi-cli.prj"); + if(!Files.exists(projectFile)) { + Files.createFile(projectFile); + } - File projReportsDir = new File(projectDir, "reports"); - File projXmlDir = new File(projectDir, "xml"); - projReportsDir.mkdir(); - projXmlDir.mkdir(); + Files.createDirectories(projectDir.resolve("reports")); + Files.createDirectories(projectDir.resolve("xml")); - String name = "Headless"; - String description = "Created for Headless execution."; - regiDomain = new RegiDomainFactory().createProject(name, description, prjFile); + String name = "Headless"; + String description = "Created for Headless execution."; + RegiDomain regiDomain = new RegiDomainFactory().createProject(name, description, new RmaFile(projectFile.toAbsolutePath().toString())); - regiDomain.loadProjectFile(); + regiDomain.loadProjectFile(); - DatabaseConnectionManager connectionManager = (DatabaseConnectionManager) regiDomain.getManager( - RegiDomain.DOMAIN_CONNECTION_MANAGER, DatabaseConnectionManager.class); + DatabaseConnectionManager connectionManager = (DatabaseConnectionManager) regiDomain.getManager( + RegiDomain.DOMAIN_CONNECTION_MANAGER, DatabaseConnectionManager.class); - if (connectionManager == null) { - connectionManager = regiDomain.buildDatabaseConnectionManager(); - } + if (connectionManager == null) { + connectionManager = regiDomain.buildDatabaseConnectionManager(); + } - //conigure the database connection. - String dbUrl = options.getOracleUrl(); - String username = options.getOracleUser(); - char[] password = options.getOraclePassword(); - String tzId = options.getRowcpsTimezone(); - String officeId = options.getOracleOfficeId(); + String cdaUrl = System.getenv("CDA_URL"); + String apiKey = System.getenv("API_KEY"); + String officeId = System.getenv("OFFICE_ID"); - DirectOracleAuthenticationSource directOracleAuthenticationSource = new DirectOracleAuthenticationSource("", dbUrl, officeId); - connectionManager.setTimeZoneId(tzId); - connectionManager.setUsername(username); + CdaAuthenticationSource cdaAuthenticationSource = new CdaAuthenticationSource("", cdaUrl, officeId, new CwmsApiKeyAuthExtension(apiKey)); + try + { + ServerSuite serverSuite = ServerSuiteUtil.login("REGI CLI", cdaAuthenticationSource, false, false, false); + DataAccessFactory dataAccessFactory = serverSuite.getDataAccessFactory(); + try(var key = dataAccessFactory.getDataAccessKey("REGI CLI")) { + String username = dataAccessFactory.getDao(CwmsSecurityDao.class).getCurrentUserId(key); + connectionManager.setUsername(username); + } + connectionManager.setTimeZoneId("UTC"); connectionManager.setUserOfficeId(officeId); connectionManager.saveData(); - TimeZoneDisplayService tsDS = ServiceLookup.getTimeZoneDisplayService(); tsDS.setTimeZone(connectionManager.getTimeZone()); - try - { - ServerSuiteUtil.login("REGI Headless", directOracleAuthenticationSource, username, password); - } - catch(LoginException ex) - { - throw new DbConnectionException(ex); - } - regiDomain.connect(ServerSuiteUtil.getServerSuite()); - List managerList = regiDomain.getManagerList(); - + regiDomain.getManagerList(); regiDomain.saveProject(); + RegiDomain.setCurrentProject(regiDomain); Project.setCurrentProject(regiDomain); + return regiDomain; + } + catch(LoginException | DbIoException ex) + { + throw new DbConnectionException(ex); } - return regiDomain; } - public ManagerId getManagerId(CLIOptions opt) + public ManagerId getManagerId() { - ManagerId retval = idProvider.getManagerId(); - - return retval; + return idProvider.getManagerId(); } - private ManagerIdProvider idProvider = buildNewProvider(); private static ManagerIdProvider buildNewProvider() { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java b/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java index c955c60..70c3559 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java @@ -9,7 +9,7 @@ import java.util.logging.Logger; import usace.rowcps.headless.metrics.RegiHeadlessMetricsServiceProvider; import usace.rowcps.metrics.RegiMetricsService; -import wcds.dbi.DbiProperties; +import hec.db.cwms.DbiProperties; /** * diff --git a/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java b/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java index 32b1b74..a40a329 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java @@ -27,22 +27,9 @@ public Object evaluateExpression(Reader reader, Map variables) // I think this would let us restrict the classes loadable by python. ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader(); -// try { -// Class aClass = ctxtLoader.loadClass("usace.rowcps.regi.model.AtLocationMananger"); -// } catch (ClassNotFoundException ex) { -// Logger.getLogger(PythonEvaluator.class.getName()).log(Level.SEVERE, null, ex); -// } ScriptEngineManager scriptManager = new ScriptEngineManager(ctxtLoader); ScriptEngine pythonEngine = scriptManager.getEngineByName(ENGINE_NAME); -// if (pythonEngine instanceof (PyScriptEngine)) { -// (PyScriptEngine) object = ((PyScriptEngine)) pythonEngine; -// -// } - - //new PythonScriptContainer() - //ScriptEngineFactory factory = pythonEngine.getFactory(); - SimpleScriptContext context = (SimpleScriptContext) pythonEngine.getContext(); Object javaValue = null; diff --git a/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java b/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java index b4dc93f..17dc332 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java @@ -1,5 +1,6 @@ package usace.rowcps.headless; +import java.io.IOException; import usace.rowcps.headless.interfaces.ScriptEvaluator; import hec.db.DbConnectionException; import hec.db.DbIoException; @@ -45,7 +46,7 @@ public static void main(String[] args) { runHeadless(parser, args, opt); } - catch (DbConnectionException | DbPluginNotFoundException | InvalidDbConnectionException ex) + catch (DbConnectionException | DbPluginNotFoundException | InvalidDbConnectionException | IOException ex) { LOGGER.log(Level.SEVERE, "Headless error connecting to database.", ex); System.exit(-1); @@ -73,21 +74,23 @@ public static void main(String[] args) * @throws CmdLineException * @throws DbPluginNotFoundException */ - static void runHeadlessTest(String[] args) throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException - { + static void runHeadlessTest(String[] args) + throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException, + IOException { CLIOptions opt = new CLIOptions(System.getProperties()); CmdLineParser parser = new CmdLineParser(opt); runHeadless(parser, args, opt); } - private static void runHeadless(CmdLineParser parser, String[] args, CLIOptions opt) throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException - { + private static void runHeadless(CmdLineParser parser, String[] args, CLIOptions opt) + throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException, + IOException { parser.parseArgument(args); System.setProperties(opt.getProperties()); HeadlessRegiDomainFactory factory = new HeadlessRegiDomainFactory(); - ManagerId managerId = factory.getManagerId(opt); - RegiDomain regiDomain = factory.createDomain(opt, managerId); + ManagerId managerId = factory.getManagerId(); + RegiDomain regiDomain = factory.createDomain(); if (regiDomain != null) { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java b/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java index 2bb5d1c..c4d0368 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java @@ -30,16 +30,6 @@ public Collection getFactories() return factories; } -// public void printNames() -// { -// CalcFactoryRegistry aDefault = getRegistry(DEFAULT_VERSION); -// Collection factories = aDefault.getFactories(); -// for (ScriptableCalcFactory factory : factories) { -// //System.out.println("Found factory:" + factory.getName()); -// logger.log(Level.FINE, "Found factory:" + factory.getName()); -// } -// } - @Override public ScriptableCalcFactory getFactory(String name) { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java b/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java deleted file mode 100644 index af029f9..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.assocexport; - -/** - * - * @author stephen - */ -public interface ScriptableExportAssociations -{ - /** - * Export all Time Series Associations in the database - * - * @param fileLoc The file to write the CSV to - * @param lineDelimiter the delimiter to use between lines (\n recommended) - * @param valueDelimiter The delimiter to use between values (\t - * recommended) - */ - public void exportAllTSAssociations(String fileLoc, String lineDelimiter, String valueDelimiter); - - /** - * Export the Time Series Associations for a given project - * - * @param project The project to export for - * @param fileLoc The file to write the CSV to - * @param lineDelimiter the delimiter to use between lines (\n recommended) - * @param valueDelimiter The delimiter to use between values (\t - * recommended) - */ - public void exportTSAssociations(String project, String fileLoc, String lineDelimiter, String valueDelimiter); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java deleted file mode 100644 index 340e714..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.assocexport; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.headless.sigstages.exportdb.ScriptableExportSigStagesImpl; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class ScriptableExportAssociationsFactory implements ScriptableCalcFactory -{ - public ScriptableExportAssociationsFactory() - { - } - - @Override - public String getName() - { - return "Export Associations"; - } - - @Override - public String getDescription() - { - return "Exports some or all of the Associations in the database."; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableExportTSAssociationsImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java deleted file mode 100644 index 137f348..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.assocexport; - -import hec.data.location.LocationTemplate; -import hec.data.project.AtProjectDescriptor; -import hec.data.project.IProject; -import hec.data.project.IProjectCatalog; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.NavigableMap; -import java.util.Objects; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import usace.rowcps.data.association.IAssociationProvider; -import usace.rowcps.data.association.ITimeSeriesAssociation; -import usace.rowcps.data.outputformatter.CSVOutputFormatter; -import usace.rowcps.data.outputformatter.OutputFormatter; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.AtAssociationCache; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.status.AtProjectManager; - -/** - * - * @author stephen - */ -public class ScriptableExportTSAssociationsImpl implements ScriptableExportAssociations, ScriptableCalc -{ - private final ManagerId _managerId; - private final RegiDomain _regiDomain; - private static final Logger LOGGER = Logger.getLogger(ScriptableExportTSAssociationsImpl.class.getSimpleName()); - private static final String GLOBAL = "?GLOBAL?"; - - public ScriptableExportTSAssociationsImpl(RegiDomain regiDomain, ManagerId managerId) - { - _managerId = managerId; - _regiDomain = regiDomain; - } - - private List getAllProjects() - { - try - { - AtProjectManager manager = _regiDomain.getAtProjectManager(_managerId); - IProjectCatalog projectCatalog = manager.getProjectCatalog(CacheUsage.NORMAL); - List projectDescriptorList = projectCatalog.getProjectDescriptorList(); - - Set templatesForDescriptors = projectDescriptorList.stream() - .map(projDesc -> projDesc.getProjectLocationRef()) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - NavigableMap iProjects = manager.getIProjects(templatesForDescriptors, CacheUsage.NORMAL); - - return new ArrayList<>(iProjects.values()); - } - catch(DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Error Retrieving Associations!", ex); - return Collections.emptyList(); - } - } - - @Override - public void exportAllTSAssociations(String fileLoc, String lineDelimiter, String valueDelimiter) - { - OutputFormatter formatter = new CSVOutputFormatter(lineDelimiter, valueDelimiter); - List allProjects = getAllProjects(); - for(IProject project : allProjects) - { - configureFormatter(formatter, project.getProjectId()); - AtAssociationCache atAssociationCache = _regiDomain.getAtAssociationCache(_managerId); - IAssociationProvider timeSeriesAssociationProvider = atAssociationCache.getTimeSeriesAssociationsProvider(project.getLocation().getLocationTemplate()); - if(timeSeriesAssociationProvider != null) - { - timeSeriesAssociationProvider.serializeToFormat(formatter); - } - } - formatter.write(fileLoc); - } - - private IProject getProject(String projName) - { - try - { - AtProjectManager manager = _regiDomain.getAtProjectManager(_managerId); - IProjectCatalog projectCatalog = manager.getProjectCatalog(CacheUsage.NORMAL); - List projectDescriptorList = projectCatalog.getProjectDescriptorList(); - - Set templatesForDescriptors = projectDescriptorList.stream() - .map(projDesc -> projDesc.getProjectLocationRef()) - .filter(Objects::nonNull) - .filter(projDesc -> projDesc.getLocationId().equals(projName)) - .collect(Collectors.toSet()); - - NavigableMap iProjects = manager.getIProjects(templatesForDescriptors, CacheUsage.NORMAL); - - return iProjects.values().stream() - .filter(project -> project.getProjectId().equals(projName)) - .findFirst() - .orElse(null); - } - catch(DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Error Retrieving Associations!", ex); - return null; - } - } - - @Override - public void exportTSAssociations(String projectId, String fileLoc, String lineDelimiter, String valueDelimiter) - { - OutputFormatter formatter = new CSVOutputFormatter(lineDelimiter, valueDelimiter); - IProject project = getProject(projectId); - if(project == null) - { - LOGGER.log(Level.SEVERE, "Error: Project with name {0} unable to be retrieved.", project); - } - else - { - configureFormatter(formatter, project.getProjectId()); - AtAssociationCache atAssociationCache = _regiDomain.getAtAssociationCache(_managerId); - IAssociationProvider timeSeriesAssociationProvider = atAssociationCache.getTimeSeriesAssociationsProvider(project.getLocation().getLocationTemplate()); - if(timeSeriesAssociationProvider != null) - { - timeSeriesAssociationProvider.serializeToFormat(formatter); - } - else - { - LOGGER.log(Level.SEVERE, "Error: Project with name {0} has no TS associations provider.", project); - } - formatter.write(fileLoc); - } - } - - private void configureFormatter(OutputFormatter formatter, String projectId) - { - formatter.addReplacementString(GLOBAL, projectId); - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java index 0e9329e..544f0d9 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java @@ -81,7 +81,6 @@ import usace.rowcps.data.project.TsUsageId; import usace.rowcps.headless.calculator.AbstractScriptableCalc; import usace.rowcps.headless.calculator.inflow.AbstractThreadedBlockRetriever; -import static usace.rowcps.headless.calculator.status.ScriptableStatusGraphicImpl.LATCH_SECONDS; import usace.rowcps.headless.interfaces.ScriptableCalc; import usace.rowcps.metrics.RegiMetricsService; import usace.rowcps.regi.event.IThreadedBlockRetriever; @@ -103,6 +102,7 @@ public class ScriptableGateSettingsImpl extends AbstractScriptableCalc implements ScriptableCalc, ScriptableGateSettings { + public final static String LATCH_SECONDS = "rowcps.latchseconds"; private static final Logger LOGGER = Logger.getLogger(ScriptableGateSettings.class.getName()); public ScriptableGateSettingsImpl(RegiDomain regiDomain, ManagerId managerId) { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java deleted file mode 100644 index 724ec2b..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package usace.rowcps.headless.calculator.poolpercent; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author ryan - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class PoolPercentCalcFactory implements ScriptableCalcFactory -{ - - @Override - public String getName() - { - return "Pool Percent"; - } - - @Override - public String getDescription() - { - return "Recalculates Pool Percentages at a Location"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptablePoolPercentImpl(regiDomain, managerid); - } - -} \ No newline at end of file diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java deleted file mode 100644 index c4c278c..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -package usace.rowcps.headless.calculator.poolpercent; - -import hec.data.TimeWindow; -import hec.data.location.LocationTemplate; -import hec.data.project.IProject; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import usace.metrics.services.Metrics; -import usace.rowcps.computation.pool.DbCommitPoolCalc; -import usace.rowcps.data.pool.DbPool; -import usace.rowcps.data.pool.PoolTimeSeries; -import usace.rowcps.data.pool.RegiPool; -import usace.rowcps.headless.calculator.AbstractScriptableCalc; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.OptionalParams; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.pool.AtPoolManager; -import usace.rowcps.regi.status.AtProjectManager; - -import java.util.Date; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author ryan - */ -public class ScriptablePoolPercentImpl extends AbstractScriptableCalc implements ScriptableCalc -{ - - private static final Logger LOGGER = Logger.getLogger(ScriptablePoolPercentImpl.class.getName()); - - public ScriptablePoolPercentImpl(RegiDomain regiDomain, ManagerId managerId) - { - super(regiDomain, managerId); - } - - public void calculatePoolPercents(String officeId, String locationStr, Date startDate, Date endDate) - { - LocationTemplate locRef = new LocationTemplate(officeId, locationStr); - - Metrics metrics = RegiMetricsService.createMetrics(this.getClass().getSimpleName(), "calculatePoolPercents"); - OptionalParams funcParams = new OptionalParams(metrics); - - LOGGER.log(Level.INFO, "Calculating Pool Percents for {0} from: {1} to: {2}", new Object[]{locRef, startDate, endDate}); - DbCommitPoolCalc poolCalc = new DbCommitPoolCalc(); - AtPoolManager poolMan = regiDomain.getAtPoolManager(managerId); - AtProjectManager projectMan = regiDomain.getAtProjectManager(managerId); - - try - { - //Retrieval of the project also fills in the associations, this is required for the pool calculations. - IProject project = projectMan.getIProject(locRef, CacheUsage.NORMAL); - if (project == null) - { - LOGGER.log(Level.SEVERE, () -> "Unable to calculate pool time series. Project " + locRef + " does not exist."); - return; - } - - Set pools = poolMan.retrievePools(locRef, CacheUsage.NORMAL, funcParams); - pools.stream() - .filter(pool -> pool.getTsId() == null) - .filter(DbPool.class::isInstance) - .map(DbPool.class::cast) - .forEach(pool -> pool.getMetaData().setTsId(retrieveDefaultTsId(pool))); - - TimeWindow tw = new TimeWindow(startDate, true, endDate, true); - - poolCalc.calcTimeSeries(getRegiDomain(), getManagerId(), pools, tw, funcParams); - - LOGGER.log(Level.INFO, "Calculated Pool Percents for {0} from: {1} to: {2}", new Object[]{locRef, startDate, endDate}); - } - catch (DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Unable to calculate pool time series data.", ex); - } - } - - // Based on method from PoolsPanel - public String retrieveDefaultTsId(RegiPool pool) - { - LocationTemplate template = pool.getLocationRef(); - String output = AtProjectManager.getDefaultPoolTimeSeriesIdMask(template); - AtProjectManager projMan = regiDomain.getAtProjectManager(managerId); - try - { - output = projMan.retrievePoolTimeSeriesIdMask(template); - } - catch (DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Unable to retrieve elevation time series association for " + template.getLocationId() + ". Defaulting to " + output, ex); - } - - String poolName = pool.getPoolName(); - if (poolName.length() > PoolTimeSeries.MAX_POOL_NAME_LENGTH) - { - poolName = poolName.substring(0, PoolTimeSeries.MAX_POOL_NAME_LENGTH); - } - - return output.replace(AtProjectManager.POOL_NAME_MASK, poolName); - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java deleted file mode 100644 index 63665cc..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2018 - * United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) - * All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. - * Source may not be released without written approval from HEC - */ -package usace.rowcps.headless.calculator.status; - -import com.rma.ui.pinnable.IPinnableComponentContainer; -import com.rma.ui.pinnable.PinnableComponentManager; -import hec.data.location.LocationGroup; -import hec.data.location.LocationTemplate; -import java.util.List; -import usace.rowcps.basinpie.ui.annotations.BasinPieAnnotationLayer; -import usace.rowcps.data.maptemplate.annotations.AnnotationData; -import usace.rowcps.data.maptemplate.annotations.BarChartAnnotationPayload; -import usace.rowcps.data.maptemplate.annotations.PieChartAnnotationPayload; -import usace.rowcps.decisionsupport.ui.annotations.chartpanel.BarChartAnnotationPanel; -import usace.rowcps.regi.interfaces.model.ManagerIdProvider; - -/** - * - * @author josh - */ -public class HeadlessBasinPieAnnotationLayer extends BasinPieAnnotationLayer -{ - - private final List _activeLocations; - - public HeadlessBasinPieAnnotationLayer(ManagerIdProvider managerIdProvider, - LocationGroup locationGroup, List activeLocations) - { - super(managerIdProvider, locationGroup); - _activeLocations = activeLocations; - } - - @Override - protected List getActiveLocations() - { - return _activeLocations; - } - - @Override - public void addAnnotation(AnnotationData annotationData) - { - IPinnableComponentContainer iPinnableComponentContainer = createAnnotation(annotationData); - if (iPinnableComponentContainer != null) - { - PinnableComponentManager pcm = PinnableComponentManager.getManager(this); - pcm.addPinnableComponent(iPinnableComponentContainer); - - applyAnnotationData(iPinnableComponentContainer, annotationData, true); - annotationData.addPropertyChangeListener(this); - } - } - - public void updateBarChartGraphics() - { - getContainers().keySet().stream() - .filter(BarChartAnnotationPanel.class::isInstance) - .map(BarChartAnnotationPanel.class::cast) - .forEach(BarChartAnnotationPanel::updateBarChart); - } - - @Override - protected void updateAnnotationActiveProjects(AnnotationData data) - { - if (data.getPayload() instanceof PieChartAnnotationPayload) - { - PieChartAnnotationPayload payload = (PieChartAnnotationPayload) data.getPayload(); - payload.setActiveLocations(_activeLocations); - } - else if (data.getPayload() instanceof BarChartAnnotationPayload) - { - BarChartAnnotationPayload payload = (BarChartAnnotationPayload) data.getPayload(); - payload.setActiveLocations(_activeLocations); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java deleted file mode 100644 index 9466111..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.calculator.status; - -import hec.data.basin.IBasin; -import hec.data.location.AssignedLocation; -import hec.data.location.LocationCategoryRef; -import hec.data.location.LocationGroup; -import hec.data.location.LocationGroupRef; -import hec.data.location.LocationTemplate; -import hec.data.project.IProject; -import hec.db.DbConnectionException; -import hec.db.DbException; -import hec.db.DbIoException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.NavigableMap; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import usace.metrics.services.Metrics; -import usace.metrics.services.Timer; -import usace.rowcps.computation.basinconnectivity.BasinConnectivityModel; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.regi.basin.IBasinConnectivityLocation; -import usace.rowcps.regi.basin.IBasinConnectivityModel; -import usace.rowcps.regi.interfaces.model.ManagerIdProvider; -import usace.rowcps.regi.model.AtBasinManager; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.OptionalParams; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.status.AtProjectManager; - -/** - * - * @author josh - */ -public class LocationGroupFactory -{ - ManagerIdProvider _managerIdProvider; - NavigableMap _projectsMap; - Set _projectGroups; - final private BasinConnectivityModel _basinConnectivityModel; - RegiDomain _regiDomain; - - public LocationGroupFactory(ManagerIdProvider managerIdProvider) - { - _managerIdProvider = managerIdProvider; - _basinConnectivityModel = new BasinConnectivityModel(_managerIdProvider.getManagerId()); - _regiDomain = (RegiDomain) RegiDomain.getCurrentProject(); - loadProjectsMap(); - } - - /** - * This method returns the populated LocationGroup for "Project Group" - * with the given projectGroupId - * @param projectGroupId - * @return - */ - public LocationGroup retrieveProjectGroup(String projectGroupId) - { - OptionalParams params = OptionalParams.createForMetrics(getClass().getSimpleName(), "retrieveProjectGroup"); - LocationGroup retval = null; - Set projectGroups = getProjectGroups(params); - for(LocationGroup locGroup : projectGroups) - { - if(locGroup.getName().equalsIgnoreCase(projectGroupId)) - { - retval = locGroup; - break; - } - } - - return retval; - } - - private Set retrieveProjectGroups(OptionalParams params) - { - OptionalParams funcParams = OptionalParams.forMetrics(params, "retrieveProjectGroups"); - AtBasinManager atBasinManager = _regiDomain.getAtBasinManager(_managerIdProvider.getManagerId()); - Set projectGroups = new HashSet<>(); - - try - { - projectGroups.addAll(atBasinManager.getBasinCatalog(funcParams)); - } - catch(DbConnectionException | DbIoException ex) - { - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Unable to retrieve ProjectGroup catalog from the database.", ex); - } - - return projectGroups; - } - - private Set getProjectGroups(OptionalParams params) - { - OptionalParams funcParams = OptionalParams.forMetrics(params, "getProjectGroups"); - if(_projectGroups != null && _projectGroups.size() > 0) - { - return _projectGroups; - } - else - { - _projectGroups = retrieveProjectGroups(funcParams); - } - - return _projectGroups; - } - - public LocationGroup retrieveLocationGroupForBasin(String basinId) - { - //try getting the IBasin from the AtBasinManager - IBasin basin = retrieveIBasin(basinId); - if(basin == null) - { - Logger.getLogger(LocationGroupFactory.class.getName()).log(Level.SEVERE, "Unable to retrieve Basin from CWMS database for BasinId: {0}", basinId); - return null; - } - - Metrics metrics = RegiMetricsService.createMetrics(getClass().getSimpleName(), "getLocationGroup"); - OptionalParams funcParams = new OptionalParams(metrics); - try(Timer.Context ctx = metrics.createTimer().start()) - { - LocationGroup lg = new LocationGroup(); - lg.setName(basin.getBasinId()); - lg.setDbOfficeId(basin.getOfficeId()); - lg.setLocationGroupRef(new LocationGroupRef(new LocationCategoryRef(AtBasinManager.BASIN_CATEGORY_REF_ID, basin.getOfficeId()), basin.getOfficeId(), basin.getBasinId())); - - //all stream locations are associated with the - LocationTemplate basinLocation = basin.getLocationTemplate(); - - if(!_basinConnectivityModel.isDataAvailableForLocation(basinLocation)) - { - _basinConnectivityModel.fillModel(basin, _projectsMap, funcParams); - } - - IBasinConnectivityLocation primaryStream = _basinConnectivityModel.getStreamBase(new LocationTemplate(basin.getOfficeId(), basin.getPrimaryStream())); - - List assignedLocations = buildAssignedLocations(primaryStream, basinLocation); - - for(int i = 0; i < assignedLocations.size(); i++) - { - assignedLocations.get(i).setAttribute(Double.valueOf(i)); - } - - lg.setAssignedLocations(new HashSet<>(assignedLocations)); - - return lg; - } - } - - /** - * This method returns the basin connectivity model that was populated - * by the retrieveLocationGroupForBasin() method. - * - * @return IBasinConnectivityModel - */ - public IBasinConnectivityModel getBasinConnectivityModel() - { - return _basinConnectivityModel; - } - - private List buildAssignedLocations(IBasinConnectivityLocation streamBase, LocationTemplate basinLocation) - { - List assignedLocations = new ArrayList<>(); - - LocationTemplate streamBaseLocation = streamBase.getLocationTemplate(); - - AssignedLocation aLoc = new AssignedLocation(streamBaseLocation, streamBase.getLocationId(), 0.0, basinLocation); - - aLoc.setDescription(" (" + streamBase.getLocationKind() + ")"); - - assignedLocations.add(aLoc); - - streamBase.getStreamBases().forEach(sbase -> assignedLocations.addAll(buildAssignedLocations(sbase, basinLocation))); - - return assignedLocations; - } - - private IBasin retrieveIBasin(String basinId) - { - IBasin retval = null; - AtBasinManager atBasinManager = _regiDomain.getAtBasinManager(_managerIdProvider.getManagerId()); - try - { - List allBasins = atBasinManager.retrieveAllBasins(CacheUsage.NORMAL, OptionalParams.createForMetrics(getClass().getSimpleName(), "retrieveIBasin", basinId)); - for(IBasin iBasin : allBasins) - { - if(iBasin.getBasinId().equalsIgnoreCase(basinId)) - { - retval = iBasin; - break; - } - } - } - catch (DbException ex) - { - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error retrieving Basin:", ex); - } - return retval; - } - - private NavigableMap getProjectsMap() - { - if(_projectsMap != null) - { - return _projectsMap; - } - else - { - loadProjectsMap(); - } - return _projectsMap; - } - - private void loadProjectsMap() - { - AtBasinManager atBasinManager = _regiDomain.getAtBasinManager(_managerIdProvider.getManagerId()); - AtProjectManager atProjectManager = _regiDomain.getAtProjectManager(_managerIdProvider.getManagerId()); - Metrics metrics = RegiMetricsService.createMetrics(getClass().getSimpleName(), "getProejcts"); - OptionalParams funcParams = new OptionalParams(metrics); - try - { - _projectsMap = IBasinConnectivityModel.retrieveAllProjects(atBasinManager, atProjectManager, funcParams); - } - catch (DbIoException | DbConnectionException ex) - { - Logger.getLogger(LocationGroupFactory.class.getName()).log(Level.SEVERE, "Error loading projects map:", ex); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java deleted file mode 100644 index 72b8568..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java +++ /dev/null @@ -1,1151 +0,0 @@ -package usace.rowcps.headless.calculator.status; - -import com.rma.ui.pinnable.PinnableComponentGlassPane; -import com.rma.ui.pinnable.PinnableComponentGlassPaneFactory; -import com.rma.ui.pinnable.PinnableContainer; -import hec.data.location.AssignedLocation; -import hec.data.location.Location; -import hec.data.location.LocationGroup; -import hec.data.location.LocationTemplate; -import hec.data.project.IProject; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import hec.heclib.util.HecTime; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; -import usace.rowcps.data.maptemplate.IMapTemplate; -import usace.rowcps.data.maptemplate.streamplot.StreamGageGraphicOptionData; -import usace.rowcps.decisionsupport.ui.basintree.BasinTreeSelectionData; -import usace.rowcps.decisionsupport.ui.basintree.BasinTreeSelectionService; -import usace.rowcps.decisionsupport.ui.basintree.SimpleBasinTreeSelectionData; -import usace.rowcps.decisionsupport.ui.mappanel.template.impl.TimeInfoSource; -import usace.rowcps.decisionsupport.ui.streamplot.StreamData; -import usace.rowcps.decisionsupport.ui.streamplot.StreamPlotPanel; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.AtLocationManager; -import usace.rowcps.regi.model.AtMapTemplateManager; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; -import hec.map.geoui.interp.TimeInfo; -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.LayoutManager; -import java.awt.image.BufferedImage; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.time.Instant; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.SortedSet; -import java.util.TimeZone; -import java.util.TreeSet; -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import java.util.concurrent.RunnableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import javax.imageio.IIOImage; -import javax.imageio.ImageWriteParam; -import javax.imageio.ImageWriter; -import javax.swing.JComponent; -import javax.swing.JLayer; -import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; -import rma.services.GlobalServiceLoader; -import rma.services.GlobalServiceLoaderDelegate; -import usace.metrics.services.Metrics; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.basinpie.ui.BasinPieModel; -import usace.rowcps.computation.services.CalcFlowGroupTimeSeriesService; -import usace.rowcps.data.charttemplate.IChartTemplate; -import usace.rowcps.data.maptemplate.graphicoptions.ReleasesGraphicOptionData; -import usace.rowcps.data.maptemplate.reservoir.ReservoirGraphicOptionData; -import usace.rowcps.decisionsupport.ui.graphics.releases.ReleasesGraphicData; -import usace.rowcps.decisionsupport.ui.graphics.utilities.GraphicConstants; -import usace.rowcps.headless.calculator.AbstractScriptableCalc; -import usace.rowcps.regi.interfaces.model.ProjectChildLocationCacheService; -import usace.rowcps.regi.model.AtChartTemplateManager; -import usace.rowcps.regi.model.OptionalParams; -import usace.rowcps.regi.ui.gfx2d.PiePanel; -import usace.rowcps.decisionsupport.ui.basintree.OperationSupportBasinTreeModel; -import usace.rowcps.mappanel.ui.template.MapTemplateLayer; -import usace.rowcps.decisionsupport.ui.basintree.BasinTreeModel; -import usace.rowcps.decisionsupport.ui.graphics.releases.ReleasesGraphicPanel; -import usace.rowcps.decisionsupport.ui.reservoirplot.ReservoirPlotPanel; -import usace.rowcps.decisionsupport.ui.reservoirplot.ReservoirPlotPanelData; -import usace.rowcps.mappanel.ui.MapPanelDateRangeService; -import usace.rowcps.mappanel.ui.SimpleMapPanelDateRange; -import usace.rowcps.regi.basin.IBasinConnectivityModel; -import usace.rowcps.regi.executor.FutureDescriptor; -import usace.rowcps.regi.status.AtProjectManager; - -/** - * - * @author ryan - */ -public class ScriptableStatusGraphicImpl extends AbstractScriptableCalc - implements ScriptableCalc -{ - private static final Logger LOGGER = Logger.getLogger(ScriptableStatusGraphicImpl.class.getName()); - public final static String LATCH_SECONDS = "rowcps.latchseconds"; - private final BasinTreeSelectionData _selectionData = new SimpleBasinTreeSelectionData(new ArrayList<>(), new LocationGroup()); - - public ScriptableStatusGraphicImpl(RegiDomain regiDomain, ManagerId manId) - { - super(regiDomain, manId); - System.setProperty("java.awt.headless", "true"); - } - - public void generateReservoirStatusImage(String officeId, String locationId, - String templateName, Date current, - final int width, final int height, - String filename) throws DbConnectionException, DbIoException, IOException, InterruptedException, ExecutionException, TimeoutException - { - SimpleMapPanelDateRange simpleDateRange = new SimpleMapPanelDateRange(current); - MapPanelDateRangeService.registerRange(getManagerId(), simpleDateRange); - - LocationTemplate locTemp = new LocationTemplate(officeId, locationId); - - TimeInfo utcTimeInfo = getUtcTimeInfo(current, regiDomain.getTimeZone()); - - TimeInfoSource utcTimeInfoSource = () -> utcTimeInfo; - - checkForKnownNeededServices(); - - MapTemplateLayer mtl = getMapTemplateLayer(templateName); - - ReservoirGraphicOptionData optionData = mtl.getGraphicsOptions(); - - CountDownLatch cdl = new CountDownLatch(1); - PropertyChangeListener pcl = (PropertyChangeEvent evt) -> - { - if (GraphicConstants.DATA_FILLED_EVENT.equals(evt.getPropertyName())) - { - cdl.countDown(); - } - }; - - optionData.addPropertyChangeListener(pcl); - - AtProjectManager atProjectManager = this.regiDomain.getAtProjectManager(managerId); - IProject iProject = atProjectManager.getIProject(locTemp, CacheUsage.NORMAL); - - ReservoirPlotPanelData plotPanelData = new ReservoirPlotPanelData(iProject, utcTimeInfoSource, managerId, optionData); - plotPanelData.addPropertyChangeListener(pcl); - - ReservoirPlotPanel reservoirPlotPanel; - - RunnableFuture panelFuture = new FutureTask<>(() -> new ReservoirPlotPanel(iProject, managerId, utcTimeInfoSource, plotPanelData)); - SwingUtilities.invokeLater(panelFuture); - reservoirPlotPanel = panelFuture.get(1, TimeUnit.MINUTES); - - Integer seconds = Integer.getInteger(LATCH_SECONDS, 11 * 60); // This one goes to 11... - boolean normalExit = cdl.await(seconds, TimeUnit.SECONDS); - if (!normalExit) - { - LOGGER.log(Level.WARNING, "Timeout exceeded loading reservoir status graphic data."); - } - - optionData.removePropertyChangeListener(pcl); - - // This next sleep is important b/c the latch gets set after the SwingWorker doInBackground complete but before done() - // are called. We need the done() methods to execute before we proceed. - Thread.sleep(2000); - - String imageFormat = getFormatFromFile(filename); - - Dimension d = computePreferredSize(reservoirPlotPanel, width, height); - - layoutAndSave(reservoirPlotPanel, d, filename, imageFormat); - } - - private Dimension computePreferredSize(Component comp, int requestedWidth, int requestedHeight) - { - comp.setPreferredSize(null); //Causes the component to recompute its pref size - Dimension prefSize = comp.getPreferredSize(); - Dimension reqSize = new Dimension(requestedWidth, requestedHeight); - - //This should prevent most clipping issues where the size provided is too small for the data. - return computeLargestDimension(prefSize, reqSize); - } - - private Dimension computeLargestDimension(Dimension dim1, Dimension dim2) - { - return new Dimension(Math.max(dim1.width, dim2.width), Math.max(dim1.height, dim2.height)); - } - - private boolean checkForKnownNeededServices() - { - boolean hasCalcFlow = hasGlobalService(CalcFlowGroupTimeSeriesService.class); - if (!hasCalcFlow) - { - ServiceLoader serviceLoader = ServiceLoader.load(CalcFlowGroupTimeSeriesService.class); - hasCalcFlow = hasService(CalcFlowGroupTimeSeriesService.class, serviceLoader); - } - - if (!hasCalcFlow) - { - String mesg = "The CalcFlowGroupTimeSeriesService was not found and is known to be needed by Regi Headless. " - + "Without this service the headless Status Graphic generation may not generate the correct values. " - + "Even if the necessary classes are in the classpath, the services may still not be found " - + "if the jars do not include the necessary META-INF services folder. " - + "For example, public-package-jars\\usace-rowcps-computation.jar contains implementation classes " - + "but not the service definitions."; - LOGGER.warning(mesg); - } - - boolean hasProjectChild = hasGlobalService(ProjectChildLocationCacheService.class); - if (!hasProjectChild) - { - String mesg = "A ProjectChildLocationCacheService was not found and is known to be needed by Regi Headless. " - + "Without this service the headless Status Graphic generation may not generate the correct values. " - + "Even if the necessary classes are in the classpath, the services may still not be found " - + "if the jars do not include the necessary META-INF services folder. " - + "For example, public-package-jars\\usace-rowcps-regi.jar contains implementation classes " - + "but not the service definitions."; - LOGGER.warning(mesg); - } - - return hasCalcFlow && hasProjectChild; - } - - private boolean hasGlobalService(Class klass) - { - GlobalServiceLoaderDelegate instance = GlobalServiceLoader.getInstance(); - ServiceLoader serviceLoader = instance.getServiceLoader(klass); - - return hasService(klass, serviceLoader); - } - - private boolean hasService(Class klass, ServiceLoader sl) - { - boolean hasCalcFlow = false; - ServiceLoader serviceLoader; - - GlobalServiceLoaderDelegate instance = GlobalServiceLoader.getInstance(); - serviceLoader = instance.getServiceLoader(klass); - - for (Object service : serviceLoader) - { - hasCalcFlow = true; - break; - } - return hasCalcFlow; - } - - public void generateStreamStatusImage(String officeId, String locationId, - String templateName, Date current, - final int width, final int height, - String filename) throws DbConnectionException, DbIoException, IOException, InterruptedException, ExecutionException, TimeoutException - { - - LocationTemplate locTemp = new LocationTemplate(officeId, locationId); - - AtLocationManager locMan = this.regiDomain.getAtLocationManager(getManagerId()); - Location loc = locMan.retrieveLocation(locTemp, CacheUsage.NORMAL); - - final TimeInfo ti = getUtcTimeInfo(current, this.regiDomain.getTimeZone()); - - TimeInfoSource timeInfoSource = () -> ti; - - SimpleMapPanelDateRange simpleDateRange = new SimpleMapPanelDateRange(current); - MapPanelDateRangeService.registerRange(getManagerId(), simpleDateRange); - - MapTemplateLayer mapTemplateLayer = getMapTemplateLayer(templateName); - - if(mapTemplateLayer == null) - { - LOGGER.log(Level.SEVERE, "Unable to locate MapTemplateLayer with the name:{0}", templateName); - return; - } - - StreamGageGraphicOptionData sggod = mapTemplateLayer.getStreamGageGraphicOptions(); - TimeZone timeZone = this.regiDomain.getTimeZone(); - final StreamData streamData = new StreamData(loc, sggod, timeInfoSource, timeZone, getManagerId()); - - final CountDownLatch cdl = new CountDownLatch(1); - PropertyChangeListener pcl = (PropertyChangeEvent evt) -> - { - if (GraphicConstants.DATA_FILLED_EVENT.equals(evt.getPropertyName())) - { - cdl.countDown(); - } - }; - - streamData.addPropertyChangeListener(pcl); - Future future = streamData.retrieveData(); - future.get(11, TimeUnit.MINUTES); //No return from this, but we need to wait until it's done. - - String imageFormat = getFormatFromFile(filename); - - StreamPlotPanel panel = new StreamPlotPanel(streamData); // Why is this building a panel on background thread? - - Dimension d = computePreferredSize(panel, width, height); - - layoutAndSave(panel, d, filename, imageFormat); - } - - public void generateReleasesStatusImage(String officeId, String locationId, - String templateName, Date current, - final int width, final int height, - String filename) throws DbConnectionException, DbIoException, IOException, InterruptedException, TimeoutException, ExecutionException - { - Metrics metrics = RegiMetricsService.createMetrics(getClass().getSimpleName()); - - MyReleasesGraphicData data = buildReleasesGraphicData(officeId, locationId, current, metrics); - - CompletableFuture future = data.retrieveOutletGroups(new OptionalParams(metrics)); - data.updateDataScopeSynchronous(new OptionalParams(metrics)); - LOGGER.log(Level.FINE, "(Headless)Data scope retrieval complete."); - future.get(); - LOGGER.log(Level.FINE, "(Headless)Retrieval of outlet groups complete."); - - //This needs to occur *after* all of the futures have been completed. - data.fireDataUpdateEvent(); - - saveReleasesToFile(data, width, height, filename); - } - - private MyReleasesGraphicData buildReleasesGraphicData(String officeId, String locationId, Date current, Metrics metrics) throws DbConnectionException, DbIoException - { - LocationTemplate locTemp = new LocationTemplate(officeId, locationId); - AtLocationManager locMan = this.regiDomain.getAtLocationManager(getManagerId()); - Location loc = locMan.retrieveLocation(locTemp, CacheUsage.NORMAL); - TimeInfo utcTimeInfo = getUtcTimeInfo(current, this.regiDomain.getTimeZone()); - TimeInfoSource utcTimeInfoSource = () -> utcTimeInfo; - SimpleMapPanelDateRange simpleDateRange = new SimpleMapPanelDateRange(current); - MapPanelDateRangeService.registerRange(getManagerId(), simpleDateRange); - ReleasesGraphicOptionData graphicOptionData = new ReleasesGraphicOptionData(); - - return new MyReleasesGraphicData(loc, managerId, utcTimeInfoSource, graphicOptionData, new OptionalParams(metrics)); - } - - private void saveReleasesToFile(ReleasesGraphicData data, int width, int height, String filename) - { - try - { - SwingUtilities.invokeAndWait(() -> - { - ReleasesGraphicPanel releasesGraphicPanel = new ReleasesGraphicPanel(false, true); - releasesGraphicPanel.setData(data); - - //This is a bit assinine, but it's used to massage the preferred sizes - //The detail component's pref size is constantly recomputed on paint....why? because science! and my youthful ignorance. - renderGraphic(releasesGraphicPanel); - renderGraphic(releasesGraphicPanel); - renderGraphic(releasesGraphicPanel); - renderGraphic(releasesGraphicPanel); - - Dimension imageDimension = computePreferredSize(releasesGraphicPanel, width, height); - String imageFormat = getFormatFromFile(filename); - - try - { - layoutAndSave(releasesGraphicPanel, imageDimension, filename, imageFormat); - } - catch (IOException ex) - { - LOGGER.log(Level.SEVERE, "Unable to save to file " + filename, ex); - } - }); - } - catch (InterruptedException ex) - { - LOGGER.log(Level.SEVERE, "Event thread was interrupted", ex); - } - catch (InvocationTargetException ex) - { - LOGGER.log(Level.SEVERE, "An uncaught exception occurred on the Event Thread for generateReleasesStatusImage.", ex); - } - } - - private void renderGraphic(JComponent comp) - { - layoutComponent(comp, comp.getSize()); - BufferedImage img = new BufferedImage(comp.getWidth(), comp.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D g = img.createGraphics(); - comp.print(g); - computePreferredSize(comp, comp.getWidth(), comp.getHeight()); - } - - private void layoutComponent(JComponent component, Dimension d) - { - LayoutManager layout = component.getLayout(); - if (layout != null) - { - layout.layoutContainer(component); - } - component.setSize(d); - component.addNotify(); - component.invalidate(); - component.validate(); - component.addNotify(); - if (layout != null) - { - layout.layoutContainer(component); - } - } - - public static class MyReleasesGraphicData extends ReleasesGraphicData - { - private boolean _hasRetrieved = false; - - public MyReleasesGraphicData(Location loc, ManagerId manId, - TimeInfoSource tis, - ReleasesGraphicOptionData options, - OptionalParams optionalParams) - { - super(loc, manId, tis, options, optionalParams); - } - - @Override - public CompletableFuture updateDataScope(OptionalParams params) - { - if (!_hasRetrieved) - { - LOGGER.log(Level.FINE, "(Headless)Updating data scope"); - _hasRetrieved = true; - return super.updateDataScope(params); - } - return CompletableFuture.completedFuture(null); - } - - public void updateDataScopeSynchronous(OptionalParams params) throws InterruptedException, ExecutionException - { - updateDataScope(params).get(); - } - - @Override - public void fireDataUpdateEvent() - { - //Exposing this publicly - super.fireDataUpdateEvent(); //To change body of generated methods, choose Tools | Templates. - } - } - - public TimeInfo getUtcTimeInfo(Date current, TimeZone displayTimeZone) - { - // The time controls internally use HecTimes with utc values and Regi formats them to the display timezone in the ui - // components. - // In headless the user is giving us a Date object and a timezone that date object is in. - // So imagine the user wants a graphic displayed at midnight on 4/18 in CDT. Say that UTC is ahead of CDT by 5 hours - // so we need hectime to actually store the time at 5AM - HecTime utcStart = new HecTime(); - utcStart.setTimeInMillis(current.getTime()); - - Calendar endCal = Calendar.getInstance(displayTimeZone); - endCal.setTime(current); - endCal.add(Calendar.DAY_OF_MONTH, 1); - //truncate down to start of day // - HecTime utcEnd = new HecTime(); - utcEnd.setTimeInMillis(endCal.getTimeInMillis()); - - HecTime utcCurrent = new HecTime(); - utcCurrent.setTimeInMillis(current.getTime()); - - utcCurrent.showTimeAsBeginningOfDay(true); - - int stepSize = 1000 * 60 * 60; // millisPerHour - TimeInfo ti = new TimeInfo(utcStart, utcEnd, utcCurrent, stepSize); - return ti; - } - - private List getMapTemplates() throws DbIoException, DbConnectionException - { - RegiDomain currentProject = (RegiDomain) RegiDomain.getCurrentProject(); - final AtMapTemplateManager tm = currentProject.getAtMapTemplateManager(getManagerId()); - final List mapTemplates = tm.retrieveMapTemplates(currentProject.getUserOfficeId(), - CacheUsage.NORMAL); - return mapTemplates; - } - - private MapTemplateLayer getMapTemplateLayer(String templateName) throws DbIoException, DbConnectionException - { - //Map template layer will require this if we have an annotation layer. - BasinTreeSelectionData selectionData = BasinTreeSelectionService.getBasinTreeSelectionData(getManagerIdProvider().getManagerId()); - if (selectionData != _selectionData) - { - //_selectionData needs to be a class member, because both key and value are weak references. - BasinTreeSelectionService.registerBasinTreeSelectionData(getManagerIdProvider().getManagerId(), _selectionData); - } - - MapTemplateLayer retval = null; - List mapTemplates = getMapTemplates(); - IMapTemplate matching = find(templateName, mapTemplates); - - if (matching != null) - { - retval = new MapTemplateLayer(matching, getManagerIdProvider()); - } - - return retval; - } - - private IMapTemplate find(String templateName, - List mapTemplates) - { - IMapTemplate retval = null; - - if (mapTemplates != null && !mapTemplates.isEmpty() && templateName != null) - { - for (IMapTemplate mapTemplate : mapTemplates) - { - if (templateName.equalsIgnoreCase(mapTemplate.getName())) - { - retval = mapTemplate; - break; - } - } - } - - return retval; - } - - public void generateBasinPieImageForGroup(final String officeId, - final String locationStr, - final String groupId, - final Date date, final int width, - final int height, final String template, - final String file) throws Exception - { - String[] locations = new String[] {locationStr}; - Date[] dates = new Date[] {date}; - String[] templates = new String[]{template}; - generateBasinPieImagesForGroup(officeId, locations, groupId, dates, width, - height, templates, file); - } - - public void generateBasinPieImageForBasin(final String officeId, - final String locationStr, - final String basinId, - final Date date, final int width, - final int height, final String template, - final String file) throws Exception - { - String[] locations = new String[] {locationStr}; - Date[] dates = new Date[] {date}; - String[] templates = new String[]{template}; - generateBasinPieImagesForBasin(officeId, locations, basinId, dates, width, - height, templates, file); - } - -/** - * This method generates a suite a basin pie images for a given basin - * 1 basin pie image for each possible assigned location as a reference. - * - * @param officeId - * @param basinId - * @param dates - * @param width - * @param height - * @param templateIds - * @param file - * @throws Exception - */ - public void generateAllBasinPieImagesForBasin(final String officeId, - final String basinId, - final Date[] dates, - final int width, final int height, - final String[] templateIds, - final String file) throws Exception - { - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveLocationGroupForBasin(basinId); - - OperationSupportBasinTreeModel basinTreeModel = new OperationSupportBasinTreeModel(); - IBasinConnectivityModel basinConnModel = locationGroupFactory.getBasinConnectivityModel(); - basinTreeModel.fillBasinTree(locationGroup, basinConnModel); - - generateAllBasinPieImages(officeId, locationGroup, basinTreeModel, dates, width, height, templateIds, file); - } - - /** - * This method generates a suite a basin pie images for a given basin - * 1 basin pie image for each possible assigned location as a reference. - * - * @param officeId - * @param groupId - * @param dates - * @param width - * @param height - * @param templateIds - * @param file - * @throws Exception - */ - public void generateAllBasinPieImagesForGroup(final String officeId, - final String groupId, - final Date[] dates, - final int width, final int height, - final String[] templateIds, - final String file) throws Exception - { - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveProjectGroup(groupId); - - BasinTreeModel basinTreeModel = new BasinTreeModel(null); - basinTreeModel.fillBasinTree(locationGroup); - - generateAllBasinPieImages(officeId, locationGroup, basinTreeModel, dates, width, height, templateIds, file); - } - - private void generateAllBasinPieImages(final String officeId, - final LocationGroup locationGroup, - final BasinTreeModel basinTreeModel, - final Date[] dates, - final int width, final int height, - final String[] templateIds, - final String file) throws Exception - { - List referenceLocations = new ArrayList<>(); - - Set assignedLocations = locationGroup.getAssignedLocations(); - for (AssignedLocation assignedLocation : assignedLocations) - { - referenceLocations.add(assignedLocation.getLocRef()); - } - - List templates = getTemplates(templateIds, officeId); - final Dimension d = new Dimension(width, height); - String imageFormat = getFormatFromFile(file); - - generateImages(officeId, referenceLocations, locationGroup, basinTreeModel, dates, d, templates, file, imageFormat); - } - - public void generateBasinPieImagesForBasin(final String officeId, - final String locationStrs[], - final String basinId, - final Date[] dates, final int width, - final int height, - final String[] templateIds, - final String filename) throws Exception - { - System.setProperty("java.awt.headless", "true"); - if (width <= 0 || height <= 0) - { // is there a max? - LOGGER.warning("Width and Height parameters must be > 0"); - return; - } - - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveLocationGroupForBasin(basinId); - - OperationSupportBasinTreeModel basinTreeModel = new OperationSupportBasinTreeModel(); - IBasinConnectivityModel basinConnModel = locationGroupFactory.getBasinConnectivityModel(); - basinTreeModel.fillBasinTree(locationGroup, basinConnModel); - - List templates = getTemplates(templateIds, officeId); - - List locs = new ArrayList<>(); - for (String locationStr : locationStrs) - { - final LocationTemplate locRef = new LocationTemplate(officeId, locationStr); - locs.add(locRef); - } - - String imageFormat = getFormatFromFile(filename); - final Dimension dimension = new Dimension(width, height); - - generateImages(officeId, locs, locationGroup, basinTreeModel, dates, dimension, templates, filename, imageFormat); - } - - public void generateBasinPieImagesForGroup(final String officeId, - final String locationStrs[], - final String groupId, - final Date[] dates, final int width, - final int height, - final String[] templateIds, - final String filename) throws Exception - { - System.setProperty("java.awt.headless", "true"); - if (width <= 0 || height <= 0) - { // is there a max? - LOGGER.warning("Width and Height parameters must be > 0"); - return; - } - - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveProjectGroup(groupId); - BasinTreeModel treeModel = new BasinTreeModel(); - treeModel.fillBasinTree(locationGroup); - - List templates = getTemplates(templateIds, officeId); - - List locs = new ArrayList<>(); - for (String locationStr : locationStrs) - { - final LocationTemplate locRef = new LocationTemplate(officeId, locationStr); - locs.add(locRef); - } - - String imageFormat = getFormatFromFile(filename); - final Dimension dimension = new Dimension(width, height); - - generateImages(officeId, locs, locationGroup, treeModel, dates, dimension, templates, filename, imageFormat); - } - - public void generateImages(String officeId, - List referenceLocations, - LocationGroup locationGroup, - BasinTreeModel treeModel, - Date[] dates, - Dimension d, - List templates, - String filePattern, String imageFormat) - throws ExecutionException, DbConnectionException, InterruptedException - { - SortedSet dateSet = new TreeSet<>(); - dateSet.addAll(Arrays.asList(dates)); - - Date startDate = dateSet.first(); - Date endDate = dateSet.last(); - - for (IChartTemplate chartTemplate : templates) - { - LOGGER.log(Level.INFO, "Generating images for template:{0}", chartTemplate.getId()); - BasinPieModel pieModel = buildAndInitializeBasinPieModel(locationGroup, chartTemplate, startDate, endDate, treeModel); - - for (Date date : dateSet) - { - for (LocationTemplate locRef : referenceLocations) - { - String file = getFileName(date, filePattern, locRef.getLocationId(), imageFormat, chartTemplate.getIdSuffix(), officeId, locationGroup.getName(), d.width, d.height); - drawImage(treeModel, locRef, pieModel, d, date, file, imageFormat); - } - } - } - } - - public List getTemplates(final String[] templateIds, - final String officeId) throws DbConnectionException, DbIoException - { - List templates = new ArrayList<>(); - AtChartTemplateManager chartTemplateManager = regiDomain.getAtChartTemplateManager(managerId); - for (String template : templateIds) - { - String templateId = IChartTemplate.CHART_TEMPLATE_CATEGORY_ID + "." + officeId + "." + template; - - IChartTemplate chartTemplate = chartTemplateManager.retrieveChartTemplate(officeId, templateId, CacheUsage.NORMAL); - if (chartTemplate == null) - { - // try again using the user-provided string. - chartTemplate = chartTemplateManager.retrieveChartTemplate(officeId, template, CacheUsage.NORMAL); - } - - if (chartTemplate == null) - { - LOGGER.log(Level.WARNING, "Could not locate chart:{0}", templateId); - } - else - { - templates.add(chartTemplate); - } - - } - return templates; - } - - public static String getFileName(Date date, final String filePattern, - final String locationStr, - String imageFormat, String chartTemplate, - String officeId, String basinId, int width, - int height) - { - - String dateStr = getDateString(date); - - SimpleTemplateEngine engine = new SimpleTemplateEngine(); - engine.addPattern("date", dateStr); - engine.addPattern("office_id", officeId); - engine.addPattern("location_id", locationStr); - engine.addPattern("chart_template_id", chartTemplate); - engine.addPattern("basin_id", basinId); - engine.addPattern("image_format", imageFormat); - engine.addPattern("width", Integer.toString(width)); - engine.addPattern("height", Integer.toString(height)); - - String filename = engine.makeReplacements(filePattern); -// Replace anything that isn't a-z or A-z or 0-9 or [:\/)(.-] with an underscore. - return filename.replaceAll("[^a-zA-Z0-9:\\\\\\/\\)\\(\\.\\- ]", "_"); - } - - public static String getDateString(Date date) - { - Instant asInstant = date.toInstant(); - String dateStr = asInstant.toString(); // like: 2017-02-24T22:23:21.149Z - dateStr = dateStr.replaceAll(":", "_"); - return dateStr; - } - - public void drawImage(BasinTreeModel treeModel, - LocationTemplate locRef, - BasinPieModel pieModel, Dimension d, - Date date, String file, - String imageFormat) throws InterruptedException, ExecutionException - { - - final CountDownLatch latch = new CountDownLatch(1); - final SwingWorker worker = new SwingWorker() - { - @Override - protected Void doInBackground() throws Exception - { - List relavantLocations = treeModel.getRelevantLocations(locRef); - LOGGER.log(Level.INFO, "Found {0} locations relevant to {1}", new Object[] - { - relavantLocations.size(), locRef - }); - pieModel.setActiveLocations(relavantLocations, true); - - return null; - } - - @Override - protected void done() - { - try - { - LOGGER.log(Level.INFO, "Creating Basin Pie Panel."); - writeBasinImage(d, pieModel, date, file, imageFormat); - latch.countDown(); - } - catch (IOException ex) - { - LOGGER.log(Level.SEVERE, null, ex); - } - } - }; - - worker.execute(); - - Void got = worker.get(); // This returns as soon as doInBackground finishes. - boolean normalExit = latch.await(Integer.getInteger(LATCH_SECONDS, 11 * 60), TimeUnit.SECONDS); - if (!normalExit) - { - LOGGER.log(Level.WARNING, "Exceeded timeout waiting for basin image to draw."); - } - - } - - public BasinPieModel buildAndInitializeBasinPieModel( - LocationGroup locationGroup, IChartTemplate chartTemplate, - Date startDate, Date endDate, - BasinTreeModel treeModel) throws InterruptedException - { - BasinPieModel pieModel = new BasinPieModel(managerId, locationGroup, chartTemplate, startDate, endDate); - CountDownLatch initlatch = new CountDownLatch(1); - pieModel.addPropertyChangeListener((PropertyChangeEvent evt) -> - { - if ("PieDataChangedProperty".equals(evt.getPropertyName())) - { - LOGGER.log(Level.FINER, "PieDataChanged edt:{0} latch:{1}", - new Object[] - { - SwingUtilities.isEventDispatchThread(), initlatch.getCount() - }); - initlatch.countDown(); - } - }); - List forInitCache = treeModel.getRelevantLocations(null); - LOGGER.log(Level.INFO, "Initializing BasinPieModel with {0} locations.", forInitCache.size()); - pieModel.initCache(forInitCache); // this can take a while but it fires a property change event when its done. - - boolean normalExit = initlatch.await(Integer.getInteger(LATCH_SECONDS, 11 * 60), TimeUnit.SECONDS); - if (!normalExit) - { - LOGGER.log(Level.WARNING, "Exceeded timeout waiting for basin pie model to load."); - } - - return pieModel; - } - - private void writeBasinImage(Dimension d, BasinPieModel pieModel, - Date date, String file, String imageFormat) throws FileNotFoundException, IOException - { - LocationGroup locationGroup = pieModel.getLocationGroup(); - PiePanel piePanel = new PiePanel(); - IChartTemplate chartTemplate = pieModel.getChartTemplate(); - List dataIdentifiers = chartTemplate.getDataIdentifiers(); - Set poolIds = new HashSet<>(); - poolIds.addAll(dataIdentifiers); - - TimeZone timezone = regiDomain.getTimeZone(); - piePanel.setTimeZone(timezone); - - JLayer piePanelJLayerWrapper = new JLayer(piePanel); - HeadlessBasinPieAnnotationLayer basinPieAnnotationLayer = new HeadlessBasinPieAnnotationLayer(getManagerIdProvider(), locationGroup, pieModel.getActiveLocations()); - basinPieAnnotationLayer.fillPanel(poolIds, date, chartTemplate); - - PinnableComponentGlassPane glassPane = PinnableComponentGlassPaneFactory.createNewGlassPane(basinPieAnnotationLayer, piePanel); - - piePanelJLayerWrapper.setGlassPane(glassPane); - glassPane.addPinnableContainer(basinPieAnnotationLayer); - PinnableContainer container = glassPane.getPinnableContainer(basinPieAnnotationLayer); - basinPieAnnotationLayer.setPinnableContainer(container); - container.setSize(d); - - List> futures = basinPieAnnotationLayer.resetFromChartTemplate(); - futures.stream().map((future) -> - { - if (future instanceof FutureDescriptor) - { - return ((FutureDescriptor) future).getFuture(); - } - return future; - }).forEach((future)-> - { - try - { - future.get(); - } - catch (InterruptedException | ExecutionException ex) - { - LOGGER.log(Level.INFO, "Well that didn't work...", ex); - } - }); - - PinnableComponentGlassPaneFactory.getGlassPane(basinPieAnnotationLayer).setVisible(true); - - LOGGER.fine("Filling panel with model."); - piePanel.fillPanel(pieModel); - LOGGER.log(Level.INFO, "Setting active date:{0}", date); - piePanel.setActiveDate(date); - - //This updates the data of bar charts. This has to happen after we've loaded the data. Otherwise it doesn't - //Load the bar chart correctly. - basinPieAnnotationLayer.updateBarChartGraphics(); - - layoutAndSave(piePanelJLayerWrapper, d, file, imageFormat); - } - - /** - * Saves a copy of the plot as a image type - * - * @param os the output stream to write to. - * @param panel - * @param imageType i.e. "png" or "jpg". - * @param compression sets the compression for the image if the image writer - * supports it - * @return - * @throws java.io.IOException - */ - protected boolean saveToStream(OutputStream os, final JComponent panel, - String imageType, float compression) throws IOException - { - // This next comment came from the source this was loosely based on. - /** - * Add a revalidate here in order for headless scripting to work. Due to - * a joining of the building and displaying of the plot in showPlot(), - * any component changes to recompute preferred sizes and exports look - * bad and components overlap. If we do this here, then we can build and - * show the plot, tweak some properties and export correctly. - */ - - BufferedImage bImage; - - if (SwingUtilities.isEventDispatchThread()) - { - bImage = saveToImage(panel.getSize(), panel); - } - else - { - Callable imageCallable = () -> saveToImage(panel.getSize(), panel); - FutureTask futureTask = new FutureTask<>(imageCallable); - - SwingUtilities.invokeLater(futureTask); - try - { - // Not sure how long to wait here. Infinite is wrong. - bImage = futureTask.get(5, TimeUnit.MINUTES); - } - catch (InterruptedException ex) - { - Thread.currentThread().interrupt(); - throw new IOException("Background paint was interrupted.", ex); - } - catch (ExecutionException ex) - { - throw new IOException("Background paint encountered ExecutionException.", ex); - } - catch (TimeoutException ex) - { - throw new IOException("Timeout waiting for paint to complete.", ex); - } - } - return writeImage(imageType, compression, os, bImage); - } - - public boolean writeImage(String imageType, float compression, - OutputStream os, BufferedImage bImage) - { - Iterator iter = javax.imageio.ImageIO.getImageWritersByFormatName(imageType); - if (!iter.hasNext()) - { - LOGGER.log(Level.WARNING, "No Image writers exist for Image Type = {0}", imageType); - return true; - } - ImageWriter next = iter.next(); - ImageWriteParam defaultWriteParam = next.getDefaultWriteParam(); - if (defaultWriteParam.canWriteCompressed() && compression != hec.lang.Const.UNDEFINED_INT) - { - defaultWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); - defaultWriteParam.setCompressionQuality(compression / 100); - } - writeToStream(next, os, bImage, defaultWriteParam); - return false; - } - - public static BufferedImage saveToImage(Dimension d, JComponent panel) - { - - BufferedImage bImage = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_RGB); - paintIntoImage(bImage, d, panel); - - return bImage; - } - - private static void paintIntoImage(BufferedImage bImage, Dimension d, - JComponent panel) - { - Graphics2D g = bImage.createGraphics(); - - boolean useTrans = false; - - if (!useTrans) - { - Color color = new Color(226, 226, 226); // make backgroup grey - g.setColor(color); - g.fillRect(0, 0, d.width, d.height); - } - else - { - // This doesn't work. - Color color = new Color(0, 0, 0, 0); - g.setColor(color); - g.setComposite(AlphaComposite.Clear); - g.fillRect(0, 0, d.width, d.height); - g.setComposite(AlphaComposite.SrcOver); - } - - panel.paint(g); - g.dispose(); - } - - public static void writeToStream(ImageWriter writer, OutputStream fs, - BufferedImage bImage, - ImageWriteParam defaultWriteParam) - { - try - { - writer.setOutput(javax.imageio.ImageIO.createImageOutputStream(fs)); - writer.write(null, new IIOImage(bImage, null, null), defaultWriteParam); - } - catch (IOException e) - { - LOGGER.log(Level.SEVERE, "Exception encountered writing image.", e); - } - finally - { - writer.dispose(); - try - { - if (fs != null) - { - fs.flush(); - fs.close(); - } - } - catch (IOException ioe) - { - LOGGER.log(Level.SEVERE, "IOException encountered while closing OutputStream.", ioe); - } - } - } - - protected String getFormatFromFile(String file) - { - String format = "png"; - - if (file != null && !file.isEmpty()) - { - String asLower = file.toLowerCase(); - - if (asLower.endsWith(".jpg") || asLower.endsWith(".jpeg")) - { - return "jpg"; - } - - } - - return format; - } - - public void layoutAndSave(final JComponent component, final Dimension d, - String file, String imageFormat) throws IOException - { - if (SwingUtilities.isEventDispatchThread()) - { - layoutComponent(component, d); - } - else - { - Callable imageCallable = () -> - { - layoutComponent(component, d); - return Boolean.TRUE; - }; - FutureTask futureTask = new FutureTask<>(imageCallable); - - SwingUtilities.invokeLater(futureTask); - try - { - // Not sure how long to wait here. Infinite is wrong. - Boolean dontcare = futureTask.get(1, TimeUnit.MINUTES); - } - catch (InterruptedException ex) - { - Thread.currentThread().interrupt(); - throw new IOException("Background layout was interrupted.", ex); - } - catch (ExecutionException ex) - { - throw new IOException("Background layout encountered ExecutionException.", ex); - } - catch (TimeoutException ex) - { - throw new IOException("Timeout waiting for layout to complete.", ex); - } - } - - File f = new File(file); - f.getParentFile().mkdirs(); - - try (FileOutputStream fos = new FileOutputStream(f); - BufferedOutputStream bos = new BufferedOutputStream(fos);) - { - LOGGER.info("Writing to output stream"); - saveToStream(bos, component, imageFormat, 100.0f); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java deleted file mode 100644 index 116c062..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java +++ /dev/null @@ -1,54 +0,0 @@ -package usace.rowcps.headless.calculator.status; - -import java.util.HashMap; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Very simple templating system which replaces %keyword% with supplied values. - * Supported patterns look like: "J:\\temp\\headless\\%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - * @author ryan - */ -public class SimpleTemplateEngine { - private static final Logger logger = Logger.getLogger(SimpleTemplateEngine.class.getName()); - - protected HashMap replacements = new HashMap<>(); - public SimpleTemplateEngine() { - } - - static Pattern pattern = Pattern.compile("%\\w+%"); // This defines the %word% pattern we will look for. - - public void addPattern( String pattern, String value){ - if(pattern.contains("%")){ - logger.warning("Supplied pattern contained '%' character, this is unlikely to work correctly."); - } - replacements.put("%" + pattern + "%", value); - } - - public String makeReplacements(String text ){ - return makeReplacements(text, replacements); - } - - public static String makeReplacements(String text, HashMap replacements) { - Matcher matcher = pattern.matcher(text); - - StringBuffer buffer = new StringBuffer(); - - while (matcher.find()) { - String found = matcher.group(); - String replacement = replacements.get(found); - if (replacement != null) { - matcher.appendReplacement(buffer, ""); - buffer.append(replacement); - } else { - logger.info("Unrecognized replacement pattern:" + found + ". " - + " Recognized replacement patterns are:" + replacements.keySet()); - } - } - matcher.appendTail(buffer); - - return buffer.toString(); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java deleted file mode 100644 index 3865b69..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package usace.rowcps.headless.calculator.status; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author ryan - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class StatusCalcFactory implements ScriptableCalcFactory -{ - - @Override - public String getName() - { - return "Status"; - } - - @Override - public String getDescription() - { - return "Generates Status Graphic images"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableStatusGraphicImpl(regiDomain, managerid); - } - -} \ No newline at end of file diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java deleted file mode 100644 index a7b8444..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.exportdb; - -import usace.rowcps.headless.sigstages.importdb.*; -import usace.rowcps.headless.sigstages.retrieve.*; -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class ExportSigStagesCalcFactory implements ScriptableCalcFactory -{ - public ExportSigStagesCalcFactory() - { - } - - @Override - public String getName() - { - return "Export Sig States"; - } - - @Override - public String getDescription() - { - return "Reads the database and writes a text file that is used to retrieve NWS Gage info"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableExportSigStagesImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java deleted file mode 100644 index 1596d41..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -/* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. -*/ -package usace.rowcps.headless.sigstages.exportdb; - -import hec.data.location.AssignedLocation; -import hec.data.location.LocationGroup; -import hec.data.location.LocationGroupRef; -import hec.data.location.LocationTemplate; -import hec.data.meta.Catalog; -import hec.data.meta.LocationCatalogQuery; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.AgencyAlias; -import usace.rowcps.regi.model.AtLocationGroupManager; -import usace.rowcps.regi.model.AtLocationManager; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.model.ManagerId; - -/** - * - * @author stephen - */ -public class ScriptableExportSigStagesImpl implements ScriptableExportSigstages, ScriptableCalc -{ - private RegiDomain _regiDomain; - private ManagerId _managerId; - private String _office; - - public static final String DELIMETER = System.getProperty("sigstages.delim", ";"); - public static final String CSVDELIMETER = System.getProperty("sigstages.csv.delim", "\n"); - public static final String CSVSEPARATOR = System.getProperty("sigstages.csv.separator", ","); - - public ScriptableExportSigStagesImpl(RegiDomain regiDomain, ManagerId managerId) - { - _regiDomain = regiDomain; - _managerId = managerId; - _office = "SWF"; - } - - @Override - public boolean exportSigStages(String file) - { - Path toPath = Paths.get(file); - - AtLocationManager atLocManager = _regiDomain.getAtLocationManager(_managerId); - - try (BufferedWriter writer = new BufferedWriter(new FileWriter(toPath.toFile()))) - { - Map usedIds = new HashMap<>(); - AtLocationGroupManager lgm = _regiDomain.getAtLocationGroupManager(_managerId); - LocationGroupRef lgr = AgencyAlias.Agency.NWS_HANDBOOK_5_ID.getLocationGroupRef(_regiDomain); - LocationGroup usgsAliases = lgm.retrieveLocationGroup(lgr, CacheUsage.NORMAL); - for(AssignedLocation al : usgsAliases.getAssignedLocationsSorted()) - { - String aliasId = al.getAliasId(); - LocationTemplate location = al.getLocRef(); - usedIds.put(location, aliasId); - } - - Catalog catalog = atLocManager.retrieveLocationCatalog(CacheUsage.NORMAL); - for(int i=0; i < catalog.size(); i++) - { - List rowList = catalog.getRow(i); - LocationTemplate locationTemplate = LocationCatalogQuery.convertToLocationTemplate(rowList); - if(locationTemplate != null) - { - String locationId = locationTemplate.getLocationId(); - String aliasId = usedIds.get(locationTemplate); - if(Objects.equals(aliasId, locationId) || aliasId == null || "".equals(aliasId)) - { - writer.write(locationId); - } - else - { - writer.write(locationId + DELIMETER + aliasId); - } - writer.write("\n"); - } - } - } - catch (DbConnectionException|DbIoException|IOException ex) - { - Logger.getLogger(ScriptableExportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - return false; - } - return true; - } - - @Override - public void setOffice(String office) - { - _office = office; - } - - @Override - public String getOffice() - { - return _office; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java deleted file mode 100644 index dec7ac5..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.exportdb; - -import usace.rowcps.headless.sigstages.importdb.*; -import usace.rowcps.headless.sigstages.retrieve.*; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstage; - -/** - * - * @author stephen - */ -public interface ScriptableExportSigstages -{ - public boolean exportSigStages(String toFile); - public void setOffice(String office); - public String getOffice(); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java deleted file mode 100644 index 72037de..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.importdb; - -import usace.rowcps.headless.sigstages.retrieve.*; -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class ImportSigStagesCalcFactory implements ScriptableCalcFactory -{ - public ImportSigStagesCalcFactory() - { - } - - @Override - public String getName() - { - return "Import Sig States"; - } - - @Override - public String getDescription() - { - return "Reads a CSV File and then import that data into the database."; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableImportSigStagesImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java deleted file mode 100644 index 14ae0d6..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java +++ /dev/null @@ -1,95 +0,0 @@ -/* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. -*/ -package usace.rowcps.headless.sigstages.importdb; - -import hec.data.level.ILocationLevel; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Date; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.level.importer.CSVLocationLevelImportUtil; -import usace.rowcps.regi.model.AtLocationLevelManager; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.model.ManagerId; - -/** - * - * @author stephen - */ -public class ScriptableImportSigStagesImpl implements ScriptableImportSigstages, ScriptableCalc -{ - private RegiDomain _regiDomain; - private ManagerId _managerId; - - public static final String DELIMETER = System.getProperty("sigstages.delim", ";"); - public static final String CSVDELIMETER = System.getProperty("sigstages.csv.delim", "\n"); - public static final String CSVSEPARATOR = System.getProperty("sigstages.csv.separator", ","); - - public ScriptableImportSigStagesImpl(RegiDomain regiDomain, ManagerId managerId) - { - _regiDomain = regiDomain; - _managerId = managerId; - } - - @Override - public boolean importSigStages(String file, Date effectiveDate) - { - boolean retval = true; - AtLocationLevelManager atLocLevelMgr = _regiDomain.getAtLocationLevelManager(_managerId); - Connection c = null; - try { - Path p = Paths.get(file); - c = atLocLevelMgr.getPooledConnection(); - CSVLocationLevelImportUtil importUtil = new CSVLocationLevelImportUtil(); - importUtil.setPath(p); - importUtil.readFile(true); - List locationLevels = importUtil.getLocationLevelList(); - for(int locationLevelIndex = 0; locationLevelIndex < locationLevels.size(); locationLevelIndex++) - { - ILocationLevel level = locationLevels.get(locationLevelIndex); - try { - level.setDate(effectiveDate); - atLocLevelMgr.addLocationLevel(level); - } catch (DbConnectionException | DbIoException ex) { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - retval = false; - break; - } - } - - if(retval) - { - try { - atLocLevelMgr.commitData(); - } catch (DbConnectionException | DbIoException ex) { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - retval = false; - } - } - } catch (DbConnectionException ex) { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - finally - { - try - { - if(c != null && !c.isClosed()) c.close(); - } - catch (SQLException ex) - { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - return retval; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java deleted file mode 100644 index 0883a58..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.importdb; - -import java.util.Date; - -/** - * - * @author stephen - */ -public interface ScriptableImportSigstages -{ - public boolean importSigStages(String file, Date effectiveDate); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java deleted file mode 100644 index 063dd7e..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class RetrieveSigStagesCalcFactory implements ScriptableCalcFactory -{ - public RetrieveSigStagesCalcFactory() - { - } - - @Override - public String getName() - { - return "Retrieve Sig States"; - } - - @Override - public String getDescription() - { - return "Reads a newline delimited file containing NWS Names, then writes the sigstages to a CSV"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new RetrieveSigStagesImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java deleted file mode 100644 index 6a609e5..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java +++ /dev/null @@ -1,488 +0,0 @@ -/* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. -*/ -package usace.rowcps.headless.sigstages.retrieve; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; -import usace.metrics.services.Metrics; -import usace.metrics.services.Timer; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Action; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Bankfull; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Flood; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Low; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Major; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Moderate; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstage; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstages; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Site; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -public class RetrieveSigStagesImpl implements RetrieveSigstages, ScriptableCalc -{ - private RegiDomain _regiDomain; - private ManagerId _managerId; - - private JAXBContext _jaxbContext = null; - - public final static String DOWNLOADURL = System.getProperty("sigstages.downloadurl", "http://water.weather.gov/ahps2/hydrograph_to_xml.php?gage=GAGENAME&output=xml"); - public static final String DELIMETER = System.getProperty("sigstages.delim", ";"); - public static final String CSVDELIMETER = System.getProperty("sigstages.csv.delim", "\n"); - public static final String CSVSEPARATOR = System.getProperty("sigstages.csv.separator", ","); - public static int THREADCOUNT = 2; - - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("ddMMMyyyy HHmm"); - private static final DateFormat ISO_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm"); - - private static final int SHEF_MISSING_VALUE = -9999; - - private String _parameter; - private String _parameterType; - private String _duration; - private Map _specifiedLevelOverride; - private String _office; - private String _csvHeader; - - protected RetrieveSigStagesImpl() - { - super(); - _parameter = "Stage"; - _parameterType = "Inst"; - _duration = "0"; - _specifiedLevelOverride = new HashMap<>(); - _office = "SWF"; - _csvHeader = "Office,Location Level,Effective Date,Constant Level,Unit,Seasonal Value,Interpolate,Calendar Interval,Time Interval,Origin Date,Calendar Offset,TSID\n"; - String threadCount = System.getProperty("sigstages.threadcount", Runtime.getRuntime().availableProcessors()+"").trim(); - if(threadCount.matches("^[\\d]+$")) - { - THREADCOUNT = Integer.parseInt(threadCount); - } - } - - public void setCSVHeader(String csvHeader) - { - //TODO: Be sure this actually is a valid header - _csvHeader = csvHeader; - } - - public String getCSVHeader() - { - return _csvHeader; - } - - public RetrieveSigStagesImpl(RegiDomain regiDomain, ManagerId managerId) - { - this(); - _regiDomain = regiDomain; - _managerId = managerId; - } - - @Override - public void retrieveSigstages(String sourceFile, String outputFile, int milliDelay) - { - Path inputPath = Paths.get(sourceFile); - Path outputPath = Paths.get(outputFile); - retrieveSigstages(inputPath, outputPath, milliDelay); - } - - public void retrieveSigstages(Path source, Path outputPath, int milliDelay) - { - SigstageLocation[] locations; - try - { - locations = readLocationFile(source); - fetchSitesThreaded(milliDelay, locations); - locationsToCSV(outputPath, locations); - } - catch (IOException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - - public void locationsToCSV(Path file, SigstageLocation... locations) - { - Metrics metrics = RegiMetricsService.createMetrics("locationsToCSV"); - try(Timer.Context context = metrics.createTimer().start()) - { - - StringBuilder csvBuilder = new StringBuilder(getCSVHeader()); - for(int locationIndex = 0; locationIndex < locations.length; locationIndex++) - { - if(locations[locationIndex] == null) - { - continue; - } - if(locations[locationIndex].getSite() == null) - { - continue; - } - Site site = locations[locationIndex].getSite(); - - if(site.getSigstages() == null) - { - continue; - } - Sigstages sigstages = site.getSigstages(); - - List allStages = new ArrayList<>(); - - if(sigstages.getAction() == null) - { - continue; - } - Action action = sigstages.getAction(); - allStages.add(action); - - Bankfull bankfull = sigstages.getBankfull(); - allStages.add(bankfull); - - Flood flood = sigstages.getFlood(); - allStages.add(flood); - - Low low = sigstages.getLow(); - allStages.add(low); - - Major major = sigstages.getMajor(); - allStages.add(major); - - //Record record = sigstages.getRecord(); - //allStages.add(record); - - Moderate moderate = sigstages.getModerate(); - allStages.add(moderate); - - for(int stageIndex = 0; stageIndex < allStages.size(); stageIndex++) - { - Sigstage stage = allStages.get(stageIndex); - if(stage.getValue() == 0 || stage.getValue() == SHEF_MISSING_VALUE) - { - continue; - } - String dateTime = ""; - if(site.getGenerationtime() != null && !site.getGenerationtime().isEmpty()) - { - Date generationDateTime = null; - - try { - generationDateTime = ISO_FORMAT.parse(site.getGenerationtime()); - } - catch (ParseException ex) { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - - dateTime = DATE_FORMAT.format(generationDateTime); - } - csvBuilder.append(_office); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(stage.getType().generateID(locations[locationIndex].getOriginal(), _parameter, _parameterType, _duration, getSpecifiedLevelOverride(stage.getType()))); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(dateTime); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(stage.getValue()); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(stage.getUnits()); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVDELIMETER); - } - } - - try (BufferedWriter writer = new BufferedWriter(new FileWriter(file.toFile()))) - { - writer.write(csvBuilder.toString()); - } - catch (IOException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - -// public void fetchSites(Location... locationNames) -// { -// for(int locationNamesIndex = 0; locationNamesIndex < locationNames.length; locationNamesIndex++) -// { -// String fullURL = DOWNLOADURL.replace("GAGENAME", locationNames[locationNamesIndex].getNWS()); -// try -// { -// Location loc = locationNames[locationNamesIndex]; -// Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.FINE, null, "Retrieving " + loc); -// loc.setSite(fetchSite(fullURL)); -// Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.FINE, null, "Retrieved " + loc); -// } catch (Exception ex) -// { -// Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); -// } -// } -// } - - public void fetchSitesThreaded(int milliDelay, SigstageLocation... locationNames) - { - Metrics metrics = RegiMetricsService.createMetrics("fetchSitesThreaded"); - try(Timer.Context context = metrics.createTimer().start()) - { - final CountDownLatch cdl = new CountDownLatch(1); - BlockingQueue threadPoolQueue = new LinkedBlockingQueue<>(); - ThreadPoolExecutor threadPool = new ThreadPoolExecutor(THREADCOUNT / 2, THREADCOUNT, 1, TimeUnit.SECONDS, threadPoolQueue){ - @Override - protected void terminated() - { - cdl.countDown(); - } - }; - - for (final SigstageLocation l : locationNames) { - - threadPool.execute(new Runnable(){ - - @Override - public void run() - { - Metrics metrics = RegiMetricsService.createMetrics("fetchSitesThreadedRunnable"); - try(Timer.Context timerContext = metrics.createTimer().start()) - { - String fullURL = DOWNLOADURL.replace("GAGENAME", l.getNWS()); - try { - Site locationSite = fetchSite(fullURL); - l.setSite(locationSite); - - // report the number of locations at this site - int sameSiteLocations = countNumStages(locationSite); - String logString = "retrieved " + sameSiteLocations + " level" - + (sameSiteLocations==1? " ":"s ") + "for " - + l.getNWS(); - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.INFO, logString); - } - catch (Exception ex) - { - Logger logger = Logger.getLogger(RetrieveSigStagesImpl.class.getName()); - logger.isLoggable(Level.SEVERE); - if(logger.isLoggable(Level.FINE)) - { - logger.log(Level.SEVERE, "error retrieving at site " + l.getNWS(), ex); - } - else - { - String logMessage = "error retrieving at site " + l.getNWS() + " " + ex.getMessage(); - logger.log(Level.SEVERE, logMessage); - } - } - } - } - }); - - try - { - cdl.await(milliDelay, TimeUnit.MILLISECONDS); - } - catch (InterruptedException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, "timeout while retrieving site " + l.getNWS(), ex); - } - } - threadPool.shutdown(); - try - { - cdl.await(); - } - catch (InterruptedException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - - public Site fetchSite(String fullURL) throws Exception - { - Metrics metrics = RegiMetricsService.createMetrics("fetchSite"); - try(Timer.Context context = metrics.createTimer().start()) - { - if(_jaxbContext == null) - { - _jaxbContext = JAXBContext.newInstance("usace.rowcps.headless.sigstages.retrieve.xmlmodel"); - } - Unmarshaller unmarshaller = _jaxbContext.createUnmarshaller(); - URL url = new URL(fullURL); - InputStream input = url.openStream(); - Site site = ((Site)unmarshaller.unmarshal(input)); - return site; - } - } - - private static final Pattern VALIDNWS = Pattern.compile("^[A-Za-z]{4}[\\d]$"); - - public SigstageLocation[] readLocationFile(Path source) throws FileNotFoundException, IOException - { - Metrics metrics = RegiMetricsService.createMetrics("readLocationFile"); - try(Timer.Context context = metrics.createTimer().start()) - { - List locations = new ArrayList<>(); - - try (BufferedReader reader = new BufferedReader(new FileReader(source.toFile()))) { - String line; - while((line = reader.readLine()) != null) - { - line = line.trim(); - String[] lineArray = line.split(DELIMETER); - if(lineArray.length == 0) - { - continue; - } - String nws = (lineArray.length > 1) ? lineArray[1] : lineArray[0]; - if(VALIDNWS.matcher(nws).matches()) - { - String original = lineArray[0]; - SigstageLocation location = new SigstageLocation(original, nws); - locations.add(location); - } - } - } - - SigstageLocation[] locationsArray = new SigstageLocation[locations.size()]; - locationsArray = locations.toArray(locationsArray); - return locationsArray; - } - } - - // count all valid locations at a site - private int countNumStages(Site site) - { - int numStages = 0; - - if(site == null) - return numStages; - - Sigstages stages = site.getSigstages(); - - if(stages == null) - return numStages; - - if(stages.getAction() != null && stages.getAction().getValue() != 0 && stages.getAction().getValue() != SHEF_MISSING_VALUE) - numStages++; - else - return numStages; - - if(stages.getBankfull() != null && stages.getBankfull().getValue() != 0 && stages.getBankfull().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getFlood() != null && stages.getFlood().getValue() != 0 && stages.getFlood().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getLow() != null && stages.getLow().getValue() != 0 && stages.getLow().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getMajor() != null && stages.getMajor().getValue() != 0 && stages.getMajor().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getModerate() != null && stages.getModerate().getValue() != 0 && stages.getModerate().getValue() != SHEF_MISSING_VALUE) - numStages++; - - return numStages; - } - - @Override - public void setParameter(String parameter) - { - _parameter = parameter; - } - - @Override - public String getParameter() - { - return _parameter; - } - - @Override - public void setParameterType(String parameterType) - { - _parameterType = parameterType; - } - - @Override - public String getParameterType() - { - return _parameterType; - } - - @Override - public void setDuration(String duration) - { - _duration = duration; - } - - @Override - public String getDuration() - { - return _duration; - } - - @Override - public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText) - { - _specifiedLevelOverride.put(type, overrideText); - } - - @Override - public String getSpecifiedLevelOverride(Sigstage.Type type) - { - String specifiedLevel = _specifiedLevelOverride.get(type); - if(specifiedLevel == null) - { - specifiedLevel = type.toString(); - } - return specifiedLevel; - } - - @Override - public void setOffice(String office) - { - _office = office; - } - - @Override - public String getOffice() - { - return _office; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java deleted file mode 100644 index 1a518a6..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve; - -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstage; - -/** - * - * @author stephen - */ -public interface RetrieveSigstages -{ - public void retrieveSigstages(String sourceFile, String outputFile, int milliDelay); - public void setParameter(String parameter); - public String getParameter(); - public void setParameterType(String parameterType); - public String getParameterType(); - public void setDuration(String duration); - public String getDuration(); - public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText); - public String getSpecifiedLevelOverride(Sigstage.Type type); - public void setOffice(String office); - public String getOffice(); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java deleted file mode 100644 index 98fbeb7..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve; - -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Site; - -/** - * - * @author stephen - */ -public class SigstageLocation -{ - private String _originalLocation; - private String _nwsLocation; - private Site _site; - - public SigstageLocation() - { - super(); - _site = null; - _originalLocation = ""; - _nwsLocation = ""; - } - - public SigstageLocation(String orig, String nws) - { - this(); - _originalLocation = orig; - _nwsLocation = nws; - } - - public String getOriginal() - { - return _originalLocation; - } - - public String getNWS() - { - return _nwsLocation; - } - - public void setOriginal(String original) - { - _originalLocation = original; - } - - public void setNWS(String nws) - { - _nwsLocation = nws; - } - - public Site getSite() - { - return _site; - } - - public void setSite(Site site) - { - _site = site; - } - - @Override - public String toString() - { - return getOriginal() + ";" + getNWS() + " " + getSite().getName(); - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java deleted file mode 100644 index 06c23fc..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "action") -public class Action implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType(){ - return Type.ACTION; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java deleted file mode 100644 index 5e4b4c2..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *       <attribute name="dignity" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "alt_rating") -public class AltRating { - - @XmlElement(required = true) - protected List datum; - @XmlAttribute(name = "dignity", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dignity; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - - /** - * Gets the value of the dignity property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDignity() { - return dignity; - } - - /** - * Sets the value of the dignity property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDignity(String value) { - this.dignity = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java deleted file mode 100644 index 34142cf..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "bankfull") -public class Bankfull implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.BANKFULL; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java deleted file mode 100644 index ad24775..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java +++ /dev/null @@ -1,268 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence minOccurs="0">
- *         <element ref="{}valid"/>
- *         <element ref="{}primary"/>
- *         <element ref="{}secondary"/>
- *         <element ref="{}pedts"/>
- *       </sequence>
- *       <attribute name="flow" type="{http://www.w3.org/2001/XMLSchema}float" />
- *       <attribute name="flowUnits" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="stage" type="{http://www.w3.org/2001/XMLSchema}float" />
- *       <attribute name="stageUnits" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "valid", - "primary", - "secondary", - "pedts" -}) -@XmlRootElement(name = "datum") -public class Datum { - - protected Valid valid; - protected Primary primary; - protected Secondary secondary; - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String pedts; - @XmlAttribute(name = "flow") - protected Float flow; - @XmlAttribute(name = "flowUnits") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String flowUnits; - @XmlAttribute(name = "stage") - protected Float stage; - @XmlAttribute(name = "stageUnits") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String stageUnits; - - /** - * Gets the value of the valid property. - * - * @return - * possible object is - * {@link Valid } - * - */ - public Valid getValid() { - return valid; - } - - /** - * Sets the value of the valid property. - * - * @param value - * allowed object is - * {@link Valid } - * - */ - public void setValid(Valid value) { - this.valid = value; - } - - /** - * Gets the value of the primary property. - * - * @return - * possible object is - * {@link Primary } - * - */ - public Primary getPrimary() { - return primary; - } - - /** - * Sets the value of the primary property. - * - * @param value - * allowed object is - * {@link Primary } - * - */ - public void setPrimary(Primary value) { - this.primary = value; - } - - /** - * Gets the value of the secondary property. - * - * @return - * possible object is - * {@link Secondary } - * - */ - public Secondary getSecondary() { - return secondary; - } - - /** - * Sets the value of the secondary property. - * - * @param value - * allowed object is - * {@link Secondary } - * - */ - public void setSecondary(Secondary value) { - this.secondary = value; - } - - /** - * Gets the value of the pedts property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getPedts() { - return pedts; - } - - /** - * Sets the value of the pedts property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setPedts(String value) { - this.pedts = value; - } - - /** - * Gets the value of the flow property. - * - * @return - * possible object is - * {@link Float } - * - */ - public Float getFlow() { - return flow; - } - - /** - * Sets the value of the flow property. - * - * @param value - * allowed object is - * {@link Float } - * - */ - public void setFlow(Float value) { - this.flow = value; - } - - /** - * Gets the value of the flowUnits property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getFlowUnits() { - return flowUnits; - } - - /** - * Sets the value of the flowUnits property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setFlowUnits(String value) { - this.flowUnits = value; - } - - /** - * Gets the value of the stage property. - * - * @return - * possible object is - * {@link Float } - * - */ - public Float getStage() { - return stage; - } - - /** - * Sets the value of the stage property. - * - * @param value - * allowed object is - * {@link Float } - * - */ - public void setStage(Float value) { - this.stage = value; - } - - /** - * Gets the value of the stageUnits property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStageUnits() { - return stageUnits; - } - - /** - * Sets the value of the stageUnits property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStageUnits(String value) { - this.stageUnits = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java deleted file mode 100644 index d795985..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java +++ /dev/null @@ -1,152 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}AHPSXMLversion"/>
- *         <element ref="{}status"/>
- *         <element ref="{}quality"/>
- *         <element ref="{}standing"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "ahpsxmLversion", - "status", - "quality", - "standing" -}) -@XmlRootElement(name = "disclaimers") -public class Disclaimers { - - @XmlElement(name = "AHPSXMLversion") - protected float ahpsxmLversion; - @XmlElement(required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String status; - @XmlElement(required = true) - protected Quality quality; - @XmlElement(required = true) - protected Standing standing; - - /** - * Gets the value of the ahpsxmLversion property. - * - */ - public float getAHPSXMLversion() { - return ahpsxmLversion; - } - - /** - * Sets the value of the ahpsxmLversion property. - * - */ - public void setAHPSXMLversion(float value) { - this.ahpsxmLversion = value; - } - - /** - * Gets the value of the status property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStatus() { - return status; - } - - /** - * Sets the value of the status property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStatus(String value) { - this.status = value; - } - - /** - * Gets the value of the quality property. - * - * @return - * possible object is - * {@link Quality } - * - */ - public Quality getQuality() { - return quality; - } - - /** - * Sets the value of the quality property. - * - * @param value - * allowed object is - * {@link Quality } - * - */ - public void setQuality(Quality value) { - this.quality = value; - } - - /** - * Gets the value of the standing property. - * - * @return - * possible object is - * {@link Standing } - * - */ - public Standing getStanding() { - return standing; - } - - /** - * Sets the value of the standing property. - * - * @param value - * allowed object is - * {@link Standing } - * - */ - public void setStanding(Standing value) { - this.standing = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java deleted file mode 100644 index da6f6fa..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "flood") -public class Flood implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.FLOOD; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java deleted file mode 100644 index 1690728..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java +++ /dev/null @@ -1,140 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.datatype.XMLGregorianCalendar; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *       <attribute name="issued" use="required" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
- *       <attribute name="timezone" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "forecast") -public class Forecast { - - @XmlElement(required = true) - protected List datum; - @XmlAttribute(name = "issued", required = true) - @XmlSchemaType(name = "dateTime") - protected XMLGregorianCalendar issued; - @XmlAttribute(name = "timezone", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String timezone; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - - /** - * Gets the value of the issued property. - * - * @return - * possible object is - * {@link XMLGregorianCalendar } - * - */ - public XMLGregorianCalendar getIssued() { - return issued; - } - - /** - * Sets the value of the issued property. - * - * @param value - * allowed object is - * {@link XMLGregorianCalendar } - * - */ - public void setIssued(XMLGregorianCalendar value) { - this.issued = value; - } - - /** - * Gets the value of the timezone property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimezone() { - return timezone; - } - - /** - * Sets the value of the timezone property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimezone(String value) { - this.timezone = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java deleted file mode 100644 index 09ca9ff..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "low") -public class Low implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.LOW; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java deleted file mode 100644 index d5deb79..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "major") -public class Major implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.MAJOR; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java deleted file mode 100644 index 4c59bfe..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "moderate") -public class Moderate implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.MODERATE; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java deleted file mode 100644 index 0974e70..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java +++ /dev/null @@ -1,252 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the usace.rowcps.headless.sigstages.xmlmodel package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _Pedts_QNAME = new QName("", "pedts"); - private final static QName _AHPSXMLversion_QNAME = new QName("", "AHPSXMLversion"); - private final static QName _Status_QNAME = new QName("", "status"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: usace.rowcps.headless.sigstages.xmlmodel - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link Datum } - * - */ - public Datum createDatum() { - return new Datum(); - } - - /** - * Create an instance of {@link Valid } - * - */ - public Valid createValid() { - return new Valid(); - } - - /** - * Create an instance of {@link Primary } - * - */ - public Primary createPrimary() { - return new Primary(); - } - - /** - * Create an instance of {@link Secondary } - * - */ - public Secondary createSecondary() { - return new Secondary(); - } - - /** - * Create an instance of {@link Rating } - * - */ - public Rating createRating() { - return new Rating(); - } - - /** - * Create an instance of {@link Sigstages } - * - */ - public Sigstages createSigstages() { - return new Sigstages(); - } - - /** - * Create an instance of {@link Low } - * - */ - public Low createLow() { - return new Low(); - } - - /** - * Create an instance of {@link Action } - * - */ - public Action createAction() { - return new Action(); - } - - /** - * Create an instance of {@link Bankfull } - * - */ - public Bankfull createBankfull() { - return new Bankfull(); - } - - /** - * Create an instance of {@link Flood } - * - */ - public Flood createFlood() { - return new Flood(); - } - - /** - * Create an instance of {@link Moderate } - * - */ - public Moderate createModerate() { - return new Moderate(); - } - - /** - * Create an instance of {@link Major } - * - */ - public Major createMajor() { - return new Major(); - } - - /** - * Create an instance of {@link Record } - * - */ - public Record createRecord() { - return new Record(); - } - - /** - * Create an instance of {@link Observed } - * - */ - public Observed createObserved() { - return new Observed(); - } - - /** - * Create an instance of {@link Disclaimers } - * - */ - public Disclaimers createDisclaimers() { - return new Disclaimers(); - } - - /** - * Create an instance of {@link Quality } - * - */ - public Quality createQuality() { - return new Quality(); - } - - /** - * Create an instance of {@link Standing } - * - */ - public Standing createStanding() { - return new Standing(); - } - - /** - * Create an instance of {@link Zerodatum } - * - */ - public Zerodatum createZerodatum() { - return new Zerodatum(); - } - - /** - * Create an instance of {@link Forecast } - * - */ - public Forecast createForecast() { - return new Forecast(); - } - - /** - * Create an instance of {@link Site } - * - */ - public Site createSite() { - return new Site(); - } - - /** - * Create an instance of {@link Sigflows } - * - */ - public Sigflows createSigflows() { - return new Sigflows(); - } - - /** - * Create an instance of {@link AltRating } - * - */ - public AltRating createAltRating() { - return new AltRating(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "pedts") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - public JAXBElement createPedts(String value) { - return new JAXBElement(_Pedts_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "AHPSXMLversion") - public JAXBElement createAHPSXMLversion(Float value) { - return new JAXBElement(_AHPSXMLversion_QNAME, Float.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "status") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - public JAXBElement createStatus(String value) { - return new JAXBElement(_Status_QNAME, String.class, null, value); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java deleted file mode 100644 index 3ce6f18..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "observed") -public class Observed { - - @XmlElement(required = true) - protected List datum; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java deleted file mode 100644 index 4e6239c..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "primary") -public class Primary { - - @XmlValue - protected float value; - @XmlAttribute(name = "name", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String name; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java deleted file mode 100644 index 90e3341..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="trace" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "quality") -public class Quality { - - @XmlValue - protected String content; - @XmlAttribute(name = "trace", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String trace; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the trace property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTrace() { - return trace; - } - - /** - * Sets the value of the trace property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTrace(String value) { - this.trace = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java deleted file mode 100644 index 0c5c09e..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *       <attribute name="dignity" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "rating") -public class Rating { - - @XmlElement(required = true) - protected List datum; - @XmlAttribute(name = "dignity", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dignity; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - - /** - * Gets the value of the dignity property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDignity() { - return dignity; - } - - /** - * Sets the value of the dignity property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDignity(String value) { - this.dignity = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java deleted file mode 100644 index 2c0e70b..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "record") -public class Record implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.RECORD; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java deleted file mode 100644 index b49c329..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "secondary") -public class Secondary { - - @XmlValue - protected float value; - @XmlAttribute(name = "name", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String name; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java deleted file mode 100644 index ef64c41..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java +++ /dev/null @@ -1,239 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}low"/>
- *         <element ref="{}action"/>
- *         <element ref="{}flood"/>
- *         <element ref="{}bankfull"/>
- *         <element ref="{}moderate"/>
- *         <element ref="{}major"/>
- *         <element ref="{}record"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "low", - "action", - "flood", - "bankfull", - "moderate", - "major", - "record" -}) -@XmlRootElement(name = "sigflows") -public class Sigflows { - - @XmlElement(required = true) - protected Low low; - @XmlElement(required = true) - protected Action action; - @XmlElement(required = true) - protected Flood flood; - @XmlElement(required = true) - protected Bankfull bankfull; - @XmlElement(required = true) - protected Moderate moderate; - @XmlElement(required = true) - protected Major major; - @XmlElement(required = true) - protected Record record; - - /** - * Gets the value of the low property. - * - * @return - * possible object is - * {@link Low } - * - */ - public Low getLow() { - return low; - } - - /** - * Sets the value of the low property. - * - * @param value - * allowed object is - * {@link Low } - * - */ - public void setLow(Low value) { - this.low = value; - } - - /** - * Gets the value of the action property. - * - * @return - * possible object is - * {@link Action } - * - */ - public Action getAction() { - return action; - } - - /** - * Sets the value of the action property. - * - * @param value - * allowed object is - * {@link Action } - * - */ - public void setAction(Action value) { - this.action = value; - } - - /** - * Gets the value of the flood property. - * - * @return - * possible object is - * {@link Flood } - * - */ - public Flood getFlood() { - return flood; - } - - /** - * Sets the value of the flood property. - * - * @param value - * allowed object is - * {@link Flood } - * - */ - public void setFlood(Flood value) { - this.flood = value; - } - - /** - * Gets the value of the bankfull property. - * - * @return - * possible object is - * {@link Bankfull } - * - */ - public Bankfull getBankfull() { - return bankfull; - } - - /** - * Sets the value of the bankfull property. - * - * @param value - * allowed object is - * {@link Bankfull } - * - */ - public void setBankfull(Bankfull value) { - this.bankfull = value; - } - - /** - * Gets the value of the moderate property. - * - * @return - * possible object is - * {@link Moderate } - * - */ - public Moderate getModerate() { - return moderate; - } - - /** - * Sets the value of the moderate property. - * - * @param value - * allowed object is - * {@link Moderate } - * - */ - public void setModerate(Moderate value) { - this.moderate = value; - } - - /** - * Gets the value of the major property. - * - * @return - * possible object is - * {@link Major } - * - */ - public Major getMajor() { - return major; - } - - /** - * Sets the value of the major property. - * - * @param value - * allowed object is - * {@link Major } - * - */ - public void setMajor(Major value) { - this.major = value; - } - - /** - * Gets the value of the record property. - * - * @return - * possible object is - * {@link Record } - * - */ - public Record getRecord() { - return record; - } - - /** - * Sets the value of the record property. - * - * @param value - * allowed object is - * {@link Record } - * - */ - public void setRecord(Record value) { - this.record = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java deleted file mode 100644 index 74f51c2..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -/** - * - * @author stephen - */ -public interface Sigstage -{ - public float getValue(); - public String getUnits(); - - public Type getType(); - - public enum Type - { - ACTION ("Action"), - BANKFULL ("Bankfull"), - FLOOD ("Flood"), - LOW ("Low"), - MAJOR ("Major"), - MODERATE ("Moderate"), - RECORD ("Record"); - - private String _typeName; - - private Type(String s) - { - _typeName = s; - } - - @Override - public String toString() - { - return _typeName; - } - - public String generateID(String location, String parameter, String parameterType, String duration, String specifiedLevel) - { - StringBuilder build = new StringBuilder(); - if(specifiedLevel == null || specifiedLevel.equals("")) - { - specifiedLevel = _typeName; - } - build.append(location); - build.append("."); - build.append(parameter); - build.append("."); - build.append(parameterType); - build.append("."); - build.append(duration); - build.append("."); - build.append(specifiedLevel); - return build.toString(); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java deleted file mode 100644 index 540d49e..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java +++ /dev/null @@ -1,239 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}low"/>
- *         <element ref="{}action"/>
- *         <element ref="{}bankfull"/>
- *         <element ref="{}flood"/>
- *         <element ref="{}moderate"/>
- *         <element ref="{}major"/>
- *         <element ref="{}record"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "low", - "action", - "bankfull", - "flood", - "moderate", - "major", - "record" -}) -@XmlRootElement(name = "sigstages") -public class Sigstages { - - @XmlElement(required = true) - protected Low low = null; - @XmlElement(required = true) - protected Action action = null; - @XmlElement(required = true) - protected Bankfull bankfull = null; - @XmlElement(required = true) - protected Flood flood = null; - @XmlElement(required = true) - protected Moderate moderate = null; - @XmlElement(required = true) - protected Major major = null; - @XmlElement(required = true) - protected Record record = null; - - /** - * Gets the value of the low property. - * - * @return - * possible object is - * {@link Low } - * - */ - public Low getLow() { - return low; - } - - /** - * Sets the value of the low property. - * - * @param value - * allowed object is - * {@link Low } - * - */ - public void setLow(Low value) { - this.low = value; - } - - /** - * Gets the value of the action property. - * - * @return - * possible object is - * {@link Action } - * - */ - public Action getAction() { - return action; - } - - /** - * Sets the value of the action property. - * - * @param value - * allowed object is - * {@link Action } - * - */ - public void setAction(Action value) { - this.action = value; - } - - /** - * Gets the value of the bankfull property. - * - * @return - * possible object is - * {@link Bankfull } - * - */ - public Bankfull getBankfull() { - return bankfull; - } - - /** - * Sets the value of the bankfull property. - * - * @param value - * allowed object is - * {@link Bankfull } - * - */ - public void setBankfull(Bankfull value) { - this.bankfull = value; - } - - /** - * Gets the value of the flood property. - * - * @return - * possible object is - * {@link Flood } - * - */ - public Flood getFlood() { - return flood; - } - - /** - * Sets the value of the flood property. - * - * @param value - * allowed object is - * {@link Flood } - * - */ - public void setFlood(Flood value) { - this.flood = value; - } - - /** - * Gets the value of the moderate property. - * - * @return - * possible object is - * {@link Moderate } - * - */ - public Moderate getModerate() { - return moderate; - } - - /** - * Sets the value of the moderate property. - * - * @param value - * allowed object is - * {@link Moderate } - * - */ - public void setModerate(Moderate value) { - this.moderate = value; - } - - /** - * Gets the value of the major property. - * - * @return - * possible object is - * {@link Major } - * - */ - public Major getMajor() { - return major; - } - - /** - * Sets the value of the major property. - * - * @param value - * allowed object is - * {@link Major } - * - */ - public void setMajor(Major value) { - this.major = value; - } - - /** - * Gets the value of the record property. - * - * @return - * possible object is - * {@link Record } - * - */ - public Record getRecord() { - return record; - } - - /** - * Sets the value of the record property. - * - * @param value - * allowed object is - * {@link Record } - * - */ - public void setRecord(Record value) { - this.record = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java deleted file mode 100644 index 3289619..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java +++ /dev/null @@ -1,385 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}disclaimers"/>
- *         <element ref="{}sigstages"/>
- *         <element ref="{}sigflows"/>
- *         <element ref="{}zerodatum"/>
- *         <element ref="{}rating"/>
- *         <element ref="{}alt_rating"/>
- *         <element ref="{}observed"/>
- *         <element ref="{}forecast"/>
- *       </sequence>
- *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
- *       <attribute name="timezone" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="generationtime" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "disclaimers", - "sigstages", - "sigflows", - "zerodatum", - "rating", - "altRating", - "observed", - "forecast" -}) -@XmlRootElement(name = "site") -public class Site { - - @XmlElement(required = true) - protected Disclaimers disclaimers; - @XmlElement(required = true) - protected Sigstages sigstages = null; - @XmlElement(required = true) - protected Sigflows sigflows; - @XmlElement(required = true) - protected Zerodatum zerodatum; - @XmlElement(required = true) - protected Rating rating; - @XmlElement(name = "alt_rating", required = true) - protected AltRating altRating; - @XmlElement(required = true) - protected Observed observed; - @XmlElement(required = true) - protected Forecast forecast; - @XmlAttribute(name = "id", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String id; - @XmlAttribute(name = "name", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String name; - @XmlAttribute(name = "timezone", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String timezone; - @XmlAttribute(name = "generationtime", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String generationtime = ""; - - /** - * Gets the value of the disclaimers property. - * - * @return - * possible object is - * {@link Disclaimers } - * - */ - public Disclaimers getDisclaimers() { - return disclaimers; - } - - /** - * Sets the value of the disclaimers property. - * - * @param value - * allowed object is - * {@link Disclaimers } - * - */ - public void setDisclaimers(Disclaimers value) { - this.disclaimers = value; - } - - /** - * Gets the value of the sigstages property. - * - * @return - * possible object is - * {@link Sigstages } - * - */ - public Sigstages getSigstages() { - return sigstages; - } - - /** - * Sets the value of the sigstages property. - * - * @param value - * allowed object is - * {@link Sigstages } - * - */ - public void setSigstages(Sigstages value) { - this.sigstages = value; - } - - /** - * Gets the value of the sigflows property. - * - * @return - * possible object is - * {@link Sigflows } - * - */ - public Sigflows getSigflows() { - return sigflows; - } - - /** - * Sets the value of the sigflows property. - * - * @param value - * allowed object is - * {@link Sigflows } - * - */ - public void setSigflows(Sigflows value) { - this.sigflows = value; - } - - /** - * Gets the value of the zerodatum property. - * - * @return - * possible object is - * {@link Zerodatum } - * - */ - public Zerodatum getZerodatum() { - return zerodatum; - } - - /** - * Sets the value of the zerodatum property. - * - * @param value - * allowed object is - * {@link Zerodatum } - * - */ - public void setZerodatum(Zerodatum value) { - this.zerodatum = value; - } - - /** - * Gets the value of the rating property. - * - * @return - * possible object is - * {@link Rating } - * - */ - public Rating getRating() { - return rating; - } - - /** - * Sets the value of the rating property. - * - * @param value - * allowed object is - * {@link Rating } - * - */ - public void setRating(Rating value) { - this.rating = value; - } - - /** - * Gets the value of the altRating property. - * - * @return - * possible object is - * {@link AltRating } - * - */ - public AltRating getAltRating() { - return altRating; - } - - /** - * Sets the value of the altRating property. - * - * @param value - * allowed object is - * {@link AltRating } - * - */ - public void setAltRating(AltRating value) { - this.altRating = value; - } - - /** - * Gets the value of the observed property. - * - * @return - * possible object is - * {@link Observed } - * - */ - public Observed getObserved() { - return observed; - } - - /** - * Sets the value of the observed property. - * - * @param value - * allowed object is - * {@link Observed } - * - */ - public void setObserved(Observed value) { - this.observed = value; - } - - /** - * Gets the value of the forecast property. - * - * @return - * possible object is - * {@link Forecast } - * - */ - public Forecast getForecast() { - return forecast; - } - - /** - * Sets the value of the forecast property. - * - * @param value - * allowed object is - * {@link Forecast } - * - */ - public void setForecast(Forecast value) { - this.forecast = value; - } - - /** - * Gets the value of the id property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getId() { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setId(String value) { - this.id = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the timezone property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimezone() { - return timezone; - } - - /** - * Sets the value of the timezone property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimezone(String value) { - this.timezone = value; - } - - /** - * Gets the value of the generationtime property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getGenerationtime(){ - return generationtime; - } - - /** - * Sets the value of the generationtime property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setGenerationtime(String value){ - this.generationtime = value; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java deleted file mode 100644 index e326da1..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java +++ /dev/null @@ -1,159 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="audience" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="dignity" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="trace" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "standing") -public class Standing { - - @XmlValue - protected String content; - @XmlAttribute(name = "audience", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String audience; - @XmlAttribute(name = "dignity", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dignity; - @XmlAttribute(name = "trace", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String trace; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the audience property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAudience() { - return audience; - } - - /** - * Sets the value of the audience property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAudience(String value) { - this.audience = value; - } - - /** - * Gets the value of the dignity property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDignity() { - return dignity; - } - - /** - * Sets the value of the dignity property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDignity(String value) { - this.dignity = value; - } - - /** - * Gets the value of the trace property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTrace() { - return trace; - } - - /** - * Sets the value of the trace property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTrace(String value) { - this.trace = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java deleted file mode 100644 index 0da5c47..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.datatype.XMLGregorianCalendar; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>dateTime">
- *       <attribute name="timezone" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "valid") -public class Valid { - - @XmlValue - @XmlSchemaType(name = "dateTime") - protected XMLGregorianCalendar value; - @XmlAttribute(name = "timezone", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String timezone; - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link XMLGregorianCalendar } - * - */ - public XMLGregorianCalendar getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link XMLGregorianCalendar } - * - */ - public void setValue(XMLGregorianCalendar value) { - this.value = value; - } - - /** - * Gets the value of the timezone property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimezone() { - return timezone; - } - - /** - * Sets the value of the timezone property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimezone(String value) { - this.timezone = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java deleted file mode 100644 index 2961f2d..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "zerodatum") -public class Zerodatum { - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - -} diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java index 4c97c79..6e168d2 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java @@ -7,8 +7,7 @@ package usace.rowcps.headless; import java.util.TimeZone; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; import usace.rowcps.cwms.Installer; import usace.rowcps.headless.tests.TestVariables; @@ -149,7 +148,7 @@ private static String[] getArgsForFileAndTimeZone(String file, TimeZone tz) return args; } - @BeforeClass + @BeforeAll public static void beforeClass() { //Sets up DB info diff --git a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java index e6802b9..fa8c949 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java @@ -6,25 +6,24 @@ */ package usace.rowcps.headless.calculator.inflow; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.Calendar; import java.util.Date; import java.util.NavigableSet; import java.util.TimeZone; import java.util.logging.Logger; -import org.junit.Test; - import hec.data.DataSetException; import hec.data.location.LocationTemplate; import hec.data.tx.DataSetTxIllegalArgumentException; import hec.db.DbConnectionException; import hec.db.DbException; import hec.db.DbIoException; +import org.junit.jupiter.api.Test; import usace.rowcps.regi.executor.ManagerIdType; import usace.rowcps.regi.model.ManagerId; -import static org.junit.Assert.assertEquals; - /** * * @author Ryan A. Miles (ryanm@rmanet.com) diff --git a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java index a959776..e3f2d00 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java @@ -6,9 +6,11 @@ */ package usace.rowcps.headless.calculator.inflow; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.Arrays; -import static org.junit.Assert.*; -import org.junit.Test; +import org.junit.jupiter.api.Test; import usace.rowcps.data.inflow.InflowDataType; /** diff --git a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java index 054c918..e04155d 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java @@ -6,10 +6,11 @@ */ package usace.rowcps.headless.calculator.inflow; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.ArrayList; import java.util.List; -import static org.junit.Assert.*; -import org.junit.Test; +import org.junit.jupiter.api.Test; import usace.rowcps.data.inflow.InflowDataType; /** @@ -38,7 +39,7 @@ public void validateUniqueInflowDataTypes() if (!nonUniqueDataTypes.isEmpty()) { - assertTrue("Non unique data types found: " + nonUniqueDataTypes.toString(), false); + assertTrue(false, "Non unique data types found: " + nonUniqueDataTypes); } } } From 2d92df33962737d9a0c4d993a281226992ded45b Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 14:56:17 -0700 Subject: [PATCH 02/26] update README.md --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 743cd8d..7d6b916 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,66 @@ # REGI-Headless -This is a temporary readme file and will be updated in the future. \ No newline at end of file +> [!IMPORTANT] +> **Notice: Project Refactor in Progress** +> This project is undergoing a large refactor for CWMS Data API support. +> It will transition from a Java project consuming Jython scripts to a **Python project** that +> utilizes **JPype** to call underlying REGI Java libraries. + +`REGI-Headless` is a Java-based command-line tool and library designed to run +**REGI** calculations in a headless environment. +It allows users to execute complex hydrological calculations and manage gate settings via Jython +scripts without the need for a graphical interface. + +## Features + +- **Headless Execution**: Run REGI calculations as part of automated workflows or on servers. +- **Database Integration**: Connects to CWMS data retrieval and storage. +- **Modular Calculations**: Includes support for: + - Inflow calculations (Clone, Compute, Auto-Adjust, Balance All, etc.) + - Flow Group and gate settings calculations. + +## Project Structure + +- `regi-headless/`: Core Java implementation, including `RegiCLI`. +- `district-scripts/`: Example scripts and district-specific configurations. +- `docs/`: Additional documentation. + +## Getting Started + +### Prerequisites + +- Java JDK 21 or higher. +- Access to a CWMS + +### Building + + +```powershell +./gradlew build +``` + +Details TBD. + +## Usage + +TBD + +### Command Line Options + +TBD + +### Example + +TBD + +## Testing + +TBD + +## Maintainers + +See [MAINTAINERS.md](MAINTAINERS.md) for a list of project maintainers. + +## License + +See [LICENSE](LICENSE) for licensing information. \ No newline at end of file From f39abb03fd6f2fad143f9a70c92c3b8f1265922a Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 15:47:38 -0700 Subject: [PATCH 03/26] remove unused transitive dependencies --- gradle/libs.versions.toml | 10 ---------- regi-headless/build.gradle | 14 +++++++++++++- .../test/java/usace/rowcps/headless/TestFrame.java | 1 - .../java/usace/rowcps/headless/TestHeadless.java | 10 ---------- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fd6e634..530fd77 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,11 +12,6 @@ regi = "3.5.0-alpha001" jython-standalone = "2.7.2" args4j = "2.32" -# Natives -windows-jre = "1.8.0_201" -solaris-jre = "1.8.0_202-Solaris-SPARC" -jython-starter = "2.2.4.0" - # Test junit = "6.1.0" @@ -30,11 +25,7 @@ hec-db-cda = { module = "mil.army.usace.hec:hec-db-cda", version = "14.1.0" } hec-cwms-ratings-cda = { module = "mil.army.usace.hec:hec-cwms-ratings-io-cda", version = "4.2.2"} # REGI Dependencies -regi-basinpie-ui = {module = "mil.army.wmist.regi:basin-pie-ui", version.ref = "regi"} regi-computation = {module = "mil.army.wmist.regi:computation", version.ref = "regi"} -regi-decisionsupport-ui = {module = "mil.army.wmist.regi:decision-support-ui", version.ref = "regi"} -regi-mappanel-ui = {module = "mil.army.wmist.regi:map-panel-ui", version.ref = "regi"} -regi-ui = {module = "mil.army.wmist.regi:regi-ui", version.ref = "regi"} # Regi-tools Dependencies regi-tools-regi-core = {module = "mil.army.wmist.regi-tools:regi-core", version.ref = "regi-tools"} @@ -45,7 +36,6 @@ regi-tools-regi-cwms = {module = "mil.army.wmist.regi-tools:regi-cwms", version. # Third Party jython-standalone = {module = "org.python:jython-standalone", version.ref = "jython-standalone"} args4j = {module = "args4j:args4j", version.ref = "args4j"} -otel = {module = "io.opentelemetry:opentelemetry-api", version="1.58.0"} # Test junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index 26da9f7..c4a6bf1 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -11,7 +11,6 @@ dependencies { implementation(libs.bundles.regi) {artifact {extension = "jar"}} implementation(libs.bundles.regi.tools) implementation(libs.bundles.regi.tools) {artifact {extension = "jar"} } - implementation(libs.otel) runtimeOnly(libs.hec.cwms.ratings.cda) testImplementation(libs.bundles.junit.api) @@ -25,6 +24,19 @@ configurations.configureEach { exclude group: 'mil.army.usace.hec.swingx', module: '*' exclude group: 'org.swinglabs', module: '*' exclude group: 'org.jfree', module: '*' + exclude group: 'org.netbeans.modules', module: '*' + exclude group: 'org.netbeans.api', module: '*' + exclude group: 'mil.army.usace.hec.map', module: 'hec-osmmap' + exclude group: 'mil.army.usace.hec', module: 'hec-geojson' + exclude group: 'mil.army.usace.hec', module: 'dssplugin-excel' + exclude group: 'mil.army.usace.hec', module: 'dssgui' + exclude group: 'com.fifesoft', module: 'rstaui' + exclude group: 'mil.army.usace.hec', module: 'rma-javafx-core' + exclude group: 'mil.army.usace.hec', module: 'hec-vrt-io' + exclude group: 'org.apache.xmlgraphics', module: '*' + exclude group: 'org.apache.poi', module: '*' + exclude group: 'javax.media', module: '*' + exclude group: 'com.vividsolutions', module: 'jts' } jar { diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java b/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java index 8d2f38e..2b46ad7 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java @@ -43,7 +43,6 @@ public TestFrame() throws HeadlessException public static void main(String[] args) { - TestHeadless.beforeClass(); TestFrame frame = new TestFrame(); frame.pack(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java index 6e168d2..4cf8ac7 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java @@ -7,8 +7,6 @@ package usace.rowcps.headless; import java.util.TimeZone; -import org.junit.jupiter.api.BeforeAll; -import usace.rowcps.cwms.Installer; import usace.rowcps.headless.tests.TestVariables; /** @@ -147,12 +145,4 @@ private static String[] getArgsForFileAndTimeZone(String file, TimeZone tz) return args; } - - @BeforeAll - public static void beforeClass() - { - //Sets up DB info - Installer installer = new Installer(); - installer.restored(); - } } From 65a8526abc5c7b7f103ecdf1460b5660d1fbbe06 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 15:55:23 -0700 Subject: [PATCH 04/26] update to use gradle action for dedicated caching --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8fca131..4aaeeba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,9 @@ jobs: with: distribution: temurin java-version: 21 - cache: gradle + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v6 - name: Make Gradle wrapper executable run: chmod +x ./gradlew From 80fec2cd764ad74600af3875cc720d89388b2432 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 16:26:18 -0700 Subject: [PATCH 05/26] add in dependency submission for gradle SBOM generation --- .github/workflows/build.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4aaeeba..0be5339 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,6 +31,31 @@ jobs: - name: Make Gradle wrapper executable run: chmod +x ./gradlew - + - name: Build and test - run: ./gradlew clean build \ No newline at end of file + run: ./gradlew clean build + + dependency-submission: + name: Submit Gradle dependencies + needs: build + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 21 + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v6 + + - name: Submit Gradle dependencies + uses: gradle/actions/dependency-submission@v6 + \ No newline at end of file From 8a38a8489aaecbcd46ac32053e5edb5622cf7e19 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 8 Jul 2026 15:20:36 -0700 Subject: [PATCH 06/26] remove example scripts of removed API's --- .../legacy-examples/solaris/BasinPie.py | 288 ------------------ .../legacy-examples/solaris/ExportBasinPie.sh | 2 - .../solaris/ExportStatusGraphic.sh | 2 - .../legacy-examples/solaris/PoolPercent.py | 64 ---- .../solaris/Sigstages_DBExport.py | 13 - .../solaris/Sigstages_DBImport.py | 34 --- .../solaris/Sigstages_Download.py | 27 -- .../legacy-examples/solaris/StageDBExport.sh | 2 - .../legacy-examples/solaris/StageDBImport.sh | 2 - .../legacy-examples/solaris/StageDownload.sh | 2 - .../legacy-examples/solaris/StatusDemo.py | 57 ---- .../solaris/credentials.properties | 3 - .../legacy-examples/solaris/poolpercent.sh | 2 - .../legacy-examples/solaris/printInfo.py | 15 - .../legacy-examples/windows/BasinPie.py | 243 --------------- .../windows/ExportBasinPie.bat | 2 - .../windows/ExportStatusGraphic.bat | 2 - .../legacy-examples/windows/PoolPercent.py | 73 ----- .../windows/Sigstages_DBExport.py | 13 - .../windows/Sigstages_DBImport.py | 34 --- .../windows/Sigstages_Download.py | 27 -- .../legacy-examples/windows/StageDBExport.bat | 2 - .../legacy-examples/windows/StageDBImport.bat | 2 - .../legacy-examples/windows/StageDownload.bat | 2 - .../legacy-examples/windows/StatusDemo.py | 84 ----- .../windows/credentials.properties | 7 - .../legacy-examples/windows/headless.password | 2 - .../legacy-examples/windows/poolpercent.bat | 2 - .../legacy-examples/windows/printInfo.py | 15 - .../headless/examples/Assoc_DBExport.py | 31 -- .../headless/examples/PoolPercentCalc.py | 31 -- .../ScriptableGateFlowImplTest.java_old | 45 --- .../headless/examples/Sigstages_DBExport.py | 8 - .../headless/examples/Sigstages_DBImport.py | 8 - .../headless/examples/Sigstages_Download.py | 21 -- .../rowcps/headless/examples/StatusDemo.py | 56 ---- .../usace/rowcps/headless/examples/hello.py | 1 - .../rowcps/headless/tests/15618-StatusDemo.py | 76 ----- .../rowcps/headless/tests/Assoc_DBExport.py | 19 -- .../rowcps/headless/tests/BasinPieExport.py | 219 ------------- .../rowcps/headless/tests/PoolPercentCalc.py | 32 -- .../headless/tests/PoolPercent_15614.py | 66 ---- .../headless/tests/Sigstages_DBExport.py | 8 - .../headless/tests/Sigstages_DBImport.py | 11 - .../headless/tests/Sigstages_Download.py | 23 -- .../usace/rowcps/headless/tests/StatusDemo.py | 56 ---- 46 files changed, 1734 deletions(-) delete mode 100644 district-scripts/legacy-examples/solaris/BasinPie.py delete mode 100644 district-scripts/legacy-examples/solaris/ExportBasinPie.sh delete mode 100644 district-scripts/legacy-examples/solaris/ExportStatusGraphic.sh delete mode 100644 district-scripts/legacy-examples/solaris/PoolPercent.py delete mode 100644 district-scripts/legacy-examples/solaris/Sigstages_DBExport.py delete mode 100644 district-scripts/legacy-examples/solaris/Sigstages_DBImport.py delete mode 100644 district-scripts/legacy-examples/solaris/Sigstages_Download.py delete mode 100644 district-scripts/legacy-examples/solaris/StageDBExport.sh delete mode 100644 district-scripts/legacy-examples/solaris/StageDBImport.sh delete mode 100644 district-scripts/legacy-examples/solaris/StageDownload.sh delete mode 100644 district-scripts/legacy-examples/solaris/StatusDemo.py delete mode 100644 district-scripts/legacy-examples/solaris/credentials.properties delete mode 100644 district-scripts/legacy-examples/solaris/poolpercent.sh delete mode 100644 district-scripts/legacy-examples/solaris/printInfo.py delete mode 100644 district-scripts/legacy-examples/windows/BasinPie.py delete mode 100644 district-scripts/legacy-examples/windows/ExportBasinPie.bat delete mode 100644 district-scripts/legacy-examples/windows/ExportStatusGraphic.bat delete mode 100644 district-scripts/legacy-examples/windows/PoolPercent.py delete mode 100644 district-scripts/legacy-examples/windows/Sigstages_DBExport.py delete mode 100644 district-scripts/legacy-examples/windows/Sigstages_DBImport.py delete mode 100644 district-scripts/legacy-examples/windows/Sigstages_Download.py delete mode 100644 district-scripts/legacy-examples/windows/StageDBExport.bat delete mode 100644 district-scripts/legacy-examples/windows/StageDBImport.bat delete mode 100644 district-scripts/legacy-examples/windows/StageDownload.bat delete mode 100644 district-scripts/legacy-examples/windows/StatusDemo.py delete mode 100644 district-scripts/legacy-examples/windows/credentials.properties delete mode 100644 district-scripts/legacy-examples/windows/headless.password delete mode 100644 district-scripts/legacy-examples/windows/poolpercent.bat delete mode 100644 district-scripts/legacy-examples/windows/printInfo.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/Assoc_DBExport.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/PoolPercentCalc.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/ScriptableGateFlowImplTest.java_old delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBExport.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBImport.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_Download.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/StatusDemo.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/examples/hello.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/15618-StatusDemo.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/Assoc_DBExport.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/BasinPieExport.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercentCalc.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercent_15614.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBExport.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBImport.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_Download.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/StatusDemo.py diff --git a/district-scripts/legacy-examples/solaris/BasinPie.py b/district-scripts/legacy-examples/solaris/BasinPie.py deleted file mode 100644 index eef25a7..0000000 --- a/district-scripts/legacy-examples/solaris/BasinPie.py +++ /dev/null @@ -1,288 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -import os, sys -import getopt -sys.path.insert(0, os.path.abspath("..")) -#from examples import printInfo - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Basin Pie functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Basin Pie functionality can be scripted. - """ - print msg - -def headless_examples(): - #printInfo.printAll() - # This gets a scriptable Basin Pie object. - basinPie = registry.getCalculation(1.0, "Status") - - - ###################################################################################### - # # - # Please refer to the functions for the parametrization for generating the graphics. # - # # - ###################################################################################### - - # Configure the calendar for the date and time of the Basin Pie graphic - timeZone = TimeZone.getTimeZone("US/Central") - startCal = Calendar.getInstance(timeZone) - startCal.clear() - startCal.set(Calendar.YEAR, 2016) - startCal.set(Calendar.MONTH, 4) - startCal.set(Calendar.DATE, 5) - startCal.set(Calendar.HOUR_OF_DAY, 0) - # Month 4 means May to java... - - # If the filepath does not end in .jpg then the image will be saved in png format. - filepath = "../headless/basin.jpg" - #filepath = "../headless/basin.png" - - # Generate a single image, - # at a single location within a basin, - # at single date, - # with a single chart template - # and write to specified file. - #print "Demonstrating a call to generateBasinPieImageForBasin" - #generateBasinPieImageForBasin("SWF", "RRLT2", "Trinity_R_Basin", - # startCal.getTime(), 700, 807, - # "Design Capacity", - # filepath) - - # Generate multiple images - # First built the dates - dates = [] - for i in range(0, 3): - dates.append(startCal.getTime()) - startCal.add(Calendar.DATE, 1) - - # When generating multiple image files the filepath may contain replacement keywords. - # If these keywords are found in the filepath they are replaced with named piece of data. - # Once the replacements are made, illegal characters in the filename are replaced with '_'. - # The following keywords are currently recognized: - # %date% - # %office_id% - # %location_id% - # %chart_template_id% - # %basin_id% - # %image_format% - # Example: filepath like: - # "../headless/%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - # Will generate the following files: - # ../headless/SWF_Trinity_R_Basin_RSRT2_Conservation Pool (static)_2016-04-02T00_00_00Z.png - - filepath = "../headless/%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - - # Generate a basin pie image, - # for each of the specified locations in the specified basin, - # for each of the dates, - # for each of the chart templates - # replace %% patterns in the specified filepath template - # and write each image to its generated filepath -# print "Demonstrating a call to generateBasinPieImages" -# generateBasinPieImages("SWF", ["LOLT2"], "Trinity_R_Basin", -# dates, 700, 807, -# ["Design Capacity"], -# filepath) - - # Generate an image - # for the locations found in a basin - # for each of the dates, - # for each of the chart templates - # replace %% patterns in the specified filepath template - # and write each image to its generated filepath - - print "Demonstrating a call to generateBasinPieImageForGroup" - generateBasinPieImageForGroup("SWF", "DAWT2", "Trinity", startCal.getTime(), 700, 807,"Design Capacity","../headless/generateBasinPieImageForGroup/test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateBasinPieImagesForGroup" - generateBasinPieImagesForGroup("SWF", ["LVNT2","STIT2"], "XYZ", [startCal.getTime()], 700, 807,["Design Capacity"],"../headless/generateBasinPieImagesForGroup/test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateBasinPieImageForBasin" - generateBasinPieImageForBasin("SWF", "DAWT2", "Trinity_R_Basin", startCal.getTime(), 700, 807,"Design Capacity","../headless/generateBasinPieImageForBasin/test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateBasinPieImagesForBasin" - generateBasinPieImagesForBasin("SWF", ["LOLT2","DAWT2"], "Trinity_R_Basin", [startCal.getTime()], 700, 807,["Design Capacity"],"../headless/generateBasinPieImagesForBasin/test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateAllBasinPieImagesForBasin" - generateAllBasinPieImagesForBasin("SWF", "Trinity_R_Basin", [startCal.getTime()], 800, 600, ["Conservation Pool (static)"], "../headless/generateAllForBasin/test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateAllBasinPieImagesForGroup" - generateAllBasinPieImagesForGroup("SWF", "XYZ", [startCal.getTime()], 800, 600, ["Conservation Pool (static)"], "../headless/generateAllForGroup/test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - -def generateBasinPieImageForBasin(office_id, location_id, basin_id, - date, width, height, - chart_template_id, - filepath): - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_id: The location for which the basin pie image is desired - :param basin_id: The id of the Basin - :param date: This specifies the time for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_id: The id of the chart template to use. - :param filepath: Path of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImageForBasin(office_id, location_id, basin_id, - date, width, height, - chart_template_id, - filepath) - -def generateBasinPieImagesForBasin(office_id, location_ids, basin_id, - dates, width, height, - chart_template_ids, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_ids: A list of the locations for which basin pie images are desired - :param basin_id: The id of the Basin - :param dates: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_ids: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImagesForBasin(office_id, location_ids, basin_id, - dates, width, height, - chart_template_ids, - filepath) - -def generateBasinPieImageForGroup(office_id, location_id, group_id, - date, width, height, - chart_template_id, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_id: A list of the locations for which basin pie images are desired - :param group_id: The id of the Group - :param date: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_id: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImageForGroup(office_id, location_id, group_id, - date, width, height, - chart_template_id, - filepath) - -def generateBasinPieImagesForGroup(office_id, location_ids, group_id, - dates, width, height, - chart_template_ids, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_ids: A list of the locations for which basin pie images are desired - :param group_id: The id of the Group - :param dates: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_ids: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImagesForGroup(office_id, location_ids, group_id, - dates, width, height, - chart_template_ids, - filepath) - -def generateAllBasinPieImagesForBasin(office_id, basin_id, - dates, width, height, - chart_template_ids, - filepath): - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateAllBasinPieImagesForBasin(office_id, basin_id, - dates, width, height, - chart_template_ids, - filepath) - -def generateAllBasinPieImagesForGroup(office_id, group_id, - dates, width, height, - chart_template_ids, - filepath): - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateAllBasinPieImagesForGroup(office_id, group_id, - dates, width, height, - chart_template_ids, - filepath) - -# basinPie.generateBasinPieImage("SWF", "RSRT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/basin.jpg") - -# basinPie.generateBasinPieImage("SWF", "Basin-Trinity_R_Basin", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Basin-Trinity_R_Basin.png") -# basinPie.generateBasinPieImage("SWF", "W_Fork_Triniy_R", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/W_Fork_Triniy_R.png") -# basinPie.generateBasinPieImage("SWF", "Mountain_Ck", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Mountain_Ck.png") -# basinPie.generateBasinPieImage("SWF", "GPAT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/GPAT2.png") -# basinPie.generateBasinPieImage("SWF", "GPET2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/GPET2.png") -# basinPie.generateBasinPieImage("SWF", "JPLT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/JPLT2.png") -# basinPie.generateBasinPieImage("SWF", "GPRT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/GPRT2.png") -# basinPie.generateBasinPieImage("SWF", "TGXT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/TGXT2.png") -# basinPie.generateBasinPieImage("SWF", "FWOT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/FWOT2.png") -# basinPie.generateBasinPieImage("SWF", "Clear_Fk_Trinity", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Clear_Fk_Trinity.png") -# basinPie.generateBasinPieImage("SWF", "FWHT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/FWHT2.png") -# basinPie.generateBasinPieImage("SWF", "CFBT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/CFBT2.png") -# basinPie.generateBasinPieImage("SWF", "BNBT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/BNBT2.png") -# basinPie.generateBasinPieImage("SWF", "ADOT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/ADOT2.png") -# basinPie.generateBasinPieImage("SWF", "WEAT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/WEAT2.png") -# basinPie.generateBasinPieImage("SWF", "LWFT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/LWFT2.png") -# basinPie.generateBasinPieImage("SWF", "WFTT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/WFTT2.png") -# basinPie.generateBasinPieImage("SWF", "FLWT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/FLWT2.png") -# basinPie.generateBasinPieImage("SWF", "EAMT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/EAMT2.png") -# basinPie.generateBasinPieImage("SWF", "BOYT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/BOYT2.png") -# basinPie.generateBasinPieImage("SWF", "Big_Sandy_Cr", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Big_Sandy_Cr.png") -# basinPie.generateBasinPieImage("SWF", "BRPT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/BRPT2.png") -# basinPie.generateBasinPieImage("SWF", "BCAT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/BCAT2.png") -# basinPie.generateBasinPieImage("SWF", "BPRT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/BPRT2.png") -# basinPie.generateBasinPieImage("SWF", "Elm_Fk", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Elm_Fk.png") -# basinPie.generateBasinPieImage("SWF", "CART2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/CART2.png") -# basinPie.generateBasinPieImage("SWF", "Denton_Crk", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Denton_Crk.png") -# basinPie.generateBasinPieImage("SWF", "DCGT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/DCGT2.png") -# basinPie.generateBasinPieImage("SWF", "GPVT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/GPVT2.png") -# basinPie.generateBasinPieImage("SWF", "EFLT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/EFLT2.png") -# basinPie.generateBasinPieImage("SWF", "LEWT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/LEWT2.png") -# basinPie.generateBasinPieImage("SWF", "RRLT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/RRLT2.png") -# basinPie.generateBasinPieImage("SWF", "DALT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/DALT2.png") -# basinPie.generateBasinPieImage("SWF", "TRDT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/TRDT2.png") -# basinPie.generateBasinPieImage("SWF", "E_Fork", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/E_Fork.png") -# basinPie.generateBasinPieImage("SWF", "CNLT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/CNLT2.png") -# basinPie.generateBasinPieImage("SWF", "FNYT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/FNYT2.png") -# basinPie.generateBasinPieImage("SWF", "FRHT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/FRHT2.png") -# basinPie.generateBasinPieImage("SWF", "LVNT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/LVNT2.png") -# basinPie.generateBasinPieImage("SWF", "RSRT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/RSRT2.png") -# basinPie.generateBasinPieImage("SWF", "TDDT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/TDDT2.png") -# basinPie.generateBasinPieImage("SWF", "Richland_Ck", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Richland_Ck.png") -# basinPie.generateBasinPieImage("SWF", "TRNT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/TRNT2.png") -# basinPie.generateBasinPieImage("SWF", "Chambers_Ck", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/Chambers_Ck.png") -# basinPie.generateBasinPieImage("SWF", "BRDT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/BRDT2.png") -# basinPie.generateBasinPieImage("SWF", "BDWT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/BDWT2.png") -# basinPie.generateBasinPieImage("SWF", "DWST2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/DWST2.png") -# basinPie.generateBasinPieImage("SWF", "DAWT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/DAWT2.png") -# basinPie.generateBasinPieImage("SWF", "LOLT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/LOLT2.png") - -# basinPie.generateBasinPieImage("SWF", "LOLT2", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/test_%office%_LOLT2.png") - -# basinPie.generateBasinPieImage("SWF", ["LOLT2","DAWT2"], "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/") -# basinPie.generateBasinPieImagesForBasin("SWF", "Trinity_R_Basin", startCal.getTime(), 800, 600, "Conservation Pool (static)", "../headless/") - -if __name__ == "__builtin__": - Usage() - headless_examples() - -if __name__ == "__main__": - Usage() \ No newline at end of file diff --git a/district-scripts/legacy-examples/solaris/ExportBasinPie.sh b/district-scripts/legacy-examples/solaris/ExportBasinPie.sh deleted file mode 100644 index 5e5af80..0000000 --- a/district-scripts/legacy-examples/solaris/ExportBasinPie.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//BasinPie.py diff --git a/district-scripts/legacy-examples/solaris/ExportStatusGraphic.sh b/district-scripts/legacy-examples/solaris/ExportStatusGraphic.sh deleted file mode 100644 index 5be26fb..0000000 --- a/district-scripts/legacy-examples/solaris/ExportStatusGraphic.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//StatusDemo.py diff --git a/district-scripts/legacy-examples/solaris/PoolPercent.py b/district-scripts/legacy-examples/solaris/PoolPercent.py deleted file mode 100644 index 0d825c6..0000000 --- a/district-scripts/legacy-examples/solaris/PoolPercent.py +++ /dev/null @@ -1,64 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -percentCalc = registry.getCalculation(1.0, "Pool Percent") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) - - -# percentCalc contains a single callable method calculatePoolPercents which takes the followind arguments: -# officeId -# locationId -# startDate -# endDate -# This recomputes the pool percentages for SWF.LEWT2 -percentCalc.calculatePoolPercents("SWF", "LEWT2", startCal.getTime(), endCal.getTime()) - - diff --git a/district-scripts/legacy-examples/solaris/Sigstages_DBExport.py b/district-scripts/legacy-examples/solaris/Sigstages_DBExport.py deleted file mode 100644 index 4562fac..0000000 --- a/district-scripts/legacy-examples/solaris/Sigstages_DBExport.py +++ /dev/null @@ -1,13 +0,0 @@ -sigstages = registry.getCalculation(1.0, "Export Sig States") - -#sigstages has the following API exposed: -# -# public void exportSigStages(String file); - -# Purpose: -# Sigstages_DBExport.py retrieves information from the SWF database -# and writes the handbook_5 code for each location to a .txt file -# this file is read later by Sigstages_Download.py - -outpath = "sites.txt" -sigstages.exportSigStages(outpath) \ No newline at end of file diff --git a/district-scripts/legacy-examples/solaris/Sigstages_DBImport.py b/district-scripts/legacy-examples/solaris/Sigstages_DBImport.py deleted file mode 100644 index 84d08de..0000000 --- a/district-scripts/legacy-examples/solaris/Sigstages_DBImport.py +++ /dev/null @@ -1,34 +0,0 @@ -from java.util import Calendar -from java.util import TimeZone - -# this retrieves a Sig States caluclation object -sigstates = registry.getCalculation(1.0, "Import Sig States") - -#sigstates has the following API exposed: -# -# public void importSigStages(String file, Date effectiveDate); - -# Purpose: -# Sigstages_DBImport.py imports each of the location levels from -# the sig stage data into the REGI database for use in the REGI application - -# the file to be read in order to import the correct data to the REGI sigstates -# if you have your own .csv file, you can enter its full name here to import -# from that location instead, but sigstages.csv is the default generated from -# the Sigstages_Download script -inpath = "sigstages.csv" - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the sig states caluclation requires an effective date -# here we create a java Calendar object that will be used to create that date -cal = Calendar.getInstance(timeZone) -cal.clear() -cal.set(Calendar.YEAR, 1899) -cal.set(Calendar.MONTH, Calendar.JANUARY) -cal.set(Calendar.DAY_OF_MONTH, 1) - -# the importSigStates method takes: -# inpath (csv file) -# effective date (calendar date) -sigstates.importSigStages(inpath, cal.getTime()) diff --git a/district-scripts/legacy-examples/solaris/Sigstages_Download.py b/district-scripts/legacy-examples/solaris/Sigstages_Download.py deleted file mode 100644 index ec66eb0..0000000 --- a/district-scripts/legacy-examples/solaris/Sigstages_Download.py +++ /dev/null @@ -1,27 +0,0 @@ -sigstates = registry.getCalculation(1.0, "Retrieve Sig States") - -#sigstates has the following API exposed: -# -# public void retrieveSigstages(String sourceFile, String outputFile, int milliDelay); -# public void setParameter(String parameter); -# public String getParameter(String parameter); -# public void setParameterType(String parameterType); -# public String getParameter(); -# public void setDuration(String duration); -# public String getDuration(); -# public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText); -# public void getSpecifiedLevelOverride(Sigstage.Type type); -# public void setOffice(String office); -# public String getOffice(); - -# Purpose: -# Sigstages_Download.py accesses the AHPS data on the locations listed in -# "sites.txt" and retrieves the relevant sig stage information for each -# location, and stores in the sigstages.csv - -inpath = "sites.txt" # file to read the relevant sig stage sites from -outpath = "sigstages.csv" # file to write the relevant sig stage information gathered to -accessDelay = 5 # time delay in milliseconds between accesses to the AHPS site, to prevent blocking out - -sigstates.retrieveSigstages(inpath, outpath, accessDelay) - diff --git a/district-scripts/legacy-examples/solaris/StageDBExport.sh b/district-scripts/legacy-examples/solaris/StageDBExport.sh deleted file mode 100644 index 3b6e6b8..0000000 --- a/district-scripts/legacy-examples/solaris/StageDBExport.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//Sigstages_DBExport.py diff --git a/district-scripts/legacy-examples/solaris/StageDBImport.sh b/district-scripts/legacy-examples/solaris/StageDBImport.sh deleted file mode 100644 index e1a3d03..0000000 --- a/district-scripts/legacy-examples/solaris/StageDBImport.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//Sigstages_DBImport.py diff --git a/district-scripts/legacy-examples/solaris/StageDownload.sh b/district-scripts/legacy-examples/solaris/StageDownload.sh deleted file mode 100644 index 72af8d8..0000000 --- a/district-scripts/legacy-examples/solaris/StageDownload.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//Sigstages_Download.py diff --git a/district-scripts/legacy-examples/solaris/StatusDemo.py b/district-scripts/legacy-examples/solaris/StatusDemo.py deleted file mode 100644 index 8f2fda6..0000000 --- a/district-scripts/legacy-examples/solaris/StatusDemo.py +++ /dev/null @@ -1,57 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -import sys -import getopt - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Stream Status functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Stream Status functionality can be scripted. - """ - print msg - -def headless_examples(): - # This gets a scriptable Stream Status object. - streamStatus = registry.getCalculation(1.0, "Status") - - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - # Configure the calendar - startCal = Calendar.getInstance(timeZone) - startCal.clear() - startCal.set(Calendar.YEAR, 2016) - startCal.set(Calendar.MONTH, 3) - startCal.set(Calendar.DATE, 2) - startCal.set(Calendar.HOUR_OF_DAY, 0) - # Month 4 means May to java... - - # If the filepath does not end in .jpg then the image will be saved in png format. - - # Generate a single image, - # at a single location within a basin, - # at single date, - # with a single chart template - # and write to specified file. - print "Demonstrating a call to generateStreamStatusImage" - streamFilepath = "../headless/StatusGraphics/streamStatus.jpg" - streamStatus.generateStreamStatusImage("SWF", "RSRT2", "Flood Control Focus View", startCal.getTime(), 800, 600, streamFilepath) - - #print "Demonstrating a call to generateReservoirStatusImage" - #reservoirFilePath = "../headless/StatusGraphics/reservoirStatus.jpg" - #streamStatus.generateReservoirStatusImage("SWF", "GPVT2", "Flood Control Focus View", startCal.getTime(), 800, 600, reservoirFilePath) - - #print "Demonstrating a call to generateReleasesStatusImage" - #releasesFilePath = "../headless/StatusGraphics/releasesStatus.jpg" - #streamStatus.generateReleasesStatusImage("SWF", "WTYT2", "Flood Control Focus View", startCal.getTime(), 800, 600, releasesFilePath) - -if __name__ == "__builtin__": - Usage() - headless_examples() - -if __name__ == "__main__": - Usage() \ No newline at end of file diff --git a/district-scripts/legacy-examples/solaris/credentials.properties b/district-scripts/legacy-examples/solaris/credentials.properties deleted file mode 100644 index 314d33c..0000000 --- a/district-scripts/legacy-examples/solaris/credentials.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Required properties file that contains the CWMS-REGI project information -rowcps.projectDir=./Regi Base/bang/ -rowcps.projectName=bang diff --git a/district-scripts/legacy-examples/solaris/poolpercent.sh b/district-scripts/legacy-examples/solaris/poolpercent.sh deleted file mode 100644 index 55a301b..0000000 --- a/district-scripts/legacy-examples/solaris/poolpercent.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//PoolPercent.py diff --git a/district-scripts/legacy-examples/solaris/printInfo.py b/district-scripts/legacy-examples/solaris/printInfo.py deleted file mode 100644 index 65604f4..0000000 --- a/district-scripts/legacy-examples/solaris/printInfo.py +++ /dev/null @@ -1,15 +0,0 @@ -from java.util import TimeZone -from java.lang import System - -def printTimeZone(): - tz = TimeZone.getDefault() - id = tz.getID() - - regiTzId = System.getProperty("rowcps.timezone") - regiTz = TimeZone.getTimeZone(regiTzId) - - print "Default system timezone:{0}, Observes daylight: {1}".format(id, str(tz.useDaylightTime())) - print "Regi timezone:{0}, Observes daylight: {1}".format(regiTzId, str(regiTz.useDaylightTime())) - -def printAll(): - printTimeZone() \ No newline at end of file diff --git a/district-scripts/legacy-examples/windows/BasinPie.py b/district-scripts/legacy-examples/windows/BasinPie.py deleted file mode 100644 index de3409d..0000000 --- a/district-scripts/legacy-examples/windows/BasinPie.py +++ /dev/null @@ -1,243 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -import os, sys -from usace.rowcps.headless import LoggingOptions - -sys.path.insert(0, os.path.abspath("..")) - - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Basin Pie functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Basin Pie functionality can be scripted. - """ - print msg - - -def headless_examples(): - - # Description of: LoggingOptions.setDbMessageLevel(int level) - # - # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended - # level is 2, as this provides basic information about the time series - # retrieval/storage. - # - # Message Level | Description - # --------------|-------------------------------------------------------------------------------------------------------------------------------| - # <=0 | Default value, does not do anything. Lower values do not change behavior. | - # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | - # 2 | Adds message with name of time series, and the units to retrieve/store. | - # 3 | Adds message with the current time. | - # 4 | Adds message with first 10 dates and values from each time series. | - # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | - # --------------|-------------------------------------------------------------------------------------------------------------------------------| - - LoggingOptions.setDbMessageLevel(2) - - # This gets a scriptable Basin Pie object. - basinPie = registry.getCalculation(1.0, "Status") - - - ###################################################################################### - # # - # Please refer to the functions for the parametrization for generating the graphics. # - # # - ###################################################################################### - - - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - - # Configure the calendar for the date and time of the Basin Pie graphic - # Defaults to top of current hour - startCal = Calendar.getInstance(timeZone) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - - # When generating multiple image files the filepath may contain replacement keywords. - # If these keywords are found in the filepath they are replaced with named piece of data. - # Once the replacements are made, illegal characters in the filename are replaced with '_'. - # The following keywords are currently recognized: - # %date% - # %office_id% - # %location_id% - # %chart_template_id% - # %basin_id% - # %image_format% - # Example: filepath like: - # "headless\\%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - # Will generate the following files: - # headless\\SWF_Trinity_R_Basin_RSRT2_Conservation Pool (static)_2016-04-02T00_00_00Z.png - - filepath = "\\headless\\%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - - # Generate a basin pie image, - # for each of the specified locations in the specified basin, - # for each of the dates, - # for each of the chart templates - # replace %% patterns in the specified filepath template - # and write each image to its generated filepath - # print "Demonstrating a call to generateBasinPieImages" - # generateBasinPieImages("SWF", ["LOLT2"], "Trinity_R_Basin", - # dates, 700, 807, - # ["Design Capacity"], - # filepath) - - # Generate an image - # for the locations found in a basin - # for each of the dates, - # for each of the chart templates - # replace %% patterns in the specified filepath template - # and write each image to its generated filepath - - print "Demonstrating a call to generateBasinPieImageForGroup" - generateBasinPieImageForGroup("SWF", "DAWT2", "Trinity", startCal.getTime(), 700, 807,"Design Capacity","headless\\generateBasinPieImageForGroup\\test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateBasinPieImagesForGroup" - generateBasinPieImagesForGroup("SWF", ["LVNT2","STIT2"], "XYZ", [startCal.getTime()], 700, 807,["Design Capacity"],"headless\\generateBasinPieImagesForGroup\\test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateBasinPieImageForBasin" - generateBasinPieImageForBasin("SWF", "DAWT2", "Trinity_R_Basin", startCal.getTime(), 700, 807,"Design Capacity","headless\\generateBasinPieImageForBasin\\test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateBasinPieImagesForBasin" - generateBasinPieImagesForBasin("SWF", ["LOLT2","DAWT2"], "Trinity_R_Basin", [startCal.getTime()], 700, 807,["Design Capacity"],"headless\\generateBasinPieImagesForBasin\\test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateAllBasinPieImagesForBasin" - generateAllBasinPieImagesForBasin("SWF", "Trinity_R_Basin", [startCal.getTime()], 800, 600, ["Conservation Pool (static)"], "headless\\generateAllForBasin\\test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - print "Demonstrating a call to generateAllBasinPieImagesForGroup" - generateAllBasinPieImagesForGroup("SWF", "XYZ", [startCal.getTime()], 800, 600, ["Conservation Pool (static)"], "headless\\generateAllForGroup\\test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png") - - -def generateBasinPieImageForBasin(office_id, location_id, basin_id, - date, width, height, - chart_template_id, - filepath): - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_id: The location for which the basin pie image is desired - :param basin_id: The id of the Basin - :param date: This specifies the time for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_id: The id of the chart template to use. - :param filepath: Path of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImageForBasin(office_id, location_id, basin_id, - date, width, height, - chart_template_id, - filepath) - - -def generateBasinPieImagesForBasin(office_id, location_ids, basin_id, - dates, width, height, - chart_template_ids, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_ids: A list of the locations for which basin pie images are desired - :param basin_id: The id of the Basin - :param dates: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_ids: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImagesForBasin(office_id, location_ids, basin_id, - dates, width, height, - chart_template_ids, - filepath) - - -def generateBasinPieImageForGroup(office_id, location_id, group_id, - date, width, height, - chart_template_id, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_id: A list of the locations for which basin pie images are desired - :param group_id: The id of the Group - :param date: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_id: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImageForGroup(office_id, location_id, group_id, - date, width, height, - chart_template_id, - filepath) - - -def generateBasinPieImagesForGroup(office_id, location_ids, group_id, - dates, width, height, - chart_template_ids, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_ids: A list of the locations for which basin pie images are desired - :param group_id: The id of the Group - :param dates: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_ids: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImagesForGroup(office_id, location_ids, group_id, - dates, width, height, - chart_template_ids, - filepath) - - -def generateAllBasinPieImagesForBasin(office_id, basin_id, - dates, width, height, - chart_template_ids, - filepath): - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateAllBasinPieImagesForBasin(office_id, basin_id, - dates, width, height, - chart_template_ids, - filepath) - - -def generateAllBasinPieImagesForGroup(office_id, group_id, - dates, width, height, - chart_template_ids, - filepath): - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateAllBasinPieImagesForGroup(office_id, group_id, - dates, width, height, - chart_template_ids, - filepath) - - -if __name__ == "__builtin__": - Usage() - headless_examples() - - -if __name__ == "__main__": - Usage() diff --git a/district-scripts/legacy-examples/windows/ExportBasinPie.bat b/district-scripts/legacy-examples/windows/ExportBasinPie.bat deleted file mode 100644 index 375dae3..0000000 --- a/district-scripts/legacy-examples/windows/ExportBasinPie.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ../examples/BasinPie.py diff --git a/district-scripts/legacy-examples/windows/ExportStatusGraphic.bat b/district-scripts/legacy-examples/windows/ExportStatusGraphic.bat deleted file mode 100644 index 7e949f0..0000000 --- a/district-scripts/legacy-examples/windows/ExportStatusGraphic.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\StatusDemo.py diff --git a/district-scripts/legacy-examples/windows/PoolPercent.py b/district-scripts/legacy-examples/windows/PoolPercent.py deleted file mode 100644 index ed68fc6..0000000 --- a/district-scripts/legacy-examples/windows/PoolPercent.py +++ /dev/null @@ -1,73 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -percentCalc = registry.getCalculation(1.0, "Pool Percent") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -startCal.add(Calendar.DATE, -5) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -# percentCalc contains a single callable method calculatePoolPercents which takes the followind arguments: -# officeId -# locationId -# startDate -# endDate -# This recomputes the pool percentages for SWF.LEWT2 -percentCalc.calculatePoolPercents("SWF", "LEWT2", startCal.getTime(), endCal.getTime()) - - diff --git a/district-scripts/legacy-examples/windows/Sigstages_DBExport.py b/district-scripts/legacy-examples/windows/Sigstages_DBExport.py deleted file mode 100644 index 4562fac..0000000 --- a/district-scripts/legacy-examples/windows/Sigstages_DBExport.py +++ /dev/null @@ -1,13 +0,0 @@ -sigstages = registry.getCalculation(1.0, "Export Sig States") - -#sigstages has the following API exposed: -# -# public void exportSigStages(String file); - -# Purpose: -# Sigstages_DBExport.py retrieves information from the SWF database -# and writes the handbook_5 code for each location to a .txt file -# this file is read later by Sigstages_Download.py - -outpath = "sites.txt" -sigstages.exportSigStages(outpath) \ No newline at end of file diff --git a/district-scripts/legacy-examples/windows/Sigstages_DBImport.py b/district-scripts/legacy-examples/windows/Sigstages_DBImport.py deleted file mode 100644 index 1b2d8e8..0000000 --- a/district-scripts/legacy-examples/windows/Sigstages_DBImport.py +++ /dev/null @@ -1,34 +0,0 @@ -from java.util import Calendar -from java.util import TimeZone - -# this retrieves a Sig States caluclation object -sigstates = registry.getCalculation(1.0, "Import Sig States") - -#sigstates has the following API exposed: -# -# public void importSigStages(String file, Date effectiveDate); - -# Purpose: -# Sigstages_DBImport.py imports each of the location levels from -# the sig stage data into the REGI database for use in the REGI application - -# the file to be read in order to import the correct data to the REGI sigstates -# if you have your own .csv file, you can enter its full name here to import -# from that location instead, but sigstages.csv is the default generated from -# the Sigstages_Download script -inpath = "sigstages.csv" - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the sig states calculation requires an effective date -# here we create a java Calendar object that will be used to create that date -cal = Calendar.getInstance(timeZone) -cal.clear() -cal.set(Calendar.YEAR, 1899) -cal.set(Calendar.MONTH, Calendar.JANUARY) -cal.set(Calendar.DAY_OF_MONTH, 1) - -# the importSigStates method takes: -# inpath (csv file) -# effective date (calendar date) -sigstates.importSigStages(inpath, cal.getTime()) diff --git a/district-scripts/legacy-examples/windows/Sigstages_Download.py b/district-scripts/legacy-examples/windows/Sigstages_Download.py deleted file mode 100644 index ec66eb0..0000000 --- a/district-scripts/legacy-examples/windows/Sigstages_Download.py +++ /dev/null @@ -1,27 +0,0 @@ -sigstates = registry.getCalculation(1.0, "Retrieve Sig States") - -#sigstates has the following API exposed: -# -# public void retrieveSigstages(String sourceFile, String outputFile, int milliDelay); -# public void setParameter(String parameter); -# public String getParameter(String parameter); -# public void setParameterType(String parameterType); -# public String getParameter(); -# public void setDuration(String duration); -# public String getDuration(); -# public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText); -# public void getSpecifiedLevelOverride(Sigstage.Type type); -# public void setOffice(String office); -# public String getOffice(); - -# Purpose: -# Sigstages_Download.py accesses the AHPS data on the locations listed in -# "sites.txt" and retrieves the relevant sig stage information for each -# location, and stores in the sigstages.csv - -inpath = "sites.txt" # file to read the relevant sig stage sites from -outpath = "sigstages.csv" # file to write the relevant sig stage information gathered to -accessDelay = 5 # time delay in milliseconds between accesses to the AHPS site, to prevent blocking out - -sigstates.retrieveSigstages(inpath, outpath, accessDelay) - diff --git a/district-scripts/legacy-examples/windows/StageDBExport.bat b/district-scripts/legacy-examples/windows/StageDBExport.bat deleted file mode 100644 index b7c0ab0..0000000 --- a/district-scripts/legacy-examples/windows/StageDBExport.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\Sigstages_DBExport.py diff --git a/district-scripts/legacy-examples/windows/StageDBImport.bat b/district-scripts/legacy-examples/windows/StageDBImport.bat deleted file mode 100644 index f4b08de..0000000 --- a/district-scripts/legacy-examples/windows/StageDBImport.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\Sigstages_DBImport.py diff --git a/district-scripts/legacy-examples/windows/StageDownload.bat b/district-scripts/legacy-examples/windows/StageDownload.bat deleted file mode 100644 index 05646cf..0000000 --- a/district-scripts/legacy-examples/windows/StageDownload.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\Sigstages_Download.py diff --git a/district-scripts/legacy-examples/windows/StatusDemo.py b/district-scripts/legacy-examples/windows/StatusDemo.py deleted file mode 100644 index d322233..0000000 --- a/district-scripts/legacy-examples/windows/StatusDemo.py +++ /dev/null @@ -1,84 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Stream Status functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Stream Status functionality can be scripted. - """ - print msg - - -def headless_examples(): - # Description of: LoggingOptions.setDbMessageLevel(int level) - # - # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended - # level is 2, as this provides basic information about the time series - # retrieval/storage. - # - # Message Level | Description - # --------------|-------------------------------------------------------------------------------------------------------------------------------| - # <=0 | Default value, does not do anything. Lower values do not change behavior. | - # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | - # 2 | Adds message with name of time series, and the units to retrieve/store. | - # 3 | Adds message with the current time. | - # 4 | Adds message with first 10 dates and values from each time series. | - # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | - # --------------|-------------------------------------------------------------------------------------------------------------------------------| - - LoggingOptions.setDbMessageLevel(2) - - # This gets a scriptable Stream Status object. - streamStatus = registry.getCalculation(1.0, "Status") - - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - - # Configure the calendar - # Default start is top of the current hour - startCal = Calendar.getInstance(timeZone) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - - # If the filepath does not end in .jpg then the image will be saved in png format. - - # Generate a single image, - # at a single location within a basin, - # at single date, - # with a single chart template - # and write to specified file. - # Supports PNG and jpg output - - path = "headless\\StatusGraphics\\" - - print "Demonstrating a call to generateStreamStatusImage" - streamStatus.generateStreamStatusImage("SWF", "RSRT2", "Flood Control Focus View", startCal.getTime(), 800, 600, path + "streamStatus.jpg") - - print "Demonstrating a call to generateReservoirStatusImage" - streamStatus.generateReservoirStatusImage("SWF", "GPVT2", "Flood Control Focus View", startCal.getTime(), 800, 600, path + "reservoirStatus.jpg") - - print "Demonstrating a call to generateReleasesStatusImage" - streamStatus.generateReleasesStatusImage("SWF", "WTYT2", "Flood Control Focus View", startCal.getTime(), 800, 600, path + "releasesStatus.jpg") - - -if __name__ == "__builtin__": - Usage() - headless_examples() - - -if __name__ == "__main__": - Usage() diff --git a/district-scripts/legacy-examples/windows/credentials.properties b/district-scripts/legacy-examples/windows/credentials.properties deleted file mode 100644 index ddb565c..0000000 --- a/district-scripts/legacy-examples/windows/credentials.properties +++ /dev/null @@ -1,7 +0,0 @@ -rowcps.projectDir=.\\Regi Base\\bang\\ -rowcps.projectName=bang - -oracle.url=jdbc:oracle:thin:@10.0.0.36:1539:V122SWT1811REGI -oracle.officeId=SWT - -hec.passwd=headless.password \ No newline at end of file diff --git a/district-scripts/legacy-examples/windows/headless.password b/district-scripts/legacy-examples/windows/headless.password deleted file mode 100644 index 5b27e06..0000000 --- a/district-scripts/legacy-examples/windows/headless.password +++ /dev/null @@ -1,2 +0,0 @@ -v2.0 -bang:1521:v11203swf02|QZg5V85RPTaV2ew1XkEVhBd/vHtxTr/rsDmgHyBfSoD= diff --git a/district-scripts/legacy-examples/windows/poolpercent.bat b/district-scripts/legacy-examples/windows/poolpercent.bat deleted file mode 100644 index d64ad3c..0000000 --- a/district-scripts/legacy-examples/windows/poolpercent.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\PoolPercent.py diff --git a/district-scripts/legacy-examples/windows/printInfo.py b/district-scripts/legacy-examples/windows/printInfo.py deleted file mode 100644 index 65604f4..0000000 --- a/district-scripts/legacy-examples/windows/printInfo.py +++ /dev/null @@ -1,15 +0,0 @@ -from java.util import TimeZone -from java.lang import System - -def printTimeZone(): - tz = TimeZone.getDefault() - id = tz.getID() - - regiTzId = System.getProperty("rowcps.timezone") - regiTz = TimeZone.getTimeZone(regiTzId) - - print "Default system timezone:{0}, Observes daylight: {1}".format(id, str(tz.useDaylightTime())) - print "Regi timezone:{0}, Observes daylight: {1}".format(regiTzId, str(regiTz.useDaylightTime())) - -def printAll(): - printTimeZone() \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Assoc_DBExport.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/Assoc_DBExport.py deleted file mode 100644 index 80a9e97..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Assoc_DBExport.py +++ /dev/null @@ -1,31 +0,0 @@ -exportAssociations = registry.getCalculation(1.0, "Export Associations") - -#exportAssociations has the following API exposed: -# -# public void exportAllTSAssociations(String outputPath, String lineSeparator, String valueSeparator); -# public void exportTSAssociations(String project, String fileLoc, String lineDelimiter, String valueDelimiter); - -print("Exporting all Associations") -outputPath = "Associations.csv" -lineSeparator = "\n" -valueSeparator = "\t" -exportAssociations.exportAllTSAssociations(outputPath, lineSeparator, valueSeparator) -print("Exported successfully.") - -print("Exporting BDWT2's Associations.") -outputPath = "BDWT2 Associations.csv" -projectName="BDWT2" -exportAssociations.exportTSAssociations(projectName, outputPath, lineSeparator, valueSeparator) -print("Exported successfully.") - -print("Exporting SMCT2's Associations.") -outputPath = "SMCT2 Associations.csv" -projectName="SMCT2" -exportAssociations.exportTSAssociations(projectName, outputPath, lineSeparator, valueSeparator) -print("Exported successfully.") - -print("Exporting TXKT2's Associations.") -outputPath = "TXKT2 Associations.csv" -projectName="TXKT2" -exportAssociations.exportTSAssociations(projectName, outputPath, lineSeparator, valueSeparator) -print("Exported successfully.") \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/PoolPercentCalc.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/PoolPercentCalc.py deleted file mode 100644 index 6afae66..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/PoolPercentCalc.py +++ /dev/null @@ -1,31 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone - -# this gets a scriptable Pool Percent object -percentCalc = registry.getCalculation(1.0, "Pool Percent") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) - - -# percentCalc contains a single callable method calculatePoolPercents which takes the followind arguments: -# officeId -# locationId -# startDate -# endDate -# This recomputes the pool percentages for SWF.LEWT2 -percentCalc.calculatePoolPercents("SWF", "LEWT2", startCal.getTime(), endCal.getTime()) - - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/ScriptableGateFlowImplTest.java_old b/regi-headless/src/test/resources/usace/rowcps/headless/examples/ScriptableGateFlowImplTest.java_old deleted file mode 100644 index 89995c7..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/ScriptableGateFlowImplTest.java_old +++ /dev/null @@ -1,45 +0,0 @@ -package usace.cwms.headless.jar; - -import java.util.Calendar; -import org.junit.Test; - - -/** - * - * @author ryan - */ -public class ScriptableGateFlowImplTest extends UiRegiDomainTest - -{ - - public ScriptableGateFlowImplTest() - { - } - - @Test - public void testSomeMethod() - { - ScriptableGateFlowCalc cal = new ScriptableGateFlowImpl(getRegiDomain(), getManagerId()); - //Time zone must be set because the Solaris time zone is UTC - TimeZone timeZone = TimeZone.getTimeZone("US/Central"); - Calendar startCal = Calendar.getInstance(timeZone); - startCal.clear(); - startCal.set(2015, 3, 2, 12, 6); - - - long startTime = startCal.getTimeInMillis(); - - - - Calendar endCal = Calendar.getInstance(timeZone); - endCal.clear(); - endCal.set(Calendar.YEAR, 2015); - endCal.set(Calendar.MONTH, 6); - long endTime = endCal.getTimeInMillis(); -//start 1430463600000 - // end 1435734000000 - cal.computeFlowGroup("SWF", "LEWT2", startTime, endTime, "Flow.LEWT2.ConduitGate_Total"); - - } - -} diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBExport.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBExport.py deleted file mode 100644 index 38ead57..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBExport.py +++ /dev/null @@ -1,8 +0,0 @@ -sigstages = registry.getCalculation(1.0, "Export Sig States") - -#sigstages has the following API exposed: -# -# public void exportSigStages(String file); - -outpath = "sites.txt" -sigstages.exportSigStages(outpath) \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBImport.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBImport.py deleted file mode 100644 index aab8982..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_DBImport.py +++ /dev/null @@ -1,8 +0,0 @@ -sigstates = registry.getCalculation(1.0, "Import Sig States") - -#sigstates has the following API exposed: -# -# public void importSigStages(String file); - -inpath = "sigstages.csv" -sigstates.importSigStages(inpath) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_Download.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_Download.py deleted file mode 100644 index d6f4aa5..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/Sigstages_Download.py +++ /dev/null @@ -1,21 +0,0 @@ -sigstates = registry.getCalculation(1.0, "Retrieve Sig States") - -#sigstates has the following API exposed: -# -# public void retrieveSigstages(String sourceFile, String outputFile); // Read names from sourceFile, write CSV to outputFile -# public void retrieveSigstages(String sourceFile, String outputFile); -# public void setParameter(String parameter); -# public String getParameter(String parameter); -# public void setParameterType(String parameterType); -# public String getParameter(); -# public void setDuration(String duration); -# public String getDuration(); -# public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText); -# public void getSpecifiedLevelOverride(Sigstage.Type type); -# public void setOffice(String office); -# public String getOffice(); - -inpath = "sites.txt" -outpath = "sigstages.csv" -sigstates.retrieveSigstages(inpath, outpath) - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/StatusDemo.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/StatusDemo.py deleted file mode 100644 index 080de94..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/StatusDemo.py +++ /dev/null @@ -1,56 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -import sys -import getopt - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Stream Status functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Stream Status functionality can be scripted. - """ - print msg - -def headless_examples(): - # This gets a scriptable Stream Status object. - streamStatus = registry.getCalculation(1.0, "Status") - - # Configure the calendar - timeZone = streamStatus.getRegiTimeZone(); - startCal = Calendar.getInstance(timeZone) - startCal.clear() - startCal.set(Calendar.YEAR, 2016) - startCal.set(Calendar.MONTH, 0) - startCal.set(Calendar.DATE, 1) - startCal.set(Calendar.HOUR, 0) - # Month 4 means May to java... - - # If the filepath does not end in .jpg then the image will be saved in png format. - - # Generate a single image, - # at a single location within a basin, - # at single date, - # with a single chart template - # and write to specified file. - #print "Demonstrating a call to generateStreamStatusImage" - #streamFilepath = "J:\\temp\\headless\\StatusGraphics\\streamStatusStandard.jpg" - #streamStatus.generateStreamStatusImage("SWF", "RSRT2", "Flood Control Focus View", startCal.getTime(), 800, 600, streamFilepath) - - #print "Demonstrating a call to generateReservoirStatusImage" - reservoirFilePath = "J:\\temp\\headless\\StatusGraphics\\reservoirStatus.jpg" - streamStatus.generateReservoirStatusImage("SWF", "GPVT2", "Flood Control Focus View", startCal.getTime(), 800, 600, reservoirFilePath) - - #print "Demonstrating a call to generateReleasesStatusImage" - #releasesFilePath = "J:\\temp\\headless\\StatusGraphics\\releasesStatus.jpg" - #streamStatus.generateReleasesStatusImage("SWF", "WTYT2", "Flood Control Focus View", startCal.getTime(), 800, 600, releasesFilePath) - -if __name__ == "__builtin__": - Usage() - headless_examples() - -if __name__ == "__main__": - Usage() \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/hello.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/hello.py deleted file mode 100644 index 6805cc5..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/hello.py +++ /dev/null @@ -1 +0,0 @@ -print "Python Script - Hello, world!", regiDomain.getName() \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/15618-StatusDemo.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/15618-StatusDemo.py deleted file mode 100644 index ed3fd02..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/15618-StatusDemo.py +++ /dev/null @@ -1,76 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -import sys -import getopt - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Stream Status functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Stream Status functionality can be scripted. - """ - print msg - -def headless_examples(): - # This gets a scriptable Stream Status object. - streamStatus = registry.getCalculation(1.0, "Status") - - # Configure the calendar - #Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - startCal = Calendar.getInstance(timeZone) - startCal.clear() - startCal.set(Calendar.YEAR, 2018) - startCal.set(Calendar.MONTH, 7) - startCal.set(Calendar.DATE, 27) - startCal.set(Calendar.HOUR_OF_DAY, 0) - # Month 4 means May to java... - - # If the filepath does not end in .jpg then the image will be saved in png format. - # Generate a single image, - # at a single location within a basin, - # at single date, - # with a single chart template - # and write to specified file. - print "Demonstrating a call to generateStreamStatusImage" - filepath = "E:\\temp\\15618\\" - maptemplate = "OpsSupport_133658" - officeID = "SWT" - #streamFilepath = "J:\\temp\\headless\\StatusGraphics\\streamStatus.jpg" - fileStream = filepath + "A_Stream_" - fileReservoir = filepath + "B_Reservoir_" - fileReleases = filepath + "C_Releases_" - - width = 640 - height = 480 - - print "Demonstrating a call to generateStreamStatusImage" - #streamStatus.generateStreamStatusImage(officeID, "RIPL", maptemplate, startCal.getTime(), width, height, fileStream+"RIPL.png") - #streamStatus.generateStreamStatusImage(officeID, "CHEW", maptemplate, startCal.getTime(), width, height, fileStream+"CHEW.png") - #streamStatus.generateStreamStatusImage(officeID, "TULA", maptemplate, startCal.getTime(), width, height, fileStream+"TULA.png") - - print "Demonstrating a call to generateReservoirStatusImage" - #reservoirFilePath = "J:\\temp\\headless\\StatusGraphics\\reservoirStatus.jpg" - #streamStatus.generateReservoirStatusImage(officeID, "KEYS", maptemplate, startCal.getTime(), width, height, fileReservoir+"KEYS.png") - #streamStatus.generateReservoirStatusImage(officeID, "FGIB", maptemplate, startCal.getTime(), width, height, fileReservoir+"FGIB.png") - - for i in range(1): - streamStatus.generateReservoirStatusImage(officeID, "SKIA", maptemplate, startCal.getTime(), width, height, fileReservoir+"SKIA" + str(i) + ".png") - startCal.add(Calendar.HOUR_OF_DAY, 1) - - print "Demonstrating a call to generateReleasesStatusImage" - #releasesFilePath = "J:\\temp\\headless\\StatusGraphics\\releasesStatus.jpg" - #streamStatus.generateReleasesStatusImage(officeID, "FGIB", maptemplate, startCal.getTime(), width, height, fileReleases+"FGIB.png") - #streamStatus.generateReleasesStatusImage(officeID, "KEYS", maptemplate, startCal.getTime(), width, height, fileReleases+"KEYS.png") - #streamStatus.generateReleasesStatusImage(officeID, "TENK", maptemplate, startCal.getTime(), width, height, fileReleases+"TENK.png") - -if __name__ == "__builtin__": - Usage() - headless_examples() - -if __name__ == "__main__": - Usage() \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Assoc_DBExport.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/Assoc_DBExport.py deleted file mode 100644 index 6aefc8f..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Assoc_DBExport.py +++ /dev/null @@ -1,19 +0,0 @@ -from usace.rowcps.headless.tests import TestVariables - -exportAssociations = registry.getCalculation(1.0, "Export Associations") - -#exportAssociations has the following API exposed: -# -# public void exportAllTSAssociations(String outputPath, String lineSeparator, String valueSeparator); -# public void exportTSAssociations(String project, String fileLoc, String lineDelimiter, String valueDelimiter); - -print("Exporting all Associations") -outputPath = "Associations.csv" -lineSeparator = "\n" -valueSeparator = "\t" -locs = TestVariables.ALL_PROJECTS -exportAssociations.exportAllTSAssociations(TestVariables.HEADLESS_FILE_LOCATION + outputPath, lineSeparator, valueSeparator) - -for loc in locs: - exportAssociations.exportTSAssociations(loc, TestVariables.HEADLESS_FILE_LOCATION + loc + " " + outputPath, lineSeparator, valueSeparator) - print("Exported successfully.") diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/BasinPieExport.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/BasinPieExport.py deleted file mode 100644 index 2ad90da..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/BasinPieExport.py +++ /dev/null @@ -1,219 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -import os, sys -import getopt -from usace.rowcps.headless.tests import TestVariables -sys.path.insert(0, os.path.abspath("..")) -#from examples import printInfo - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Basin Pie functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Basin Pie functionality can be scripted. - """ - print msg - -def headless_examples(): - - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - # Configure the calendar for the date and time of the Basin Pie graphic - startCal = Calendar.getInstance(timeZone) - startCal.clear() - startCal.set(Calendar.YEAR, 2016) - startCal.set(Calendar.MONTH, 4) - startCal.set(Calendar.DATE, 5) - # Month 4 means May to java... - - # Generate multiple images - # First built the dates - for i in range(0, 3): - startCal.add(Calendar.DATE, 1) - - # When generating multiple image files the filepath may contain replacement keywords. - # If these keywords are found in the filepath they are replaced with named piece of data. - # Once the replacements are made, illegal characters in the filename are replaced with '_'. - # The following keywords are currently recognized: - # %date% - # %office_id% - # %location_id% - # %chart_template_id% - # %basin_id% - # %image_format% - # Example: filepath like: - # "J:\\temp\\headless\\%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - # Will generate the following files: - # J:\\temp\\headless\\SWT_Trinity_R_Basin_RSRT2_Conservation Pool (static)_2016-04-02T00_00_00Z.png - - fileName = "test_%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - filePath = TestVariables.HEADLESS_FILE_LOCATION + "BasinPieExport\\" - - # Generate a basin pie image, - # for each of the specified locations in the specified basin, - # for each of the dates, - # for each of the chart templates - # replace %% patterns in the specified filepath template - # and write each image to its generated filepath -# print "Demonstrating a call to generateBasinPieImages" -# generateBasinPieImages("SWT", ["LOLT2"], "Trinity_R_Basin", -# dates, 700, 807, -# ["Design Capacity"], -# filepath) - - # Generate an image - # for the locations found in a basin - # for each of the dates, - # for each of the chart templates - # replace %% patterns in the specified filepath template - # and write each image to its generated filepath - - office = TestVariables.OFFICE_ID - templateId1 = "RyanM Headless Testing2" - templateId2 = "Conservation Pool (static)" - time = startCal.getTime() - loc1 = TestVariables.GATE_LOCATION - loc2 = TestVariables.INFLOW_LOCATION - loc3 = TestVariables.POOL_LOCATION - loc4 = TestVariables.LOCATION_4 - basin = "CANADIAN_BASIN" - group = "A Small Group" - width = 797 - height = 682 - - print "Demonstrating a call to generateBasinPieImageForGroup" - generateBasinPieImageForGroup(office, loc1, group, time, width, height, templateId1, filePath + "generateBasinPieImageForGroup\\" + fileName) - - print "Demonstrating a call to generateBasinPieImagesForGroup" - generateBasinPieImagesForGroup(office, [loc3,loc2], group, [time], width, height, [templateId1], filePath + "generateBasinPieImagesForGroup\\" + fileName) - - print "Demonstrating a call to generateBasinPieImageForBasin" - generateBasinPieImageForBasin(office, loc1, basin, time, width, height, templateId1, filePath + "generateBasinPieImageForBasin\\" + fileName) - - print "Demonstrating a call to generateBasinPieImagesForBasin" - generateBasinPieImagesForBasin(office, [loc4, loc1], basin, [time], width, height,[templateId1], filePath + "generateBasinPieImagesForBasin\\" + fileName) - - print "Demonstrating a call to generateAllBasinPieImagesForBasin" - generateAllBasinPieImagesForBasin(office, basin, [time], width, height, [templateId2], filePath + "generateAllForBasin\\" + fileName) - - print "Demonstrating a call to generateAllBasinPieImagesForGroup" - generateAllBasinPieImagesForGroup(office, group, [time], width, height, [templateId2], filePath + "generateAllForGroup\\" + fileName) - - -def generateBasinPieImageForBasin(office_id, location_id, basin_id, - date, width, height, - chart_template_id, - filepath): - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_id: The location for which the basin pie image is desired - :param basin_id: The id of the Basin - :param date: This specifies the time for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_id: The id of the chart template to use. - :param filepath: Path of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImageForBasin(office_id, location_id, basin_id, - date, width, height, - chart_template_id, - filepath) - -def generateBasinPieImagesForBasin(office_id, location_ids, basin_id, - dates, width, height, - chart_template_ids, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_ids: A list of the locations for which basin pie images are desired - :param basin_id: The id of the Basin - :param dates: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_ids: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImagesForBasin(office_id, location_ids, basin_id, - dates, width, height, - chart_template_ids, - filepath) - -def generateBasinPieImageForGroup(office_id, location_id, group_id, - date, width, height, - chart_template_id, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_id: A list of the locations for which basin pie images are desired - :param group_id: The id of the Group - :param date: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_id: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImageForGroup(office_id, location_id, group_id, - date, width, height, - chart_template_id, - filepath) - -def generateBasinPieImagesForGroup(office_id, location_ids, group_id, - dates, width, height, - chart_template_ids, - filepath): - # type: (string, string, string, [date], int, int, [string], string) -> void - """ - - :param office_id: The office id used for finding the specified locations, basin and chart_template - :param location_ids: A list of the locations for which basin pie images are desired - :param group_id: The id of the Group - :param dates: A list of the times for which the image should be generated - :param width: width in pixels - :param height: height in pixels - :param chart_template_ids: The ids of the chart template to use. - :param filepath: Path (template) of where to write the file. - """ - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateBasinPieImagesForGroup(office_id, location_ids, group_id, - dates, width, height, - chart_template_ids, - filepath) - -def generateAllBasinPieImagesForBasin(office_id, basin_id, - dates, width, height, - chart_template_ids, - filepath): - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateAllBasinPieImagesForBasin(office_id, basin_id, - dates, width, height, - chart_template_ids, - filepath) - -def generateAllBasinPieImagesForGroup(office_id, group_id, - dates, width, height, - chart_template_ids, - filepath): - basinPie = registry.getCalculation(1.0, "Status") - basinPie.generateAllBasinPieImagesForGroup(office_id, group_id, - dates, width, height, - chart_template_ids, - filepath) - -if __name__ == "__builtin__": - Usage() - headless_examples() - -if __name__ == "__main__": - Usage() \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercentCalc.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercentCalc.py deleted file mode 100644 index 7dd2a33..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercentCalc.py +++ /dev/null @@ -1,32 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -# this gets a scriptable Pool Percent object -percentCalc = registry.getCalculation(1.0, "Pool Percent") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) - - -# percentCalc contains a single callable method calculatePoolPercents which takes the following arguments: -# officeId -# locationId -# startDate -# endDate -# This recomputes the pool percentages for SWT.LEWT2 -percentCalc.calculatePoolPercents(TestVariables.OFFICE_ID, TestVariables.POOL_LOCATION, startCal.getTime(), endCal.getTime()) - - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercent_15614.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercent_15614.py deleted file mode 100644 index 922be96..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/PoolPercent_15614.py +++ /dev/null @@ -1,66 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -percentCalc = registry.getCalculation(1.0, "Pool Percent") - -#Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 7) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 8) - - -# percentCalc contains a single callable method calculatePoolPercents which takes the followind arguments: -# officeId -# locationId -# startDate -# endDate -# This recomputes the pool percentages for SWF.LEWT2 -officeID = "SWT" -percentCalc.calculatePoolPercents(officeID, "EUFA", startCal.getTime(), endCal.getTime()) -#percentCalc.calculatePoolPercents(officeID, "SKIA", startCal.getTime(), endCal.getTime()) - - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBExport.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBExport.py deleted file mode 100644 index fac919a..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBExport.py +++ /dev/null @@ -1,8 +0,0 @@ -from usace.rowcps.headless.tests import TestVariables -sigstages = registry.getCalculation(1.0, "Export Sig States") - -# sigstages has the following API exposed: -# -# public void exportSigStages(String file); -outpath = TestVariables.HEADLESS_FILE_LOCATION + "SigStages\\sites.txt" -sigstages.exportSigStages(outpath) \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBImport.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBImport.py deleted file mode 100644 index f8edbb1..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_DBImport.py +++ /dev/null @@ -1,11 +0,0 @@ -from usace.rowcps.headless.tests import TestVariables - -sigstates = registry.getCalculation(1.0, "Import Sig States") - -# sigstates has the following API exposed: -# -# public void importSigStages(String file); -path = TestVariables.HEADLESS_FILE_LOCATION + "SigStages\\" - -inpath = path + "sigstages.csv" -sigstates.importSigStages(inpath) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_Download.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_Download.py deleted file mode 100644 index b70f6ca..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/Sigstages_Download.py +++ /dev/null @@ -1,23 +0,0 @@ -from usace.rowcps.headless.tests import TestVariables - -sigstates = registry.getCalculation(1.0, "Retrieve Sig States") - -# sigstates has the following API exposed: -# -# public void retrieveSigstages(String sourceFile, String outputFile); // Read names from sourceFile, write CSV to outputFile -# public void setParameter(String parameter); -# public String getParameter(String parameter); -# public void setParameterType(String parameterType); -# public String getParameter(); -# public void setDuration(String duration); -# public String getDuration(); -# public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText); -# public void getSpecifiedLevelOverride(Sigstage.Type type); -# public void setOffice(String office); -# public String getOffice(); -path = TestVariables.HEADLESS_FILE_LOCATION + "SigStages\\" - -inpath = path + "sites.txt" -outpath = path + "sigstages.csv" -sigstates.retrieveSigstages(inpath, outpath) - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/StatusDemo.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/StatusDemo.py deleted file mode 100644 index 50a2372..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/StatusDemo.py +++ /dev/null @@ -1,56 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -def Usage(): - msg = """ - This file demonstrates how to utilize the Headless Stream Status functionality. - This script is not meant to be executed by itself but should be executed from the RegiCLI. - Among other things the RegiCLI opens the specified study and connects to the database using the specified - credentials. Once RegiCLI has completed the preliminary steps it will execute the specified python scripts - and allow the scripts to call into the Java classes and methods. - This file is an example of how the Stream Status functionality can be scripted. - """ - print msg - -def headless_examples(): - # This gets a scriptable Stream Status object. - streamStatus = registry.getCalculation(1.0, "Status") - - # Configure the calendar - timeZone = TimeZone.getTimeZone("US/Central") - startCal = Calendar.getInstance(timeZone) - startCal.clear() - startCal.set(Calendar.YEAR, 2018) - startCal.set(Calendar.MONTH, 6) - startCal.set(Calendar.DATE, 2) - # Month 4 means May to java... - - # If the filepath does not end in .jpg then the image will be saved in png format. - - # Generate a single image, - # at a single location within a basin, - # at single date, - # with a single chart template - # and write to specified file. - filePath = TestVariables.HEADLESS_FILE_LOCATION + "StatusGraphics\\" - office = TestVariables.OFFICE_ID - streamLoc = TestVariables.STREAM_GAGE_LOCATION - projectLoc = TestVariables.INFLOW_LOCATION - releasesLoc = TestVariables.GATE_LOCATION - template = "RyanM Headless Testing" - time = startCal.getTime() - width = 800 - height = 600 - - streamStatus.generateStreamStatusImage(office, streamLoc, template, time, width, height, filePath + "streamStatus.jpg") - streamStatus.generateReservoirStatusImage(office, projectLoc, template, time, width, height, filePath + "reservoirStatus.jpg") - streamStatus.generateReleasesStatusImage(office, releasesLoc, template, time, width, height, filePath + "releasesStatus.jpg") - -if __name__ == "__builtin__": - Usage() - headless_examples() - -if __name__ == "__main__": - Usage() \ No newline at end of file From 269cc39cd84e1ac45605077bcf88b8d42bf3e1c6 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Thu, 9 Jul 2026 13:41:14 -0700 Subject: [PATCH 07/26] code review updates --- README.md | 15 ++++++++++++--- .../headless/HeadlessRegiDomainFactory.java | 1 + .../gatesettings/ScriptableGateSettingsImpl.java | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7d6b916..cd6752e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > [!IMPORTANT] > **Notice: Project Refactor in Progress** -> This project is undergoing a large refactor for CWMS Data API support. +> This project is undergoing a large refactor for [CWMS Data API](https://github.com/USACE/cwms-data-api) support. > It will transition from a Java project consuming Jython scripts to a **Python project** that > utilizes **JPype** to call underlying REGI Java libraries. @@ -30,7 +30,16 @@ scripts without the need for a graphical interface. ### Prerequisites - Java JDK 21 or higher. -- Access to a CWMS + +### CWMS Data API Configuration + +The library reads the following environment variables when establishing the CWMS Data API data source: + +- `CDA_URL`: Base URL for the CWMS Data API endpoint. +- `API_KEY`: API key used for CWMS Data API authentication and authorization. +- `OFFICE_ID`: CWMS office identifier used to scope the session. + +The factory uses these values to authenticate, resolve the current user, and persist the connected office and time zone into the REGI project. ### Building @@ -63,4 +72,4 @@ See [MAINTAINERS.md](MAINTAINERS.md) for a list of project maintainers. ## License -See [LICENSE](LICENSE) for licensing information. \ No newline at end of file +See [LICENSE](LICENSE) for licensing information. diff --git a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java index 494dd94..b2cff43 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java @@ -84,6 +84,7 @@ public RegiDomain createDomain() throws DbConnectionException, TimeZoneDisplayService tsDS = ServiceLookup.getTimeZoneDisplayService(); tsDS.setTimeZone(connectionManager.getTimeZone()); regiDomain.connect(ServerSuiteUtil.getServerSuite()); + //Resolve manager proxies to ensure they are initialized before saving the project regiDomain.getManagerList(); regiDomain.saveProject(); RegiDomain.setCurrentProject(regiDomain); diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java index 544f0d9..3c2bffd 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java @@ -102,7 +102,7 @@ public class ScriptableGateSettingsImpl extends AbstractScriptableCalc implements ScriptableCalc, ScriptableGateSettings { - public final static String LATCH_SECONDS = "rowcps.latchseconds"; + private static final String LATCH_SECONDS = "rowcps.latchseconds"; private static final Logger LOGGER = Logger.getLogger(ScriptableGateSettings.class.getName()); public ScriptableGateSettingsImpl(RegiDomain regiDomain, ManagerId managerId) { From 372ca4a975a6ebb190aa50e1c7131fb85e4f68b1 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Thu, 2 Jul 2026 20:20:30 -0700 Subject: [PATCH 08/26] migrate Jython-based Java application to Python-based impl with JPype - build orchestration with gradle --- README.md | 77 +++- build.gradle | 52 ++- gradle/libs.versions.toml | 1 + regi-headless/build.gradle | 86 ++++- .../usace/rowcps/headless/CLIOptions.java | 341 ------------------ .../headless/HeadlessRegiDomainFactory.java | 14 +- .../rowcps/headless/PythonEvaluator.java | 72 ---- .../java/usace/rowcps/headless/RegiCLI.java | 152 -------- regi-headless/src/main/python/pyproject.toml | 17 + .../src/main/python/regi_python/__init__.py | 10 + .../main/python/regi_python/regi_python.py | 76 ++++ .../python/regi_python/regi_python_logging.py | 47 +++ .../retrieve/xmlmodel/HydroGenData.xsd | 218 ----------- .../rowcps/headless/credentials.properties | 9 - .../usace/rowcps/headless/hec.passwd | 2 - 15 files changed, 344 insertions(+), 830 deletions(-) delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/CLIOptions.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java create mode 100644 regi-headless/src/main/python/pyproject.toml create mode 100644 regi-headless/src/main/python/regi_python/__init__.py create mode 100644 regi-headless/src/main/python/regi_python/regi_python.py create mode 100644 regi-headless/src/main/python/regi_python/regi_python_logging.py delete mode 100644 regi-headless/src/main/resources/usace/rowcps/headless/sigstages/retrieve/xmlmodel/HydroGenData.xsd delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/credentials.properties delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/hec.passwd diff --git a/README.md b/README.md index cd6752e..99d78f4 100644 --- a/README.md +++ b/README.md @@ -6,23 +6,24 @@ > It will transition from a Java project consuming Jython scripts to a **Python project** that > utilizes **JPype** to call underlying REGI Java libraries. -`REGI-Headless` is a Java-based command-line tool and library designed to run -**REGI** calculations in a headless environment. -It allows users to execute complex hydrological calculations and manage gate settings via Jython -scripts without the need for a graphical interface. +`REGI-Headless` provides a Python-based interface for running **REGI** calculations in a headless environment. It allows users to execute complex hydrological calculations and manage gate settings via Python scripts, leveraging the performance and stability of the original REGI Java libraries. ## Features -- **Headless Execution**: Run REGI calculations as part of automated workflows or on servers. -- **Database Integration**: Connects to CWMS data retrieval and storage. -- **Modular Calculations**: Includes support for: +- **Headless Execution**: Run REGI calculations as part of automated workflows, CI/CD pipelines, or on servers. +- **Python-First API**: Write calculation scripts in standard Python 3. +- **Java Interoperability**: Direct access to REGI Java libraries via JPype. +- **Modular Calculations**: Full support for: - Inflow calculations (Clone, Compute, Auto-Adjust, Balance All, etc.) - - Flow Group and gate settings calculations. + - Flow Group + - Gate settings calculations. ## Project Structure -- `regi-headless/`: Core Java implementation, including `RegiCLI`. -- `district-scripts/`: Example scripts and district-specific configurations. +- `regi-headless/`: Core implementation. + - `src/main/python/`: The `regi-python` package source. + - `src/main/java/`: Java-based headless support and factories. +- `district-scripts/`: Legacy Jython scripts and district-specific configurations. - `docs/`: Additional documentation. ## Getting Started @@ -30,6 +31,7 @@ scripts without the need for a graphical interface. ### Prerequisites - Java JDK 21 or higher. +- **Python 3.11** or higher. ### CWMS Data API Configuration @@ -43,28 +45,67 @@ The factory uses these values to authenticate, resolve the current user, and per ### Building +The project uses Gradle to manage both Java and Python builds. To build the Python wheel including all Java dependencies: ```powershell -./gradlew build +./gradlew buildPythonWheel ``` -Details TBD. +The resulting wheel file will be located in `regi-headless/build/install/regi-python/dist/`. ## Usage -TBD +### Installation -### Command Line Options +Install the built wheel into your Python environment: -TBD +```powershell +pip install regi_python-*.whl +``` + +### Script Example + +The Python bridge uses a context manager to handle the JVM lifecycle and a callback mechanism for calculations. + +```python +from regi_python import regi_session, run_headless +from java.util import Calendar, TimeZone + +def my_calculations(registry): + # 'registry' is a RegiCalcRegistry instance + gate_calc = registry.getCalculation(1.0, "Gate Flow") + + # Configure time window + tz = TimeZone.getTimeZone("US/Central") + start = Calendar.getInstance(tz) + start.set(2025, 0, 1) # Jan 1, 2025 + + end = Calendar.getInstance(tz) + end.set(2025, 0, 2) # Jan 2, 2025 + + # Execute calculation + gate_calc.computeAll("OFFICE", "PROJECT", start.getTimeInMillis(), end.getTimeInMillis()) + +if __name__ == "__main__": + with regi_session(): + run_headless(my_calculations) +``` -### Example +### Environment Variables -TBD +- `JAVA_HOME`: Path to your Java installation (required for JPype). +- `REGI_LOG_LEVEL`: Logging level (e.g., `DEBUG`, `INFO`, `ERROR`). +- `CDA_URL`: URL for the CWMS Data API. +- `CDA_API_KEY`: API Key for CDA authentication. +- `OFFICE_ID`: Office ID for CDA authentication. ## Testing -TBD +To run the automated tests which build the wheel and execute a test script in a virtual environment: + +```powershell +./gradlew testPythonWheel +``` ## Maintainers diff --git a/build.gradle b/build.gradle index 84613dc..c5a87e7 100644 --- a/build.gradle +++ b/build.gradle @@ -3,14 +3,52 @@ plugins { id "org.sonarqube" version "7.3.1.8318" } -def versionLabel(gitInfo) { - def branch = gitInfo.branchName // all branches are snapshots, only tags get released - def tag = gitInfo.lastTag - // tag is returned as is. Branch may need cleanup - return branch == null ? tag : "99." + branch.replace("/","-") + "-SNAPSHOT" +def gitOutput(String... args) { + return providers.exec { + commandLine(['git'] + args.toList()) + ignoreExitValue = true + }.standardOutput.asText.get().trim() +} + +def pep440VersionFromLatestTag() { + def tag = gitOutput('describe', '--tags', '--abbrev=0') + if (!tag) { + tag = '0.0.0' + } + + def baseVersion = tag.startsWith('v') ? tag.substring(1) : tag + + def distanceText = tag == '0.0.0' + ? gitOutput('rev-list', 'HEAD', '--count') + : gitOutput('rev-list', "${tag}..HEAD", '--count') + def distance = distanceText?.isInteger() ? distanceText.toInteger() : 0 + + def hash = gitOutput('rev-parse', '--short=7', 'HEAD') + def dirty = gitOutput('status', '--porcelain') ? true : false + + if (distance == 0 && !dirty) { + return baseVersion + } + + def version = "${baseVersion}.post${distance}" + def localParts = [] + + if (hash) { + localParts.add("g${hash}") + } + + if (dirty) { + localParts.add("dirty") + } + + if (!localParts.isEmpty()) { + version += "+" + localParts.join(".") + } + + return version } allprojects { - group = 'mil.army.wmist.regi-headless' - version = versionLabel(versionDetails()) + group = 'mil.army.wmist.regi-python' + version = pep440VersionFromLatestTag() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 530fd77..9cd9e82 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -36,6 +36,7 @@ regi-tools-regi-cwms = {module = "mil.army.wmist.regi-tools:regi-cwms", version. # Third Party jython-standalone = {module = "org.python:jython-standalone", version.ref = "jython-standalone"} args4j = {module = "args4j:args4j", version.ref = "args4j"} +otel = {module = "io.opentelemetry:opentelemetry-api", version="1.58.0"} # Test junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index c4a6bf1..8ed64bc 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -1,6 +1,9 @@ +import com.pswidersk.gradle.python.VenvTask + plugins { id 'regi-headless.deps-conventions' id 'regi-headless.java-conventions' + id 'com.pswidersk.python-plugin' version '3.2.16' } dependencies { @@ -45,6 +48,85 @@ jar { } } -test { - useJUnitPlatform() +pythonPlugin { + pythonVersion = "3.11.15" + condaVersion = "26.3.2-2" + condaInstaller = "Miniforge3" + installDir = file(layout.buildDirectory.dir("python")) +} + +tasks.register('installPythonBuildTools', VenvTask) { + group = 'build setup' + description = 'Installs Python packages needed to build the wheel.' + + venvExec = 'pip' + args = ['install', '--upgrade', 'pip', 'build'] +} + +tasks.register('buildPythonWheel', VenvTask) { + group = "distribution" + description = "Builds a Python .whl file using the Gradle-managed Python environment." + + dependsOn bundlePython + dependsOn installPythonBuildTools + + workingDir = file("${buildDir}/install/regi-python") + venvExec = "python" + args = ["-m", "build", "--wheel"] + + doLast { + println "Python Wheel built in: ${workingDir}/dist" + } +} + +tasks.register('bundlePython', Sync) { + description = 'Bundles Python scripts and creates the java_lib directory' + into "${buildDir}/install/regi-python/" + + from('src/main/python') { + include 'pyproject.toml' + filter { line -> line.replaceAll('@VERSION@', project.version.toString()) } + } + + from('src/main/python') { + exclude 'pyproject.toml' + } + + into('regi-python/lib') { + from configurations.runtimeClasspath + from jar.archiveFile + exclude "**/*.nbm" + } +} + +tasks.register('testPythonWheel') { + group = 'verification' + description = 'Creates a venv, installs the wheel, and runs a test script.' + dependsOn buildPythonWheel + + doLast { + def venvName = "test_venv" + def wheelDir = "${projectDir}/build/install/regi-headless/dist" + def testScript = "src\\test\\resources\\usace\\rowcps\\headless\\examples\\GateFlowCalc2_Jpype.py" + + // 1. Create VENV if it doesn't exist + exec { + commandLine 'cmd', '/c', "python -m venv ${venvName}" + } + + // 2. Install Wheel and Run Script + // We chain these using '&&' so they run in the same shell session where the venv is active + exec { + workingDir projectDir + def wheelFile = fileTree(dir: wheelDir, include: '*.whl').singleFile.absolutePath + def venvActivate = file("${venvName}/Scripts/activate.bat").absolutePath + environment 'CDA_URL', project.findProperty('CDA_URL') ?: "" + environment 'API_KEY', project.findProperty('API_KEY') ?: "" + environment 'OFFICE_ID', project.findProperty('OFFICE_ID') ?: "" + environment 'JAVA_HOME', System.getProperty('java.home') + commandLine 'cmd', '/c', "\"${venvActivate}\" && pip install --force-reinstall \"${wheelFile}\" && python -u ${testScript}" + standardOutput = System.out + errorOutput = System.err + } + } } diff --git a/regi-headless/src/main/java/usace/rowcps/headless/CLIOptions.java b/regi-headless/src/main/java/usace/rowcps/headless/CLIOptions.java deleted file mode 100644 index bf6a1f6..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/CLIOptions.java +++ /dev/null @@ -1,341 +0,0 @@ -package usace.rowcps.headless; - -import hec.lang.PasswordFileEntry; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TimeZone; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.Option; -import rma.services.ServiceLookup; -import rma.services.tz.TimeZoneDisplayService; - -/** - * - * @author ryan - */ -public class CLIOptions -{ - private static final Logger logger = Logger.getLogger(CLIOptions.class.getName()); - //public String rowcpsTimezone; - //public String oracleUrl; - //public String oracleUser; - //public String oraclePassword; - //private Map properties = new HashMap(); - Properties props; - - public final static String URL = "oracle.url"; - public final static String USER = "oracle.user"; - public final static String PASSWORD = "oracle.password"; - public final static String OFFICEID = "oracle.officeId"; - - public final static String TIMEZONE = "rowcps.timezone"; - public final static String PROJ_DIR = "rowcps.projectDir"; - public final static String PROJ_NAME = "rowcps.projectName"; - - public final static String HEC_PASSWD_FILE = "hec.passwd"; - - public CLIOptions() - { - this(System.getProperties()); - } - - public CLIOptions(Properties defaultProperties) - { - props = new Properties(defaultProperties); - } - - @Option(name = "-D", metaVar = "=", usage = "use value for given property") - private void setProperty(final String property) throws CmdLineException - { - String[] arr = property.split("="); - setProperty(arr); - } - - public void setProperty(String[] arr) throws CmdLineException - { - if (arr.length != 2) { - throw new CmdLineException("Properties must be specified in the form:" + - "="); - } - props.setProperty(arr[0], arr[1]); - //properties.put(arr[0], arr[1]); - } - - public Object getProperty(String key) - { - return props.get(key); - } - - /** - * @return the rowcpsTimezone - */ - public String getRowcpsTimezone() - { - return props.getProperty(TIMEZONE); - //return rowcpsTimezone; - } - - public File getRowcpsProjectDir() - { - File retval = null; - - String path = props.getProperty(PROJ_DIR); - if(path != null){ - retval = new File(path); - } - - return retval; - } - - @Option(name = "-D" + PROJ_DIR, metaVar = "", usage = "directory containing Regi project") - public void setRowcpsProjectDir(String filepath) - { - props.setProperty(PROJ_DIR, filepath); - } - - @Option(name = "-D" + HEC_PASSWD_FILE, metaVar = "", usage = "directory containing Regi project") - public void setHecPasswordFilepath(String filepath) - { - props.setProperty(HEC_PASSWD_FILE, filepath); - } - - public String getHecPasswordFilepath(){ - return props.getProperty(HEC_PASSWD_FILE); - } - - public PasswordFileEntry getHecPasswordFileEntry() - { - PasswordFileEntry retval = null; - - // String office = System.getProperty("cwms.dbi.OfficeId"); - String dburl = getOracleUrl(); - if (dburl != null && !dburl.isEmpty()) { - String instance = dburl; - - int idx = dburl.indexOf("@"); - if (idx != -1) { - instance = dburl.substring(idx + 1); - } - - hec.io.PasswordFile passwordFile = null; - try { - String filePath = getHecPasswordFilepath(); - passwordFile = new hec.io.PasswordFile(filePath, false); - retval = passwordFile.getEntry(instance); - - if (retval == null) { - /* - * System.out.println( - * "getConnectionInfo: Failed to find Password Entry for instance " - * + instance); - */ - logger.severe("getConnectionInfo: Failed to find Password Entry for instance " + instance); - - } -// // _connectionInfo = new -// // ConnectionInfo(office,dburl,entry.getUserName(),entry.getPassword()); -// _connectionLoginInfo = new ConnectionLoginInfoImpl(dburl, entry.getUserName(), entry.getPassword(), -// getOfficeId()); - } catch (java.io.IOException ioe) { - /* - * System.out.println( - * "getConnectionInfo: Error reading password file " + ioe); - */ - logger.severe("getConnectionInfo: Error reading password file " + ioe); - - } finally { - if (passwordFile != null) { - passwordFile.close(); - } - } - } - - return retval; - } - - - public String getRowcpsProjectName() - { - return props.getProperty(PROJ_NAME); - } - - @Option(name = "-D" + PROJ_NAME, usage = "name of Regi project") - public void setRowcpsProjectName(String name) - { - props.setProperty(PROJ_NAME, name); - } - - public String getOracleOfficeId() - { - return props.getProperty(OFFICEID); - } - - @Option(name = "-D" + OFFICEID, usage = "office id") - public void setOracleOfficeId(String id) - { - props.setProperty(OFFICEID, id); - } - - /** - * @param rowcpsTimezone the rowcpsTimezone to set - */ - @Option(name = "-D" + TIMEZONE) - public void setRowcpsTimezone(String rowcpsTimezone) throws CmdLineException - { - setProperty(new String[]{TIMEZONE, rowcpsTimezone}); - TimeZone timeZone = TimeZone.getTimeZone(rowcpsTimezone); - if(timeZone == null) - { - timeZone = TimeZone.getDefault(); - Logger.getLogger(CLIOptions.class.getName()).log(Level.WARNING, "Attempted to set invalid time zone to Regi Domain: "+rowcpsTimezone); - } - TimeZoneDisplayService timeZoneDisplayService = ServiceLookup.getTimeZoneDisplayService(); - timeZoneDisplayService.setTimeZone(timeZone); - } - - /** - * @return the oracleUrl - */ - public String getOracleUrl() - { - return props.getProperty(URL); - //return oracleUrl; - } - - /** - * @param oracleUrl the oracleUrl to set - */ - @Option(name = "-D" + URL) - public void setOracleUrl(String oracleUrl) throws CmdLineException - { - //this.oracleUrl = oracleUrl; - setProperty(new String[]{URL, oracleUrl}); - } - - /** - * @return the oracleUser - */ - public String getOracleUser() - { - String user = props.getProperty(USER); - - if (user == null) { - - PasswordFileEntry entry = getHecPasswordFileEntry(); - if (entry != null) { - user = entry.getUserName(); - } - - } - return user; - //return oracleUser; - } - - /** - * @param oracleUser the oracleUser to set - */ - @Option(name = "-D" + USER) - public void setOracleUser(String oracleUser) throws CmdLineException - { - //this.oracleUser = oracleUser; - setProperty(new String[]{USER, oracleUser}); - } - - /** - * @return the oraclePassword - */ - public char[] getOraclePassword() - { - char[] pass = null; - //return oraclePassword; - String passStr = props.getProperty(PASSWORD); - if (passStr != null) { - pass = passStr.toCharArray(); - } else { - PasswordFileEntry entry = getHecPasswordFileEntry(); - if(entry != null){ - pass = entry.getPassword().toCharArray(); - } - } - - return pass; - } - - /** - * @param oraclePassword the oraclePassword to set - */ - @Option(name = "-D" + PASSWORD) - public void setOraclePassword(String oraclePassword) throws CmdLineException - { - setProperty(new String[]{PASSWORD, oraclePassword}); - //this.oraclePassword = oraclePassword; - } - - @Option(name = "-p", aliases = {"-properties"}, metaVar = "", - usage = "import properties from given file") - public void importProperties(File file) - { - if (file != null && file.exists()) { - Properties fileProps = new Properties(); - - try (BufferedReader br = new BufferedReader(new FileReader(file))) { - fileProps.load(br); - - Set> entrySet = fileProps.entrySet(); - for (Map.Entry entry : entrySet) { - Object keyObj = entry.getKey(); - Object valueObj = entry.getValue(); - - if (keyObj != null && valueObj != null) { - props.put(keyObj, valueObj); - } - } - } catch (FileNotFoundException ex) { - Logger.getLogger(CLIOptions.class.getName()).log(Level.SEVERE, null, ex); - } catch (IOException ex) { - Logger.getLogger(CLIOptions.class.getName()).log(Level.SEVERE, null, ex); - } - } - else{ - Logger.getLogger(CLIOptions.class.getName()).log(Level.SEVERE, "Unable to find credentials file at: "+(file ==null ? "null" : file)); - } - } - - @Option(name = "-f", aliases = {"-file"}, metaVar = "", - usage = "script file to execute") - public void setScriptFile(File file) - { - props.setProperty("script", file.getAbsolutePath()); - } - - public String getScriptPath() - { - return props.getProperty("script"); - } - - public File getScriptFile() - { - File retval = null; - String scriptPath = getScriptPath(); - if (scriptPath != null && !scriptPath.isEmpty()) { - File afile = new File(scriptPath); - if (afile.exists()) { - retval = afile; - } - } - return retval; - } - - Properties getProperties() { - return new Properties(props); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java index b2cff43..1b4f073 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java @@ -27,10 +27,6 @@ import usace.rowcps.regi.model.ManagerId; import usace.rowcps.regi.model.RegiDomain; -/** - * - * @author ryan - */ public class HeadlessRegiDomainFactory { @@ -40,11 +36,11 @@ public class HeadlessRegiDomainFactory public RegiDomain createDomain() throws DbConnectionException, DbPluginNotFoundException, IOException { - Path projectDir = Paths.get("regi-projects", "regi-cli"); + Path projectDir = Paths.get("regi-projects", "regi-python"); logger.log(Level.INFO, "Creating project dir: "+ projectDir); Files.createDirectories(projectDir); - Path projectFile = projectDir.resolve("regi-cli.prj"); + Path projectFile = projectDir.resolve("regi-python.prj"); if(!Files.exists(projectFile)) { Files.createFile(projectFile); } @@ -66,15 +62,15 @@ public RegiDomain createDomain() throws DbConnectionException, } String cdaUrl = System.getenv("CDA_URL"); - String apiKey = System.getenv("API_KEY"); + String apiKey = System.getenv("CDA_API_KEY"); String officeId = System.getenv("OFFICE_ID"); CdaAuthenticationSource cdaAuthenticationSource = new CdaAuthenticationSource("", cdaUrl, officeId, new CwmsApiKeyAuthExtension(apiKey)); try { - ServerSuite serverSuite = ServerSuiteUtil.login("REGI CLI", cdaAuthenticationSource, false, false, false); + ServerSuite serverSuite = ServerSuiteUtil.login("regi-python", cdaAuthenticationSource, false, false, false); DataAccessFactory dataAccessFactory = serverSuite.getDataAccessFactory(); - try(var key = dataAccessFactory.getDataAccessKey("REGI CLI")) { + try(var key = dataAccessFactory.getDataAccessKey("regi-python")) { String username = dataAccessFactory.getDao(CwmsSecurityDao.class).getCurrentUserId(key); connectionManager.setUsername(username); } diff --git a/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java b/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java deleted file mode 100644 index a40a329..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java +++ /dev/null @@ -1,72 +0,0 @@ -package usace.rowcps.headless; - -import usace.rowcps.headless.interfaces.ScriptEvaluator; -import java.io.Reader; -import java.util.Map; -import javax.script.Bindings; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleScriptContext; - -/** - * - * @author ryan - */ -public class PythonEvaluator implements ScriptEvaluator -{ - - public final static String ENGINE_NAME = "python"; - private static final String REFERENCE_ERROR = "ReferenceError"; - private static final String NAME_ERROR = "NameError"; - - @Override - public Object evaluateExpression(Reader reader, Map variables) - { - - // I think this would let us restrict the classes loadable by python. - ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader(); - - ScriptEngineManager scriptManager = new ScriptEngineManager(ctxtLoader); - ScriptEngine pythonEngine = scriptManager.getEngineByName(ENGINE_NAME); - - SimpleScriptContext context = (SimpleScriptContext) pythonEngine.getContext(); - - Object javaValue = null; - try { - Bindings bindings = populateBingings(pythonEngine, variables); // fyi bindings actually SimpleBindings - javaValue = pythonEngine.eval(reader, bindings); - } catch (ScriptException e) { - handleException(e, variables); - } - return javaValue; - } - - private static Bindings populateBingings(ScriptEngine engine, Map variables) - { - Bindings bindings = engine.createBindings(); - for (Map.Entry entrySet : variables.entrySet()) { - String name = entrySet.getKey(); - Object value = entrySet.getValue(); - bindings.put(name, value); - } - - return bindings; - } - - private static Object handleException(ScriptException exception, Map variables) - { - if (isReferenceError(exception)) { - throw new IllegalArgumentException("Couldn't resolve some variables in expression with vars " + variables. - keySet(), exception); - } - throw new RuntimeException(exception); - } - - private static boolean isReferenceError(ScriptException exception) - { - String message = exception.getMessage(); - return message.startsWith(REFERENCE_ERROR); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java b/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java deleted file mode 100644 index 17dc332..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java +++ /dev/null @@ -1,152 +0,0 @@ -package usace.rowcps.headless; - -import java.io.IOException; -import usace.rowcps.headless.interfaces.ScriptEvaluator; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import hec.db.DbPluginNotFoundException; -import hec.db.InvalidDbConnectionException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.CmdLineParser; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.regi.factories.RowcpsExecutorService; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.preferences.RegiPreferences; - -/** - * - * @author ryan - */ -public class RegiCLI -{ - - private static final Logger LOGGER = Logger.getLogger(RegiCLI.class.getName()); - - static - { - RegiMetricsService.init(RegiPreferences.getClientNode().node("Metrics"), "REGI Headless"); - } - - public static void main(String[] args) - { - CLIOptions opt = new CLIOptions(System.getProperties()); - CmdLineParser parser = new CmdLineParser(opt); - - try - { - runHeadless(parser, args, opt); - } - catch (DbConnectionException | DbPluginNotFoundException | InvalidDbConnectionException | IOException ex) - { - LOGGER.log(Level.SEVERE, "Headless error connecting to database.", ex); - System.exit(-1); - return; - } - catch (CmdLineException | RuntimeException e) - { - LOGGER.log(Level.SEVERE, "Error running headless", e); - System.err.println("java -jar myprogram.jar [options...] arguments..."); - parser.printUsage(System.err); - System.exit(-1); - return; - } - - LOGGER.info("Exiting."); - System.exit(0); - } - - /** - * Used by TestHeadless unit test class to run headless without calling System.exit(0) - * - * @param args - * @throws DbConnectionException - * @throws InvalidDbConnectionException - * @throws CmdLineException - * @throws DbPluginNotFoundException - */ - static void runHeadlessTest(String[] args) - throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException, - IOException { - CLIOptions opt = new CLIOptions(System.getProperties()); - CmdLineParser parser = new CmdLineParser(opt); - runHeadless(parser, args, opt); - } - - private static void runHeadless(CmdLineParser parser, String[] args, CLIOptions opt) - throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException, - IOException { - parser.parseArgument(args); - System.setProperties(opt.getProperties()); - - HeadlessRegiDomainFactory factory = new HeadlessRegiDomainFactory(); - ManagerId managerId = factory.getManagerId(); - RegiDomain regiDomain = factory.createDomain(); - - if (regiDomain != null) - { - ScriptEvaluator pe = new PythonEvaluator(); - Map vars = new HashMap<>(); - - RegiCalcRegistry reg = new RegiCalcRegistry(regiDomain, managerId); - vars.put("registry", reg); - - File scriptFile = opt.getScriptFile(); - - try - { - FileReader fr = new FileReader(scriptFile); - LOGGER.info("Evaluating script file"); - Object retval = pe.evaluateExpression(fr, vars); - - LOGGER.info("Jython script completed normally, commiting data."); - regiDomain.commitData(managerId); - LOGGER.info("RegiDomain committed data."); - } - catch (DbConnectionException | DbIoException | FileNotFoundException ex) - { - LOGGER.log(Level.SEVERE, "Exception occurred while evaluating Jython file:" + System.lineSeparator() + scriptFile, ex); - } - finally - { - LOGGER.info("RegiDomain closing."); - shutdownRowcpsAccessFactory(managerId); - regiDomain.closing(); - } - } - } - - private static void shutdownRowcpsAccessFactory(ManagerId managerId) - { - LOGGER.log(Level.INFO, "Shutting down RowcpsExecutorService for {0}", managerId); - RowcpsExecutorService res = RowcpsExecutorService.getInstance(managerId); - - res.shutdown(); // signal shutdown - this will stop accepting new jobs and allow existing jobs to complete. - boolean exitted = false; - try - { - // We are willing to wait a little to achieve a clean shutdown. - exitted = res.awaitTermination(3000, TimeUnit.MILLISECONDS); - - } - catch (InterruptedException ie) - { - Thread.currentThread().interrupt(); - } - if (!exitted) - { - // Some of the running tasks didn't exit in the time we were willing to wait. - List wereWaiting = res.shutdownNow(); // This will interrupt them if they support interruption. - } - LOGGER.log(Level.INFO, "RowcpsExecutorService for {0} shutdown complete.", managerId); - } -} diff --git a/regi-headless/src/main/python/pyproject.toml b/regi-headless/src/main/python/pyproject.toml new file mode 100644 index 0000000..3cdfac3 --- /dev/null +++ b/regi-headless/src/main/python/pyproject.toml @@ -0,0 +1,17 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "regi-python" +version = "@VERSION@" +description = "USACE Regi-Headless Python Bridge" +dependencies = [ + "JPype1>=1.4.1", +] + +[tool.setuptools] +packages = ["regi-python"] + +[tool.setuptools.package-data] +"regi-python" = ["lib/*.jar"] \ No newline at end of file diff --git a/regi-headless/src/main/python/regi_python/__init__.py b/regi-headless/src/main/python/regi_python/__init__.py new file mode 100644 index 0000000..43f1d05 --- /dev/null +++ b/regi-headless/src/main/python/regi_python/__init__.py @@ -0,0 +1,10 @@ +from .regi_python import regi_session, run_headless +from importlib.metadata import version, PackageNotFoundError + +__all__ = ["regi_session", "run_headless"] + +try: + __version__ = version("regi_python") # Use the 'name' from pyproject.toml +except PackageNotFoundError: + # package is not installed + __version__ = "unknown" \ No newline at end of file diff --git a/regi-headless/src/main/python/regi_python/regi_python.py b/regi-headless/src/main/python/regi_python/regi_python.py new file mode 100644 index 0000000..64b459c --- /dev/null +++ b/regi-headless/src/main/python/regi_python/regi_python.py @@ -0,0 +1,76 @@ +# Copyright (c) 2026 +# United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) +# All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. +# Source may not be released without written approval from HEC + +import os +import logging +import jpype +import jpype.imports +from contextlib import contextmanager +from pathlib import Path +from regi_python_logging import configure_logging + +logger = configure_logging() + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +LIB_PATH = os.path.join(BASE_DIR, "lib", "*") +java_home = os.environ.get('JAVA_HOME') +java_bin = os.path.join(java_home, 'bin') +if java_bin not in os.environ['PATH']: + os.environ['PATH'] = java_bin + os.pathsep + os.environ['PATH'] + +@contextmanager +def regi_session(): + """ + Context manager to handle JVM lifecycle. + Usage: + with regi_session(): + run_headless(my_func) + """ + if not jpype.isJVMStarted(): + logger.info("Starting JVM...") + jpype.startJVM( + jpype.getDefaultJVMPath(), + convertStrings=True, + classpath=[LIB_PATH] + ) + + try: + yield + finally: + if jpype.isJVMStarted(): + logger.info("Shutting down JVM...") + jpype.shutdownJVM() + +def run_headless(calculation_callback): + # We must import these inside the function or after JVM starts + from usace.rowcps.headless import HeadlessRegiDomainFactory, RegiCalcRegistry + from usace.rowcps.regi.factories import RowcpsExecutorService + from java.util.concurrent import TimeUnit + factory = HeadlessRegiDomainFactory() + logger.info("Attempting to create RegiDomain...") + regi_domain = factory.createDomain() + + if regi_domain is not None: + manager_id = factory.getManagerId() + registry = RegiCalcRegistry(regi_domain, manager_id) + + try: + logger.info("Executing callback...") + calculation_callback(registry) + regi_domain.commitData(manager_id) + except Exception as e: + logger.error("Execution failed.", exc_info=True) + raise + finally: + _shutdown_executor(manager_id) + regi_domain.closing() + +def _shutdown_executor(manager_id): + from usace.rowcps.regi.factories import RowcpsExecutorService + from java.util.concurrent import TimeUnit + res = RowcpsExecutorService.getInstance(manager_id) + res.shutdown() + if not res.awaitTermination(3000, TimeUnit.MILLISECONDS): + res.shutdownNow() \ No newline at end of file diff --git a/regi-headless/src/main/python/regi_python/regi_python_logging.py b/regi-headless/src/main/python/regi_python/regi_python_logging.py new file mode 100644 index 0000000..0980008 --- /dev/null +++ b/regi-headless/src/main/python/regi_python/regi_python_logging.py @@ -0,0 +1,47 @@ +# Copyright (c) 2026 +# United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) +# All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. +# Source may not be released without written approval from HEC + +import logging +import os + + +def _get_log_level(): + log_level_name = os.environ.get("REGI_LOG_LEVEL", "INFO").upper() + log_level = getattr(logging, log_level_name, None) + invalid_log_level = not isinstance(log_level, int) + if invalid_log_level: + log_level = logging.INFO + return log_level, invalid_log_level, log_level_name + +def configure_logging(): + log_level, invalid_log_level, log_level_name = _get_log_level() + + log_format = os.environ.get( + "REGI_LOG_FORMAT", + "%(asctime)s %(levelname)s %(name)s " + "[job=%(aws_batch_job_id)s attempt=%(aws_batch_job_attempt)s] - %(message)s", + ) + + class AwsBatchFilter(logging.Filter): + def filter(self, record): + record.aws_batch_job_id = os.environ.get("AWS_BATCH_JOB_ID", "-") + record.aws_batch_job_attempt = os.environ.get("AWS_BATCH_JOB_ATTEMPT", "-") + return True + + handler = logging.StreamHandler() + handler.setLevel(log_level) + handler.setFormatter(logging.Formatter(log_format)) + handler.addFilter(AwsBatchFilter()) + + logger = logging.getLogger("regi-launcher") + logger.setLevel(log_level) + logger.handlers.clear() + logger.addHandler(handler) + logger.propagate = False + + if invalid_log_level: + logger.warning("Invalid REGI_LOG_LEVEL '%s'; using INFO.", log_level_name) + + return logger \ No newline at end of file diff --git a/regi-headless/src/main/resources/usace/rowcps/headless/sigstages/retrieve/xmlmodel/HydroGenData.xsd b/regi-headless/src/main/resources/usace/rowcps/headless/sigstages/retrieve/xmlmodel/HydroGenData.xsd deleted file mode 100644 index e1bb1ea..0000000 --- a/regi-headless/src/main/resources/usace/rowcps/headless/sigstages/retrieve/xmlmodel/HydroGenData.xsd +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/credentials.properties b/regi-headless/src/test/resources/usace/rowcps/headless/credentials.properties deleted file mode 100644 index ee2dba3..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/credentials.properties +++ /dev/null @@ -1,9 +0,0 @@ -rowcps.projectDir=C:\\Users\\ryanm\\Documents\\Regi Base\\ -rowcps.projectName=bang - -oracle.url=jdbc:oracle:thin:@10.0.0.36:1539:V122SWT1811REGI -oracle.user=m5hectest -oracle.password=swt1811db -oracle.officeId=SWT - -hec.passwd=src\\test\\java\\usace\\rowcps\\headless\\hec.passwd \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/hec.passwd b/regi-headless/src/test/resources/usace/rowcps/headless/hec.passwd deleted file mode 100644 index 5b27e06..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/hec.passwd +++ /dev/null @@ -1,2 +0,0 @@ -v2.0 -bang:1521:v11203swf02|QZg5V85RPTaV2ew1XkEVhBd/vHtxTr/rsDmgHyBfSoD= From 4730bac5e591ccbe2dacf26a48ccf2a9611ea637 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Thu, 2 Jul 2026 20:24:03 -0700 Subject: [PATCH 09/26] add GitHub Action to publish the wheel --- .github/workflows/build.yml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0be5339..6ad6ae4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,9 @@ on: branches: - main pull_request: + release: + types: + - created permissions: contents: read @@ -33,7 +36,33 @@ jobs: run: chmod +x ./gradlew - name: Build and test - run: ./gradlew clean build + run: ./gradlew clean build buildPythonWheel + - name: Upload Python wheel artifact + uses: actions/upload-artifact@v4 + with: + name: python-wheel + path: "**/build/install/*/dist/*.whl" + if-no-files-found: error + + publish-wheel: + name: Publish Python wheel to GitHub Release + needs: build + runs-on: ubuntu-latest + if: github.event_name == 'release' + permissions: + contents: write + + steps: + - name: Download Python wheel artifact + uses: actions/download-artifact@v4 + with: + name: python-wheel + path: dist + + - name: Publish wheel to GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: dist/**/*.whl dependency-submission: name: Submit Gradle dependencies From 5414dcd70cbb3a31029f29d83760fea36dd3dcb7 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Mon, 6 Jul 2026 09:58:31 -0700 Subject: [PATCH 10/26] update to use plugin for python wheel build --- .github/workflows/build-wheel.yml | 50 ++++++ .github/workflows/build.yml | 63 +------- .github/workflows/release.yml | 46 ++++++ regi-headless/build.gradle | 116 +++++++++----- .../java/usace/rowcps/headless/TestFrame.java | 151 ------------------ .../usace/rowcps/headless/TestHeadless.java | 148 ----------------- .../rowcps/headless/tests/TestVariables.java | 39 ----- .../src/test/python/test_python_wheel.py | 36 +++++ 8 files changed, 216 insertions(+), 433 deletions(-) create mode 100644 .github/workflows/build-wheel.yml create mode 100644 .github/workflows/release.yml delete mode 100644 regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java delete mode 100644 regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java delete mode 100644 regi-headless/src/test/java/usace/rowcps/headless/tests/TestVariables.java create mode 100644 regi-headless/src/test/python/test_python_wheel.py diff --git a/.github/workflows/build-wheel.yml b/.github/workflows/build-wheel.yml new file mode 100644 index 0000000..7b3fdae --- /dev/null +++ b/.github/workflows/build-wheel.yml @@ -0,0 +1,50 @@ +name: Build Python Wheel + +on: + workflow_call: + inputs: + ref: + description: Git ref to check out + required: false + type: string + default: "" + +jobs: + build-wheel: + name: Build Python wheel + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + with: + fetch-depth: 0 + ref: ${{ inputs.ref || github.ref }} + + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 21 + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v6 + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + + - name: Build and test + run: ./gradlew clean build buildPythonWheel + + - name: Collect wheel + run: | + mkdir -p dist + find . -path "*/build/install/*/dist/*.whl" -exec cp {} dist/ \; + + - name: Upload Python wheel artifact + uses: actions/upload-artifact@v4 + with: + name: python-wheel + path: dist/*.whl + if-no-files-found: error + retention-days: 14 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6ad6ae4..2652c45 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,68 +5,22 @@ on: branches: - main pull_request: - release: - types: - - created permissions: contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: - build: + build-wheel: name: Build and test - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v7 - with: - fetch-depth: 0 - - - name: Set up Java - uses: actions/setup-java@v5 - with: - distribution: temurin - java-version: 21 - - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v6 - - - name: Make Gradle wrapper executable - run: chmod +x ./gradlew - - - name: Build and test - run: ./gradlew clean build buildPythonWheel - - name: Upload Python wheel artifact - uses: actions/upload-artifact@v4 - with: - name: python-wheel - path: "**/build/install/*/dist/*.whl" - if-no-files-found: error - - publish-wheel: - name: Publish Python wheel to GitHub Release - needs: build - runs-on: ubuntu-latest - if: github.event_name == 'release' - permissions: - contents: write - - steps: - - name: Download Python wheel artifact - uses: actions/download-artifact@v4 - with: - name: python-wheel - path: dist - - - name: Publish wheel to GitHub Release - uses: softprops/action-gh-release@v2 - with: - files: dist/**/*.whl + uses: ./.github/workflows/build-wheel.yml dependency-submission: name: Submit Gradle dependencies - needs: build + needs: build-wheel runs-on: ubuntu-latest if: github.event_name == 'push' && github.ref == 'refs/heads/main' permissions: @@ -86,5 +40,4 @@ jobs: uses: gradle/actions/setup-gradle@v6 - name: Submit Gradle dependencies - uses: gradle/actions/dependency-submission@v6 - \ No newline at end of file + uses: gradle/actions/dependency-submission@v6 \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e0833f6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,46 @@ +name: Release + +on: + release: + types: + - published + +permissions: + contents: write + actions: read + +concurrency: + group: release-${{ github.event.release.id }} + cancel-in-progress: false + +jobs: + build-wheel: + name: Build wheel from release tag + uses: ./.github/workflows/build-wheel.yml + with: + ref: ${{ github.event.release.tag_name }} + + publish-wheel: + name: Publish Python wheel to GitHub Release + needs: build-wheel + runs-on: ubuntu-latest + + steps: + - name: Download Python wheel artifact + uses: actions/download-artifact@v4 + with: + name: python-wheel + path: dist + + - name: Generate checksums + run: | + cd dist + sha256sum *.whl > SHA256SUMS.txt + + - name: Publish wheel to GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.event.release.tag_name }} + files: | + dist/*.whl + dist/SHA256SUMS.txt \ No newline at end of file diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index 8ed64bc..48f8043 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -57,31 +57,31 @@ pythonPlugin { tasks.register('installPythonBuildTools', VenvTask) { group = 'build setup' - description = 'Installs Python packages needed to build the wheel.' + description = 'Installs Python packages needed to build and test the wheel.' venvExec = 'pip' - args = ['install', '--upgrade', 'pip', 'build'] -} - -tasks.register('buildPythonWheel', VenvTask) { - group = "distribution" - description = "Builds a Python .whl file using the Gradle-managed Python environment." - - dependsOn bundlePython - dependsOn installPythonBuildTools + args = ['install', '--upgrade', 'pip', 'build', 'pytest'] - workingDir = file("${buildDir}/install/regi-python") - venvExec = "python" - args = ["-m", "build", "--wheel"] + outputs.file(layout.buildDirectory.file("python-build-tools/install.marker")) doLast { - println "Python Wheel built in: ${workingDir}/dist" + def markerFile = layout.buildDirectory.file("python-build-tools/install.marker").get().asFile + markerFile.parentFile.mkdirs() + markerFile.text = "pip build pytest installed\n" } } tasks.register('bundlePython', Sync) { description = 'Bundles Python scripts and creates the java_lib directory' - into "${buildDir}/install/regi-python/" + + dependsOn jar + + into layout.buildDirectory.dir("install/regi-python") + + inputs.dir("src/main/python") + inputs.file(jar.archiveFile) + inputs.files(configurations.runtimeClasspath) + inputs.property("version", project.version.toString()) from('src/main/python') { include 'pyproject.toml' @@ -99,34 +99,70 @@ tasks.register('bundlePython', Sync) { } } -tasks.register('testPythonWheel') { +tasks.register('buildPythonWheel', VenvTask) { + group = "distribution" + description = "Builds a Python .whl file using the Gradle-managed Python environment." + + dependsOn bundlePython + dependsOn installPythonBuildTools + + workingDir = layout.buildDirectory.dir("install/regi-python").get().asFile + venvExec = "python" + args = ["-m", "build", "--wheel"] + + inputs.files(fileTree(layout.buildDirectory.dir("install/regi-python")) { + exclude "dist/**" + exclude "build/**" + exclude "*.egg-info/**" + }) + inputs.property("version", project.version.toString()) + outputs.dir(layout.buildDirectory.dir("install/regi-python/dist")) + + doFirst { + delete layout.buildDirectory.dir("install/regi-python/dist") + } + + doLast { + println "Python Wheel built in: ${workingDir}/dist" + } +} + +tasks.register('installPythonWheelForSmokeTest', VenvTask) { group = 'verification' - description = 'Creates a venv, installs the wheel, and runs a test script.' + description = 'Installs the built Python wheel into the Gradle-managed Python environment.' + dependsOn buildPythonWheel + venvExec = 'pip' + + inputs.files(fileTree(dir: "${buildDir}/install/regi-python/dist", include: '*.whl')) + outputs.file(layout.buildDirectory.file("test-python-wheel/install.marker")) + + doFirst { + def wheelFile = fileTree(dir: "${buildDir}/install/regi-python/dist", include: '*.whl').singleFile + args = ['install', '--force-reinstall', wheelFile.absolutePath] + } + doLast { - def venvName = "test_venv" - def wheelDir = "${projectDir}/build/install/regi-headless/dist" - def testScript = "src\\test\\resources\\usace\\rowcps\\headless\\examples\\GateFlowCalc2_Jpype.py" - - // 1. Create VENV if it doesn't exist - exec { - commandLine 'cmd', '/c', "python -m venv ${venvName}" - } - - // 2. Install Wheel and Run Script - // We chain these using '&&' so they run in the same shell session where the venv is active - exec { - workingDir projectDir - def wheelFile = fileTree(dir: wheelDir, include: '*.whl').singleFile.absolutePath - def venvActivate = file("${venvName}/Scripts/activate.bat").absolutePath - environment 'CDA_URL', project.findProperty('CDA_URL') ?: "" - environment 'API_KEY', project.findProperty('API_KEY') ?: "" - environment 'OFFICE_ID', project.findProperty('OFFICE_ID') ?: "" - environment 'JAVA_HOME', System.getProperty('java.home') - commandLine 'cmd', '/c', "\"${venvActivate}\" && pip install --force-reinstall \"${wheelFile}\" && python -u ${testScript}" - standardOutput = System.out - errorOutput = System.err - } + def wheelFile = fileTree(dir: "${buildDir}/install/regi-python/dist", include: '*.whl').singleFile + def markerFile = layout.buildDirectory.file("test-python-wheel/install.marker").get().asFile + markerFile.parentFile.mkdirs() + markerFile.text = "${wheelFile.name}\n${wheelFile.length()} bytes\n" } } +tasks.register('testPythonWheel', VenvTask) { + group = 'verification' + description = 'Runs pytest against the installed Python wheel.' + + dependsOn installPythonWheelForSmokeTest + + venvExec = 'python' + args = ['-m', 'pytest', 'src/test/python'] + + inputs.files(fileTree(dir: 'src/test/python', include: '**/*.py')) + outputs.upToDateWhen { false } +} + +check { + dependsOn testPythonWheel +} diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java b/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java deleted file mode 100644 index 2b46ad7..0000000 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2018 - * United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) - * All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. - * Source may not be released without written approval from HEC - */ -package usace.rowcps.headless; - -import java.awt.GridLayout; -import java.awt.HeadlessException; -import java.awt.event.ActionEvent; -import java.io.IOException; -import java.nio.file.FileVisitOption; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.List; -import java.util.ArrayList; -import static java.util.stream.Collectors.toList; -import javax.swing.AbstractAction; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.SwingUtilities; - -/** - * - * @author @author Ryan A. Miles (ryanm@rmanet.com) - */ -public class TestFrame extends JFrame -{ - private static final Logger LOGGER = Logger.getLogger(TestFrame.class.getName()); - private final ExecutorService _executor = Executors.newSingleThreadExecutor(); - private final List _buttons = new ArrayList<>(); - - public TestFrame() throws HeadlessException - { - buildComponents(); - } - - public static void main(String[] args) - { - TestFrame frame = new TestFrame(); - frame.pack(); - frame.setDefaultCloseOperation(EXIT_ON_CLOSE); - frame.setMinimumSize(frame.getPreferredSize()); - frame.setVisible(true); - } - - private void buildComponents() - { - setLayout(new GridLayout(0, 3, 2, 2)); - - String[] files = readFilesInTestFolder(); - - for (String testData : files) - { - JButton btn = new JButton(new ButtonAction(testData, testData)); - _buttons.add(btn); - add(btn); - } - } - - private String[] readFilesInTestFolder() - { - Path path = Paths.get(TestHeadless.getJythonTestFolder()); - List paths = new ArrayList<>(); - try - { - paths.addAll(Files.walk(path, FileVisitOption.FOLLOW_LINKS) - .map(Path::getFileName) - .map(Path::toString) - .filter(file -> file.endsWith("py")) - .collect(toList())); - } - catch (IOException | RuntimeException ex) - { - - } - - return paths.toArray(new String[0]); - } - - private void performHeadless(String file) - { - disableButtons(); - - _executor.submit(() -> - { - String[] args = TestHeadless.getArgsForFile(file); - try - { - RegiCLI.runHeadlessTest(args); - //Reset logging options - LoggingOptions.disableFlowGroupCompLogging(); - LoggingOptions.setMetricsEnabled(false); - LoggingOptions.setDbMessageLevel(0); - } - catch (Throwable ex) - { - logThrowable(ex); - } - - SwingUtilities.invokeLater(this::enableButtons); - }); - } - - private void logThrowable(Throwable ex) - { - if (ex.getCause() != null) - { - logThrowable(ex.getCause()); - } - LOGGER.log(Level.SEVERE, "Exception occurred", ex); - } - - private void disableButtons() - { - for (JButton btn : _buttons) - { - btn.setEnabled(false); - } - } - - private void enableButtons() - { - for (JButton btn : _buttons) - { - btn.setEnabled(true); - } - } - - private class ButtonAction extends AbstractAction - { - private final String _file; - public ButtonAction(String name, String file) - { - super(name); - _file = file; - } - - @Override - public void actionPerformed(ActionEvent e) - { - performHeadless(_file); - } - } -} diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java deleted file mode 100644 index 4cf8ac7..0000000 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2018 - * United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) - * All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. - * Source may not be released without written approval from HEC - */ -package usace.rowcps.headless; - -import java.util.TimeZone; -import usace.rowcps.headless.tests.TestVariables; - -/** - * This class is intended for use by developers to run headless after making changes. Run a single test at a time - * otherwise it might be a while... - * - * All files are relative to the JYTHON_FILE_ROOT variable, which should be in this same folder. - * - * @author @author Ryan A. Miles (ryanm@rmanet.com) - */ -public class TestHeadless -{ - static final String JYTHON_FILE_ROOT = "src\\test\\java\\usace\\rowcps\\headless\\"; - static final String CREDENTIALS_FILE = "usace/rowcps/headless/credentials.properties"; - - //I'd like this to be the office, but we haven't connected yet. - //Could get it from the credentials probably. - static final String SUB_FOLDER = "tests"; - -// @Test //23-001 - migration - public void testAssoc_DBExport() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("Assoc_DBExport.py")); - } - -// @Test //23-001 - migration - public void testBasinPieExport() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("BasinPieExport.py")); - } - -// @Test //23-001 - migration - public void testGateFlowPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("GateFlow.py")); - } - -// @Test //23-001 - migration - public void testGateFlowCalcPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("GateFlowCalc.py")); - } - -// @Test //23-001 - migration - public void testGateSettingsPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("GateSettings.py")); - } - -// @Test //23-001 - migration - public void testInflowCalcAutoAdjustPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("InflowCalcAutoAdjust.py")); - } - -// @Test //23-001 - migration - public void testInflowCalcBalanceAllPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("InflowCalcBalanceAll.py")); - } - -// @Test //23-001 - migration - public void testInflowCalcClonePy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("InflowCalcClone.py")); - } - -// @Test //23-001 - migration - public void testInflowCalcComputeEvapAsFlowPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("InflowCalcComputeEvapAsFlow.py")); - } - - -// @Test //23-001 - migration - public void testInflowCalcComputedInflowPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("InflowCalcComputedInflow.py")); - } - -// @Test //23-001 - migration - public void testInflowCalcZeroNegativePy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("InflowCalcZeroNegative.py")); - } - -// @Test //23-001 - migration - public void testPoolPercentCalcPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("PoolPercentCalc.py")); - } - -// @Test //23-001 - migration - public void testSigstages_DBExportPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("Sigstages_DBExport.py")); - } - -// @Test //23-001 - migration - public void testSigstages_DBImportPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("Sigstages_DBImport.py")); - } - -// @Test //23-001 - migration - public void testSigstages_DownloadPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("Sigstages_Download.py")); - } - -// @Test //23-001 - migration - public void testStatusDemoPy() throws Exception - { - RegiCLI.runHeadlessTest(getArgsForFile("StatusDemo.py")); - } - - static String[] getArgsForFile(String file) - { - return getArgsForFileAndTimeZone(SUB_FOLDER + "\\" + file, TimeZone.getTimeZone("US/Central")); - } - - static String getJythonTestFolder() - { - return JYTHON_FILE_ROOT + SUB_FOLDER; - } - - private static String[] getArgsForFileAndTimeZone(String file, TimeZone tz) - { - TestVariables.init(); - String[] args = new String[] - { - "-Drowcps.timezone=" + tz.getID(), - "-p", JYTHON_FILE_ROOT + CREDENTIALS_FILE, - "-f", JYTHON_FILE_ROOT + file, - }; - - return args; - } -} diff --git a/regi-headless/src/test/java/usace/rowcps/headless/tests/TestVariables.java b/regi-headless/src/test/java/usace/rowcps/headless/tests/TestVariables.java deleted file mode 100644 index 417caeb..0000000 --- a/regi-headless/src/test/java/usace/rowcps/headless/tests/TestVariables.java +++ /dev/null @@ -1,39 +0,0 @@ -package usace.rowcps.headless.tests; - -/** - * I couldn't get this into a python file...it kept saying it couldn't find the module. I think it's because the - * evaluator only takes in one file? - * - * Anyway, this is intended to provide the global test information for all of the python scripts. I set this up for the - * SWT office and locations. I've also updated these tests to use an output file location that we can get all our files - * to so it's not so scattered. - * - * @author Ryan A. Miles (ryanm@rmanet.com) - */ -public final class TestVariables -{ - - //Office ID for current tests. - public static final String OFFICE_ID = "SWT"; - //These are intended to be unique, please don't use the same variables. - public static final String GATE_LOCATION = "FGIB"; - public static final String INFLOW_LOCATION = "EUFA"; - public static final String POOL_LOCATION = "ARBU"; - public static final String LOCATION_4 = "ALTU"; - public static final String[] ALL_PROJECTS = new String[] - { - GATE_LOCATION, INFLOW_LOCATION, POOL_LOCATION, LOCATION_4 - }; - public static final String STREAM_GAGE_LOCATION = "RIPL"; - public static final String HEADLESS_FILE_LOCATION = "C:\\Temp\\Headless\\"; - - public static void init() - { - - } - - private TestVariables() - { - throw new AssertionError("Don't instantiate this class"); - } -} diff --git a/regi-headless/src/test/python/test_python_wheel.py b/regi-headless/src/test/python/test_python_wheel.py new file mode 100644 index 0000000..625b717 --- /dev/null +++ b/regi-headless/src/test/python/test_python_wheel.py @@ -0,0 +1,36 @@ +# Copyright (c) 2026 +# United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) +# All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. +# Source may not be released without written approval from HEC + +import importlib.metadata +from pathlib import Path + + +def test_wheel_distribution_metadata_is_installed(): + dist = importlib.metadata.distribution("regi-python") + + assert dist.metadata["Name"] == "regi-python" + assert dist.version + + +def test_wheel_can_import_top_level_package(): + import regi_python + + assert regi_python is not None + + +def test_public_api_is_exposed(): + import regi_python + + assert callable(regi_python.regi_session) + assert callable(regi_python.run_headless) + + +def test_bundled_java_libraries_are_present(): + import regi_python + package_dir = Path(regi_python.__file__).parent + lib_dir = package_dir / "lib" + + assert lib_dir.is_dir() + assert any(lib_dir.glob("*.jar")) From 93d84297b220f0ddcaba96f241dea451dcc3a5d5 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Mon, 6 Jul 2026 10:16:57 -0700 Subject: [PATCH 11/26] fix dash vs underscore --- regi-headless/build.gradle | 18 +++++++++--------- regi-headless/src/main/python/pyproject.toml | 6 +++--- .../src/main/python/regi_python/__init__.py | 2 +- .../src/main/python/regi_python/regi_python.py | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index 48f8043..edc66ab 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -76,7 +76,7 @@ tasks.register('bundlePython', Sync) { dependsOn jar - into layout.buildDirectory.dir("install/regi-python") + into layout.buildDirectory.dir("install/regi_python") inputs.dir("src/main/python") inputs.file(jar.archiveFile) @@ -92,7 +92,7 @@ tasks.register('bundlePython', Sync) { exclude 'pyproject.toml' } - into('regi-python/lib') { + into('regi_python/lib') { from configurations.runtimeClasspath from jar.archiveFile exclude "**/*.nbm" @@ -106,20 +106,20 @@ tasks.register('buildPythonWheel', VenvTask) { dependsOn bundlePython dependsOn installPythonBuildTools - workingDir = layout.buildDirectory.dir("install/regi-python").get().asFile + workingDir = layout.buildDirectory.dir("install/regi_python").get().asFile venvExec = "python" args = ["-m", "build", "--wheel"] - inputs.files(fileTree(layout.buildDirectory.dir("install/regi-python")) { + inputs.files(fileTree(layout.buildDirectory.dir("install/regi_python")) { exclude "dist/**" exclude "build/**" exclude "*.egg-info/**" }) inputs.property("version", project.version.toString()) - outputs.dir(layout.buildDirectory.dir("install/regi-python/dist")) + outputs.dir(layout.buildDirectory.dir("install/regi_python/dist")) doFirst { - delete layout.buildDirectory.dir("install/regi-python/dist") + delete layout.buildDirectory.dir("install/regi_python/dist") } doLast { @@ -135,16 +135,16 @@ tasks.register('installPythonWheelForSmokeTest', VenvTask) { venvExec = 'pip' - inputs.files(fileTree(dir: "${buildDir}/install/regi-python/dist", include: '*.whl')) + inputs.files(fileTree(dir: "${buildDir}/install/regi_python/dist", include: '*.whl')) outputs.file(layout.buildDirectory.file("test-python-wheel/install.marker")) doFirst { - def wheelFile = fileTree(dir: "${buildDir}/install/regi-python/dist", include: '*.whl').singleFile + def wheelFile = fileTree(dir: "${buildDir}/install/regi_python/dist", include: '*.whl').singleFile args = ['install', '--force-reinstall', wheelFile.absolutePath] } doLast { - def wheelFile = fileTree(dir: "${buildDir}/install/regi-python/dist", include: '*.whl').singleFile + def wheelFile = fileTree(dir: "${buildDir}/install/regi_python/dist", include: '*.whl').singleFile def markerFile = layout.buildDirectory.file("test-python-wheel/install.marker").get().asFile markerFile.parentFile.mkdirs() markerFile.text = "${wheelFile.name}\n${wheelFile.length()} bytes\n" diff --git a/regi-headless/src/main/python/pyproject.toml b/regi-headless/src/main/python/pyproject.toml index 3cdfac3..48db039 100644 --- a/regi-headless/src/main/python/pyproject.toml +++ b/regi-headless/src/main/python/pyproject.toml @@ -5,13 +5,13 @@ build-backend = "setuptools.build_meta" [project] name = "regi-python" version = "@VERSION@" -description = "USACE Regi-Headless Python Bridge" +description = "USACE REGI Python Bridge" dependencies = [ "JPype1>=1.4.1", ] [tool.setuptools] -packages = ["regi-python"] +packages = ["regi_python"] [tool.setuptools.package-data] -"regi-python" = ["lib/*.jar"] \ No newline at end of file +"regi_python" = ["lib/*.jar"] \ No newline at end of file diff --git a/regi-headless/src/main/python/regi_python/__init__.py b/regi-headless/src/main/python/regi_python/__init__.py index 43f1d05..0b4c1e6 100644 --- a/regi-headless/src/main/python/regi_python/__init__.py +++ b/regi-headless/src/main/python/regi_python/__init__.py @@ -4,7 +4,7 @@ __all__ = ["regi_session", "run_headless"] try: - __version__ = version("regi_python") # Use the 'name' from pyproject.toml + __version__ = version("regi_python") except PackageNotFoundError: # package is not installed __version__ = "unknown" \ No newline at end of file diff --git a/regi-headless/src/main/python/regi_python/regi_python.py b/regi-headless/src/main/python/regi_python/regi_python.py index 64b459c..b41829c 100644 --- a/regi-headless/src/main/python/regi_python/regi_python.py +++ b/regi-headless/src/main/python/regi_python/regi_python.py @@ -9,7 +9,7 @@ import jpype.imports from contextlib import contextmanager from pathlib import Path -from regi_python_logging import configure_logging +from .regi_python_logging import configure_logging logger = configure_logging() From d3fa081f86559a0f55c44451808ef73d82e1aec2 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Mon, 6 Jul 2026 11:03:04 -0700 Subject: [PATCH 12/26] standardize python logger with JUL --- .../rowcps/headless/PythonJulHandler.java | 47 +++++++++++ .../usace/rowcps/headless/PythonLogSink.java | 7 ++ .../main/python/regi_python/regi_python.py | 10 +-- .../python/regi_python/regi_python_logging.py | 80 +++++++++++++++++-- 4 files changed, 129 insertions(+), 15 deletions(-) create mode 100644 regi-headless/src/main/java/usace/rowcps/headless/PythonJulHandler.java create mode 100644 regi-headless/src/main/java/usace/rowcps/headless/PythonLogSink.java diff --git a/regi-headless/src/main/java/usace/rowcps/headless/PythonJulHandler.java b/regi-headless/src/main/java/usace/rowcps/headless/PythonJulHandler.java new file mode 100644 index 0000000..532f277 --- /dev/null +++ b/regi-headless/src/main/java/usace/rowcps/headless/PythonJulHandler.java @@ -0,0 +1,47 @@ +package usace.rowcps.headless; + +import java.util.logging.ErrorManager; +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.LogRecord; + +public final class PythonJulHandler extends Handler { + + private final PythonLogSink sink; + + private final Formatter messageFormatter = new Formatter() { + @Override + public String format(LogRecord record) { + return formatMessage(record); + } + }; + + public PythonJulHandler(PythonLogSink sink) { + this.sink = sink; + } + + @Override + public void publish(LogRecord record) { + if (record == null || !isLoggable(record)) { + return; + } + + try { + String message = messageFormatter.format(record); + sink.log(record, message); + } catch (RuntimeException ex) { + // Safeguard against failures in Python log handling. + reportError("Failed to publish JUL record to Python logging.", ex, ErrorManager.WRITE_FAILURE); + } + } + + @Override + public void flush() { + // No-op. Python logging handlers manage their own flushing. + } + + @Override + public void close() { + // No-op. + } +} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/PythonLogSink.java b/regi-headless/src/main/java/usace/rowcps/headless/PythonLogSink.java new file mode 100644 index 0000000..70a2ea0 --- /dev/null +++ b/regi-headless/src/main/java/usace/rowcps/headless/PythonLogSink.java @@ -0,0 +1,7 @@ +package usace.rowcps.headless; + +import java.util.logging.LogRecord; + +public interface PythonLogSink { + void log(LogRecord record, String message); +} diff --git a/regi-headless/src/main/python/regi_python/regi_python.py b/regi-headless/src/main/python/regi_python/regi_python.py index b41829c..c3694e8 100644 --- a/regi-headless/src/main/python/regi_python/regi_python.py +++ b/regi-headless/src/main/python/regi_python/regi_python.py @@ -1,15 +1,8 @@ -# Copyright (c) 2026 -# United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) -# All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. -# Source may not be released without written approval from HEC - import os -import logging import jpype import jpype.imports from contextlib import contextmanager -from pathlib import Path -from .regi_python_logging import configure_logging +from .regi_python_logging import configure_logging, configure_jul_to_python_logging logger = configure_logging() @@ -35,6 +28,7 @@ def regi_session(): convertStrings=True, classpath=[LIB_PATH] ) + configure_jul_to_python_logging(logger) try: yield diff --git a/regi-headless/src/main/python/regi_python/regi_python_logging.py b/regi-headless/src/main/python/regi_python/regi_python_logging.py index 0980008..6942c87 100644 --- a/regi-headless/src/main/python/regi_python/regi_python_logging.py +++ b/regi-headless/src/main/python/regi_python/regi_python_logging.py @@ -1,10 +1,8 @@ -# Copyright (c) 2026 -# United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) -# All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. -# Source may not be released without written approval from HEC - -import logging import os +import logging +from jpype import JImplements, JOverride + +_java_log_sink = None def _get_log_level(): @@ -15,6 +13,7 @@ def _get_log_level(): log_level = logging.INFO return log_level, invalid_log_level, log_level_name + def configure_logging(): log_level, invalid_log_level, log_level_name = _get_log_level() @@ -44,4 +43,71 @@ def filter(self, record): if invalid_log_level: logger.warning("Invalid REGI_LOG_LEVEL '%s'; using INFO.", log_level_name) - return logger \ No newline at end of file + return logger + + +def configure_jul_to_python_logging(python_logger): + global _java_log_sink + + from java.util.logging import Logger, Level + from usace.rowcps.headless import PythonJulHandler + + java_level = _python_level_to_jul_level(python_logger.getEffectiveLevel()) + + root_logger = Logger.getLogger("") + root_logger.setLevel(java_level) + + for handler in root_logger.getHandlers(): + root_logger.removeHandler(handler) + + _java_log_sink = PythonLogSink(python_logger) + + handler = PythonJulHandler(_java_log_sink) + handler.setLevel(java_level) + + root_logger.addHandler(handler) + + +def _python_level_to_jul_level(python_level): + from java.util.logging import Level + + if python_level <= logging.DEBUG: + return Level.FINE + if python_level <= logging.INFO: + return Level.INFO + if python_level <= logging.WARNING: + return Level.WARNING + if python_level <= logging.ERROR: + return Level.SEVERE + return Level.OFF + + +def _jul_level_to_python_level(jul_level_name): + mapping = { + "SEVERE": logging.ERROR, + "WARNING": logging.WARNING, + "INFO": logging.INFO, + "CONFIG": logging.INFO, + "FINE": logging.DEBUG, + "FINER": logging.DEBUG, + "FINEST": logging.DEBUG, + } + return mapping.get(str(jul_level_name), logging.INFO) + + +@JImplements("usace.rowcps.headless.PythonLogSink") +class PythonLogSink: + def __init__(self, python_logger): + self._logger = python_logger + + @JOverride + def log(self, record, message): + level = _jul_level_to_python_level(record.getLevel().getName()) + name = str(record.getLoggerName() or "java") + message = str(message) + + thrown = record.getThrown() + if thrown is not None: + message = f"{message}\n{thrown}" + + self._logger.log(level, "[%s] %s", name, message) \ No newline at end of file From 1f968e6fa9ed57c4d5cb8e0bb0f2d2b7bebed3b0 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Mon, 6 Jul 2026 12:11:15 -0700 Subject: [PATCH 13/26] standardize python logger with JUL --- .../python/regi_python/regi_python_logging.py | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/regi-headless/src/main/python/regi_python/regi_python_logging.py b/regi-headless/src/main/python/regi_python/regi_python_logging.py index 6942c87..3764731 100644 --- a/regi-headless/src/main/python/regi_python/regi_python_logging.py +++ b/regi-headless/src/main/python/regi_python/regi_python_logging.py @@ -49,7 +49,7 @@ def filter(self, record): def configure_jul_to_python_logging(python_logger): global _java_log_sink - from java.util.logging import Logger, Level + from java.util.logging import Logger from usace.rowcps.headless import PythonJulHandler java_level = _python_level_to_jul_level(python_logger.getEffectiveLevel()) @@ -60,24 +60,27 @@ def configure_jul_to_python_logging(python_logger): for handler in root_logger.getHandlers(): root_logger.removeHandler(handler) + PythonLogSink = _create_python_log_sink_class() _java_log_sink = PythonLogSink(python_logger) handler = PythonJulHandler(_java_log_sink) handler.setLevel(java_level) root_logger.addHandler(handler) - + def _python_level_to_jul_level(python_level): from java.util.logging import Level + if python_level <= logging.NOTSET: + return Level.ALL if python_level <= logging.DEBUG: return Level.FINE if python_level <= logging.INFO: return Level.INFO if python_level <= logging.WARNING: return Level.WARNING - if python_level <= logging.ERROR: + if python_level <= logging.CRITICAL: return Level.SEVERE return Level.OFF @@ -91,23 +94,32 @@ def _jul_level_to_python_level(jul_level_name): "FINE": logging.DEBUG, "FINER": logging.DEBUG, "FINEST": logging.DEBUG, + "ALL": logging.NOTSET, + "OFF": logging.CRITICAL + 10, } return mapping.get(str(jul_level_name), logging.INFO) -@JImplements("usace.rowcps.headless.PythonLogSink") -class PythonLogSink: - def __init__(self, python_logger): - self._logger = python_logger +def _create_python_log_sink_class(): + # JPype resolves @JImplements interfaces immediately, so define this class only + # after the JVM has started; otherwise importing this module would fail. + from jpype import JImplements, JOverride + + @JImplements("usace.rowcps.headless.PythonLogSink") + class PythonLogSink: + def __init__(self, python_logger): + self._logger = python_logger + + @JOverride + def log(self, record, message): + level = _jul_level_to_python_level(record.getLevel().getName()) + name = str(record.getLoggerName() or "java") + message = str(message) - @JOverride - def log(self, record, message): - level = _jul_level_to_python_level(record.getLevel().getName()) - name = str(record.getLoggerName() or "java") - message = str(message) + thrown = record.getThrown() + if thrown is not None: + message = f"{message}\n{thrown}" - thrown = record.getThrown() - if thrown is not None: - message = f"{message}\n{thrown}" + self._logger.log(level, "[%s] %s", name, message) - self._logger.log(level, "[%s] %s", name, message) \ No newline at end of file + return PythonLogSink \ No newline at end of file From d75b40d5e90fabadcd1be19137e3e0fb1a7241c1 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 08:18:28 -0700 Subject: [PATCH 14/26] fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99d78f4..b5d5b95 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ The library reads the following environment variables when establishing the CWMS Data API data source: - `CDA_URL`: Base URL for the CWMS Data API endpoint. -- `API_KEY`: API key used for CWMS Data API authentication and authorization. +- `CDA_API_KEY`: API key used for CWMS Data API authentication and authorization. - `OFFICE_ID`: CWMS office identifier used to scope the session. The factory uses these values to authenticate, resolve the current user, and persist the connected office and time zone into the REGI project. From 87564b8cf1d782993847aef39d5b133cba9d443a Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 08:53:36 -0700 Subject: [PATCH 15/26] update all example scripts and remove redundant examples --- .../legacy-examples/solaris/GateFlow.py | 195 ----------------- .../legacy-examples/solaris/GateSettings.py | 75 ------- .../legacy-examples/solaris/GateSettings.sh | 2 - .../solaris/InflowAutoAdjust.sh | 2 - .../solaris/InflowBalanceAll.sh | 2 - .../solaris/InflowCalcAutoAdjust.py | 98 --------- .../solaris/InflowCalcBalanceAll.py | 91 -------- .../solaris/InflowCalcClone.py | 90 -------- .../solaris/InflowCalcComputeEvapAsFlow.py | 23 -- .../solaris/InflowCalcComputedInflow.py | 25 --- .../solaris/InflowCalcMultipleActions.py | 106 ---------- .../solaris/InflowCalcZeroNegative.py | 93 --------- .../legacy-examples/solaris/InflowClone.sh | 2 - .../legacy-examples/solaris/InflowComputed.sh | 2 - .../solaris/InflowEvapAsFlow.sh | 2 - .../solaris/InflowMultiAction.sh | 2 - .../solaris/InflowZeroNegative.sh | 2 - .../solaris/RunHeadlessJython.sh | 82 -------- .../legacy-examples/solaris/__init__.py | 0 .../legacy-examples/solaris/flow.sh | 2 - .../legacy-examples/windows/GateFlow.py | 196 ------------------ .../legacy-examples/windows/GateSettings.bat | 2 - .../legacy-examples/windows/GateSettings.py | 86 -------- .../windows/InflowAutoAdjust.bat | 2 - .../windows/InflowBalanceAll.bat | 2 - .../windows/InflowCalcAutoAdjust.py | 104 ---------- .../windows/InflowCalcBalanceAll.py | 97 --------- .../windows/InflowCalcClone.py | 96 --------- .../windows/InflowCalcComputeEvapAsFlow.py | 33 --- .../windows/InflowCalcComputedInflow.py | 35 ---- .../windows/InflowCalcMultipleActions.py | 115 ---------- .../windows/InflowCalcZeroNegative.py | 97 --------- .../legacy-examples/windows/InflowClone.bat | 2 - .../windows/InflowComputed.bat | 2 - .../windows/InflowEvapAsFlow.bat | 2 - .../windows/InflowMultiAction.bat | 2 - .../windows/InflowZeroNegative.bat | 2 - .../windows/RunHeadlessJython.bat | 47 ----- .../legacy-examples/windows/__init__.py | 0 .../legacy-examples/windows/flow.bat | 3 - .../rowcps/headless/examples/GateFlowCalc.py | 124 ++++------- .../rowcps/headless/examples/GateFlowCalc2.py | 39 ++-- .../rowcps/headless/examples/GateSettings.py | 64 +++--- .../rowcps/headless/examples/InflowCalc.py | 58 +++--- .../headless/examples/InflowCalcAutoAdjust.py | 54 ++--- .../headless/examples/InflowCalcBalanceAll.py | 54 ++--- .../headless/examples/InflowCalcClone.py | 54 ++--- .../examples/InflowCalcComputeEvapAsFlow.py | 40 ++-- .../examples/InflowCalcComputedInflow.py | 41 ++-- .../examples/InflowCalcZeroNegative.py | 54 ++--- .../examples/LoggingOptionsExamples.py | 38 +++- .../usace/rowcps/headless/tests/GateFlow.py | 187 ----------------- .../rowcps/headless/tests/GateFlowCalc.py | 22 -- .../rowcps/headless/tests/GateSettings.py | 45 ---- .../headless/tests/InflowCalcAutoAdjust.py | 36 ---- .../headless/tests/InflowCalcBalanceAll.py | 36 ---- .../rowcps/headless/tests/InflowCalcClone.py | 34 --- .../tests/InflowCalcComputeEvapAsFlow.py | 23 -- .../tests/InflowCalcComputedInflow.py | 37 ---- .../headless/tests/InflowCalcZeroNegative.py | 34 --- .../headless/tests/LoggingOptionsExamples.py | 69 ------ 61 files changed, 318 insertions(+), 2646 deletions(-) delete mode 100644 district-scripts/legacy-examples/solaris/GateFlow.py delete mode 100644 district-scripts/legacy-examples/solaris/GateSettings.py delete mode 100644 district-scripts/legacy-examples/solaris/GateSettings.sh delete mode 100644 district-scripts/legacy-examples/solaris/InflowAutoAdjust.sh delete mode 100644 district-scripts/legacy-examples/solaris/InflowBalanceAll.sh delete mode 100644 district-scripts/legacy-examples/solaris/InflowCalcAutoAdjust.py delete mode 100644 district-scripts/legacy-examples/solaris/InflowCalcBalanceAll.py delete mode 100644 district-scripts/legacy-examples/solaris/InflowCalcClone.py delete mode 100644 district-scripts/legacy-examples/solaris/InflowCalcComputeEvapAsFlow.py delete mode 100644 district-scripts/legacy-examples/solaris/InflowCalcComputedInflow.py delete mode 100644 district-scripts/legacy-examples/solaris/InflowCalcMultipleActions.py delete mode 100644 district-scripts/legacy-examples/solaris/InflowCalcZeroNegative.py delete mode 100644 district-scripts/legacy-examples/solaris/InflowClone.sh delete mode 100644 district-scripts/legacy-examples/solaris/InflowComputed.sh delete mode 100644 district-scripts/legacy-examples/solaris/InflowEvapAsFlow.sh delete mode 100644 district-scripts/legacy-examples/solaris/InflowMultiAction.sh delete mode 100644 district-scripts/legacy-examples/solaris/InflowZeroNegative.sh delete mode 100644 district-scripts/legacy-examples/solaris/RunHeadlessJython.sh delete mode 100644 district-scripts/legacy-examples/solaris/__init__.py delete mode 100644 district-scripts/legacy-examples/solaris/flow.sh delete mode 100644 district-scripts/legacy-examples/windows/GateFlow.py delete mode 100644 district-scripts/legacy-examples/windows/GateSettings.bat delete mode 100644 district-scripts/legacy-examples/windows/GateSettings.py delete mode 100644 district-scripts/legacy-examples/windows/InflowAutoAdjust.bat delete mode 100644 district-scripts/legacy-examples/windows/InflowBalanceAll.bat delete mode 100644 district-scripts/legacy-examples/windows/InflowCalcAutoAdjust.py delete mode 100644 district-scripts/legacy-examples/windows/InflowCalcBalanceAll.py delete mode 100644 district-scripts/legacy-examples/windows/InflowCalcClone.py delete mode 100644 district-scripts/legacy-examples/windows/InflowCalcComputeEvapAsFlow.py delete mode 100644 district-scripts/legacy-examples/windows/InflowCalcComputedInflow.py delete mode 100644 district-scripts/legacy-examples/windows/InflowCalcMultipleActions.py delete mode 100644 district-scripts/legacy-examples/windows/InflowCalcZeroNegative.py delete mode 100644 district-scripts/legacy-examples/windows/InflowClone.bat delete mode 100644 district-scripts/legacy-examples/windows/InflowComputed.bat delete mode 100644 district-scripts/legacy-examples/windows/InflowEvapAsFlow.bat delete mode 100644 district-scripts/legacy-examples/windows/InflowMultiAction.bat delete mode 100644 district-scripts/legacy-examples/windows/InflowZeroNegative.bat delete mode 100644 district-scripts/legacy-examples/windows/RunHeadlessJython.bat delete mode 100644 district-scripts/legacy-examples/windows/__init__.py delete mode 100644 district-scripts/legacy-examples/windows/flow.bat delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlow.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlowCalc.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/GateSettings.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcAutoAdjust.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcBalanceAll.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcClone.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputeEvapAsFlow.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputedInflow.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcZeroNegative.py delete mode 100644 regi-headless/src/test/resources/usace/rowcps/headless/tests/LoggingOptionsExamples.py diff --git a/district-scripts/legacy-examples/solaris/GateFlow.py b/district-scripts/legacy-examples/solaris/GateFlow.py deleted file mode 100644 index ef36bec..0000000 --- a/district-scripts/legacy-examples/solaris/GateFlow.py +++ /dev/null @@ -1,195 +0,0 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance(timeZone) -# startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -6) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -# startCal.set(Calendar.YEAR, 2015) -# startCal.set(Calendar.MONTH, 9) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(timeZone) -# endCal.clear() -endCal.add(Calendar.DAY_OF_MONTH, 5) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -# endCal.set(Calendar.YEAR, 2015) -# endCal.set(Calendar.MONTH, 11) - -officeID = "SWF" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = True -flowGroup = "ConduitGate_Total" -locationList = ["ACTT2", - "ALAT2", - "BDWT2", - "BLNT2", - "BNBT2", - "CLDL1", - "DAWT2", -# "GGLT2", -# "GNGT2", -# "GPVT2", -# "HORT2", -# "JFNT2", -# "JPLT2", -# "JSPT2", -# "LEWT2", -# "LVNT2", -# "PCTT2", -# "RRLT2", -# "FRHT2", -# "SCLT2", -# "SMCT2", -# "SOMT2", -# "STIT2", -# "TXKT2", -# "WTYT2", -# "TRNT2", -# "FFLT2", -# "BPRT2", -# "EAMT2", -# "FLWT2", -# "LLST2", -# "GBYT2", -# "PSMT2", -# "TBLT2", -# "TBRT2", -# "GPET2", -# "BSLT2", -# "SAGT2", -# "MSDT2", - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = True -FlowGroupList = ["ACTT2", - "ALAT2", - "BDWT2", - "BLNT2", - "BNBT2", - "DAWT2", - "GGLT2", -# "GNGT2", -# "GPVT2", -# "HORT2", -# "JPLT2", -# "LEWT2", -# "LVNT2", -# "PCTT2", -# "RRLT2", -# "FRHT2", -# "SCLT2", -# "SMCT2", -# "SOMT2", -# "STIT2", -# "TXKT2", -# "WTYT2", -# "TRNT2", -# "FFLT2", -# "EAMT2", -# "FLWT2", -# "LLST2", -# "GBYT2", -# "PSMT2", -# "SAGT2", - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) - -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - compute_All_Flowgroups(officeID, location, startCal, endCal) - - - diff --git a/district-scripts/legacy-examples/solaris/GateSettings.py b/district-scripts/legacy-examples/solaris/GateSettings.py deleted file mode 100644 index e061cbd..0000000 --- a/district-scripts/legacy-examples/solaris/GateSettings.py +++ /dev/null @@ -1,75 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Gate Settings object -gateSettings = registry.getCalculation(1.0, "Gate Settings") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) - - -# gateSettings contains four callable methods -# void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; -# void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; -# void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; -# void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; - -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the specified input time series. -gateSettings.createGateSettingsOutletFromTs("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "TG1", "WTYT2-TG1.Opening-Spillway_Gate.Const.0.0.MANUAL" ) - -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the regi association configured input time series. -gateSettings.createGateSettingsOutlet("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "TG1") - -# This is an example of a call that would create gate settings at all outlets at WTYT2 which are in the TainterGateWTY group from the association configured time series. -gateSettings.createGateSettingsGroup("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "WTYT2-TainterGateWTY" ) - -# This is an example of a call that would create gate settings for every outlet in a rating group at WTYT2. -gateSettings.createGateSettings("SWF", "WTYT2", startCal.getTime(), endCal.getTime() ) - - - diff --git a/district-scripts/legacy-examples/solaris/GateSettings.sh b/district-scripts/legacy-examples/solaris/GateSettings.sh deleted file mode 100644 index e33d758..0000000 --- a/district-scripts/legacy-examples/solaris/GateSettings.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//GateSettings.py diff --git a/district-scripts/legacy-examples/solaris/InflowAutoAdjust.sh b/district-scripts/legacy-examples/solaris/InflowAutoAdjust.sh deleted file mode 100644 index 482bf5a..0000000 --- a/district-scripts/legacy-examples/solaris/InflowAutoAdjust.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//InflowCalcAutoAdjust.py diff --git a/district-scripts/legacy-examples/solaris/InflowBalanceAll.sh b/district-scripts/legacy-examples/solaris/InflowBalanceAll.sh deleted file mode 100644 index 971daf8..0000000 --- a/district-scripts/legacy-examples/solaris/InflowBalanceAll.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//InflowCalcBalanceAll.py diff --git a/district-scripts/legacy-examples/solaris/InflowCalcAutoAdjust.py b/district-scripts/legacy-examples/solaris/InflowCalcAutoAdjust.py deleted file mode 100644 index f35ac31..0000000 --- a/district-scripts/legacy-examples/solaris/InflowCalcAutoAdjust.py +++ /dev/null @@ -1,98 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - - -def auto_Adjust(officeID, location, startCal, useLimits, freezeRain): - # Takes in locations defined by user in group and adjusts the selected inflow. If a location fails or has an error, the script will continue. check the console log - # for any further information. - try: - inflowCalc.autoAdjust(officeID, location, startCal.getTime(), useLimits, freezeRain) - except Exception as e: - print "Error Adjusting Values at {0} {1}".format(officeID, location) - print e - print "" - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar - -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoAdjusts for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any order. Additional stations can be added -# to the end provided they follow the same format. UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, -# the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" - -officeID = "SWF" -useLimits_ON = False -freezeRain_ON = False -locationList = ["ACTT2", - "ALAT2", -# "BLNT2", -# "BNBT2", -# "CLDL1", -# "DAWT2", - "ACTT2", - "TXKT2", - ] -for location in locationList: - print "Now Running", location - auto_Adjust(officeID, location, startCal, useLimits_ON, freezeRain_ON) - - - diff --git a/district-scripts/legacy-examples/solaris/InflowCalcBalanceAll.py b/district-scripts/legacy-examples/solaris/InflowCalcBalanceAll.py deleted file mode 100644 index 895c5ff..0000000 --- a/district-scripts/legacy-examples/solaris/InflowCalcBalanceAll.py +++ /dev/null @@ -1,91 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def balance_all(officeID, location, startCal): - # Takes in locations defined by user in group and balances the selected inflow - try: - inflowCalc.balanceAll(officeID, location, startCal.getTime()) - except Exception as e: - print "Error Computing Balance all at {0} {1}".format(officeID, location) - print e - print "" - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar - -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 1) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any order. Additonial stations can be added -# to the end provided they follow the same format. -officeID = "SWF" -locationList = ["ACTT2", - "ALAT2", -# "BLNT2", -# "BNBT2", -# "CLDL1", -# "DAWT2", - "ACTT2", - "TXKT2", - ] -for location in locationList: - print "Now Running", location - balance_all(officeID, location, startCal) - - diff --git a/district-scripts/legacy-examples/solaris/InflowCalcClone.py b/district-scripts/legacy-examples/solaris/InflowCalcClone.py deleted file mode 100644 index 2207b7c..0000000 --- a/district-scripts/legacy-examples/solaris/InflowCalcClone.py +++ /dev/null @@ -1,90 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def clone_Inflows(officeID, location, startCal): - # Takes in locations defined by user in group and clones the selected inflow - try: - inflowCalc.cloneInflows(officeID, location, startCal.getTime()) - except Exception as e: - print "Error Cloning Inflows at {0} {1}".format(officeID, location) - print e - print "" - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar - -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 3) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This clones inflow for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any order. Additional stations can be added -# to the end provided they follow the same format. -officeID = "SWF" -locationList = ["ACTT2", - "ALAT2", -# "BLNT2", -# "BNBT2", -# "CLDL1", -# "DAWT2", - "ACTT2", - ] -for location in locationList: - print "Now Running", location - clone_Inflows(officeID, location, startCal) - - diff --git a/district-scripts/legacy-examples/solaris/InflowCalcComputeEvapAsFlow.py b/district-scripts/legacy-examples/solaris/InflowCalcComputeEvapAsFlow.py deleted file mode 100644 index 3ab7b56..0000000 --- a/district-scripts/legacy-examples/solaris/InflowCalcComputeEvapAsFlow.py +++ /dev/null @@ -1,23 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 4) - -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -endCal.clear() -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 4) -endCal.set(Calendar.DAY_OF_MONTH, 4) - -# This computes and saves evap as flow for EUFA in May 2018 -inflowCalc.computeEvapAsFlow("SWT", "EUFA", startCal.getTime(), endCal.getTime()) \ No newline at end of file diff --git a/district-scripts/legacy-examples/solaris/InflowCalcComputedInflow.py b/district-scripts/legacy-examples/solaris/InflowCalcComputedInflow.py deleted file mode 100644 index faf1ce4..0000000 --- a/district-scripts/legacy-examples/solaris/InflowCalcComputedInflow.py +++ /dev/null @@ -1,25 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.calculator.inflow import InflowComputationStorageOption - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 4) - -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -endCal.clear() -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 4) -endCal.set(Calendar.DAY_OF_MONTH, 4) - -# This computes and saves inflow for EUFA in May 2018 -# computeInflow saves the Computed Inflow, Evaporation as Flow, and Project Total Flow Group time series data -inflowCalc.computeInflow("SWT", "EUFA", startCal.getTime(), endCal.getTime()) diff --git a/district-scripts/legacy-examples/solaris/InflowCalcMultipleActions.py b/district-scripts/legacy-examples/solaris/InflowCalcMultipleActions.py deleted file mode 100644 index e73296b..0000000 --- a/district-scripts/legacy-examples/solaris/InflowCalcMultipleActions.py +++ /dev/null @@ -1,106 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def inflow_Actions(function, officeID, location, startCal, uselimits, freezerain): - # Takes in locations defined by user in group and computes the given command at the given station. - try: - if function.lower() == "cloneinflows": - inflowCalc.cloneInflows(officeID, location, startCal.getTime()) - elif function.lower() == "zeronegatives": - inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) - elif function.lower() == "balanceall": - inflowCalc.balanceAll(officeID, location, startCal.getTime()) - elif function.lower() == "autoadjust": - inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) - else: - print "Input command", function, "is not recognized. Please edit your input and try again." - except Exception as e: - print "Error Completing action {0} at {1} {2}".format(function, officeID, location) - print e - print "" -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar' -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - -officeID = "SWF" - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, -# the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" -# If the Auto Adjust command is not used, these arguments will have no influence on the other commands. -useLimits_ON = False -freezeRain_ON = False - -# Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. -# The action must come first, and they must be separated by a "@" symbol. -# Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. -actions = ["cloneInflows @ ALAT2", - "zeroNegatives @ ALAT2", - "cloneInflows @ ALAT2", - "balanceAll @ ALAT2", - "cloneInflows @ ALAT2", - "autoAdjust @ ALAT2", - ] - -for command in actions: - location = command.split('@')[1].strip() - function = command.split('@')[0].strip() - print "" - print "Now running", function, "at", location - print "" - inflow_Actions(function, officeID, location, startCal, useLimits_ON, freezeRain_ON) diff --git a/district-scripts/legacy-examples/solaris/InflowCalcZeroNegative.py b/district-scripts/legacy-examples/solaris/InflowCalcZeroNegative.py deleted file mode 100644 index 59f5e30..0000000 --- a/district-scripts/legacy-examples/solaris/InflowCalcZeroNegative.py +++ /dev/null @@ -1,93 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def zero_Negatives(officeID, location, startCal): - # Takes in locations defined by user in group and turns all negative values to 0 for the selected inflow. If a location fails or has an error, the script will continue. check the console log - # for any further information. - try: - inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) - except Exception as e: - print "Error Computing Zero Negatives at {0} {1}".format(officeID, location) - print e - print "" -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar - -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 1) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This zeroes any negatives for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any order. Additional stations can be added -# to the end provided they follow the same format. - -officeID = "SWF" -locationList = ["ACTT2", - "ALAT2", -# "BLNT2", -# "BNBT2", -# "CLDL1", -# "DAWT2", - "ACTT2", - "TXKT2", - ] -for location in locationList: - print "Now Running", location - zero_Negatives(officeID, location, startCal) - - - diff --git a/district-scripts/legacy-examples/solaris/InflowClone.sh b/district-scripts/legacy-examples/solaris/InflowClone.sh deleted file mode 100644 index 0d790af..0000000 --- a/district-scripts/legacy-examples/solaris/InflowClone.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//InflowCalcClone.py diff --git a/district-scripts/legacy-examples/solaris/InflowComputed.sh b/district-scripts/legacy-examples/solaris/InflowComputed.sh deleted file mode 100644 index 4132189..0000000 --- a/district-scripts/legacy-examples/solaris/InflowComputed.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//InflowCalcComputedInflow.py diff --git a/district-scripts/legacy-examples/solaris/InflowEvapAsFlow.sh b/district-scripts/legacy-examples/solaris/InflowEvapAsFlow.sh deleted file mode 100644 index 5aa3868..0000000 --- a/district-scripts/legacy-examples/solaris/InflowEvapAsFlow.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//InflowCalcComputeEvapAsFlow.py diff --git a/district-scripts/legacy-examples/solaris/InflowMultiAction.sh b/district-scripts/legacy-examples/solaris/InflowMultiAction.sh deleted file mode 100644 index 9a1790a..0000000 --- a/district-scripts/legacy-examples/solaris/InflowMultiAction.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//InflowCalcMultipleActions.py diff --git a/district-scripts/legacy-examples/solaris/InflowZeroNegative.sh b/district-scripts/legacy-examples/solaris/InflowZeroNegative.sh deleted file mode 100644 index 001e661..0000000 --- a/district-scripts/legacy-examples/solaris/InflowZeroNegative.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//InflowCalcZeroNegative.py diff --git a/district-scripts/legacy-examples/solaris/RunHeadlessJython.sh b/district-scripts/legacy-examples/solaris/RunHeadlessJython.sh deleted file mode 100644 index cf1da70..0000000 --- a/district-scripts/legacy-examples/solaris/RunHeadlessJython.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash - -NOT_FOUND="notFound" - -PROGRAM_ROOT=$(realpath ..) -JAR_DIR=$PROGRAM_ROOT/lib -SYS=$JAR_DIR/sys -CWMS=$JAR_DIR/cwms -REGI=$JAR_DIR/regi -LIBRARY_PATH=$PROGRAM_ROOT/lib64 -JAVA_EXE=$PROGRAM_ROOT/jre64/bin/java -ARGS=("$@") - -export LD_LIBRARY_PATH=$LIBRARY_PATH:$LD_LIBRARY_PATH -echo "LD_LIBRARY_PATH updated to $LD_LIBRARY_PATH" - -ORACLE_URL=$(getProp cwms.dbi.ConnectUsingUrl @${NOT_FOUND} dbi.properties|cut -d@ -f2) -if [ $ORACLE_URL = $NOT_FOUND ] -then - echo "Unable to locate Oracle URL from Cwms configuration. Will be taken from credentials.properties" -fi - -echo "Found Oracle URL: $ORACLE_URL" - -# Get the office id from cwms.properties using the CWMS getProp script -OFFICE_ID=$(getProp cwms.OfficeID ${NOT_FOUND} cwms.properties $CWMS_HOME/config/properties) -if [ $OFFICE_ID = $NOT_FOUND ] -then - echo "Unable to locate OfficeID from Cwms configuration. Will be taken from credentials.properties" -fi - -echo "Found Office ID: $OFFICE_ID" - -# The password file is expected to be at the following (full) path. -PASSWORD_FILE=$CWMS_HOME/config/properties/dbi.conf -if [ ! -f $PASSWORD_FILE ] -then - echo "Unable to locate password file in Cwms configuration. Will be taken from credentials.properties" -fi - -SCRIPT="" -NAME_FOUND=false - -for ((i=0; i < ${#ARGS[@]}; i++)) -do - PARAM_NAME=$(echo "${ARGS[$i]}" | tr '[:lower:]' '[:upper:]') - - if [ "$NAME_FOUND" = true ] ; then - # Use the script name as the base file name for the log file - BASENAME="$(basename "${ARGS[$i]}")" # Get only the base file name. - SCRIPT="${BASENAME%%.*}" # Remove the extension - break - elif [ "$PARAM_NAME" = "-F" ] ; then - NAME_FOUND=true - fi -done - - - -JAVA_COMMAND="-cp $JAR_DIR/*:$REGI/*:$CWMS/*:$SYS/*:"\ -" -Doracle.url=jdbc:oracle:thin:@${ORACLE_URL}"\ -" -Doracle.officeId=$OFFICE_ID"\ -" -Dhec.passwd=$PASSWORD_FILE"\ -" -Djava.library.path=$LIBRARY_PATH"\ -" -DPLUGINS=$EXT"\ -" -Doracle.metrics.clientid=\"CWMS REGI-Headless-v5.0\""\ -" -Djava.util.logging.config.file=../config/properties/logging.properties"\ -" -Drowcps.timezone=America/Chicago"\ -" usace.rowcps.headless.RegiCLI"\ -" -p ..//examples//credentials.properties"\ -" ${ARGS[*]}" - -LOG_FILE=$CWMS_HOME/cronjobs/headless/logs/$(getStartFN regi-headless-"$SCRIPT") - -echo "Running jython $SCRIPT" -echo "Output going to: $LOG_FILE" -echo "Java Command:" -echo "$JAVA_EXE $JAVA_COMMAND" -eval "$JAVA_EXE" $JAVA_COMMAND &> "$LOG_FILE" -STATUS=$? - -echo "$SCRIPT process exited with code $STATUS" \ No newline at end of file diff --git a/district-scripts/legacy-examples/solaris/__init__.py b/district-scripts/legacy-examples/solaris/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/district-scripts/legacy-examples/solaris/flow.sh b/district-scripts/legacy-examples/solaris/flow.sh deleted file mode 100644 index cc017e5..0000000 --- a/district-scripts/legacy-examples/solaris/flow.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -./RunHeadlessJython.sh -f ..//examples//GateFlow.py diff --git a/district-scripts/legacy-examples/windows/GateFlow.py b/district-scripts/legacy-examples/windows/GateFlow.py deleted file mode 100644 index ba56125..0000000 --- a/district-scripts/legacy-examples/windows/GateFlow.py +++ /dev/null @@ -1,196 +0,0 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -startCal.add(Calendar.DATE, -5) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWF" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = True -flowGroup = "ConduitGate_Total" -locationList = ["ACTT2", - "ALAT2", - "BDWT2", - "BLNT2", - "BNBT2", - "CLDL1", - "DAWT2", -# "GGLT2", -# "GNGT2", -# "GPVT2", -# "HORT2", -# "JFNT2", -# "JPLT2", -# "JSPT2", -# "LEWT2", -# "LVNT2", -# "PCTT2", -# "RRLT2", -# "FRHT2", -# "SCLT2", -# "SMCT2", -# "SOMT2", -# "STIT2", -# "TXKT2", -# "WTYT2", -# "TRNT2", -# "FFLT2", -# "BPRT2", -# "EAMT2", -# "FLWT2", -# "LLST2", -# "GBYT2", -# "PSMT2", -# "TBLT2", -# "TBRT2", -# "GPET2", -# "BSLT2", -# "SAGT2", -# "MSDT2", - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = True -FlowGroupList = ["ACTT2", - "ALAT2", - "BDWT2", - "BLNT2", - "BNBT2", - "DAWT2", - "GGLT2", -# "GNGT2", -# "GPVT2", -# "HORT2", -# "JPLT2", -# "LEWT2", -# "LVNT2", -# "PCTT2", -# "RRLT2", -# "FRHT2", -# "SCLT2", -# "SMCT2", -# "SOMT2", -# "STIT2", -# "TXKT2", -# "WTYT2", -# "TRNT2", -# "FFLT2", -# "EAMT2", -# "FLWT2", -# "LLST2", -# "GBYT2", -# "PSMT2", -# "SAGT2", - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) - -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - compute_All_Flowgroups(officeID, location, startCal, endCal) - - - diff --git a/district-scripts/legacy-examples/windows/GateSettings.bat b/district-scripts/legacy-examples/windows/GateSettings.bat deleted file mode 100644 index 529540a..0000000 --- a/district-scripts/legacy-examples/windows/GateSettings.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\GateSettings.py diff --git a/district-scripts/legacy-examples/windows/GateSettings.py b/district-scripts/legacy-examples/windows/GateSettings.py deleted file mode 100644 index ff4cfcc..0000000 --- a/district-scripts/legacy-examples/windows/GateSettings.py +++ /dev/null @@ -1,86 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Gate Settings object -gateSettings = registry.getCalculation(1.0, "Gate Settings") - - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -startCal.add(Calendar.DATE, -5) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - - -# gateSettings contains four callable methods -# void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; -# void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; -# void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; -# void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; - -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the specified input time series. -gateSettings.createGateSettingsOutletFromTs("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "TG1", "WTYT2-TG1.Opening-Spillway_Gate.Const.0.0.MANUAL" ) - -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the regi association configured input time series. -gateSettings.createGateSettingsOutlet("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "TG1") - -# This is an example of a call that would create gate settings at all outlets at WTYT2 which are in the TainterGateWTY group from the association configured time series. -gateSettings.createGateSettingsGroup("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "WTYT2-TainterGateWTY" ) - -# This is an example of a call that would create gate settings for every outlet in a rating group at WTYT2. -gateSettings.createGateSettings("SWF", "WTYT2", startCal.getTime(), endCal.getTime() ) - - - diff --git a/district-scripts/legacy-examples/windows/InflowAutoAdjust.bat b/district-scripts/legacy-examples/windows/InflowAutoAdjust.bat deleted file mode 100644 index 49cb2d4..0000000 --- a/district-scripts/legacy-examples/windows/InflowAutoAdjust.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\InflowCalcAutoAdjust.py diff --git a/district-scripts/legacy-examples/windows/InflowBalanceAll.bat b/district-scripts/legacy-examples/windows/InflowBalanceAll.bat deleted file mode 100644 index 56d0265..0000000 --- a/district-scripts/legacy-examples/windows/InflowBalanceAll.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\InflowCalcBalanceAll.py diff --git a/district-scripts/legacy-examples/windows/InflowCalcAutoAdjust.py b/district-scripts/legacy-examples/windows/InflowCalcAutoAdjust.py deleted file mode 100644 index 508c05b..0000000 --- a/district-scripts/legacy-examples/windows/InflowCalcAutoAdjust.py +++ /dev/null @@ -1,104 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - - -def auto_Adjust(officeID, location, startCal, useLimits, freezeRain): - # Takes in locations defined by user in group and adjusts the selected inflow. If a location fails or has an error, the script will continue. check the console log - # for any further information. - try: - inflowCalc.autoAdjust(officeID, location, startCal.getTime(), useLimits, freezeRain) - except Exception as e: - print "Error Adjusting Values at {0} {1}".format(officeID, location) - print e - print "" - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# Defaults to day one of the current month at 0000 -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -startCal.set(Calendar.DATE, 1) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoAdjusts for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any order. Additional stations can be added -# to the end provided they follow the same format. UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, -# the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" - -officeID = "SWF" -useLimits_ON = False -freezeRain_ON = False -locationList = ["ACTT2", - "ALAT2", -# "BLNT2", -# "BNBT2", -# "CLDL1", -# "DAWT2", - "ACTT2", - "TXKT2", - ] -for location in locationList: - print "Now Running", location - auto_Adjust(officeID, location, startCal, useLimits_ON, freezeRain_ON) - - - diff --git a/district-scripts/legacy-examples/windows/InflowCalcBalanceAll.py b/district-scripts/legacy-examples/windows/InflowCalcBalanceAll.py deleted file mode 100644 index 70eb4b2..0000000 --- a/district-scripts/legacy-examples/windows/InflowCalcBalanceAll.py +++ /dev/null @@ -1,97 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def balance_all(officeID, location, startCal): - # Takes in locations defined by user in group and balances the selected inflow - try: - inflowCalc.balanceAll(officeID, location, startCal.getTime()) - except Exception as e: - print "Error Computing Balance all at {0} {1}".format(officeID, location) - print e - print "" - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# Defaults to day one of the current month at 0000 -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -startCal.set(Calendar.DATE, 1) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any order. Additonial stations can be added -# to the end provided they follow the same format. -officeID = "SWF" -locationList = ["ACTT2", - "ALAT2", -# "BLNT2", -# "BNBT2", -# "CLDL1", -# "DAWT2", - "ACTT2", - "TXKT2", - ] -for location in locationList: - print "Now Running", location - balance_all(officeID, location, startCal) - - diff --git a/district-scripts/legacy-examples/windows/InflowCalcClone.py b/district-scripts/legacy-examples/windows/InflowCalcClone.py deleted file mode 100644 index fa068be..0000000 --- a/district-scripts/legacy-examples/windows/InflowCalcClone.py +++ /dev/null @@ -1,96 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def clone_Inflows(officeID, location, startCal): - # Takes in locations defined by user in group and clones the selected inflow - try: - inflowCalc.cloneInflows(officeID, location, startCal.getTime()) - except Exception as e: - print "Error Cloning Inflows at {0} {1}".format(officeID, location) - print e - print "" - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# Defaults to day one of the current month at 0000 -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -startCal.set(Calendar.DATE, 1) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This clones inflow for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any order. Additional stations can be added -# to the end provided they follow the same format. -officeID = "SWF" -locationList = ["ACTT2", - "ALAT2", -# "BLNT2", -# "BNBT2", -# "CLDL1", -# "DAWT2", - "ACTT2", - ] -for location in locationList: - print "Now Running", location - clone_Inflows(officeID, location, startCal) - - diff --git a/district-scripts/legacy-examples/windows/InflowCalcComputeEvapAsFlow.py b/district-scripts/legacy-examples/windows/InflowCalcComputeEvapAsFlow.py deleted file mode 100644 index 356037b..0000000 --- a/district-scripts/legacy-examples/windows/InflowCalcComputeEvapAsFlow.py +++ /dev/null @@ -1,33 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -startCal.add(Calendar.DATE, -5) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -# This computes and saves evap as flow for EUFA in May 2018 -inflowCalc.computeEvapAsFlow("SWT", "EUFA", startCal.getTime(), endCal.getTime()) diff --git a/district-scripts/legacy-examples/windows/InflowCalcComputedInflow.py b/district-scripts/legacy-examples/windows/InflowCalcComputedInflow.py deleted file mode 100644 index dbdec6e..0000000 --- a/district-scripts/legacy-examples/windows/InflowCalcComputedInflow.py +++ /dev/null @@ -1,35 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.calculator.inflow import InflowComputationStorageOption - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -startCal.add(Calendar.DATE, -5) - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -# This computes and saves inflow for EUFA in May 2018 -# computeInflow saves the Computed Inflow, Evaporation as Flow, and Project Total Flow Group time series data -inflowCalc.computeInflow("SWT", "EUFA", startCal.getTime(), endCal.getTime()) diff --git a/district-scripts/legacy-examples/windows/InflowCalcMultipleActions.py b/district-scripts/legacy-examples/windows/InflowCalcMultipleActions.py deleted file mode 100644 index 8722aa8..0000000 --- a/district-scripts/legacy-examples/windows/InflowCalcMultipleActions.py +++ /dev/null @@ -1,115 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions -import traceback - -def inflow_Actions(function, officeID, location, startCal, uselimits, freezerain): - # Takes in locations defined by user in group and computes the given command at the given station. - try: - if function.lower() == "cloneinflows": - inflowCalc.cloneInflows(officeID, location, startCal.getTime()) - elif function.lower() == "zeronegatives": - inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) - elif function.lower() == "balanceall": - inflowCalc.balanceAll(officeID, location, startCal.getTime()) - elif function.lower() == "autoadjust": - inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) - else: - print "Input command", function, "is not recognized. Please edit your input and try again." - except: - print "Error Completing action {0} at {1} {2}".format(function, officeID, location) - traceback.print_exc() - print "" -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# Defaults to day one of the current month at 0000 -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -startCal.set(Calendar.DATE, 1) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWF" - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, -# the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" -# If the Auto Adjust command is not used, these arguments will have no influence on the other commands. -useLimits_ON = False -freezeRain_ON = False - -# Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. -# The action must come first, and they must be separated by a "@" symbol. -# Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. -actions = ["cloneInflows @ ALAT2", - "zeroNegatives @ ALAT2", - "cloneInflows @ ALAT2", - "balanceAll @ ALAT2", - "cloneInflows @ ALAT2", - "autoAdjust @ ALAT2", - ] - -for command in actions: - location = command.split('@')[1].strip() - function = command.split('@')[0].strip() - print "" - print "Now running", function, "at", location - print "" - inflow_Actions(function, officeID, location, startCal, useLimits_ON, freezeRain_ON) diff --git a/district-scripts/legacy-examples/windows/InflowCalcZeroNegative.py b/district-scripts/legacy-examples/windows/InflowCalcZeroNegative.py deleted file mode 100644 index 8b93c2c..0000000 --- a/district-scripts/legacy-examples/windows/InflowCalcZeroNegative.py +++ /dev/null @@ -1,97 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions -import traceback - - -def zero_Negatives(officeID, location, startCal): - # Takes in locations defined by user in group and turns all negative values to 0 for the selected inflow. If a location fails or has an error, the script will continue. check the console log - # for any further information. - try: - inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) - except: - print "Error Computing Zero Negatives at {0} {1}".format(officeID, location) - traceback.print_exc() - print "" - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - - -LoggingOptions.setDbMessageLevel(2) - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# Defaults to day one of the current month at 0000 -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -startCal.set(Calendar.DATE, 1) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This zeroes any negatives for ACTT2 and ALAT2. Several locations are commented out and can be commented back in any -# order. Additional stations can be added to the end provided they follow the same format. - -officeID = "SWF" -locationList = ["ACTT2", - "ALAT2", - "TXKT2", - ] -for location in locationList: - print "Now Running", location - # Performs MonUtl function for the entire month - zero_Negatives(officeID, location, startCal) - - - diff --git a/district-scripts/legacy-examples/windows/InflowClone.bat b/district-scripts/legacy-examples/windows/InflowClone.bat deleted file mode 100644 index 33d5a7f..0000000 --- a/district-scripts/legacy-examples/windows/InflowClone.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\InflowCalcClone.py diff --git a/district-scripts/legacy-examples/windows/InflowComputed.bat b/district-scripts/legacy-examples/windows/InflowComputed.bat deleted file mode 100644 index 4e063c0..0000000 --- a/district-scripts/legacy-examples/windows/InflowComputed.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\InflowCalcComputedInflow.py diff --git a/district-scripts/legacy-examples/windows/InflowEvapAsFlow.bat b/district-scripts/legacy-examples/windows/InflowEvapAsFlow.bat deleted file mode 100644 index 3a55d38..0000000 --- a/district-scripts/legacy-examples/windows/InflowEvapAsFlow.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\InflowCalcComputeEvapAsFlow.py diff --git a/district-scripts/legacy-examples/windows/InflowMultiAction.bat b/district-scripts/legacy-examples/windows/InflowMultiAction.bat deleted file mode 100644 index 89b033f..0000000 --- a/district-scripts/legacy-examples/windows/InflowMultiAction.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\InflowCalcMultipleActions.py diff --git a/district-scripts/legacy-examples/windows/InflowZeroNegative.bat b/district-scripts/legacy-examples/windows/InflowZeroNegative.bat deleted file mode 100644 index bbfb3a6..0000000 --- a/district-scripts/legacy-examples/windows/InflowZeroNegative.bat +++ /dev/null @@ -1,2 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\InflowCalcZeroNegative.py diff --git a/district-scripts/legacy-examples/windows/RunHeadlessJython.bat b/district-scripts/legacy-examples/windows/RunHeadlessJython.bat deleted file mode 100644 index 1b5af80..0000000 --- a/district-scripts/legacy-examples/windows/RunHeadlessJython.bat +++ /dev/null @@ -1,47 +0,0 @@ -:: The headless scripts can also be executed from a bat file as demonstrated below -@echo off -setlocal enabledelayedexpansion - -set next_is_target=0 -for %%a in (%*) do ( - if !next_is_target! == 1 ( - set f_value=%%a - for %%b in ("!f_value!") do set "SCRIPT=%%~nb" - set next_is_target=0 - ) else ( - if "%%a"=="-f" ( - set next_is_target=1 - ) - ) -) - -set PROGRAM_ROOT=.. -set JAR_DIR=%PROGRAM_ROOT%\lib -set SYS=%JAR_DIR%\sys -set CWMS=%JAR_DIR%\cwms -set REGI=%JAR_DIR%\regi -set LIBRARY_PATH=%PROGRAM_ROOT%\lib64 -set JAVA_EXE=%PROGRAM_ROOT%\jre64\bin\java.exe -set ARGS=%* -for /F "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set DATE_TIME=%%I -set DATE_TIME=%DATE_TIME:~0,4%.%DATE_TIME:~4,2%.%DATE_TIME:~6,2%.%DATE_TIME:~8,2%.%DATE_TIME:~10,2% -set LOG_FILE=%CWMS_HOME%\cronjobs\headless\logs\regi-headless-%SCRIPT%.start.%DATE_TIME%.utc - -set JAVA_COMMAND=-cp %JAR_DIR%\*;%REGI%\*;%CWMS%\*;%SYS%\*; ^ --Dhec.passwd=%CWMS_HOME%\config\properties\dbi.conf ^ --Djava.library.path=%LIBRARY_PATH% ^ --DPLUGINS=%JAR_DIR%\ext ^ --Doracle.metrics.clientid="CWMS REGI-Headless-v5.0" ^ --Djava.util.logging.config.file=%PROGRAM_ROOT%\config\properties\logging.properties ^ --Drowcps.timezone=America\Chicago ^ -usace.rowcps.headless.RegiCLI ^ --p %PROGRAM_ROOT%\examples\credentials.properties ^ -%ARGS% - -echo Running CWMS-REGI Headless script %SCRIPT% -echo Output going to: %LOG_FILE% -echo Java command: -echo %JAVA_EXE% %JAVA_COMMAND% -%JAVA_EXE% %JAVA_COMMAND% > %LOG_FILE% 2>&1 -echo Status: %ERRORLEVEL% >> %LOG_FILE% -endlocal \ No newline at end of file diff --git a/district-scripts/legacy-examples/windows/__init__.py b/district-scripts/legacy-examples/windows/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/district-scripts/legacy-examples/windows/flow.bat b/district-scripts/legacy-examples/windows/flow.bat deleted file mode 100644 index b49557d..0000000 --- a/district-scripts/legacy-examples/windows/flow.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -:: The headless scripts can also be executed from a bat file as demonstrated below -RunHeadlessJython.bat -f ..\\examples\\GateFlow.py diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py index 7fcc9f4..8bcbab8 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py @@ -1,103 +1,49 @@ -from hec.data import Duration -from hec.data import Interval -from hec.data import ParameterType -from hec.data import Version -from hec.data.location import LocationTemplate -from java.lang import System -from java.util import Calendar -from java.util import Collections -from java.util import List -from java.util import TimeZone import os.path import sys -from usace.rowcps.computation.flowgroup import FlowGroupCalc -from usace.rowcps.regi.model import AtFlowGroupManager -from usace.rowcps.regi.model import AtManagerType -from usace.rowcps.regi.model import AtOutletManager -from usace.rowcps.regi.model import AtProjectManager -from usace.rowcps.regi.model import CacheUsage +from regi_python import regi_session, run_headless -print "Now executing GateFlowCalc.py" -print "os.arch:", System.getProperty("os.arch") -print "sys.path", sys.path -#curDir = open(".") -print "Working dir:", os.path.abspath(".") +def calculate_gate_flow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.lang import System + from java.util import Calendar, TimeZone -property = System.getProperty("java.library.path") -print "Library path: ", property + print("Now executing GateFlowCalc.py") + print("os.arch:", System.getProperty("os.arch")) + print("sys.path", sys.path) + print("Working dir:", os.path.abspath(".")) + print("Library path:", System.getProperty("java.library.path")) -sys.stdout.flush() + sys.stdout.flush() -print "regiDomain.getName()", regiDomain.getName() + gate_calc = registry.getCalculation(1.0, "Gate Flow") -#print AtManagerType -#print AtManagerType.DATABASE -#RegiDomain regiDomain = getRegiDomain() + office_id = "SWF" + project_id = "LEWT2" + flow_group_id = "Flow.LEWT2.ConduitGate_Total" -#lets get a lot of managers. remember that the managers can be pulled from regidomain thru the following: -# -#regiDomain.getAtProjectManager() -# -#but its coded below to make sure that we have the Oracle manager. -projManager = regiDomain.getAtManager(managerId, AtManagerType.DATABASE, AtProjectManager.AT_PROJECT_MANAGER_NAME, AtProjectManager) -# -outletManager = regiDomain.getAtManager(managerId, AtManagerType.DATABASE, AtOutletManager.AT_OUTLET_MANAGER_NAME, AtOutletManager) -## -flowGroupManager = regiDomain.getAtManager(managerId, AtManagerType.DATABASE, AtFlowGroupManager.AT_FLOW_GROUP_MANAGER_NAME, AtFlowGroupManager) + # Time zone must be set because the Solaris time zone is UTC + time_zone = TimeZone.getTimeZone("US/Central") + start_cal = Calendar.getInstance(time_zone) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2015) + start_cal.set(Calendar.MONTH, 1) -#our office -officeId = "SWF" -#this stuff would be grabbed from the project descriptor. -projectId = "LEWT2" -projectLocRef = LocationTemplate(officeId, projectId, None) -cg1LocRef = LocationTemplate(officeId, projectId + "-CG1", None) + end_cal = Calendar.getInstance(time_zone) + end_cal.clear() + end_cal.set(Calendar.YEAR, 2013) + end_cal.set(Calendar.MONTH, 1) -conduitGateFlowGroupMap = flowGroupManager.retrieveFlowGroups(projectLocRef, None, CacheUsage.NORMAL) -entrySet = conduitGateFlowGroupMap.entrySet() + gate_calc.computeFlowGroup( + office_id, + project_id, + start_cal.getTimeInMillis(), + end_cal.getTimeInMillis(), + flow_group_id, + ) -conduitGateFlowGroup = None -for entry in entrySet: - key = entry.getKey() - value = entry.getValue() - if "ConduitGate_Total" in key.getId(): - conduitGateFlowGroup = key - break - -if conduitGateFlowGroup is None: -# Assert.fail("Couldnt find conduit gate flow group") - print "Couldnt find conduit gate flow group" -else: - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - startCal = Calendar.getInstance(timeZone) - startCal.clear() - startCal.set(Calendar.YEAR, 2015) - startCal.set(Calendar.MONTH, 1) - startTime = startCal.getTimeInMillis() - - #this could be INST too. - parameterType = ParameterType(ParameterType.AVE) - interval = Interval("5Minutes") - duration = Duration("5Minutes") - version = Version("CALC") - intervalOffsetSeconds = 0 - newFlowGroupTimeSeries = conduitGateFlowGroup.newFlowGroupTimeSeries(parameterType, interval, duration, version, intervalOffsetSeconds, startCal.getTime(), None) - - flowGroupCalc = FlowGroupCalc() - outputTimeSeriesList = Collections.singletonList(newFlowGroupTimeSeries) - - endCal = Calendar.getInstance(timeZone) - endCal.clear() - endCal.set(Calendar.YEAR, 2013) - endCal.set(Calendar.MONTH, 1) - endTime = endCal.getTimeInMillis() - - calcTimeSeries = flowGroupCalc.calcTimeSeries(managerId, conduitGateFlowGroup, startTime, endTime, outputTimeSeriesList) - computationResult = calcTimeSeries.get(newFlowGroupTimeSeries) - #it could also be an error - computationData = computationResult - timeSeriesData = computationData.getTimeSeriesData() - timeSeriesData.tabulateValues() \ No newline at end of file +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_gate_flow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py index e5d6542..1eca4b1 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py @@ -1,25 +1,30 @@ -from java.util import Calendar -from java.util import TimeZone +from regi_python import regi_session, run_headless -names = registry.getNames(1.0) -print "names", names -gateCalc = registry.getCalculation(1.0, "Gate Flow") +def calculate_gate_flow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) + names = registry.getNames(1.0) + print("names", names) -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) + gate_calc = registry.getCalculation(1.0, "Gate Flow") -#gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTimeInMillis(), endCal.getTimeInMillis(), "Flow.LEWT2.ConduitGate_Total") + # Time zone must be set because the Solaris time zone is UTC + time_zone = TimeZone.getTimeZone("US/Central") + start_cal = Calendar.getInstance(time_zone) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2015) + start_cal.set(Calendar.MONTH, 4) -gateCalc.computeAll("SWF", "LEWT2", startCal.getTimeInMillis(), endCal.getTimeInMillis()) + end_cal = Calendar.getInstance(time_zone) + end_cal.clear() + end_cal.set(Calendar.YEAR, 2015) + end_cal.set(Calendar.MONTH, 6) + gate_calc.computeAll("SWF", "LEWT2", start_cal.getTimeInMillis(), end_cal.getTimeInMillis()) + +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_gate_flow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py index fd0512f..b1d4121 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py @@ -1,42 +1,46 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone +from regi_python import regi_session, run_headless -# this gets a scriptable Gate Settings object -gateSettings = registry.getCalculation(1.0, "Gate Settings") -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) +def calculate_gate_settings(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) + # this gets a scriptable Gate Settings object + gate_settings = registry.getCalculation(1.0, "Gate Settings") + # Time zone must be set because the Solaris time zone is UTC + time_zone = TimeZone.getTimeZone("US/Central") + # configure the start calendar + start_cal = Calendar.getInstance(time_zone) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2015) + start_cal.set(Calendar.MONTH, 4) -# gateSettings contains four callable methods -# void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; -# void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; -# void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; -# void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; + # configure the end calendar + end_cal = Calendar.getInstance(time_zone) + end_cal.clear() + end_cal.set(Calendar.YEAR, 2015) + end_cal.set(Calendar.MONTH, 6) -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the specified input time series. -gateSettings.createGateSettingsOutletFromTs("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "TG1", "WTYT2-TG1.Opening-Spillway_Gate.Const.0.0.MANUAL" ) + # gate_settings contains four callable methods + # void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; + # void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; + # void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; + # void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the regi association configured input time series. -gateSettings.createGateSettingsOutlet("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "TG1") + # This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the specified input time series. + gate_settings.createGateSettingsOutletFromTs("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime(), "TG1", "WTYT2-TG1.Opening-Spillway_Gate.Const.0.0.MANUAL") -# This is an example of a call that would create gate settings at all outlets at WTYT2 which are in the TainterGateWTY group from the association configured time series. -gateSettings.createGateSettingsGroup("SWF", "WTYT2", startCal.getTime(), endCal.getTime(), "WTYT2-TainterGateWTY" ) + # This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the regi association configured input time series. + gate_settings.createGateSettingsOutlet("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime(), "TG1") -# This is an example of a call that would create gate settings for every outlet in a rating group at WTYT2. -gateSettings.createGateSettings("SWF", "WTYT2", startCal.getTime(), endCal.getTime() ) + # This is an example of a call that would create gate settings at all outlets at WTYT2 which are in the TainterGateWTY group from the association configured time series. + gate_settings.createGateSettingsGroup("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime(), "WTYT2-TainterGateWTY") + # This is an example of a call that would create gate settings for every outlet in a rating group at WTYT2. + gate_settings.createGateSettings("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime()) +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_gate_settings) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py index 2f26e26..8e4df61 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py @@ -1,34 +1,40 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") +from regi_python import regi_session, run_headless -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) +def calculate_inflow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives + # this gets a scriptable Pool Percent object + inflow_calc = registry.getCalculation(1.0, "Inflow") -# Each method takes the followind arguments: -# officeId -# locationId -# startDate + # Time zone must be set because the Solaris time zone is UTC + time_zone = TimeZone.getTimeZone("US/Central") + # configure the start calendar + start_cal = Calendar.getInstance(time_zone) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2015) + start_cal.set(Calendar.MONTH, 4) -# autoAdjust also takes booleans: -# useLimits -# freezeRain + # inflow_calc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives -# This autoBalances ALAT2 -inflowCalc.autoAdjust("SWF", "ALAT2", startCal.getTime(), False, False) + # Each method takes the following arguments: + # officeId + # locationId + # startDate + # autoAdjust also takes booleans: + # useLimits + # freezeRain + # This autoBalances ALAT2 + inflow_calc.autoAdjust("SWF", "ALAT2", start_cal.getTime(), False, False) + + +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_inflow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py index c60eb8f..5825fa1 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py @@ -1,36 +1,38 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone +from regi_python import regi_session, run_headless -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") -# configure the start calendar +def calculate_inflow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + # this gets a ScriptableInflow instance. + inflow_calc = registry.getCalculation(1.0, "Inflow") + # configure the start calendar + start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2018) + start_cal.set(Calendar.MONTH, 6) -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 7) + # inflow_calc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives + # Each method takes the following arguments: + # officeId + # locationId + # startDate -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives + # autoAdjust also takes booleans: + # useLimits + # freezeRain -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.autoAdjust("SWF", "ALAT2", startCal.getTime(), False, False) + # This autoBalances ALAT2 + inflow_calc.autoAdjust("SWF", "ALAT2", start_cal.getTime(), False, False) +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_inflow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py index 88b6219..a9cb225 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py @@ -1,36 +1,38 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone +from regi_python import regi_session, run_headless -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") -# configure the start calendar +def calculate_inflow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + # this gets a ScriptableInflow instance. + inflow_calc = registry.getCalculation(1.0, "Inflow") + # configure the start calendar + start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2018) + start_cal.set(Calendar.MONTH, 7) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) + # inflow_calc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives + # Each method takes the following arguments: + # officeId + # locationId + # startDate -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives + # autoAdjust also takes booleans: + # useLimits + # freezeRain -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.balanceAll("SWF", "ALAT2", startCal.getTime()) + # This autoBalances ALAT2 + inflow_calc.balanceAll("SWF", "ALAT2", start_cal.getTime()) +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_inflow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py index 57609b7..d3590d5 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py @@ -1,36 +1,38 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone +from regi_python import regi_session, run_headless -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") -# configure the start calendar +def calculate_inflow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + # this gets a ScriptableInflow instance. + inflow_calc = registry.getCalculation(1.0, "Inflow") + # configure the start calendar + start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2018) + start_cal.set(Calendar.MONTH, 7) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) + # inflow_calc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives + # Each method takes the following arguments: + # officeId + # locationId + # startDate -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives + # autoAdjust also takes booleans: + # useLimits + # freezeRain -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.cloneInflows("SWF", "ALAT2", startCal.getTime()) + # This autoBalances ALAT2 + inflow_calc.cloneInflows("SWF", "ALAT2", start_cal.getTime()) +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_inflow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py index 3ab7b56..8f5bce3 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py @@ -1,23 +1,29 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone +from regi_python import regi_session, run_headless -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) +def calculate_inflow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone + # this gets a ScriptableInflow instance. + inflow_calc = registry.getCalculation(1.0, "Inflow") -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 4) + # configure the start calendar + start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2018) + start_cal.set(Calendar.MONTH, 4) -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -endCal.clear() -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 4) -endCal.set(Calendar.DAY_OF_MONTH, 4) + end_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + end_cal.clear() + end_cal.set(Calendar.YEAR, 2018) + end_cal.set(Calendar.MONTH, 4) + end_cal.set(Calendar.DAY_OF_MONTH, 4) -# This computes and saves evap as flow for EUFA in May 2018 -inflowCalc.computeEvapAsFlow("SWT", "EUFA", startCal.getTime(), endCal.getTime()) \ No newline at end of file + # This computes and saves evap as flow for EUFA in May 2018 + inflow_calc.computeEvapAsFlow("SWT", "EUFA", start_cal.getTime(), end_cal.getTime()) + + +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_inflow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py index 9def655..591325f 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py @@ -1,24 +1,29 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.calculator.inflow import InflowComputationStorageOption +from regi_python import regi_session, run_headless -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) +def calculate_inflow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone + # this gets a ScriptableInflow instance. + inflow_calc = registry.getCalculation(1.0, "Inflow") -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 4) + # configure the start calendar + start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2018) + start_cal.set(Calendar.MONTH, 4) -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -endCal.clear() -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 4) -endCal.set(Calendar.DAY_OF_MONTH, 4) + end_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + end_cal.clear() + end_cal.set(Calendar.YEAR, 2018) + end_cal.set(Calendar.MONTH, 4) + end_cal.set(Calendar.DAY_OF_MONTH, 4) -# This computes and saves inflow for EUFA in May 2018 given the computation options set above -inflowCalc.computeInflow("SWT", "EUFA", startCal.getTime(), endCal.getTime()) + # This computes and saves inflow for EUFA in May 2018 given the computation options set above + inflow_calc.computeInflow("SWT", "EUFA", start_cal.getTime(), end_cal.getTime()) + + +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_inflow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py index ca1e5a0..b0e85ad 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py @@ -1,36 +1,38 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone +from regi_python import regi_session, run_headless -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") -# configure the start calendar +def calculate_inflow(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar, TimeZone -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + # this gets a ScriptableInflow instance. + inflow_calc = registry.getCalculation(1.0, "Inflow") + # configure the start calendar + start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) + start_cal.clear() + start_cal.set(Calendar.YEAR, 2018) + start_cal.set(Calendar.MONTH, 7) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) + # inflow_calc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives + # Each method takes the following arguments: + # officeId + # locationId + # startDate -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives + # autoAdjust also takes booleans: + # useLimits + # freezeRain -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.zeroNegatives("SWF", "ALAT2", startCal.getTime()) + # This autoBalances ALAT2 + inflow_calc.zeroNegatives("SWF", "ALAT2", start_cal.getTime()) +if __name__ == "__main__": + with regi_session(): + run_headless(calculate_inflow) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py index 139adba..61835bf 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py @@ -30,4 +30,40 @@ # # By default, Metrics are disabled. -LoggingOptions.setMetricsEnabled(True) \ No newline at end of file +LoggingOptions.setMetricsEnabled(True) + +# Description of: LoggingOptions.enableAbridgedFlowGroupCompLogging() +# +# Enables the abridged flow group computation logging. This only applies to flow group computations, and will log +# information similar to a non-verbose REGI computation log. +# +# Example Output: +# Flow Group: Gated_Total 30Jun2018 2400 CDT 90.00 (cfs) +# Primary Time Series: SKIA.Flow-Controlled.Inst.1Hour.0.Rev-Regi-Flowgroup 90.00 (cfs) External Time Series: none Flow Group Computation: Total: 90.00 (cfs) +# +# By default flow group computation logging is disabled. + +LoggingOptions.enableAbridgedFlowGroupCompLogging() + +# Description of: LoggingOptions.enableAbridgedFlowGroupCompLogging() +# +# Enables the full flow group computation logging. This only applies to flow group computations, and will log +# information similar to a verbose REGI computation log. +# +# Example Output: +# Primary Time Series: +# TXKT2-Gated_Total.Flow-Out.Inst.1Hour.0.Rev-SWF-REGI 87.00 (cfs) * External Time Series: none Flow Group Computation: Total: 87.00 (cfs) | Merge Rule: Replace All Override Protection: false +# +# +# +# By default flow group computation logging is disabled. + +LoggingOptions.enableFullFlowGroupCompLogging() + +# Description of: LoggingOptions.disableFlowGroupCompLogging() +# +# Disables the logging of flow group computations. This is the default state of the LoggingOptions and does not need +# to be called unless LoggingOptions.enableAbridgedFlowGroupCompLogging() or LoggingOptions.enableFullFlowGroupCompLogging() +# have been called. + +LoggingOptions.disableFlowGroupCompLogging() \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlow.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlow.py deleted file mode 100644 index 32926c3..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlow.py +++ /dev/null @@ -1,187 +0,0 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(0) -LoggingOptions.enableAbridgedFlowGroupCompLogging() - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance(timeZone) -startCal.clear() -#startCal.add(Calendar.DAY_OF_MONTH, -6) -#startCal.set(Calendar.HOUR, 0) -#startCal.set(Calendar.MINUTE, 0) -#startCal.set(Calendar.MILLISECOND, 0) -#startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 5) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(timeZone) -endCal.clear() -#endCal.add(Calendar.DAY_OF_MONTH, 5) -#endCal.set(Calendar.HOUR, 0) -#endCal.set(Calendar.MINUTE, 0) -#endCal.set(Calendar.MILLISECOND, 0) -#endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 6) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = True -flowGroup = "Gated_Total" -locationList = ["SKIA", - "FGIB" -# "GGLT2", -# "GNGT2", -# "GPVT2", -# "HORT2", -# "JFNT2", -# "JPLT2", -# "JSPT2", -# "LEWT2", -# "LVNT2", -# "PCTT2", -# "RRLT2", -# "FRHT2", -# "SCLT2", -# "SMCT2", -# "SOMT2", -# "STIT2", -# "TXKT2", -# "WTYT2", -# "TRNT2", -# "FFLT2", -# "BPRT2", -# "EAMT2", -# "FLWT2", -# "LLST2", -# "GBYT2", -# "PSMT2", -# "TBLT2", -# "TBRT2", -# "GPET2", -# "BSLT2", -# "SAGT2", -# "MSDT2", - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = False -FlowGroupList = ["FGIB", - "SKIA", -# "GPVT2", -# "HORT2", -# "JPLT2", -# "LEWT2", -# "LVNT2", -# "PCTT2", -# "RRLT2", -# "FRHT2", -# "SCLT2", -# "SMCT2", -# "SOMT2", -# "STIT2", -# "TXKT2", -# "WTYT2", -# "TRNT2", -# "FFLT2", -# "EAMT2", -# "FLWT2", -# "LLST2", -# "GBYT2", -# "PSMT2", -# "SAGT2", - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) - -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - compute_All_Flowgroups(officeID, location, startCal, endCal) - - - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlowCalc.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlowCalc.py deleted file mode 100644 index c32a4d1..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateFlowCalc.py +++ /dev/null @@ -1,22 +0,0 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -names = registry.getNames(1.0) -print "names", names - -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - -endCal = Calendar.getInstance(timeZone) -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) - -gateCalc.computeAll(TestVariables.OFFICE_ID, TestVariables.GATE_LOCATION, startCal.getTimeInMillis(), endCal.getTimeInMillis()) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateSettings.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateSettings.py deleted file mode 100644 index c3594dd..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/GateSettings.py +++ /dev/null @@ -1,45 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone - -# this gets a scriptable Gate Settings object -gateSettings = registry.getCalculation(1.0, "Gate Settings") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.clear() -startCal.set(Calendar.YEAR, 2015) -startCal.set(Calendar.MONTH, 4) - -# configure the end calendar -endCal = Calendar.getInstance() -endCal.clear() -endCal.set(Calendar.YEAR, 2015) -endCal.set(Calendar.MONTH, 6) - - -# gateSettings contains four callable methods -# void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; -# void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; -# void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; -# void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; - -office = TestVariables.OFFICE_ID -loc = TestVariables.GATE_LOCATION - -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the specified input time series. -gateSettings.createGateSettingsOutletFromTs(office, loc, startCal.getTime(), endCal.getTime(), "TG1", loc + "-TG1.Opening-Spillway_Gate.Const.0.0.MANUAL" ) - -# This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the regi association configured input time series. -gateSettings.createGateSettingsOutlet(office, loc, startCal.getTime(), endCal.getTime(), "TG1") - -# This is an example of a call that would create gate settings at all outlets at WTYT2 which are in the TainterGateWTY group from the association configured time series. -gateSettings.createGateSettingsGroup(office, loc, startCal.getTime(), endCal.getTime(), loc + "-TainterGate" ) - -# This is an example of a call that would create gate settings for every outlet in a rating group at WTYT2. -gateSettings.createGateSettings(office, loc, startCal.getTime(), endCal.getTime() ) - - - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcAutoAdjust.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcAutoAdjust.py deleted file mode 100644 index b505c9b..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcAutoAdjust.py +++ /dev/null @@ -1,36 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 6) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.autoAdjust(TestVariables.OFFICE_ID, TestVariables.INFLOW_LOCATION, startCal.getTime(), False, False) - - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcBalanceAll.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcBalanceAll.py deleted file mode 100644 index 8d91e5f..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcBalanceAll.py +++ /dev/null @@ -1,36 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 7) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.balanceAll(TestVariables.OFFICE_ID, TestVariables.INFLOW_LOCATION, startCal.getTime()) - - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcClone.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcClone.py deleted file mode 100644 index f45eee8..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcClone.py +++ /dev/null @@ -1,34 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 7) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the followind arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.cloneInflows(TestVariables.OFFICE_ID, TestVariables.INFLOW_LOCATION, startCal.getTime()) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputeEvapAsFlow.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputeEvapAsFlow.py deleted file mode 100644 index 3a79f06..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputeEvapAsFlow.py +++ /dev/null @@ -1,23 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 4) - -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -endCal.clear() -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 4) -endCal.set(Calendar.DAY_OF_MONTH, 4) - -# This computes and saves evap as flow for EUFA in May 2018 -inflowCalc.computeEvapAsFlow(TestVariables.OFFICE_ID, TestVariables.INFLOW_LOCATION, startCal.getTime(), endCal.getTime()) \ No newline at end of file diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputedInflow.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputedInflow.py deleted file mode 100644 index 4cd6e5a..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcComputedInflow.py +++ /dev/null @@ -1,37 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.calculator.inflow import InflowComputationStorageOption -from usace.rowcps.headless.tests import TestVariables - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 4) - -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -endCal.clear() -endCal.set(Calendar.YEAR, 2018) -endCal.set(Calendar.MONTH, 4) -endCal.set(Calendar.DAY_OF_MONTH, 4) - - -# This code has been deprecated, but the API must exist. -storageOptionsSet = False -try: - inflowCalc.setComputationStorageOptions(InflowComputationStorageOption.EVAP_AS_FLOW, InflowComputationStorageOption.PROJECT_RELEASES) - storageOptionsSet = True -except: - print "Exception occurred during setComputationStorageOptions, this is expected" - -if storageOptionsSet: - throw Exception("ScriptableInflow::setComputationStorageOptions should not be working") - -# This computes and saves inflow for EUFA in May 2018 given the computation options set above -inflowCalc.computeInflow(TestVariables.OFFICE_ID, TestVariables.INFLOW_LOCATION, startCal.getTime(), endCal.getTime()) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcZeroNegative.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcZeroNegative.py deleted file mode 100644 index 5e33586..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/InflowCalcZeroNegative.py +++ /dev/null @@ -1,34 +0,0 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.tests import TestVariables - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - -startCal.clear() -startCal.set(Calendar.YEAR, 2018) -startCal.set(Calendar.MONTH, 7) - - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# This autoBalances ALAT2 -inflowCalc.zeroNegatives(TestVariables.OFFICE_ID, TestVariables.INFLOW_LOCATION, startCal.getTime()) - diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/tests/LoggingOptionsExamples.py b/regi-headless/src/test/resources/usace/rowcps/headless/tests/LoggingOptionsExamples.py deleted file mode 100644 index 61835bf..0000000 --- a/regi-headless/src/test/resources/usace/rowcps/headless/tests/LoggingOptionsExamples.py +++ /dev/null @@ -1,69 +0,0 @@ -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -LoggingOptions.setMetricsEnabled(True) - -# Description of: LoggingOptions.enableAbridgedFlowGroupCompLogging() -# -# Enables the abridged flow group computation logging. This only applies to flow group computations, and will log -# information similar to a non-verbose REGI computation log. -# -# Example Output: -# Flow Group: Gated_Total 30Jun2018 2400 CDT 90.00 (cfs) -# Primary Time Series: SKIA.Flow-Controlled.Inst.1Hour.0.Rev-Regi-Flowgroup 90.00 (cfs) External Time Series: none Flow Group Computation: Total: 90.00 (cfs) -# -# By default flow group computation logging is disabled. - -LoggingOptions.enableAbridgedFlowGroupCompLogging() - -# Description of: LoggingOptions.enableAbridgedFlowGroupCompLogging() -# -# Enables the full flow group computation logging. This only applies to flow group computations, and will log -# information similar to a verbose REGI computation log. -# -# Example Output: -# Primary Time Series: -# TXKT2-Gated_Total.Flow-Out.Inst.1Hour.0.Rev-SWF-REGI 87.00 (cfs) * External Time Series: none Flow Group Computation: Total: 87.00 (cfs) | Merge Rule: Replace All Override Protection: false -# -# -# -# By default flow group computation logging is disabled. - -LoggingOptions.enableFullFlowGroupCompLogging() - -# Description of: LoggingOptions.disableFlowGroupCompLogging() -# -# Disables the logging of flow group computations. This is the default state of the LoggingOptions and does not need -# to be called unless LoggingOptions.enableAbridgedFlowGroupCompLogging() or LoggingOptions.enableFullFlowGroupCompLogging() -# have been called. - -LoggingOptions.disableFlowGroupCompLogging() \ No newline at end of file From 34fb807be394520f4f48b2d639c8a78e6f08ca56 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 09:02:12 -0700 Subject: [PATCH 16/26] migrate district scripts to new python library calls --- district-scripts/SWF/GateFlow5.py | 402 ++++++++--------- .../SWF/GateFlow_MonthlyPumpBackFill.py | 414 +++++++++--------- district-scripts/SWF/GateFlow_PumpBackFill.py | 382 ++++++++-------- district-scripts/SWF/GateSettings.py | 160 +++---- .../SWF/InflowCalcComputeEvapAsFlow.py | 108 ++--- .../SWF/InflowCalcComputedInflow.py | 124 +++--- district-scripts/SWL/Big3-GateFlow.py | 278 ++++++------ .../SWL/Big3-InflowCalcMultipleActions.py | 260 +++++------ .../SWL/Millwd-Tri-Lks-GateFlow.py | 280 ++++++------ ...illwd-Tri-Lks-InflowCalcMultipleActions.py | 268 ++++++------ district-scripts/SWL/WhiteR-GateFlow.py | 284 ++++++------ .../SWL/WhiteR-InflowCalcMultipleActions.py | 272 ++++++------ district-scripts/SWT/GateFlowGroup1.py | 290 ++++++------ district-scripts/SWT/GateFlowGroup2.py | 256 +++++------ district-scripts/SWT/GateFlowGroup3.py | 270 ++++++------ district-scripts/SWT/GateFlowGroup4.py | 266 +++++------ district-scripts/SWT/GateFlowGroup5.py | 236 +++++----- district-scripts/SWT/GateFlowGroup6.py | 292 ++++++------ district-scripts/SWT/GateFlowGroup7.py | 278 ++++++------ district-scripts/SWT/GateFlowGroup8.py | 224 +++++----- district-scripts/SWT/GateFlowGroup9.py | 226 +++++----- district-scripts/SWT/GateFlowHUDS-WS.py | 220 +++++----- district-scripts/SWT/WaterSupplyFlowGroup.py | 264 +++++------ 23 files changed, 3142 insertions(+), 2912 deletions(-) diff --git a/district-scripts/SWF/GateFlow5.py b/district-scripts/SWF/GateFlow5.py index f64000c..d0d4e3f 100644 --- a/district-scripts/SWF/GateFlow5.py +++ b/district-scripts/SWF/GateFlow5.py @@ -1,196 +1,206 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance(timeZone) -# startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -8) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -# startCal.set(Calendar.YEAR, 2015) -# startCal.set(Calendar.MONTH, 9) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(timeZone) -# endCal.clear() -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -# endCal.set(Calendar.YEAR, 2015) -# endCal.set(Calendar.MONTH, 11) - -officeID = "SWF" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate - - -calculateSingleFlowGroups = False -flowGroupGate = "Gated_Total" -flowGroupTotal = "Project_Total" -flowGroupTurbine = "Turbine_Total" -flowGroupPumpOutBelow = "Pump_Out_Below_Total" -flowGroupUncontrol = "Uncontrolled_Total" -flowGroupJSPturbine1 = "Turbine1" -flowGroupJSPturbine2 = "Turbine2" - - -locationList = ["BNBT2", - "GGLT2", - "LEWT2", - "LVNT2", - "SCLT2" - ] -ohit2Group = ["OHIT2"] -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = True - -FlowGroupList = [ "ACTT2", - "ALAT2", - "BDWT2", - "BLNT2", - "BSLT2", - "CLDL1", - "DAWT2", - "GPET2", - "GNGT2", - "GPVT2", - "HORT2", - "JPLT2", - "JFNT2", - "JSPT2", - "TBLT2", - "PCTT2", - "RRLT2", - "FRHT2", - "SAGT2", - "SMCT2", - "SOMT2", - "STIT2", - "TXKT2", - "WTYT2", - "TRNT2", - "FFLT2", - "EAMT2", - "FLWT2", - "LLST2", - "GBYT2", - "PSMT2", - "SAGT2", - "BPRT2", - "TBRT2", - "MSDT2", - "BNBT2", - "GGLT2", - "LEWT2", - "LVNT2", - "SCLT2", - "OHIT2" - ] - -tempList = ["JFNT2"] - -#if calculateSingleFlowGroups: -# for location in locationList: -# print "Now Running", location, "SINGLE" -# compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) -# compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) -# compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) -# compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) -# compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) -#compute_Single_Flowgroup(officeID, "GGLT2", startCal, endCal, "Spillway GGL_Total") - -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - compute_All_Flowgroups(officeID, location, startCal, endCal) - -compute_Single_Flowgroup(officeID, "JSPT2", startCal, endCal, "Turbine1") -compute_Single_Flowgroup(officeID, "JSPT2", startCal, endCal, "Turbine2") - - -#if calculateSingleFlowGroups: -# for location in ohit2Group: -# print "Now Running", location, "SINGLE" -# compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + # the gate flow calculations requires a start and end time. + # here we create a java Calendar object that will be used to create the start Date + startCal = Calendar.getInstance(timeZone) + # startCal.clear() + startCal.add(Calendar.DAY_OF_MONTH, -8) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + # startCal.set(Calendar.YEAR, 2015) + # startCal.set(Calendar.MONTH, 9) + + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance(timeZone) + # endCal.clear() + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + # endCal.set(Calendar.YEAR, 2015) + # endCal.set(Calendar.MONTH, 11) + + officeID = "SWF" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out + # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate + + + calculateSingleFlowGroups = False + flowGroupGate = "Gated_Total" + flowGroupTotal = "Project_Total" + flowGroupTurbine = "Turbine_Total" + flowGroupPumpOutBelow = "Pump_Out_Below_Total" + flowGroupUncontrol = "Uncontrolled_Total" + flowGroupJSPturbine1 = "Turbine1" + flowGroupJSPturbine2 = "Turbine2" + + + locationList = ["BNBT2", + "GGLT2", + "LEWT2", + "LVNT2", + "SCLT2" + ] + ohit2Group = ["OHIT2"] + # the calculation can also be performed for all the associated groups + # the computeAll method takes: + # officeId + # projectId + # startDate + # endDate + # By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. + # Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. + + calculateAllFlowGroups = True + + FlowGroupList = [ "ACTT2", + "ALAT2", + "BDWT2", + "BLNT2", + "BSLT2", + "CLDL1", + "DAWT2", + "GPET2", + "GNGT2", + "GPVT2", + "HORT2", + "JPLT2", + "JFNT2", + "JSPT2", + "TBLT2", + "PCTT2", + "RRLT2", + "FRHT2", + "SAGT2", + "SMCT2", + "SOMT2", + "STIT2", + "TXKT2", + "WTYT2", + "TRNT2", + "FFLT2", + "EAMT2", + "FLWT2", + "LLST2", + "GBYT2", + "PSMT2", + "SAGT2", + "BPRT2", + "TBRT2", + "MSDT2", + "BNBT2", + "GGLT2", + "LEWT2", + "LVNT2", + "SCLT2", + "OHIT2" + ] + + tempList = ["JFNT2"] + + #if calculateSingleFlowGroups: + # for location in locationList: + # print "Now Running", location, "SINGLE" + # compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) + # compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) + # compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) + # compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) + # compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) + #compute_Single_Flowgroup(officeID, "GGLT2", startCal, endCal, "Spillway GGL_Total") + + if calculateAllFlowGroups: + for location in FlowGroupList: + print("Now Running", location, "GROUP") + compute_All_Flowgroups(officeID, location, startCal, endCal) + + compute_Single_Flowgroup(officeID, "JSPT2", startCal, endCal, "Turbine1") + compute_Single_Flowgroup(officeID, "JSPT2", startCal, endCal, "Turbine2") + + + #if calculateSingleFlowGroups: + # for location in ohit2Group: + # print "Now Running", location, "SINGLE" + # compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py b/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py index 704ef93..7bb1ae5 100644 --- a/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py +++ b/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py @@ -1,202 +1,212 @@ -from java.util import Calendar -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance() -# startCal.clear() -startCal.set(Calendar.HOUR, 0) ### set startCal hour/minute/second/millisecond to 0 for midnight -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -startCal.add(Calendar.YEAR, -1) ### go back one year to today -startCal.set(Calendar.MONTH, 9) ### change month to month 9 (october) -startCal.set(Calendar.DAY_OF_MONTH, 1) ### change start date to start of the month day 1 - -getYear = startCal.get(Calendar.YEAR) ### get value of startCal year/month/day to print and to initilize endCal -getMonth = startCal.get(Calendar.MONTH) -getDayofMonth = startCal.get(Calendar.DAY_OF_MONTH) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance() -# endCal.clear() -endCal.set(Calendar.HOUR, 0) ### set endCal hour/minute/second/millisecond to 0 for midnight -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -###endCal will be set to current date unless reset with the following 4 lines -#endCal.set(Calendar.YEAR, getYear) ### set endCal year same as startCal -#endCal.set(Calendar.MONTH, getMonth) ### set endCal month same as startCal -#endCal.add(Calendar.MONTH, 12) ##add 1 month to startcal month -#endCal.set(Calendar.DAY_OF_MONTH, 1) ### set to day one - -### time window starts 01Feb2019(one year ago) and ends 01Mar2019 (one year ago plus one month) - -getEndDay = endCal.get(Calendar.DAY_OF_MONTH) -getEndYear = endCal.get(Calendar.YEAR) -getEndMonth = endCal.get(Calendar.MONTH) - - -officeID = "SWF" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = True -flowGroupGate = "ConduitGate_Total" -flowGroupTotal = "Project_Total" -flowGroupTurbine = "Turbine_Total" -flowGroupPumpOutBelow = "Pump_Out_Below_Total" -flowGroupPumpOut = "Pump_Out_Total" -flowGroupPumpIn = "Pump_In_Total" -flowGroupUncontrol = "Uncontrolled_Total" - -locationList = [ - "ACTT2", - "ALAT2", - "BDWT2", - "BLNT2", - "BNBT2", - "DAWT2", - "GGLT2", - "GNGT2", - "GPVT2", - "HORT2", - "JFNT2", - "HORT2", - "JPLT2", - "LEWT2", - "LVNT2", - "PCTT2", - "RRLT2", - "SCLT2", - "SMCT2", - "SOMT2", - "STIT2", - "TXKT2", - "SAGT2", - "BCAT2", - "WTYT2" - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = False -FlowGroupList = [ - "ACTT2", - "ALAT2", - "BDWT2", - "BLNT2", - "BNBT2", - "DAWT2", - "GGLT2", - "GNGT2", - "GPVT2", - "HORT2", - "JFNT2", - "HORT2", - "JPLT2", - "LEWT2", - "LVNT2", - "PCTT2", - "RRLT2", - "SCLT2", - "SMCT2", - "SOMT2", - "STIT2", - "TXKT2", - "BCAT2", - "SAGT2", - "WTYT2" - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOut) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpIn) -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - #compute_All_Flowgroups(officeID, location, startCal, endCal) - - - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # the gate flow calculations requires a start and end time. + # here we create a java Calendar object that will be used to create the start Date + startCal = Calendar.getInstance() + # startCal.clear() + startCal.set(Calendar.HOUR, 0) ### set startCal hour/minute/second/millisecond to 0 for midnight + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + startCal.add(Calendar.YEAR, -1) ### go back one year to today + startCal.set(Calendar.MONTH, 9) ### change month to month 9 (october) + startCal.set(Calendar.DAY_OF_MONTH, 1) ### change start date to start of the month day 1 + + getYear = startCal.get(Calendar.YEAR) ### get value of startCal year/month/day to print and to initilize endCal + getMonth = startCal.get(Calendar.MONTH) + getDayofMonth = startCal.get(Calendar.DAY_OF_MONTH) + + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance() + # endCal.clear() + endCal.set(Calendar.HOUR, 0) ### set endCal hour/minute/second/millisecond to 0 for midnight + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + ###endCal will be set to current date unless reset with the following 4 lines + #endCal.set(Calendar.YEAR, getYear) ### set endCal year same as startCal + #endCal.set(Calendar.MONTH, getMonth) ### set endCal month same as startCal + #endCal.add(Calendar.MONTH, 12) ##add 1 month to startcal month + #endCal.set(Calendar.DAY_OF_MONTH, 1) ### set to day one + + ### time window starts 01Feb2019(one year ago) and ends 01Mar2019 (one year ago plus one month) + + getEndDay = endCal.get(Calendar.DAY_OF_MONTH) + getEndYear = endCal.get(Calendar.YEAR) + getEndMonth = endCal.get(Calendar.MONTH) + + + officeID = "SWF" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out + # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate + # by changing the "flowGroup" variable. + calculateSingleFlowGroups = True + flowGroupGate = "ConduitGate_Total" + flowGroupTotal = "Project_Total" + flowGroupTurbine = "Turbine_Total" + flowGroupPumpOutBelow = "Pump_Out_Below_Total" + flowGroupPumpOut = "Pump_Out_Total" + flowGroupPumpIn = "Pump_In_Total" + flowGroupUncontrol = "Uncontrolled_Total" + + locationList = [ + "ACTT2", + "ALAT2", + "BDWT2", + "BLNT2", + "BNBT2", + "DAWT2", + "GGLT2", + "GNGT2", + "GPVT2", + "HORT2", + "JFNT2", + "HORT2", + "JPLT2", + "LEWT2", + "LVNT2", + "PCTT2", + "RRLT2", + "SCLT2", + "SMCT2", + "SOMT2", + "STIT2", + "TXKT2", + "SAGT2", + "BCAT2", + "WTYT2" + ] + + # the calculation can also be performed for all the associated groups + # the computeAll method takes: + # officeId + # projectId + # startDate + # endDate + # By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. + # Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. + + calculateAllFlowGroups = False + FlowGroupList = [ + "ACTT2", + "ALAT2", + "BDWT2", + "BLNT2", + "BNBT2", + "DAWT2", + "GGLT2", + "GNGT2", + "GPVT2", + "HORT2", + "JFNT2", + "HORT2", + "JPLT2", + "LEWT2", + "LVNT2", + "PCTT2", + "RRLT2", + "SCLT2", + "SMCT2", + "SOMT2", + "STIT2", + "TXKT2", + "BCAT2", + "SAGT2", + "WTYT2" + ] + + + if calculateSingleFlowGroups: + for location in locationList: + print("Now Running", location, "SINGLE") + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOut) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpIn) + if calculateAllFlowGroups: + for location in FlowGroupList: + print("Now Running", location, "GROUP") + #compute_All_Flowgroups(officeID, location, startCal, endCal) + + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWF/GateFlow_PumpBackFill.py b/district-scripts/SWF/GateFlow_PumpBackFill.py index cb5b818..bc58977 100644 --- a/district-scripts/SWF/GateFlow_PumpBackFill.py +++ b/district-scripts/SWF/GateFlow_PumpBackFill.py @@ -1,186 +1,196 @@ -from java.util import Calendar -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance() -# startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -1) -startCal.set(Calendar.HOUR, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -# startCal.set(Calendar.YEAR, 2015) -# startCal.set(Calendar.MONTH, 9) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance() -# endCal.clear() -endCal.add(Calendar.DAY_OF_MONTH, 0) -endCal.set(Calendar.HOUR, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -# endCal.set(Calendar.YEAR, 2015) -# endCal.set(Calendar.MONTH, 11) - -officeID = "SWF" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = True -flowGroupGate = "ConduitGate_Total" -flowGroupTotal = "Project_Total" -flowGroupTurbine = "Turbine_Total" -flowGroupPumpOutBelow = "Pump_Out_Below_Total" -flowGroupPumpOut = "Pump_Out_Total" -flowGroupPumpIn = "Pump_In_Total" -flowGroupUncontrol = "Uncontrolled_Total" -flowGroupNTMWD = "Pump_NTMWD" -flowGroupUTRWD = "Pump_UTRWD" -flowGroupSS= "Pump_Sulphur_Springs" -flowGroupIrving = "Pump_Irving" -flowGroupLewisville = "Lewisville" -flowGroupUTRWD_Out = "UTRWD_Out" -flowGroupUTRWD_In = "UTRWD_In" -flowGroupIrv = "Irving" -flowGroupDenton = "Denton" -flowGroupBenbrook = "Benbrook" -flowGroupTRWD = "TRWD" -flowGroupWeatherford = "Weatherford" -flowGroupGeorgetown = "Georgetown" -flowGroupRound_Rock = "Round_Rock" -flowGroupBrushy_Ck = "Brushy_Ck" -flowGroupNTMWD_LVN = "NTMWD" -flowGroupCooper = "Cooper" -flowGroupEast_Fork = "East_Fork" -flowGroupTawakoni = "Tawakoni" - - -locationList = ["BNBT2", - "GGLT2", - "LEWT2", - "LVNT2", - "SCLT2" - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = False -FlowGroupList = ["BNBT2", - "GGLT2", - "LEWT2", - "LVNT2", - "SCLT2" - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOut) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpIn) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupNTMWD) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupSS) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupIrving) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupLewisville) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD_Out) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD_In) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupIrv) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupDenton) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupBenbrook) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTRWD) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupWeatherford) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGeorgetown) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupRound_Rock) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupBrushy_Ck) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupNTMWD_LVN) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupCooper) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupEast_Fork) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTawakoni) -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - #compute_All_Flowgroups(officeID, location, startCal, endCal) - - - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # the gate flow calculations requires a start and end time. + # here we create a java Calendar object that will be used to create the start Date + startCal = Calendar.getInstance() + # startCal.clear() + startCal.add(Calendar.DAY_OF_MONTH, -1) + startCal.set(Calendar.HOUR, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + # startCal.set(Calendar.YEAR, 2015) + # startCal.set(Calendar.MONTH, 9) + + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance() + # endCal.clear() + endCal.add(Calendar.DAY_OF_MONTH, 0) + endCal.set(Calendar.HOUR, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + # endCal.set(Calendar.YEAR, 2015) + # endCal.set(Calendar.MONTH, 11) + + officeID = "SWF" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out + # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate + # by changing the "flowGroup" variable. + calculateSingleFlowGroups = True + flowGroupGate = "ConduitGate_Total" + flowGroupTotal = "Project_Total" + flowGroupTurbine = "Turbine_Total" + flowGroupPumpOutBelow = "Pump_Out_Below_Total" + flowGroupPumpOut = "Pump_Out_Total" + flowGroupPumpIn = "Pump_In_Total" + flowGroupUncontrol = "Uncontrolled_Total" + flowGroupNTMWD = "Pump_NTMWD" + flowGroupUTRWD = "Pump_UTRWD" + flowGroupSS= "Pump_Sulphur_Springs" + flowGroupIrving = "Pump_Irving" + flowGroupLewisville = "Lewisville" + flowGroupUTRWD_Out = "UTRWD_Out" + flowGroupUTRWD_In = "UTRWD_In" + flowGroupIrv = "Irving" + flowGroupDenton = "Denton" + flowGroupBenbrook = "Benbrook" + flowGroupTRWD = "TRWD" + flowGroupWeatherford = "Weatherford" + flowGroupGeorgetown = "Georgetown" + flowGroupRound_Rock = "Round_Rock" + flowGroupBrushy_Ck = "Brushy_Ck" + flowGroupNTMWD_LVN = "NTMWD" + flowGroupCooper = "Cooper" + flowGroupEast_Fork = "East_Fork" + flowGroupTawakoni = "Tawakoni" + + + locationList = ["BNBT2", + "GGLT2", + "LEWT2", + "LVNT2", + "SCLT2" + ] + + # the calculation can also be performed for all the associated groups + # the computeAll method takes: + # officeId + # projectId + # startDate + # endDate + # By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. + # Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. + + calculateAllFlowGroups = False + FlowGroupList = ["BNBT2", + "GGLT2", + "LEWT2", + "LVNT2", + "SCLT2" + ] + + + if calculateSingleFlowGroups: + for location in locationList: + print("Now Running", location, "SINGLE") + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) + #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOut) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpIn) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupNTMWD) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupSS) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupIrving) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupLewisville) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD_Out) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD_In) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupIrv) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupDenton) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupBenbrook) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTRWD) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupWeatherford) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGeorgetown) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupRound_Rock) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupBrushy_Ck) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupNTMWD_LVN) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupCooper) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupEast_Fork) + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTawakoni) + if calculateAllFlowGroups: + for location in FlowGroupList: + print("Now Running", location, "GROUP") + #compute_All_Flowgroups(officeID, location, startCal, endCal) + + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWF/GateSettings.py b/district-scripts/SWF/GateSettings.py index 1a0a938..b94e476 100644 --- a/district-scripts/SWF/GateSettings.py +++ b/district-scripts/SWF/GateSettings.py @@ -1,79 +1,89 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Gate Settings object -gateSettings = registry.getCalculation(1.0, "Gate Settings") - -# configure the start calendar -startCal = Calendar.getInstance() -#startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -5) -startCal.set(Calendar.HOUR, 0) ######use Calendar.HOUR_OF_DAY -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance() -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.clear() -#endCal.set(Calendar.YEAR, 2016) -#endCal.set(Calendar.MONTH, 4) - - -# gateSettings contains four callable methods -# void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; -# void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; -# void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; -# void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; - -gateSettings.createGateSettingsOutletFromTs("SWF", "FFLT2", startCal.getTime(), endCal.getTime(), "Release", "FFLT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "EAMT2", startCal.getTime(), endCal.getTime(), "Release", "EAMT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "TRNT2", startCal.getTime(), endCal.getTime(), "Release", "TRNT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "BPRT2", startCal.getTime(), endCal.getTime(), "Release", "BPRT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "LLST2", startCal.getTime(), endCal.getTime(), "Release", "LLST2.Opening.Const.0.0.Rev-BRA-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "GBYT2", startCal.getTime(), endCal.getTime(), "Release", "GBYT2.Opening.Const.0.0.Rev-BRA-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "PSMT2", startCal.getTime(), endCal.getTime(), "Release", "PSMT2.Opening.Const.0.0.Rev-BRA-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "MSDT2", startCal.getTime(), endCal.getTime(), "Release", "MSDT2.Opening.Const.0.0.Rev-LCRA-Decodes" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "FRHT2", startCal.getTime(), endCal.getTime(), "Release", "FRHT2.Opening.Const.0.0.Raw-Observer" ) -gateSettings.createGateSettingsOutletFromTs("SWF", "GPET2", startCal.getTime(), endCal.getTime(), "Release", "GPET2.Opening.Const.0.0.Raw-Observer" ) +from regi_python import regi_session, run_headless +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + # the java Calendar class is used to create java Date objects + from java.util import Calendar + from usace.rowcps.headless import LoggingOptions + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # this gets a scriptable Gate Settings object + gateSettings = registry.getCalculation(1.0, "Gate Settings") + + # configure the start calendar + startCal = Calendar.getInstance() + #startCal.clear() + startCal.add(Calendar.DAY_OF_MONTH, -5) + startCal.set(Calendar.HOUR, 0) ######use Calendar.HOUR_OF_DAY + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance() + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.clear() + #endCal.set(Calendar.YEAR, 2016) + #endCal.set(Calendar.MONTH, 4) + + + # gateSettings contains four callable methods + # void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; + # void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; + # void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; + # void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; + + gateSettings.createGateSettingsOutletFromTs("SWF", "FFLT2", startCal.getTime(), endCal.getTime(), "Release", "FFLT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "EAMT2", startCal.getTime(), endCal.getTime(), "Release", "EAMT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "TRNT2", startCal.getTime(), endCal.getTime(), "Release", "TRNT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "BPRT2", startCal.getTime(), endCal.getTime(), "Release", "BPRT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "LLST2", startCal.getTime(), endCal.getTime(), "Release", "LLST2.Opening.Const.0.0.Rev-BRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "GBYT2", startCal.getTime(), endCal.getTime(), "Release", "GBYT2.Opening.Const.0.0.Rev-BRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "PSMT2", startCal.getTime(), endCal.getTime(), "Release", "PSMT2.Opening.Const.0.0.Rev-BRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "MSDT2", startCal.getTime(), endCal.getTime(), "Release", "MSDT2.Opening.Const.0.0.Rev-LCRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "FRHT2", startCal.getTime(), endCal.getTime(), "Release", "FRHT2.Opening.Const.0.0.Raw-Observer" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "GPET2", startCal.getTime(), endCal.getTime(), "Release", "GPET2.Opening.Const.0.0.Raw-Observer" ) + + + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py b/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py index 589a7f6..fd6f4e3 100644 --- a/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py +++ b/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py @@ -1,49 +1,59 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone - - -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar -##startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -## -## -##startCal.clear() -##startCal.set(Calendar.YEAR, 2018) -##startCal.set(Calendar.MONTH, 11) -## -##endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -##endCal.clear() -##endCal.set(Calendar.YEAR, 2019) -##endCal.set(Calendar.MONTH, 0) -##endCal.set(Calendar.DAY_OF_MONTH, 7) - -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -# startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -5) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -# startCal.set(Calendar.YEAR, 2015) -# startCal.set(Calendar.MONTH, 9) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -# endCal.clear() -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -locationList = ["WTYT2","JSPT2","TBLT2","SCLT2","TXKT2","BSLT2","JFNT2","CLDL1", - "BPRT2","EAMT2","FLWT2","BNBT2","JPLT2","GPET2","RRLT2","LEWT2", - "GPVT2","LVNT2","FRHT2","TRNT2","DAWT2","BDWT2","FFLT2","PSMT2", - "GBYT2","ALAT2","ACTT2","PCTT2","BLNT2","STIT2","GGLT2","GNGT2", - "SOMT2","LLST2","TBRT2","SAGT2","HORT2","MSDT2","SMCT2"] - -for loc in locationList: - inflowCalc.computeEvapAsFlow("SWF", loc, startCal.getTime(), endCal.getTime()) +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + # the java Calendar class is used to create java Date objects + from java.util import Calendar + from java.util import TimeZone + + + # this gets a ScriptableInflow instance. + inflowCalc = registry.getCalculation(1.0, "Inflow") + + # configure the start calendar + ##startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + ## + ## + ##startCal.clear() + ##startCal.set(Calendar.YEAR, 2018) + ##startCal.set(Calendar.MONTH, 11) + ## + ##endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + ##endCal.clear() + ##endCal.set(Calendar.YEAR, 2019) + ##endCal.set(Calendar.MONTH, 0) + ##endCal.set(Calendar.DAY_OF_MONTH, 7) + + startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + # startCal.clear() + startCal.add(Calendar.DAY_OF_MONTH, -5) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + # startCal.set(Calendar.YEAR, 2015) + # startCal.set(Calendar.MONTH, 9) + + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + # endCal.clear() + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + + locationList = ["WTYT2","JSPT2","TBLT2","SCLT2","TXKT2","BSLT2","JFNT2","CLDL1", + "BPRT2","EAMT2","FLWT2","BNBT2","JPLT2","GPET2","RRLT2","LEWT2", + "GPVT2","LVNT2","FRHT2","TRNT2","DAWT2","BDWT2","FFLT2","PSMT2", + "GBYT2","ALAT2","ACTT2","PCTT2","BLNT2","STIT2","GGLT2","GNGT2", + "SOMT2","LLST2","TBRT2","SAGT2","HORT2","MSDT2","SMCT2"] + + for loc in locationList: + inflowCalc.computeEvapAsFlow("SWF", loc, startCal.getTime(), endCal.getTime()) + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWF/InflowCalcComputedInflow.py b/district-scripts/SWF/InflowCalcComputedInflow.py index ff2e4d9..99d5331 100644 --- a/district-scripts/SWF/InflowCalcComputedInflow.py +++ b/district-scripts/SWF/InflowCalcComputedInflow.py @@ -1,64 +1,74 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless.calculator.inflow import InflowComputationStorageOption +from regi_python import regi_session, run_headless -# this gets a ScriptableInflow instance. -inflowCalc = registry.getCalculation(1.0, "Inflow") -# configure the start calendar -##startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -## -## -##startCal.clear() -##startCal.set(Calendar.YEAR, 2019) -##startCal.set(Calendar.MONTH, 1) -## -##endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -##endCal.clear() -##endCal.set(Calendar.YEAR, 2019) -##endCal.set(Calendar.MONTH, 1) -##endCal.set(Calendar.DAY_OF_MONTH, 4) +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + # the java Calendar class is used to create java Date objects + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless.calculator.inflow import InflowComputationStorageOption -startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -startCal.add(Calendar.DAY_OF_MONTH, -4) -startCal.set(Calendar.HOUR, 0) ######use Calendar.HOUR_OF_DAY -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) + # this gets a ScriptableInflow instance. + inflowCalc = registry.getCalculation(1.0, "Inflow") -# inflowCalc includes a setComputationStorageOptions function, which takes in either one or many -# InflowComputationStorageOption values. This is used by computeInflow to determine if it should save additional -# computed values like evaporation as flow and project releases. -# -# The InflowComputationStorageOption enum contains two values: -# EVAP_AS_FLOW -# PROJECT_RELEASES -# -# None is supported by setComputationStorageOptions as well, and clears out all storage options. -# -# inflowCalc.setComputationStorageOptions is entirely optional, and if it's not used no additional computed values will -# be stored with the computed inflow -# -# Example uses: -#inflowCalc.setComputationStorageOptions(None) -#inflowCalc.setComputationStorageOptions(InflowComputationStorageOption.EVAP_AS_FLOW) -#inflowCalc.setComputationStorageOptions(InflowComputationStorageOption.PROJECT_RELEASES) + # configure the start calendar + ##startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + ## + ## + ##startCal.clear() + ##startCal.set(Calendar.YEAR, 2019) + ##startCal.set(Calendar.MONTH, 1) + ## + ##endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + ##endCal.clear() + ##endCal.set(Calendar.YEAR, 2019) + ##endCal.set(Calendar.MONTH, 1) + ##endCal.set(Calendar.DAY_OF_MONTH, 4) -#inflowCalc.setComputationStorageOptions(InflowComputationStorageOption.EVAP_AS_FLOW, InflowComputationStorageOption.PROJECT_RELEASES) + startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + startCal.add(Calendar.DAY_OF_MONTH, -4) + startCal.set(Calendar.HOUR, 0) ######use Calendar.HOUR_OF_DAY + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + # inflowCalc includes a setComputationStorageOptions function, which takes in either one or many + # InflowComputationStorageOption values. This is used by computeInflow to determine if it should save additional + # computed values like evaporation as flow and project releases. + # + # The InflowComputationStorageOption enum contains two values: + # EVAP_AS_FLOW + # PROJECT_RELEASES + # + # None is supported by setComputationStorageOptions as well, and clears out all storage options. + # + # inflowCalc.setComputationStorageOptions is entirely optional, and if it's not used no additional computed values will + # be stored with the computed inflow + # + # Example uses: + #inflowCalc.setComputationStorageOptions(None) + #inflowCalc.setComputationStorageOptions(InflowComputationStorageOption.EVAP_AS_FLOW) + #inflowCalc.setComputationStorageOptions(InflowComputationStorageOption.PROJECT_RELEASES) -locationList = ["WTYT2","JSPT2","TBLT2","SCLT2","TXKT2","BSLT2","JFNT2","CLDL1", - "BPRT2","EAMT2","FLWT2","BNBT2","JPLT2","GPET2","RRLT2","LEWT2", - "GPVT2","LVNT2","FRHT2","TRNT2","DAWT2","BDWT2","FFLT2","PSMT2", - "GBYT2","ALAT2","ACTT2","PCTT2","BLNT2","STIT2","GGLT2","GNGT2", - "SOMT2","LLST2","TBRT2","SAGT2","HORT2","SMCT2","MSDT2"] -for loc in locationList: - inflowCalc.computeInflow("SWF", loc, startCal.getTime(), endCal.getTime()) + #inflowCalc.setComputationStorageOptions(InflowComputationStorageOption.EVAP_AS_FLOW, InflowComputationStorageOption.PROJECT_RELEASES) + + + locationList = ["WTYT2","JSPT2","TBLT2","SCLT2","TXKT2","BSLT2","JFNT2","CLDL1", + "BPRT2","EAMT2","FLWT2","BNBT2","JPLT2","GPET2","RRLT2","LEWT2", + "GPVT2","LVNT2","FRHT2","TRNT2","DAWT2","BDWT2","FFLT2","PSMT2", + "GBYT2","ALAT2","ACTT2","PCTT2","BLNT2","STIT2","GGLT2","GNGT2", + "SOMT2","LLST2","TBRT2","SAGT2","HORT2","SMCT2","MSDT2"] + for loc in locationList: + inflowCalc.computeInflow("SWF", loc, startCal.getTime(), endCal.getTime()) + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWL/Big3-GateFlow.py b/district-scripts/SWL/Big3-GateFlow.py index bc72ce4..3b09287 100644 --- a/district-scripts/SWL/Big3-GateFlow.py +++ b/district-scripts/SWL/Big3-GateFlow.py @@ -1,134 +1,144 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance(timeZone) -# startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -5) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -# startCal.set(Calendar.YEAR, 2015) -# startCal.set(Calendar.MONTH, 9) -startCal.set(Calendar.MILLISECOND, 0) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(timeZone) -# endCal.clear() -##################endCal.add(Calendar.DAY_OF_MONTH, 5) -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -# endCal.set(Calendar.YEAR, 2015) -# endCal.set(Calendar.MONTH, 11) -endCal.set(Calendar.MILLISECOND, 0) - -officeID = "SWL" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = False -flowGroup = "ConduitGate_Total" -locationList = ["ACTT2", -# "MSDT2", - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = True -FlowGroupList = ["Blue_Mtn_Dam", - "Nimrod_Dam", - "Clearwater_Dam", - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) - -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - compute_All_Flowgroups(officeID, location, startCal, endCal) - - - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + # the gate flow calculations requires a start and end time. + # here we create a java Calendar object that will be used to create the start Date + startCal = Calendar.getInstance(timeZone) + # startCal.clear() + startCal.add(Calendar.DAY_OF_MONTH, -5) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + # startCal.set(Calendar.YEAR, 2015) + # startCal.set(Calendar.MONTH, 9) + startCal.set(Calendar.MILLISECOND, 0) + + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance(timeZone) + # endCal.clear() + ##################endCal.add(Calendar.DAY_OF_MONTH, 5) + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + # endCal.set(Calendar.YEAR, 2015) + # endCal.set(Calendar.MONTH, 11) + endCal.set(Calendar.MILLISECOND, 0) + + officeID = "SWL" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out + # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate + # by changing the "flowGroup" variable. + calculateSingleFlowGroups = False + flowGroup = "ConduitGate_Total" + locationList = ["ACTT2", + # "MSDT2", + ] + + # the calculation can also be performed for all the associated groups + # the computeAll method takes: + # officeId + # projectId + # startDate + # endDate + # By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. + # Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. + + calculateAllFlowGroups = True + FlowGroupList = ["Blue_Mtn_Dam", + "Nimrod_Dam", + "Clearwater_Dam", + ] + + + if calculateSingleFlowGroups: + for location in locationList: + print("Now Running", location, "SINGLE") + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) + + if calculateAllFlowGroups: + for location in FlowGroupList: + print("Now Running", location, "GROUP") + compute_All_Flowgroups(officeID, location, startCal, endCal) + + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWL/Big3-InflowCalcMultipleActions.py b/district-scripts/SWL/Big3-InflowCalcMultipleActions.py index 25340e4..5a8378e 100644 --- a/district-scripts/SWL/Big3-InflowCalcMultipleActions.py +++ b/district-scripts/SWL/Big3-InflowCalcMultipleActions.py @@ -1,125 +1,135 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def inflow_Actions(function, officeID, location, startCal, endCal, uselimits, freezerain): - # Takes in locations defined by user in group and computes the given command at the given station. - try: - if function.lower() == "cloneinflows": - inflowCalc.cloneInflows(officeID, location, startCal.getTime()) - elif function.lower() == "computeinflow": - inflowCalc.computeInflow(officeID, location, startCal.getTime(), endCal.getTime()) - elif function.lower() == "zeronegatives": - inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) - elif function.lower() == "balanceall": - inflowCalc.balanceAll(officeID, location, startCal.getTime()) - elif function.lower() == "autoadjust": - inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) - else: - print "Input command", function, "is not recognized. Please edit your input and try again." - except Exception as e: - print "Error Completing action {0} at {1} {2}".format(function, officeID, location) - print e - print "" -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar' -#startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -timeZone = TimeZone.getTimeZone("US/Central") - -#startCal.clear() -#startCal.set(Calendar.YEAR, 2015) -#startCal.set(Calendar.MONTH, 4) - -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -7) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -endCal = Calendar.getInstance(timeZone) -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -officeID = "SWL" - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, -# the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" -# If the Auto Adjust command is not used, these arguments will have no influence on the other commands. -useLimits_ON = False -freezeRain_ON = False - -# Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. -# The action must come first, and they must be separated by a "@" symbol. -# Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. -actions = ["computeInflow @ Blue_Mtn_Dam", - "cloneInflows @ Blue_Mtn_Dam", - "autoAdjust @ Blue_Mtn_Dam", - "computeInflow @ Nimrod_Dam", - "cloneInflows @ Nimrod_Dam", - "autoAdjust @ Nimrod_Dam", - "computeInflow @ Clearwater_Dam", - "cloneInflows @ Clearwater_Dam", - "autoAdjust @ Clearwater_Dam", - ] - -for command in actions: - location = command.split('@')[1].strip() - function = command.split('@')[0].strip() - print "" - print "Now running", function, "at", location - print "" - inflow_Actions(function, officeID, location, startCal, endCal, useLimits_ON, freezeRain_ON) +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + # the java Calendar class is used to create java Date objects + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def inflow_Actions(function, officeID, location, startCal, endCal, uselimits, freezerain): + # Takes in locations defined by user in group and computes the given command at the given station. + try: + if function.lower() == "cloneinflows": + inflowCalc.cloneInflows(officeID, location, startCal.getTime()) + elif function.lower() == "computeinflow": + inflowCalc.computeInflow(officeID, location, startCal.getTime(), endCal.getTime()) + elif function.lower() == "zeronegatives": + inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) + elif function.lower() == "balanceall": + inflowCalc.balanceAll(officeID, location, startCal.getTime()) + elif function.lower() == "autoadjust": + inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) + else: + print("Input command", function, "is not recognized. Please edit your input and try again.") + except Exception as e: + print("Error Completing action {0} at {1} {2}".format(function, officeID, location)) + print(e) + print("") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # this gets a scriptable Pool Percent object + inflowCalc = registry.getCalculation(1.0, "Inflow") + + # configure the start calendar' + #startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + timeZone = TimeZone.getTimeZone("US/Central") + + #startCal.clear() + #startCal.set(Calendar.YEAR, 2015) + #startCal.set(Calendar.MONTH, 4) + + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -7) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + endCal = Calendar.getInstance(timeZone) + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + + officeID = "SWL" + + # inflowCalc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives + + # Each method takes the following arguments: + # officeId + # locationId + # startDate + + # autoAdjust also takes booleans: + # useLimits + # freezeRain + + # UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, + # the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" + # If the Auto Adjust command is not used, these arguments will have no influence on the other commands. + useLimits_ON = False + freezeRain_ON = False + + # Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. + # The action must come first, and they must be separated by a "@" symbol. + # Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. + actions = ["computeInflow @ Blue_Mtn_Dam", + "cloneInflows @ Blue_Mtn_Dam", + "autoAdjust @ Blue_Mtn_Dam", + "computeInflow @ Nimrod_Dam", + "cloneInflows @ Nimrod_Dam", + "autoAdjust @ Nimrod_Dam", + "computeInflow @ Clearwater_Dam", + "cloneInflows @ Clearwater_Dam", + "autoAdjust @ Clearwater_Dam", + ] + + for command in actions: + location = command.split('@')[1].strip() + function = command.split('@')[0].strip() + print("") + print("Now running", function, "at", location) + print("") + inflow_Actions(function, officeID, location, startCal, endCal, useLimits_ON, freezeRain_ON) + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py b/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py index 730f364..998bddc 100644 --- a/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py +++ b/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py @@ -1,135 +1,145 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance(timeZone) -# startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -5) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -# startCal.set(Calendar.YEAR, 2015) -# startCal.set(Calendar.MONTH, 9) -startCal.set(Calendar.MILLISECOND, 0) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(timeZone) -# endCal.clear() -##################endCal.add(Calendar.DAY_OF_MONTH, 5) -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -# endCal.set(Calendar.YEAR, 2015) -# endCal.set(Calendar.MONTH, 11) -endCal.set(Calendar.MILLISECOND, 0) - -officeID = "SWL" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = False -flowGroup = "ConduitGate_Total" -locationList = ["ACTT2", -# "MSDT2", - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = True -FlowGroupList = ["Millwood_Dam", - "DeQueen_Dam", - "Dierks_Dam", - "Gillham_Dam", - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) - -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - compute_All_Flowgroups(officeID, location, startCal, endCal) - - - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + # the gate flow calculations requires a start and end time. + # here we create a java Calendar object that will be used to create the start Date + startCal = Calendar.getInstance(timeZone) + # startCal.clear() + startCal.add(Calendar.DAY_OF_MONTH, -5) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + # startCal.set(Calendar.YEAR, 2015) + # startCal.set(Calendar.MONTH, 9) + startCal.set(Calendar.MILLISECOND, 0) + + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance(timeZone) + # endCal.clear() + ##################endCal.add(Calendar.DAY_OF_MONTH, 5) + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + # endCal.set(Calendar.YEAR, 2015) + # endCal.set(Calendar.MONTH, 11) + endCal.set(Calendar.MILLISECOND, 0) + + officeID = "SWL" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out + # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate + # by changing the "flowGroup" variable. + calculateSingleFlowGroups = False + flowGroup = "ConduitGate_Total" + locationList = ["ACTT2", + # "MSDT2", + ] + + # the calculation can also be performed for all the associated groups + # the computeAll method takes: + # officeId + # projectId + # startDate + # endDate + # By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. + # Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. + + calculateAllFlowGroups = True + FlowGroupList = ["Millwood_Dam", + "DeQueen_Dam", + "Dierks_Dam", + "Gillham_Dam", + ] + + + if calculateSingleFlowGroups: + for location in locationList: + print("Now Running", location, "SINGLE") + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) + + if calculateAllFlowGroups: + for location in FlowGroupList: + print("Now Running", location, "GROUP") + compute_All_Flowgroups(officeID, location, startCal, endCal) + + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py b/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py index 567bcb3..5c04e5a 100644 --- a/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py +++ b/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py @@ -1,129 +1,139 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def inflow_Actions(function, officeID, location, startCal, endCal, uselimits, freezerain): - # Takes in locations defined by user in group and computes the given command at the given station. - try: - if function.lower() == "cloneinflows": - inflowCalc.cloneInflows(officeID, location, startCal.getTime()) - elif function.lower() == "computeinflow": - inflowCalc.computeInflow(officeID, location, startCal.getTime(), endCal.getTime()) - elif function.lower() == "zeronegatives": - inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) - elif function.lower() == "balanceall": - inflowCalc.balanceAll(officeID, location, startCal.getTime()) - elif function.lower() == "autoadjust": - inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) - else: - print "Input command", function, "is not recognized. Please edit your input and try again." - except Exception as e: - print "Error Completing action {0} at {1} {2}".format(function, officeID, location) - print e - print "" -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar' -#startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -timeZone = TimeZone.getTimeZone("US/Central") - -#startCal.clear() -#startCal.set(Calendar.YEAR, 2015) -#startCal.set(Calendar.MONTH, 4) - -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -7) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -endCal = Calendar.getInstance(timeZone) -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -officeID = "SWL" - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, -# the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" -# If the Auto Adjust command is not used, these arguments will have no influence on the other commands. -useLimits_ON = False -freezeRain_ON = False - -# Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. -# The action must come first, and they must be separated by a "@" symbol. -# Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. -actions = ["computeInflow @ Dequeen_Dam", - "cloneInflows @ Dequeen_Dam", - "autoAdjust @ Dequeen_Dam", - "computeInflow @ Dierks_Dam", - "cloneInflows @ Dierks_Dam", - "autoAdjust @ Dierks_Dam", - "computeInflow @ Gillham_Dam", - "cloneInflows @ Gillham_Dam", - "autoAdjust @ Gillham_Dam", - "computeInflow @ Millwood_Dam", - "cloneInflows @ Millwood_Dam", - "autoAdjust @ Millwood_Dam", - ] - -for command in actions: - location = command.split('@')[1].strip() - function = command.split('@')[0].strip() - print "" - print "Now running", function, "at", location - print "" - inflow_Actions(function, officeID, location, startCal, endCal, useLimits_ON, freezeRain_ON) - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + # the java Calendar class is used to create java Date objects + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def inflow_Actions(function, officeID, location, startCal, endCal, uselimits, freezerain): + # Takes in locations defined by user in group and computes the given command at the given station. + try: + if function.lower() == "cloneinflows": + inflowCalc.cloneInflows(officeID, location, startCal.getTime()) + elif function.lower() == "computeinflow": + inflowCalc.computeInflow(officeID, location, startCal.getTime(), endCal.getTime()) + elif function.lower() == "zeronegatives": + inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) + elif function.lower() == "balanceall": + inflowCalc.balanceAll(officeID, location, startCal.getTime()) + elif function.lower() == "autoadjust": + inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) + else: + print("Input command", function, "is not recognized. Please edit your input and try again.") + except Exception as e: + print("Error Completing action {0} at {1} {2}".format(function, officeID, location)) + print(e) + print("") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # this gets a scriptable Pool Percent object + inflowCalc = registry.getCalculation(1.0, "Inflow") + + # configure the start calendar' + #startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + timeZone = TimeZone.getTimeZone("US/Central") + + #startCal.clear() + #startCal.set(Calendar.YEAR, 2015) + #startCal.set(Calendar.MONTH, 4) + + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -7) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + endCal = Calendar.getInstance(timeZone) + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + + officeID = "SWL" + + # inflowCalc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives + + # Each method takes the following arguments: + # officeId + # locationId + # startDate + + # autoAdjust also takes booleans: + # useLimits + # freezeRain + + # UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, + # the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" + # If the Auto Adjust command is not used, these arguments will have no influence on the other commands. + useLimits_ON = False + freezeRain_ON = False + + # Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. + # The action must come first, and they must be separated by a "@" symbol. + # Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. + actions = ["computeInflow @ Dequeen_Dam", + "cloneInflows @ Dequeen_Dam", + "autoAdjust @ Dequeen_Dam", + "computeInflow @ Dierks_Dam", + "cloneInflows @ Dierks_Dam", + "autoAdjust @ Dierks_Dam", + "computeInflow @ Gillham_Dam", + "cloneInflows @ Gillham_Dam", + "autoAdjust @ Gillham_Dam", + "computeInflow @ Millwood_Dam", + "cloneInflows @ Millwood_Dam", + "autoAdjust @ Millwood_Dam", + ] + + for command in actions: + location = command.split('@')[1].strip() + function = command.split('@')[0].strip() + print("") + print("Now running", function, "at", location) + print("") + inflow_Actions(function, officeID, location, startCal, endCal, useLimits_ON, freezeRain_ON) + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWL/WhiteR-GateFlow.py b/district-scripts/SWL/WhiteR-GateFlow.py index 1cce0db..270a0f4 100644 --- a/district-scripts/SWL/WhiteR-GateFlow.py +++ b/district-scripts/SWL/WhiteR-GateFlow.py @@ -1,137 +1,147 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -startCal = Calendar.getInstance(timeZone) -# startCal.clear() -startCal.add(Calendar.DAY_OF_MONTH, -5) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -# startCal.set(Calendar.YEAR, 2015) -# startCal.set(Calendar.MONTH, 9) -startCal.set(Calendar.MILLISECOND, 0) - -# create a java Calendar object that will be used to create the end Date -endCal = Calendar.getInstance(timeZone) -# endCal.clear() -##################endCal.add(Calendar.DAY_OF_MONTH, 5) -#endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -# endCal.set(Calendar.YEAR, 2015) -# endCal.set(Calendar.MONTH, 11) -endCal.set(Calendar.MILLISECOND, 0) - -officeID = "SWL" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") -# By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out -# or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate -# by changing the "flowGroup" variable. -calculateSingleFlowGroups = False -flowGroup = "ConduitGate_Total" -locationList = ["ACTT2", -# "MSDT2", - ] - -# the calculation can also be performed for all the associated groups -# the computeAll method takes: -# officeId -# projectId -# startDate -# endDate -# By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. -# Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. - -calculateAllFlowGroups = True -FlowGroupList = ["Beaver_Dam", - "Table_Rock_Dam", - "Bull_Shoals_Dam", - "Norfork_Dam", - "GreersFerry_Dam", - ] - - -if calculateSingleFlowGroups: - for location in locationList: - print "Now Running", location, "SINGLE" - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) - -if calculateAllFlowGroups: - for location in FlowGroupList: - print "Now Running", location, "GROUP" - compute_All_Flowgroups(officeID, location, startCal, endCal) - - - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + # the gate flow calculations requires a start and end time. + # here we create a java Calendar object that will be used to create the start Date + startCal = Calendar.getInstance(timeZone) + # startCal.clear() + startCal.add(Calendar.DAY_OF_MONTH, -5) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + # startCal.set(Calendar.YEAR, 2015) + # startCal.set(Calendar.MONTH, 9) + startCal.set(Calendar.MILLISECOND, 0) + + # create a java Calendar object that will be used to create the end Date + endCal = Calendar.getInstance(timeZone) + # endCal.clear() + ##################endCal.add(Calendar.DAY_OF_MONTH, 5) + #endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + # endCal.set(Calendar.YEAR, 2015) + # endCal.set(Calendar.MONTH, 11) + endCal.set(Calendar.MILLISECOND, 0) + + officeID = "SWL" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out + # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate + # by changing the "flowGroup" variable. + calculateSingleFlowGroups = False + flowGroup = "ConduitGate_Total" + locationList = ["ACTT2", + # "MSDT2", + ] + + # the calculation can also be performed for all the associated groups + # the computeAll method takes: + # officeId + # projectId + # startDate + # endDate + # By setting the following parameter to True, all of the following flow groups in each location in the list locationList will all be calculated. + # Items can be commented out or commented back in individually. To turn this option off, set the following parameter to False. + + calculateAllFlowGroups = True + FlowGroupList = ["Beaver_Dam", + "Table_Rock_Dam", + "Bull_Shoals_Dam", + "Norfork_Dam", + "GreersFerry_Dam", + ] + + + if calculateSingleFlowGroups: + for location in locationList: + print("Now Running", location, "SINGLE") + compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) + + if calculateAllFlowGroups: + for location in FlowGroupList: + print("Now Running", location, "GROUP") + compute_All_Flowgroups(officeID, location, startCal, endCal) + + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py b/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py index eb1fd6c..a92dbef 100644 --- a/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py +++ b/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py @@ -1,131 +1,141 @@ -# the java Calendar class is used to create java Date objects -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def inflow_Actions(function, officeID, location, startCal, endCal, uselimits, freezerain): - # Takes in locations defined by user in group and computes the given command at the given station. - try: - if function.lower() == "cloneinflows": - inflowCalc.cloneInflows(officeID, location, startCal.getTime()) - elif function.lower() == "computeinflow": - inflowCalc.computeInflow(officeID, location, startCal.getTime(), endCal.getTime()) - elif function.lower() == "zeronegatives": - inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) - elif function.lower() == "balanceall": - inflowCalc.balanceAll(officeID, location, startCal.getTime()) - elif function.lower() == "autoadjust": - inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) - else: - print "Input command", function, "is not recognized. Please edit your input and try again." - except Exception as e: - print "Error Completing action {0} at {1} {2}".format(function, officeID, location) - print e - print "" -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# this gets a scriptable Pool Percent object -inflowCalc = registry.getCalculation(1.0, "Inflow") - -# configure the start calendar' -#startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) -timeZone = TimeZone.getTimeZone("US/Central") - -#startCal.clear() -#startCal.set(Calendar.YEAR, 2015) -#startCal.set(Calendar.MONTH, 4) - -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -7) -startCal.set(Calendar.HOUR_OF_DAY, 0) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -endCal = Calendar.getInstance(timeZone) -endCal.add(Calendar.DAY_OF_MONTH, 1) -endCal.set(Calendar.HOUR_OF_DAY, 0) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -officeID = "SWL" - -# inflowCalc contains 4 callable methods: -# autoAdjust -# balanceAll -# cloneInflows -# zeroNegatives - -# Each method takes the following arguments: -# officeId -# locationId -# startDate - -# autoAdjust also takes booleans: -# useLimits -# freezeRain - -# UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, -# the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" -# If the Auto Adjust command is not used, these arguments will have no influence on the other commands. -useLimits_ON = True -freezeRain_ON = True - -# Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. -# The action must come first, and they must be separated by a "@" symbol. -# Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. -actions = ["computeInflow @ Beaver_Dam", - "cloneInflows @ Beaver_Dam", - "autoAdjust @ Beaver_Dam", - "computeInflow @ Table_Rock_Dam", - "cloneInflows @ Table_Rock_Dam", - "autoAdjust @ Table_Rock_Dam", - "computeInflow @ Bull_Shoals_Dam", - "cloneInflows @ Bull_Shoals_Dam", - "autoAdjust @ Bull_Shoals_Dam", - "computeInflow @ Norfork_Dam", - "cloneInflows @ Norfork_Dam", - "autoAdjust @ Nofork_Dam", - "computeInflow @ GreersFerry_Dam", - "cloneInflows @ GreersFerry_Dam", - "autoAdjust @ GreersFerry_Dam", - ] - -for command in actions: - location = command.split('@')[1].strip() - function = command.split('@')[0].strip() - print "" - print "Now running", function, "at", location - print "" - inflow_Actions(function, officeID, location, startCal, endCal, useLimits_ON, freezeRain_ON) +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + # the java Calendar class is used to create java Date objects + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def inflow_Actions(function, officeID, location, startCal, endCal, uselimits, freezerain): + # Takes in locations defined by user in group and computes the given command at the given station. + try: + if function.lower() == "cloneinflows": + inflowCalc.cloneInflows(officeID, location, startCal.getTime()) + elif function.lower() == "computeinflow": + inflowCalc.computeInflow(officeID, location, startCal.getTime(), endCal.getTime()) + elif function.lower() == "zeronegatives": + inflowCalc.zeroNegatives(officeID, location, startCal.getTime()) + elif function.lower() == "balanceall": + inflowCalc.balanceAll(officeID, location, startCal.getTime()) + elif function.lower() == "autoadjust": + inflowCalc.autoAdjust(officeID, location, startCal.getTime(), uselimits, freezerain) + else: + print("Input command", function, "is not recognized. Please edit your input and try again.") + except Exception as e: + print("Error Completing action {0} at {1} {2}".format(function, officeID, location)) + print(e) + print("") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # this gets a scriptable Pool Percent object + inflowCalc = registry.getCalculation(1.0, "Inflow") + + # configure the start calendar' + #startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) + timeZone = TimeZone.getTimeZone("US/Central") + + #startCal.clear() + #startCal.set(Calendar.YEAR, 2015) + #startCal.set(Calendar.MONTH, 4) + + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -7) + startCal.set(Calendar.HOUR_OF_DAY, 0) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + endCal = Calendar.getInstance(timeZone) + endCal.add(Calendar.DAY_OF_MONTH, 1) + endCal.set(Calendar.HOUR_OF_DAY, 0) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + + officeID = "SWL" + + # inflowCalc contains 4 callable methods: + # autoAdjust + # balanceAll + # cloneInflows + # zeroNegatives + + # Each method takes the following arguments: + # officeId + # locationId + # startDate + + # autoAdjust also takes booleans: + # useLimits + # freezeRain + + # UseLimits and FreezeRain are also controllable arguments for AutoAdjust. By setting "useLimits_ON" to True, + # the function will use the "useLimits command. By setting it to "False", it will be turned off. This functions the same way for "freezeRain_ON" + # If the Auto Adjust command is not used, these arguments will have no influence on the other commands. + useLimits_ON = True + freezeRain_ON = True + + # Commands can be input in a list format as seen below. The format is as follows "[ACTION] @ [LOCATION]", reading like "Perform [ACITON] at [LOCATION]. + # The action must come first, and they must be separated by a "@" symbol. + # Spaces between the Action/Location and "@" symbol can vary, although 1 space is recommended for readability. Lines can be commented out as needed. + actions = ["computeInflow @ Beaver_Dam", + "cloneInflows @ Beaver_Dam", + "autoAdjust @ Beaver_Dam", + "computeInflow @ Table_Rock_Dam", + "cloneInflows @ Table_Rock_Dam", + "autoAdjust @ Table_Rock_Dam", + "computeInflow @ Bull_Shoals_Dam", + "cloneInflows @ Bull_Shoals_Dam", + "autoAdjust @ Bull_Shoals_Dam", + "computeInflow @ Norfork_Dam", + "cloneInflows @ Norfork_Dam", + "autoAdjust @ Nofork_Dam", + "computeInflow @ GreersFerry_Dam", + "cloneInflows @ GreersFerry_Dam", + "autoAdjust @ GreersFerry_Dam", + ] + + for command in actions: + location = command.split('@')[1].strip() + function = command.split('@')[0].strip() + print("") + print("Now running", function, "at", location) + print("") + inflow_Actions(function, officeID, location, startCal, endCal, useLimits_ON, freezeRain_ON) + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup1.py b/district-scripts/SWT/GateFlowGroup1.py index b457d09..9018dc7 100644 --- a/district-scripts/SWT/GateFlowGroup1.py +++ b/district-scripts/SWT/GateFlowGroup1.py @@ -1,146 +1,156 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - -# -# GROUP 1 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN THE FIRST 2 MINUTES OF THE TOP OF THE HOUR) -# - -#FOSS -gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total") -gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Gated_Total") - -#FCOB -gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Project_Total") -gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Gated_Total") - -#SKIA -gateCalc.computeFlowGroup("SWT", "SKIA", startCal.getTime(), endCal.getTime(), "Flow.SKIA.Project_Total") -gateCalc.computeFlowGroup("SWT", "SKIA", startCal.getTime(), endCal.getTime(), "Flow.SKIA.Gated_Total") - -#HEYB -gateCalc.computeFlowGroup("SWT", "HEYB", startCal.getTime(), endCal.getTime(), "Flow.HEYB.Project_Total") -gateCalc.computeFlowGroup("SWT", "HEYB", startCal.getTime(), endCal.getTime(), "Flow.HEYB.Gated_Total") - -#KAWL -gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Project_Total") -gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Gated_Total") -gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Turbine_Total") - -#OOLO -gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Project_Total") -gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Gated_Total") - -#COPA -gateCalc.computeFlowGroup("SWT", "COPA", startCal.getTime(), endCal.getTime(), "Flow.COPA.Project_Total") -gateCalc.computeFlowGroup("SWT", "COPA", startCal.getTime(), endCal.getTime(), "Flow.COPA.Gated_Total") - -#HULA -gateCalc.computeFlowGroup("SWT", "HULA", startCal.getTime(), endCal.getTime(), "Flow.HULA.Project_Total") -gateCalc.computeFlowGroup("SWT", "HULA", startCal.getTime(), endCal.getTime(), "Flow.HULA.Gated_Total") +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + # + # GROUP 1 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN THE FIRST 2 MINUTES OF THE TOP OF THE HOUR) + # + + #FOSS + gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total") + gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Gated_Total") + + #FCOB + gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Project_Total") + gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Gated_Total") + + #SKIA + gateCalc.computeFlowGroup("SWT", "SKIA", startCal.getTime(), endCal.getTime(), "Flow.SKIA.Project_Total") + gateCalc.computeFlowGroup("SWT", "SKIA", startCal.getTime(), endCal.getTime(), "Flow.SKIA.Gated_Total") + + #HEYB + gateCalc.computeFlowGroup("SWT", "HEYB", startCal.getTime(), endCal.getTime(), "Flow.HEYB.Project_Total") + gateCalc.computeFlowGroup("SWT", "HEYB", startCal.getTime(), endCal.getTime(), "Flow.HEYB.Gated_Total") + + #KAWL + gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Project_Total") + gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Gated_Total") + gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Turbine_Total") + + #OOLO + gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Project_Total") + gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Gated_Total") + + #COPA + gateCalc.computeFlowGroup("SWT", "COPA", startCal.getTime(), endCal.getTime(), "Flow.COPA.Project_Total") + gateCalc.computeFlowGroup("SWT", "COPA", startCal.getTime(), endCal.getTime(), "Flow.COPA.Gated_Total") -#ELKC -gateCalc.computeFlowGroup("SWT", "ELKC", startCal.getTime(), endCal.getTime(), "Flow.ELKC.Project_Total") -gateCalc.computeFlowGroup("SWT", "ELKC", startCal.getTime(), endCal.getTime(), "Flow.ELKC.Gated_Total") + #HULA + gateCalc.computeFlowGroup("SWT", "HULA", startCal.getTime(), endCal.getTime(), "Flow.HULA.Project_Total") + gateCalc.computeFlowGroup("SWT", "HULA", startCal.getTime(), endCal.getTime(), "Flow.HULA.Gated_Total") -#FALL -gateCalc.computeFlowGroup("SWT", "FALL", startCal.getTime(), endCal.getTime(), "Flow.FALL.Project_Total") -gateCalc.computeFlowGroup("SWT", "FALL", startCal.getTime(), endCal.getTime(), "Flow.FALL.Gated_Total") + #ELKC + gateCalc.computeFlowGroup("SWT", "ELKC", startCal.getTime(), endCal.getTime(), "Flow.ELKC.Project_Total") + gateCalc.computeFlowGroup("SWT", "ELKC", startCal.getTime(), endCal.getTime(), "Flow.ELKC.Gated_Total") + #FALL + gateCalc.computeFlowGroup("SWT", "FALL", startCal.getTime(), endCal.getTime(), "Flow.FALL.Project_Total") + gateCalc.computeFlowGroup("SWT", "FALL", startCal.getTime(), endCal.getTime(), "Flow.FALL.Gated_Total") + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup2.py b/district-scripts/SWT/GateFlowGroup2.py index acb3122..8beac17 100644 --- a/district-scripts/SWT/GateFlowGroup2.py +++ b/district-scripts/SWT/GateFlowGroup2.py @@ -1,123 +1,133 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - -# -# GROUP 2 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN THE FIRST 2 - 4 MINUTES OF THE TOP OF THE HOUR) -# - -#ARCA -gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Project_Total") -gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Gated_Total") - -#ARBU -gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Project_Total") -gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Gated_Total") - -#BIRC -gateCalc.computeFlowGroup("SWT", "BIRC", startCal.getTime(), endCal.getTime(), "Flow.BIRC.Project_Total") -gateCalc.computeFlowGroup("SWT", "BIRC", startCal.getTime(), endCal.getTime(), "Flow.BIRC.Gated_Total") - -#ROBE -gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Project_Total") -gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Gated_Total") -gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Turbine_Total") - -#WAUR -gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Project_Total") -gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Gated_Total") - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + # + # GROUP 2 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN THE FIRST 2 - 4 MINUTES OF THE TOP OF THE HOUR) + # + + #ARCA + gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Project_Total") + gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Gated_Total") + + #ARBU + gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Project_Total") + gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Gated_Total") + + #BIRC + gateCalc.computeFlowGroup("SWT", "BIRC", startCal.getTime(), endCal.getTime(), "Flow.BIRC.Project_Total") + gateCalc.computeFlowGroup("SWT", "BIRC", startCal.getTime(), endCal.getTime(), "Flow.BIRC.Gated_Total") + + #ROBE + gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Project_Total") + gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Gated_Total") + gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Turbine_Total") + + #WAUR + gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Project_Total") + gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Gated_Total") + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup3.py b/district-scripts/SWT/GateFlowGroup3.py index 7b962f6..cf5a667 100644 --- a/district-scripts/SWT/GateFlowGroup3.py +++ b/district-scripts/SWT/GateFlowGroup3.py @@ -1,134 +1,144 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.DAY_OF_MONTH, -12) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - -# -# GROUP 3 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 5 TO 8 MINUTES OF THE TOP OF THE HOUR) -# - -#COUN -gateCalc.computeFlowGroup("SWT", "COUN", startCal.getTime(), endCal.getTime(), "Flow.COUN.Project_Total") -gateCalc.computeFlowGroup("SWT", "COUN", startCal.getTime(), endCal.getTime(), "Flow.COUN.Gated_Total") - -#HUGO -gateCalc.computeFlowGroup("SWT", "HUGO", startCal.getTime(), endCal.getTime(), "Flow.HUGO.Project_Total") -gateCalc.computeFlowGroup("SWT", "HUGO", startCal.getTime(), endCal.getTime(), "Flow.HUGO.Gated_Total") - -#MARI -gateCalc.computeFlowGroup("SWT", "MARI", startCal.getTime(), endCal.getTime(), "Flow.MARI.Project_Total") -gateCalc.computeFlowGroup("SWT", "MARI", startCal.getTime(), endCal.getTime(), "Flow.MARI.Gated_Total") - -#PATM -gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Project_Total") -gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Gated_Total") - -#FSUP -gateCalc.computeFlowGroup("SWT", "FSUP", startCal.getTime(), endCal.getTime(), "Flow.FSUP.Project_Total") -gateCalc.computeFlowGroup("SWT", "FSUP", startCal.getTime(), endCal.getTime(), "Flow.FSUP.Gated_Total") - -#CANT -gateCalc.computeFlowGroup("SWT", "CANT", startCal.getTime(), endCal.getTime(), "Flow.CANT.Project_Total") -gateCalc.computeFlowGroup("SWT", "CANT", startCal.getTime(), endCal.getTime(), "Flow.CANT.Gated_Total") - -#HUDS -gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Project_Total") -gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Gated_Total") +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.DAY_OF_MONTH, -12) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + # + # GROUP 3 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 5 TO 8 MINUTES OF THE TOP OF THE HOUR) + # + + #COUN + gateCalc.computeFlowGroup("SWT", "COUN", startCal.getTime(), endCal.getTime(), "Flow.COUN.Project_Total") + gateCalc.computeFlowGroup("SWT", "COUN", startCal.getTime(), endCal.getTime(), "Flow.COUN.Gated_Total") + + #HUGO + gateCalc.computeFlowGroup("SWT", "HUGO", startCal.getTime(), endCal.getTime(), "Flow.HUGO.Project_Total") + gateCalc.computeFlowGroup("SWT", "HUGO", startCal.getTime(), endCal.getTime(), "Flow.HUGO.Gated_Total") + + #MARI + gateCalc.computeFlowGroup("SWT", "MARI", startCal.getTime(), endCal.getTime(), "Flow.MARI.Project_Total") + gateCalc.computeFlowGroup("SWT", "MARI", startCal.getTime(), endCal.getTime(), "Flow.MARI.Gated_Total") + + #PATM + gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Project_Total") + gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Gated_Total") + + #FSUP + gateCalc.computeFlowGroup("SWT", "FSUP", startCal.getTime(), endCal.getTime(), "Flow.FSUP.Project_Total") + gateCalc.computeFlowGroup("SWT", "FSUP", startCal.getTime(), endCal.getTime(), "Flow.FSUP.Gated_Total") + + #CANT + gateCalc.computeFlowGroup("SWT", "CANT", startCal.getTime(), endCal.getTime(), "Flow.CANT.Project_Total") + gateCalc.computeFlowGroup("SWT", "CANT", startCal.getTime(), endCal.getTime(), "Flow.CANT.Gated_Total") + + #HUDS + gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Project_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Gated_Total") + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup4.py b/district-scripts/SWT/GateFlowGroup4.py index 0a52c7e..c42c619 100644 --- a/district-scripts/SWT/GateFlowGroup4.py +++ b/district-scripts/SWT/GateFlowGroup4.py @@ -1,128 +1,138 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - - -# -# GROUP 4 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 8 TO 9 MINUTES PAST THE TOP OF THE HOUR) -# - -#DENI -gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Project_Total") -gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Gated_Total") - -#PINE -gateCalc.computeFlowGroup("SWT", "PINE", startCal.getTime(), endCal.getTime(), "Flow.PINE.Project_Total") -gateCalc.computeFlowGroup("SWT", "PINE", startCal.getTime(), endCal.getTime(), "Flow.PINE.Gated_Total") - -#BROK -gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Project_Total") -gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Gated_Total") - -#SARD -gateCalc.computeFlowGroup("SWT", "SARD", startCal.getTime(), endCal.getTime(), "Flow.SARD.Project_Total") -gateCalc.computeFlowGroup("SWT", "SARD", startCal.getTime(), endCal.getTime(), "Flow.SARD.Gated_Total") - -#EUFA -gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Project_Total") -gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Gated_Total") - - - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + + # + # GROUP 4 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 8 TO 9 MINUTES PAST THE TOP OF THE HOUR) + # + + #DENI + gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Project_Total") + gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Gated_Total") + + #PINE + gateCalc.computeFlowGroup("SWT", "PINE", startCal.getTime(), endCal.getTime(), "Flow.PINE.Project_Total") + gateCalc.computeFlowGroup("SWT", "PINE", startCal.getTime(), endCal.getTime(), "Flow.PINE.Gated_Total") + + #BROK + gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Project_Total") + gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Gated_Total") + + #SARD + gateCalc.computeFlowGroup("SWT", "SARD", startCal.getTime(), endCal.getTime(), "Flow.SARD.Project_Total") + gateCalc.computeFlowGroup("SWT", "SARD", startCal.getTime(), endCal.getTime(), "Flow.SARD.Gated_Total") + + #EUFA + gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Project_Total") + gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Gated_Total") + + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup5.py b/district-scripts/SWT/GateFlowGroup5.py index 88d9996..f0133ba 100644 --- a/district-scripts/SWT/GateFlowGroup5.py +++ b/district-scripts/SWT/GateFlowGroup5.py @@ -1,113 +1,123 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - -# -# GROUP 5 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 19 TO 21 MINUTES PAST THE TOP OF THE HOUR) -# - -#MCGE -gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Project_Total") -gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Gated_Total") - -#BIGH -gateCalc.computeFlowGroup("SWT", "BIGH", startCal.getTime(), endCal.getTime(), "Flow.BIGH.Project_Total") -gateCalc.computeFlowGroup("SWT", "BIGH", startCal.getTime(), endCal.getTime(), "Flow.BIGH.Gated_Total") - -#KEMP -gateCalc.computeFlowGroup("SWT", "KEMP", startCal.getTime(), endCal.getTime(), "Flow.KEMP.Project_Total") -gateCalc.computeFlowGroup("SWT", "KEMP", startCal.getTime(), endCal.getTime(), "Flow.KEMP.Gated_Total") +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + # + # GROUP 5 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 19 TO 21 MINUTES PAST THE TOP OF THE HOUR) + # + + #MCGE + gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Project_Total") + gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Gated_Total") + + #BIGH + gateCalc.computeFlowGroup("SWT", "BIGH", startCal.getTime(), endCal.getTime(), "Flow.BIGH.Project_Total") + gateCalc.computeFlowGroup("SWT", "BIGH", startCal.getTime(), endCal.getTime(), "Flow.BIGH.Gated_Total") + + #KEMP + gateCalc.computeFlowGroup("SWT", "KEMP", startCal.getTime(), endCal.getTime(), "Flow.KEMP.Project_Total") + gateCalc.computeFlowGroup("SWT", "KEMP", startCal.getTime(), endCal.getTime(), "Flow.KEMP.Gated_Total") + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup6.py b/district-scripts/SWT/GateFlowGroup6.py index b3e4b90..933592d 100644 --- a/district-scripts/SWT/GateFlowGroup6.py +++ b/district-scripts/SWT/GateFlowGroup6.py @@ -1,146 +1,156 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -#startCal.set(Calendar.YEAR, 2025) -#startCal.set(Calendar.MONTH, 0) #e.g. 6 ==July -#startCal.set(Calendar.DAY_OF_MONTH, 14) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - - -# -# GROUP 6 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 30 TO 33 MINUTES PAST THE TOP OF THE HOUR) -# - -#WDMA -gateCalc.computeFlowGroup("SWT", "WDMA", startCal.getTime(), endCal.getTime(), "Flow.WDMA.Project_Total") -gateCalc.computeFlowGroup("SWT", "WDMA", startCal.getTime(), endCal.getTime(), "Flow.WDMA.Gated_Total") - -#WEBB -gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Project_Total") -gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Gated_Total") - -#WIST -gateCalc.computeFlowGroup("SWT", "WIST", startCal.getTime(), endCal.getTime(), "Flow.WIST.Project_Total") -gateCalc.computeFlowGroup("SWT", "WIST", startCal.getTime(), endCal.getTime(), "Flow.WIST.Gated_Total") - -#TENK -gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Project_Total") -gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Gated_Total") - -#FGIB -gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Project_Total") -gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Gated_Total") +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + #startCal.set(Calendar.YEAR, 2025) + #startCal.set(Calendar.MONTH, 0) #e.g. 6 ==July + #startCal.set(Calendar.DAY_OF_MONTH, 14) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + + # + # GROUP 6 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 30 TO 33 MINUTES PAST THE TOP OF THE HOUR) + # + + #WDMA + gateCalc.computeFlowGroup("SWT", "WDMA", startCal.getTime(), endCal.getTime(), "Flow.WDMA.Project_Total") + gateCalc.computeFlowGroup("SWT", "WDMA", startCal.getTime(), endCal.getTime(), "Flow.WDMA.Gated_Total") + + #WEBB + gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Project_Total") + gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Gated_Total") + + #WIST + gateCalc.computeFlowGroup("SWT", "WIST", startCal.getTime(), endCal.getTime(), "Flow.WIST.Project_Total") + gateCalc.computeFlowGroup("SWT", "WIST", startCal.getTime(), endCal.getTime(), "Flow.WIST.Gated_Total") + + #TENK + gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Project_Total") + gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Gated_Total") + + #FGIB + gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Project_Total") + gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Gated_Total") -#THUN -gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Project_Total") -gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Gated_Total") + #THUN + gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Project_Total") + gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Gated_Total") -#GSAL -gateCalc.computeFlowGroup("SWT", "GSAL", startCal.getTime(), endCal.getTime(), "Flow.GSAL.Project_Total") -gateCalc.computeFlowGroup("SWT", "GSAL", startCal.getTime(), endCal.getTime(), "Flow.GSAL.Gated_Total") + #GSAL + gateCalc.computeFlowGroup("SWT", "GSAL", startCal.getTime(), endCal.getTime(), "Flow.GSAL.Project_Total") + gateCalc.computeFlowGroup("SWT", "GSAL", startCal.getTime(), endCal.getTime(), "Flow.GSAL.Gated_Total") -#PENS -gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Project_Total") -gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Gated_Total") + #PENS + gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Project_Total") + gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Gated_Total") + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup7.py b/district-scripts/SWT/GateFlowGroup7.py index dcd3f19..21a0f89 100644 --- a/district-scripts/SWT/GateFlowGroup7.py +++ b/district-scripts/SWT/GateFlowGroup7.py @@ -1,139 +1,149 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -#remove or comment out the next line when done!! it was for a big backload ajm -#startCal.add(Calendar.MONTH, -10) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - - -# -# GROUP 7 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 33 TO 36 MINUTES PAST THE TOP OF THE HOUR) -# - -#CHOU -gateCalc.computeFlowGroup("SWT", "CHOU", startCal.getTime(), endCal.getTime(), "Flow.CHOU.Project_Total") -gateCalc.computeFlowGroup("SWT", "CHOU", startCal.getTime(), endCal.getTime(), "Flow.CHOU.Gated_Total") - -#NEWT -gateCalc.computeFlowGroup("SWT", "NEWT", startCal.getTime(), endCal.getTime(), "Flow.NEWT.Project_Total") -gateCalc.computeFlowGroup("SWT", "NEWT", startCal.getTime(), endCal.getTime(), "Flow.NEWT.Gated_Total") - -#TOMS -gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Project_Total") -gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Gated_Total") - -#TORO -gateCalc.computeFlowGroup("SWT", "TORO", startCal.getTime(), endCal.getTime(), "Flow.TORO.Project_Total") -gateCalc.computeFlowGroup("SWT", "TORO", startCal.getTime(), endCal.getTime(), "Flow.TORO.Gated_Total") - -#ALTU -gateCalc.computeFlowGroup("SWT", "ALTU", startCal.getTime(), endCal.getTime(), "Flow.ALTU.Project_Total") -gateCalc.computeFlowGroup("SWT", "ALTU", startCal.getTime(), endCal.getTime(), "Flow.ALTU.Gated_Total") - -#ELDR -gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Project_Total") -gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Gated_Total") - -#CHEN -gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Project_Total") -gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Gated_Total") +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + #remove or comment out the next line when done!! it was for a big backload ajm + #startCal.add(Calendar.MONTH, -10) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + + # + # GROUP 7 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 33 TO 36 MINUTES PAST THE TOP OF THE HOUR) + # + + #CHOU + gateCalc.computeFlowGroup("SWT", "CHOU", startCal.getTime(), endCal.getTime(), "Flow.CHOU.Project_Total") + gateCalc.computeFlowGroup("SWT", "CHOU", startCal.getTime(), endCal.getTime(), "Flow.CHOU.Gated_Total") + + #NEWT + gateCalc.computeFlowGroup("SWT", "NEWT", startCal.getTime(), endCal.getTime(), "Flow.NEWT.Project_Total") + gateCalc.computeFlowGroup("SWT", "NEWT", startCal.getTime(), endCal.getTime(), "Flow.NEWT.Gated_Total") + + #TOMS + gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Project_Total") + gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Gated_Total") + + #TORO + gateCalc.computeFlowGroup("SWT", "TORO", startCal.getTime(), endCal.getTime(), "Flow.TORO.Project_Total") + gateCalc.computeFlowGroup("SWT", "TORO", startCal.getTime(), endCal.getTime(), "Flow.TORO.Gated_Total") + + #ALTU + gateCalc.computeFlowGroup("SWT", "ALTU", startCal.getTime(), endCal.getTime(), "Flow.ALTU.Project_Total") + gateCalc.computeFlowGroup("SWT", "ALTU", startCal.getTime(), endCal.getTime(), "Flow.ALTU.Gated_Total") + + #ELDR + gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Project_Total") + gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Gated_Total") -#JOHN -gateCalc.computeFlowGroup("SWT", "JOHN", startCal.getTime(), endCal.getTime(), "Flow.JOHN.Project_Total") -gateCalc.computeFlowGroup("SWT", "JOHN", startCal.getTime(), endCal.getTime(), "Flow.JOHN.Gated_Total") + #CHEN + gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Project_Total") + gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Gated_Total") + #JOHN + gateCalc.computeFlowGroup("SWT", "JOHN", startCal.getTime(), endCal.getTime(), "Flow.JOHN.Project_Total") + gateCalc.computeFlowGroup("SWT", "JOHN", startCal.getTime(), endCal.getTime(), "Flow.JOHN.Gated_Total") + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup8.py b/district-scripts/SWT/GateFlowGroup8.py index 965ff26..83c0b4b 100644 --- a/district-scripts/SWT/GateFlowGroup8.py +++ b/district-scripts/SWT/GateFlowGroup8.py @@ -1,107 +1,117 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - - -# -# GROUP 8 PROJECTS (SELF-TIMED TRANSMISSIONS FROM 42 MINUTES PAST THE TOP OF THE HOUR TO THE END OF THE HOUR) -# - -#MERE -gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Project_Total") -gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Gated_Total") - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + + # + # GROUP 8 PROJECTS (SELF-TIMED TRANSMISSIONS FROM 42 MINUTES PAST THE TOP OF THE HOUR TO THE END OF THE HOUR) + # + + #MERE + gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Project_Total") + gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Gated_Total") + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowGroup9.py b/district-scripts/SWT/GateFlowGroup9.py index 057e5d3..44550e5 100644 --- a/district-scripts/SWT/GateFlowGroup9.py +++ b/district-scripts/SWT/GateFlowGroup9.py @@ -1,108 +1,118 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.add(Calendar.HOUR, -7) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - - -# -# GROUP 9 PROJECTS (SELF-TIMED TRANSMISSIONS FROM 42 MINUTES PAST THE TOP OF THE HOUR TO THE END OF THE HOUR) -# - -#KEYS -gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Project_Total") -gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Turbine_Total") -gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Gated_Total") - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.add(Calendar.HOUR, -7) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + + # + # GROUP 9 PROJECTS (SELF-TIMED TRANSMISSIONS FROM 42 MINUTES PAST THE TOP OF THE HOUR TO THE END OF THE HOUR) + # + + #KEYS + gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Project_Total") + gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Gated_Total") + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/GateFlowHUDS-WS.py b/district-scripts/SWT/GateFlowHUDS-WS.py index bf31415..4332238 100644 --- a/district-scripts/SWT/GateFlowHUDS-WS.py +++ b/district-scripts/SWT/GateFlowHUDS-WS.py @@ -1,105 +1,115 @@ -from java.util import Calendar -from java.util import TimeZone -from usace.rowcps.headless import LoggingOptions - -def compute_All_Flowgroups(officeID, location, startCal, endCal): - # Takes in locations defined by user in group and computes all flow groups - try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) - except Exception as e: - print "Error Computing all Flow Groups at {0} {1}".format(officeID, location) - print e - print '' - - -def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): - try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) - except Exception as e: - print "Error Computing Flow Group {0} at {1}".format(officeID, location) - print e - print '' - - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -# LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# Time zone must be set because the Solaris time zone is UTC -timeZone = TimeZone.getTimeZone("US/Central") - -# Defaults to start of the day 5 days ago, and ends at the top of the current hour today -# configure the start calendar -startCal = Calendar.getInstance(timeZone) -startCal.add(Calendar.DAY_OF_MONTH, -5) -startCal.add(Calendar.HOUR, -7) -#remove or comment out the next line when done!! it was for a big backload ajm -#startCal.add(Calendar.MONTH, -5) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - - -# configure the end calendar -endCal = Calendar.getInstance(timeZone) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) -#endCal.add(Calendar.MONTH, -3) - -# Calendar can be adjusted using the following functions: -# startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. -# startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) -# startCal.set(Calendar.YEAR, 2020) # Sets the year -# startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) - -officeID = "SWT" - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate -# gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") - -#HUDS -gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Pump_Out_Total") -gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Pump_In_Total") - - +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from java.util import TimeZone + from usace.rowcps.headless import LoggingOptions + + def compute_All_Flowgroups(officeID, location, startCal, endCal): + # Takes in locations defined by user in group and computes all flow groups + try: + gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + except Exception as e: + print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) + print(e) + print('') + + + def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + try: + gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + except Exception as e: + print("Error Computing Flow Group {0} at {1}".format(officeID, location)) + print(e) + print('') + + # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + # LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # Time zone must be set because the Solaris time zone is UTC + timeZone = TimeZone.getTimeZone("US/Central") + + # Defaults to start of the day 5 days ago, and ends at the top of the current hour today + # configure the start calendar + startCal = Calendar.getInstance(timeZone) + startCal.add(Calendar.DAY_OF_MONTH, -5) + startCal.add(Calendar.HOUR, -7) + #remove or comment out the next line when done!! it was for a big backload ajm + #startCal.add(Calendar.MONTH, -5) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + + # configure the end calendar + endCal = Calendar.getInstance(timeZone) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + #endCal.add(Calendar.MONTH, -3) + + # Calendar can be adjusted using the following functions: + # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. + # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) + # startCal.set(Calendar.YEAR, 2020) # Sets the year + # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + + officeID = "SWT" + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + + #HUDS + gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Pump_In_Total") + + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) diff --git a/district-scripts/SWT/WaterSupplyFlowGroup.py b/district-scripts/SWT/WaterSupplyFlowGroup.py index 79cc59e..8a7bb02 100644 --- a/district-scripts/SWT/WaterSupplyFlowGroup.py +++ b/district-scripts/SWT/WaterSupplyFlowGroup.py @@ -1,130 +1,140 @@ -from java.util import Calendar -from usace.rowcps.headless import LoggingOptions - -# Description of: LoggingOptions.setDbMessageLevel(int level) -# -# Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended -# level is 2, as this provides basic information about the time series -# retrieval/storage. -# -# Message Level | Description -# --------------|-------------------------------------------------------------------------------------------------------------------------------| -# <=0 | Default value, does not do anything. Lower values do not change behavior. | -# 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | -# 2 | Adds message with name of time series, and the units to retrieve/store. | -# 3 | Adds message with the current time. | -# 4 | Adds message with first 10 dates and values from each time series. | -# >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | -# --------------|-------------------------------------------------------------------------------------------------------------------------------| - -LoggingOptions.setDbMessageLevel(2) - - -# Description of: LoggingOptions.setMetricsEnabled(boolean value) -# -# Enables or disables the storage of REGI's Metric data pertaining to the -# performance of the application. This is incredibly helpful for identifying -# issues where the application takes an excessive amount of time to operate. -# -# Metrics also log the location of the files as an INFO message if they are -# enabled. -# -# By default, Metrics are disabled. - -#LoggingOptions.setMetricsEnabled(True) - -# not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of -# the implemented scriptable calculations -names = registry.getNames(1.0) - -# this retrieves a Gate Flow calculation object -gateCalc = registry.getCalculation(1.0, "Gate Flow") - -# the gate flow calculations requires a start and end time. -# here we create a java Calendar object that will be used to create the start Date -# -# use the current date minus 5 days. -# -startCal = Calendar.getInstance() -#startCal.clear() -#startCal.set(Calendar.YEAR, 2016) -#startCal.set(Calendar.MONTH, 8) -startCal.add(Calendar.DAY_OF_MONTH, -5) -#startCal.set(Calendar.HOUR, 0) -#startCal.add(Calendar.HOUR, -4) -startCal.set(Calendar.MINUTE, 0) -startCal.set(Calendar.SECOND, 0) -startCal.set(Calendar.MILLISECOND, 0) - -print "this is the place to write the startCal!" -print startCal.getTime().toString() - -# create a java Calendar object that will be used to create the end Date -# use the current date. -# -endCal = Calendar.getInstance() -#remove the next line when the headless time options are fixed -#endCal.add(Calendar.DAY_OF_MONTH, 1) -#endCal.set(Calendar.HOUR, 16) -#endCal.set(Calendar.YEAR, 2018) -#endCal.set(Calendar.MONTH, 6) -#endCal.set(Calendar.DAY_OF_MONTH, 6) -endCal.set(Calendar.MINUTE, 0) -endCal.set(Calendar.SECOND, 0) -endCal.set(Calendar.MILLISECOND, 0) - -print "this is the place to write the endCal!" -print endCal.getTime().toString() - -# the gateCalc object can perform its calculation for a single flow group -# the computeFlowGroup method takes: -# officeId -# projectId -# startDate -# endDate - - -# -# PROJECTS WITH WATER SUPPLY WITHDRAWS/RELEASES -# - - -#ARBU -gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Pump_Out_Total") - -#ARCA -gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Pump_Out_Total") - -#CHEN -gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Pump_Out_Total") - -#ELDR -gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Pump_Out_Total") - -#FCOB -gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Pump_Out_Total") - -#FOSS -gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Pump_Out_Total") - -#MCGE -gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Pump_Out_Total") - -#MERE -gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Pump_Out_Total") - -#OOLO -gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Pump_Out_Total") +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + # Java imports must happen after regi_session starts the JVM. + from java.util import Calendar + from usace.rowcps.headless import LoggingOptions + + # Description of: LoggingOptions.setDbMessageLevel(int level) + # + # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended + # level is 2, as this provides basic information about the time series + # retrieval/storage. + # + # Message Level | Description + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + # <=0 | Default value, does not do anything. Lower values do not change behavior. | + # 1 | Logs message when no data is found. Logs message when data is found, how much was retrieved or stored, and how long it took. | + # 2 | Adds message with name of time series, and the units to retrieve/store. | + # 3 | Adds message with the current time. | + # 4 | Adds message with first 10 dates and values from each time series. | + # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | + # --------------|-------------------------------------------------------------------------------------------------------------------------------| + + LoggingOptions.setDbMessageLevel(2) + + + # Description of: LoggingOptions.setMetricsEnabled(boolean value) + # + # Enables or disables the storage of REGI's Metric data pertaining to the + # performance of the application. This is incredibly helpful for identifying + # issues where the application takes an excessive amount of time to operate. + # + # Metrics also log the location of the files as an INFO message if they are + # enabled. + # + # By default, Metrics are disabled. + + #LoggingOptions.setMetricsEnabled(True) + + # not all of Regi is scriptable, registry is an object created by the java class RegiCLI that contains a list of + # the implemented scriptable calculations + names = registry.getNames(1.0) + + # this retrieves a Gate Flow calculation object + gateCalc = registry.getCalculation(1.0, "Gate Flow") + + # the gate flow calculations requires a start and end time. + # here we create a java Calendar object that will be used to create the start Date + # + # use the current date minus 5 days. + # + startCal = Calendar.getInstance() + #startCal.clear() + #startCal.set(Calendar.YEAR, 2016) + #startCal.set(Calendar.MONTH, 8) + startCal.add(Calendar.DAY_OF_MONTH, -5) + #startCal.set(Calendar.HOUR, 0) + #startCal.add(Calendar.HOUR, -4) + startCal.set(Calendar.MINUTE, 0) + startCal.set(Calendar.SECOND, 0) + startCal.set(Calendar.MILLISECOND, 0) + + print("this is the place to write the startCal!") + print(startCal.getTime().toString()) + + # create a java Calendar object that will be used to create the end Date + # use the current date. + # + endCal = Calendar.getInstance() + #remove the next line when the headless time options are fixed + #endCal.add(Calendar.DAY_OF_MONTH, 1) + #endCal.set(Calendar.HOUR, 16) + #endCal.set(Calendar.YEAR, 2018) + #endCal.set(Calendar.MONTH, 6) + #endCal.set(Calendar.DAY_OF_MONTH, 6) + endCal.set(Calendar.MINUTE, 0) + endCal.set(Calendar.SECOND, 0) + endCal.set(Calendar.MILLISECOND, 0) + + print("this is the place to write the endCal!") + print(endCal.getTime().toString()) + + # the gateCalc object can perform its calculation for a single flow group + # the computeFlowGroup method takes: + # officeId + # projectId + # startDate + # endDate + + + # + # PROJECTS WITH WATER SUPPLY WITHDRAWS/RELEASES + # + + + #ARBU + gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Pump_Out_Total") + + #ARCA + gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Pump_Out_Total") + + #CHEN + gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Pump_Out_Total") + + #ELDR + gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Pump_Out_Total") + + #FCOB + gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Pump_Out_Total") + + #FOSS + gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Pump_Out_Total") + + #MCGE + gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Pump_Out_Total") + + #MERE + gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Pump_Out_Total") -#PATM -gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Pump_Out_Total") + #OOLO + gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Pump_Out_Total") -#THUN -gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Pump_Out_Total") - -#TOMS -gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Pump_Out_Total") - -#WAUR -gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Pump_Out_Total") + #PATM + gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Pump_Out_Total") + #THUN + gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Pump_Out_Total") + + #TOMS + gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Pump_Out_Total") + + #WAUR + gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Pump_Out_Total") + + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) From 7acb5e5e87ad65aacd02432fd693c4d34eb1829f Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 09:24:20 -0700 Subject: [PATCH 17/26] add smoke test of district and example scripts using java mocks --- regi-headless/build.gradle | 22 ++ .../src/test/python/test_district_scripts.py | 244 ++++++++++++++++++ .../examples/LoggingOptionsExamples.py | 21 +- 3 files changed, 281 insertions(+), 6 deletions(-) create mode 100644 regi-headless/src/test/python/test_district_scripts.py diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index edc66ab..fe64972 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -163,6 +163,28 @@ tasks.register('testPythonWheel', VenvTask) { outputs.upToDateWhen { false } } +tasks.register('smokeTestDistrictScripts', VenvTask) { + group = 'verification' + description = 'Validates migrated district and example scripts against the Python entrypoint shape and Java scriptable APIs.' + + dependsOn installPythonBuildTools + + venvExec = 'python' + args = [ + '-m', 'pytest', + '-o', 'log_cli=true', + '--log-cli-level=INFO', + 'src/test/python/test_district_scripts.py' + ] + + inputs.files(fileTree(dir: '../district-scripts', include: '**/*.py')) + inputs.files(fileTree(dir: 'src/test/resources/usace/rowcps/headless/examples', include: '**/*.py')) + inputs.files(fileTree(dir: 'src/main/java/usace/rowcps/headless', include: '**/*.java')) + inputs.file('src/test/python/test_district_scripts.py') + outputs.upToDateWhen { false } +} + check { dependsOn testPythonWheel + dependsOn smokeTestDistrictScripts } diff --git a/regi-headless/src/test/python/test_district_scripts.py b/regi-headless/src/test/python/test_district_scripts.py new file mode 100644 index 0000000..44704d4 --- /dev/null +++ b/regi-headless/src/test/python/test_district_scripts.py @@ -0,0 +1,244 @@ +import importlib.util +import io +import logging +import re +import sys +import types +from contextlib import redirect_stdout +from pathlib import Path + + +MODULE_ROOT = Path(__file__).resolve().parents[3] +REPOSITORY_ROOT = MODULE_ROOT.parent +DISTRICT_SCRIPTS_ROOT = REPOSITORY_ROOT / "district-scripts" +EXAMPLE_SCRIPTS_ROOT = MODULE_ROOT / "src" / "test" / "resources" / "usace" / "rowcps" / "headless" / "examples" +JAVA_SOURCE_ROOT = MODULE_ROOT / "src" / "main" / "java" + + +JAVA_METHOD_PATTERN = re.compile( + r"\bpublic\s+(?:static\s+)?(?:[\w<>\[\], ?]+\s+)+(?P[A-Za-z_]\w*)\s*\(" +) +LOGGER = logging.getLogger(__name__) + + +def test_migrated_scripts_only_call_known_scriptable_api(monkeypatch): + java_api = _load_java_api() + _install_fake_modules(monkeypatch, java_api) + + _validate_scripts("district", DISTRICT_SCRIPTS_ROOT, _district_scripts(), java_api) + _validate_scripts("example", EXAMPLE_SCRIPTS_ROOT, _example_scripts(), java_api) + + +def _validate_scripts(label, root, scripts, java_api): + assert scripts, f"No {label} scripts found under {root}" + LOGGER.info("Validating %s %s script(s)", len(scripts), label) + + failures = [] + for script in scripts: + relative_script = script.relative_to(REPOSITORY_ROOT) + LOGGER.info("Validating %s script: %s", label, relative_script) + try: + module = _load_script(script) + with redirect_stdout(io.StringIO()): + _script_callback(module)(FakeRegistry(java_api)) + except Exception as exc: + failures.append(f"{relative_script}: {type(exc).__name__}: {exc}") + else: + LOGGER.info("Validated %s script: %s", label, relative_script) + + assert not failures, f"{label.title()} script API validation failed:\n" + "\n".join(failures) + + +def _district_scripts(): + return sorted( + path + for path in DISTRICT_SCRIPTS_ROOT.rglob("*.py") + if path.name != "__init__.py" + ) + + +def _example_scripts(): + return sorted( + path + for path in EXAMPLE_SCRIPTS_ROOT.rglob("*.py") + if path.name != "__init__.py" + ) + + +def _script_callback(module): + for name in ( + "run_calculations", + "calculate_inflow", + "calculate_gate_flow", + "calculate_gate_settings", + "configure_logging_options", + ): + callback = getattr(module, name, None) + if callback is not None: + return callback + raise AssertionError(f"No migrated script callback found in {module.__file__}") + + +def _load_java_api(): + return { + "Inflow": _java_methods( + "usace/rowcps/headless/calculator/inflow/ScriptableInflowImpl.java" + ), + "Gate Flow": _java_methods( + "usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowImpl.java" + ), + "Gate Settings": _java_methods( + "usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java" + ), + "LoggingOptions": _java_methods("usace/rowcps/headless/LoggingOptions.java"), + } + + +def _java_methods(relative_path): + source = (JAVA_SOURCE_ROOT / relative_path).read_text(encoding="utf-8") + return { + match.group("name") + for match in JAVA_METHOD_PATTERN.finditer(_strip_java_comments(source)) + } + + +def _strip_java_comments(source): + source = re.sub(r"/\*.*?\*/", "", source, flags=re.DOTALL) + return re.sub(r"//.*", "", source) + + +def _load_script(path): + module_name = "district_script_" + re.sub(r"\W+", "_", str(path.relative_to(REPOSITORY_ROOT))) + spec = importlib.util.spec_from_file_location(module_name, path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def _install_fake_modules(monkeypatch, java_api): + modules = {} + + def module(name): + value = modules.get(name) + if value is None: + value = types.ModuleType(name) + modules[name] = value + monkeypatch.setitem(sys.modules, name, value) + if "." in name: + parent_name, child_name = name.rsplit(".", 1) + setattr(module(parent_name), child_name, value) + return value + + regi_python = module("regi_python") + regi_python.regi_session = _fake_regi_session + regi_python.run_headless = lambda callback: callback(FakeRegistry(java_api)) + + java_util = module("java.util") + java_util.Calendar = FakeCalendar + java_util.TimeZone = FakeTimeZone + + java_lang = module("java.lang") + java_lang.System = FakeSystem + + headless = module("usace.rowcps.headless") + headless.LoggingOptions = type( + "LoggingOptions", + (), + {name: staticmethod(_noop) for name in java_api["LoggingOptions"]}, + ) + + inflow = module("usace.rowcps.headless.calculator.inflow") + inflow.InflowComputationStorageOption = types.SimpleNamespace( + EVAP_AS_FLOW="EVAP_AS_FLOW", + PROJECT_RELEASES="PROJECT_RELEASES", + ) + + +class _fake_regi_session: + def __enter__(self): + return None + + def __exit__(self, exc_type, exc, traceback): + return False + + +class FakeRegistry: + def __init__(self, java_api): + self._java_api = java_api + + def getNames(self, version): + return ["Inflow", "Gate Flow", "Gate Settings"] + + def getCalculation(self, version, name): + if name not in self._java_api: + raise AssertionError(f"Unknown calculation requested: {name!r}") + return FakeJavaObject(name, self._java_api[name]) + + +class FakeJavaObject: + def __init__(self, display_name, method_names): + self._display_name = display_name + self._method_names = method_names + + def __getattr__(self, name): + if name not in self._method_names: + raise AttributeError(f"{self._display_name} has no Java method {name!r}") + return _noop + + +class FakeTimeZone: + @staticmethod + def getTimeZone(name): + return FakeTimeZone() + + +class FakeSystem: + @staticmethod + def getProperty(name): + return "" + + +class FakeCalendar: + DATE = 1 + DAY_OF_MONTH = 2 + HOUR = 3 + HOUR_OF_DAY = 4 + MILLISECOND = 5 + MINUTE = 6 + MONTH = 7 + SECOND = 8 + YEAR = 9 + + @staticmethod + def getInstance(time_zone=None): + return FakeCalendar() + + def add(self, field, amount): + return None + + def clear(self): + return None + + def getTime(self): + return FakeDate() + + def getTimeInMillis(self): + return 0 + + def get(self, field): + return 0 + + def set(self, field, value): + return None + + +class FakeDate: + def getTime(self): + return 0 + + def toString(self): + return "FakeDate" + + +def _noop(*args, **kwargs): + return None diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py index 61835bf..cd5db36 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/LoggingOptionsExamples.py @@ -1,4 +1,4 @@ -from usace.rowcps.headless import LoggingOptions +from regi_python import regi_session, run_headless # Description of: LoggingOptions.setDbMessageLevel(int level) # @@ -16,7 +16,11 @@ # >4 | Same as 4, but shows all values retrieved from each time series. Higher values do not change behavior. | # --------------|-------------------------------------------------------------------------------------------------------------------------------| -LoggingOptions.setDbMessageLevel(2) +def configure_logging_options(registry): + # Java imports must happen after regi_session starts the JVM. + from usace.rowcps.headless import LoggingOptions + + LoggingOptions.setDbMessageLevel(2) # Description of: LoggingOptions.setMetricsEnabled(boolean value) @@ -30,7 +34,7 @@ # # By default, Metrics are disabled. -LoggingOptions.setMetricsEnabled(True) + LoggingOptions.setMetricsEnabled(True) # Description of: LoggingOptions.enableAbridgedFlowGroupCompLogging() # @@ -43,7 +47,7 @@ # # By default flow group computation logging is disabled. -LoggingOptions.enableAbridgedFlowGroupCompLogging() + LoggingOptions.enableAbridgedFlowGroupCompLogging() # Description of: LoggingOptions.enableAbridgedFlowGroupCompLogging() # @@ -58,7 +62,7 @@ # # By default flow group computation logging is disabled. -LoggingOptions.enableFullFlowGroupCompLogging() + LoggingOptions.enableFullFlowGroupCompLogging() # Description of: LoggingOptions.disableFlowGroupCompLogging() # @@ -66,4 +70,9 @@ # to be called unless LoggingOptions.enableAbridgedFlowGroupCompLogging() or LoggingOptions.enableFullFlowGroupCompLogging() # have been called. -LoggingOptions.disableFlowGroupCompLogging() \ No newline at end of file + LoggingOptions.disableFlowGroupCompLogging() + + +if __name__ == "__main__": + with regi_session(): + run_headless(configure_logging_options) From e1a44aff4375c3ad4c6a64deae8e695c86839875 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 09:36:06 -0700 Subject: [PATCH 18/26] add agents.md --- AGENTS.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e59f937 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,60 @@ +# AGENTS.md + +## Repository Overview + +`regi-headless` now uses a **Python-first execution model**. + +- `regi-headless/src/main/python/regi_python` is the runtime bridge. It starts the JVM with **JPype** and exposes `regi_session()` and `run_headless(calculation_callback)`. +- `district-scripts/` and the example scripts under `regi-headless/src/test/resources/...` are now Python entrypoints that call into Java through the bridge. + +Treat this repo as a Python orchestration layer over REGI Java libraries. + +## Current Architecture + +- `regi-headless/src/main/python/regi_python/regi_python.py` is the current Python entrypoint. + - `regi_session()` owns JVM startup/shutdown. + - `run_headless()` creates the REGI domain and invokes a Python callback with a Java-backed registry. +- `regi-headless/src/main/java/...` contains the Java support layer that the Python bridge calls through JPype. +- `district-scripts/` contains active district scripts written calling Java-backed calculations inside the callback. +- `regi-headless/src/test/resources/usace/rowcps/headless/examples` contains the same pattern for example scripts used by tests. + +## File Groups To Treat Differently + +- `regi-headless/src/main/python/` + - python to java bridge code + - prefer modern Python style and small, testable helpers +- `district-scripts/` + - active district-owned operational scripts + - preserve behavior unless the task explicitly changes calculation results or API usage +- `regi-headless/src/test/resources/usace/rowcps/headless/examples/` + - example scripts used by tests + - keep them aligned with the district-script pattern +- `docs/` + - useful for historical context and documentation of features moving forward + +## Working Rules + +- Keep edits scoped to the requested migration target. +- When a script needs a new Java method, update the Java public API and the test harness together; the script test suite validates against the Java source-defined scriptable API. +- Avoid broad refactors outside the requested script family. + +## Verification + +Common checks in this repo: + +- `./gradlew buildPythonWheel` +- `./gradlew testPythonWheel` + +The Python package is built from `regi-headless/src/main/python`, and the wheel test verifies the package metadata, importability, public API exposure, and bundled Java jars. + +## Environment Notes + +The Python bridge expects the Java environment to be available, and the repo documentation currently references these variables: + +- `JAVA_HOME` +- `CDA_URL` +- `CDA_API_KEY` +- `OFFICE_ID` +- `REGI_LOG_LEVEL` + +Use the repo's current bridge code and tests as the source of truth for behavior; use the docs for orientation, not as a strict contract. `regi-headless/src/test/python/test_district_scripts.py` is the main contract for migrated script shape and allowed API calls. From d9b09a912b8914e0a5a8beb6d8115e935a88a74f Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 09:48:06 -0700 Subject: [PATCH 19/26] add basic agent skill --- .../regi-python-bridge-maintenance/SKILL.md | 8 +++++++ .../agents/openai.yaml | 4 ++++ AGENTS.md | 1 + docs/agent-guides/README.md | 5 +++++ .../regi-python-bridge-maintenance.md | 21 +++++++++++++++++++ 5 files changed, 39 insertions(+) create mode 100644 .codex/skills/regi-python-bridge-maintenance/SKILL.md create mode 100644 .codex/skills/regi-python-bridge-maintenance/agents/openai.yaml create mode 100644 docs/agent-guides/README.md create mode 100644 docs/agent-guides/regi-python-bridge-maintenance.md diff --git a/.codex/skills/regi-python-bridge-maintenance/SKILL.md b/.codex/skills/regi-python-bridge-maintenance/SKILL.md new file mode 100644 index 0000000..7b5f4da --- /dev/null +++ b/.codex/skills/regi-python-bridge-maintenance/SKILL.md @@ -0,0 +1,8 @@ +--- +name: regi-python-bridge-maintenance +description: Maintain the regi_python JPype bridge, JVM lifecycle, logging bridge, and wheel packaging. Use when editing regi_python.py, regi_python_logging.py, buildPythonWheel behavior, or troubleshooting JVM startup, classpath, shutdown, or logging issues. +--- + +# Regi Python Bridge Maintenance + +Read `docs/agent-guides/regi-python-bridge-maintenance.md` and keep the bridge behavior aligned with the wheel tests. diff --git a/.codex/skills/regi-python-bridge-maintenance/agents/openai.yaml b/.codex/skills/regi-python-bridge-maintenance/agents/openai.yaml new file mode 100644 index 0000000..970b0ed --- /dev/null +++ b/.codex/skills/regi-python-bridge-maintenance/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "REGI Python Bridge Maintenance" + short_description: "Maintain the JPype bridge layer" + default_prompt: "Use $regi-python-bridge-maintenance to update or troubleshoot the regi_python JPype bridge and runtime." diff --git a/AGENTS.md b/AGENTS.md index e59f937..2ee352b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,6 +31,7 @@ Treat this repo as a Python orchestration layer over REGI Java libraries. - keep them aligned with the district-script pattern - `docs/` - useful for historical context and documentation of features moving forward + - `docs/agent-guides/` is the shared source of truth for agent-facing workflow guidance ## Working Rules diff --git a/docs/agent-guides/README.md b/docs/agent-guides/README.md new file mode 100644 index 0000000..a1f6dfd --- /dev/null +++ b/docs/agent-guides/README.md @@ -0,0 +1,5 @@ +# Agent Guides + +These files are the shared, agent-agnostic source of truth for repetitive repo workflows. + +- [regi-python-bridge-maintenance.md](regi-python-bridge-maintenance.md) diff --git a/docs/agent-guides/regi-python-bridge-maintenance.md b/docs/agent-guides/regi-python-bridge-maintenance.md new file mode 100644 index 0000000..c62a410 --- /dev/null +++ b/docs/agent-guides/regi-python-bridge-maintenance.md @@ -0,0 +1,21 @@ +# REGI Python Bridge Maintenance + +Use this guide when editing the Python bridge or troubleshooting runtime behavior. + +## Focus files + +- `regi-headless/src/main/python/regi_python/regi_python.py` +- `regi-headless/src/main/python/regi_python/regi_python_logging.py` + +## Rules + +- Start the JVM only inside `regi_session()`. +- Keep runtime-only JPype imports inside functions that run after JVM startup. +- Keep `run_headless(calculation_callback)` responsible for creating the domain, running the callback, committing, and shutting down cleanly. +- Keep Python logging and Java logging forwarding aligned. +- Keep wheel packaging and bundled jar checks working with the existing tests. + +## Common checks + +- `./gradlew buildPythonWheel` +- `./gradlew testPythonWheel` From 08a99c5c74d87113bd8174e35790788e1f314b14 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 10:35:46 -0700 Subject: [PATCH 20/26] update release readme --- README.md | 131 ++++++++++++++++++++++++++------------------------- build.gradle | 15 +++++- 2 files changed, 82 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index b5d5b95..505b26b 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,121 @@ # REGI-Headless -> [!IMPORTANT] -> **Notice: Project Refactor in Progress** -> This project is undergoing a large refactor for [CWMS Data API](https://github.com/USACE/cwms-data-api) support. -> It will transition from a Java project consuming Jython scripts to a **Python project** that -> utilizes **JPype** to call underlying REGI Java libraries. +`regi-python` is a Python-first execution layer over the REGI Java libraries. The runtime bridge uses JPype to start the JVM, load the bundled REGI jars, and run Python callbacks against a Java-backed calculation registry. -`REGI-Headless` provides a Python-based interface for running **REGI** calculations in a headless environment. It allows users to execute complex hydrological calculations and manage gate settings via Python scripts, leveraging the performance and stability of the original REGI Java libraries. +## What Lives Where -## Features +- `regi-headless/src/main/python/regi_python/` + - Python bridge code + - Public entry points: `regi_session()` and `run_headless(calculation_callback)` +- `regi-headless/src/main/java/` + - Java support layer used by the bridge calling into REGI calculation and data access libraries +- `district-scripts/` + - Copy of district-owned Python scripts used as examples for smoke tests -- **Headless Execution**: Run REGI calculations as part of automated workflows, CI/CD pipelines, or on servers. -- **Python-First API**: Write calculation scripts in standard Python 3. -- **Java Interoperability**: Direct access to REGI Java libraries via JPype. -- **Modular Calculations**: Full support for: - - Inflow calculations (Clone, Compute, Auto-Adjust, Balance All, etc.) - - Flow Group - - Gate settings calculations. +## Requirements -## Project Structure +- Java JDK 21 or higher +- Python 3.11 or higher -- `regi-headless/`: Core implementation. - - `src/main/python/`: The `regi-python` package source. - - `src/main/java/`: Java-based headless support and factories. -- `district-scripts/`: Legacy Jython scripts and district-specific configurations. -- `docs/`: Additional documentation. +### Environment variables +- `JAVA_HOME` set for JPype startup +- `CDA_URL` url for CDA instance to connect to +- `CDA_API_KEY` required for accessing and storing data in CDA +- `OFFICE_ID` session scoped office for data access +- `REGI_LOG_LEVEL` for logging verbosity -## Getting Started +## Building The Wheel -### Prerequisites +Build the Python wheel with Gradle: -- Java JDK 21 or higher. -- **Python 3.11** or higher. +```powershell +./gradlew buildPythonWheel +``` + +The wheel is written to `regi-headless/build/install/regi_python/dist/`. -### CWMS Data API Configuration +Release tags become wheel versions and must be PEP 440 compatible. For example, use `0.0.2a0`, `0.0.2b0`, or `0.0.2rc0` instead of `0.0.2-alpha`, `0.0.2-beta`, or `0.0.2-rc`. -The library reads the following environment variables when establishing the CWMS Data API data source: +Install the built wheel into a Python environment: -- `CDA_URL`: Base URL for the CWMS Data API endpoint. -- `CDA_API_KEY`: API key used for CWMS Data API authentication and authorization. -- `OFFICE_ID`: CWMS office identifier used to scope the session. +```powershell +pip install regi_python-*.whl +``` -The factory uses these values to authenticate, resolve the current user, and persist the connected office and time zone into the REGI project. +## Releases -### Building +Releases are published from the GitHub repository at [USACE-WaterManagement/regi-python](https://github.com/USACE-WaterManagement/regi-python). A release build attaches the Python wheel and checksum file to the GitHub Release for the matching tag. -The project uses Gradle to manage both Java and Python builds. To build the Python wheel including all Java dependencies: +To consume a published wheel, download the wheel asset from the release and install it with your package manager. Use the exact wheel filename from the release asset URL. ```powershell -./gradlew buildPythonWheel +pip install https://github.com/USACE-WaterManagement/regi-python/releases/download//regi_python--py3-none-any.whl ``` -The resulting wheel file will be located in `regi-headless/build/install/regi-python/dist/`. - -## Usage - -### Installation +```powershell +uv pip install https://github.com/USACE-WaterManagement/regi-python/releases/download//regi_python--py3-none-any.whl +``` -Install the built wheel into your Python environment: +```powershell +poetry add https://github.com/USACE-WaterManagement/regi-python/releases/download//regi_python--py3-none-any.whl +``` ```powershell -pip install regi_python-*.whl +pdm add https://github.com/USACE-WaterManagement/regi-python/releases/download//regi_python--py3-none-any.whl ``` -### Script Example +If your tool does not support direct wheel URLs, download the asset from the release page and install it from the local `.whl` file instead. -The Python bridge uses a context manager to handle the JVM lifecycle and a callback mechanism for calculations. +## Using The Bridge ```python from regi_python import regi_session, run_headless from java.util import Calendar, TimeZone -def my_calculations(registry): - # 'registry' is a RegiCalcRegistry instance + +def calculate_gate_flow(registry): gate_calc = registry.getCalculation(1.0, "Gate Flow") - - # Configure time window tz = TimeZone.getTimeZone("US/Central") start = Calendar.getInstance(tz) - start.set(2025, 0, 1) # Jan 1, 2025 - end = Calendar.getInstance(tz) - end.set(2025, 0, 2) # Jan 2, 2025 - - # Execute calculation + start.set(2025, 0, 1) + end.set(2025, 0, 2) gate_calc.computeAll("OFFICE", "PROJECT", start.getTimeInMillis(), end.getTimeInMillis()) + if __name__ == "__main__": with regi_session(): - run_headless(my_calculations) + run_headless(calculate_gate_flow) ``` -### Environment Variables - -- `JAVA_HOME`: Path to your Java installation (required for JPype). -- `REGI_LOG_LEVEL`: Logging level (e.g., `DEBUG`, `INFO`, `ERROR`). -- `CDA_URL`: URL for the CWMS Data API. -- `CDA_API_KEY`: API Key for CDA authentication. -- `OFFICE_ID`: Office ID for CDA authentication. +`regi_session()` owns JVM startup and shutdown. `run_headless()` creates the REGI domain, invokes the callback with a `RegiCalcRegistry`, commits the session, and closes the domain when the callback finishes. -## Testing +## Verification -To run the automated tests which build the wheel and execute a test script in a virtual environment: +Run the wheel smoke tests: ```powershell ./gradlew testPythonWheel ``` +Run the script/API compatibility smoke test: + +```powershell +./gradlew smokeTestDistrictScripts +``` + +`./gradlew check` runs both along with Java unit tests. + +## Notes + +- The Python package name is `regi_python`. +- The wheel metadata name is `regi-python`. +- The bundled Java jars are packaged inside `regi_python/lib/`. + ## Maintainers -See [MAINTAINERS.md](MAINTAINERS.md) for a list of project maintainers. +See [MAINTAINERS.md](MAINTAINERS.md). ## License -See [LICENSE](LICENSE) for licensing information. +See [LICENSE](LICENSE). diff --git a/build.gradle b/build.gradle index c5a87e7..046d611 100644 --- a/build.gradle +++ b/build.gradle @@ -10,13 +10,26 @@ def gitOutput(String... args) { }.standardOutput.asText.get().trim() } +def normalizeReleaseTag(String tag) { + if (!tag) { + return null + } + + return tag.startsWith('v') ? tag.substring(1) : tag +} + def pep440VersionFromLatestTag() { + def exactTag = gitOutput('describe', '--tags', '--exact-match') + if (exactTag) { + return normalizeReleaseTag(exactTag) + } + def tag = gitOutput('describe', '--tags', '--abbrev=0') if (!tag) { tag = '0.0.0' } - def baseVersion = tag.startsWith('v') ? tag.substring(1) : tag + def baseVersion = normalizeReleaseTag(tag) def distanceText = tag == '0.0.0' ? gitOutput('rev-list', 'HEAD', '--count') From 36ecf0d3e4b95c5dddf7cc34b6813f1b3eb4ec0f Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 11:55:03 -0700 Subject: [PATCH 21/26] readme update --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 505b26b..84b02f3 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,12 @@ Install the built wheel into a Python environment: pip install regi_python-*.whl ``` +### Notes + +- The Python package name is `regi_python`. +- The wheel metadata name is `regi-python`. +- The bundled Java jars are packaged inside `regi_python/lib/`. + ## Releases Releases are published from the GitHub repository at [USACE-WaterManagement/regi-python](https://github.com/USACE-WaterManagement/regi-python). A release build attaches the Python wheel and checksum file to the GitHub Release for the matching tag. @@ -106,12 +112,6 @@ Run the script/API compatibility smoke test: `./gradlew check` runs both along with Java unit tests. -## Notes - -- The Python package name is `regi_python`. -- The wheel metadata name is `regi-python`. -- The bundled Java jars are packaged inside `regi_python/lib/`. - ## Maintainers See [MAINTAINERS.md](MAINTAINERS.md). From 0e2655174c852de79064209763f983c8e229ea25 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 12:47:33 -0700 Subject: [PATCH 22/26] expand on python documentation --- README.md | 25 +--- docs/PYTHON_API.md | 116 ++++++++++++++++++ .../src/main/python/regi_python/__init__.py | 4 +- .../main/python/regi_python/regi_python.py | 13 +- .../python/regi_python/regi_python_logging.py | 6 +- 5 files changed, 134 insertions(+), 30 deletions(-) create mode 100644 docs/PYTHON_API.md diff --git a/README.md b/README.md index 84b02f3..a18cf3e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # REGI-Headless -`regi-python` is a Python-first execution layer over the REGI Java libraries. The runtime bridge uses JPype to start the JVM, load the bundled REGI jars, and run Python callbacks against a Java-backed calculation registry. +`regi-python` is the Python bridge over the REGI Java libraries. ## What Lives Where @@ -23,6 +23,7 @@ - `CDA_API_KEY` required for accessing and storing data in CDA - `OFFICE_ID` session scoped office for data access - `REGI_LOG_LEVEL` for logging verbosity +- `REGI_LOG_FORMAT` overrides the default Python log format ## Building The Wheel @@ -74,27 +75,7 @@ If your tool does not support direct wheel URLs, download the asset from the rel ## Using The Bridge -```python -from regi_python import regi_session, run_headless -from java.util import Calendar, TimeZone - - -def calculate_gate_flow(registry): - gate_calc = registry.getCalculation(1.0, "Gate Flow") - tz = TimeZone.getTimeZone("US/Central") - start = Calendar.getInstance(tz) - end = Calendar.getInstance(tz) - start.set(2025, 0, 1) - end.set(2025, 0, 2) - gate_calc.computeAll("OFFICE", "PROJECT", start.getTimeInMillis(), end.getTimeInMillis()) - - -if __name__ == "__main__": - with regi_session(): - run_headless(calculate_gate_flow) -``` - -`regi_session()` owns JVM startup and shutdown. `run_headless()` creates the REGI domain, invokes the callback with a `RegiCalcRegistry`, commits the session, and closes the domain when the callback finishes. +See [docs/PYTHON_API.md](docs/PYTHON_API.md) for the full Python-facing contract. ## Verification diff --git a/docs/PYTHON_API.md b/docs/PYTHON_API.md new file mode 100644 index 0000000..70d27c0 --- /dev/null +++ b/docs/PYTHON_API.md @@ -0,0 +1,116 @@ +# REGI Python API + +`regi_python` is the client-facing Python package for the REGI headless bridge. It is intentionally small: import the package, open a JVM session, and run your callback against a REGI registry. + +## Package Surface + +```python +from regi_python import regi_session, run_headless, __version__ +``` + +- `regi_session()`: context manager that starts and stops the JVM for the bridge +- `run_headless(calculation_callback)`: executes a callback against a Java-backed registry +- `__version__`: installed package version, or `"unknown"` when the package is not installed from metadata + +The package name on import is `regi_python`. The wheel metadata name is `regi-python`. + +## Runtime Requirements + +- Python 3.11 or newer +- Java JDK 21 or newer +- `JAVA_HOME` set before the bridge starts + +The wheel bundles the REGI jars inside `regi_python/lib/`, and the bridge loads those jars at JVM startup. + +## `regi_session()` + +Use `regi_session()` as the outer lifecycle boundary for any bridge work. + +Behavior: + +- starts the JVM lazily if it is not already running +- configures Java logging to flow into Python logging +- shuts the JVM down when the context exits + +Example: + +```python +from regi_python import regi_session, run_headless + +with regi_session(): + run_headless(my_callback) +``` + +Treat this context manager as the owner of the JVM lifecycle for the process. + +## `run_headless(calculation_callback)` + +`run_headless()` creates a headless REGI domain and calls your callback with a `RegiCalcRegistry` instance. + +Callback shape: + +```python +def my_callback(registry): + ... +``` + +Behavior: + +- creates the REGI domain through `HeadlessRegiDomainFactory` +- builds a `RegiCalcRegistry` with the current manager id +- calls `calculation_callback(registry)` +- commits the domain only after the callback succeeds +- always shuts down the executor and closes the domain in `finally` +- logs the failure and re-raises any exception from the callback + +The bridge is orchestration code. The callback is where client logic should live. + +## Example + +```python +from regi_python import regi_session, run_headless +from java.util import Calendar, TimeZone + + +def calculate_gate_flow(registry): + gate_calc = registry.getCalculation(1.0, "Gate Flow") + tz = TimeZone.getTimeZone("US/Central") + start = Calendar.getInstance(tz) + end = Calendar.getInstance(tz) + start.set(2025, 0, 1) + end.set(2025, 0, 2) + gate_calc.computeAll("OFFICE", "PROJECT", start.getTimeInMillis(), end.getTimeInMillis()) + + +with regi_session(): + run_headless(calculate_gate_flow) +``` + +## Logging + +The bridge uses Python logging for client-visible output. + +Environment variables: + +- `REGI_LOG_LEVEL`: accepted Python log level name such as `DEBUG`, `INFO`, `WARNING`, or `ERROR` +- `REGI_LOG_FORMAT`: overrides the default Python log format +- `AWS_BATCH_JOB_ID` and `AWS_BATCH_JOB_ATTEMPT`: injected into the default log format when present + +Java JUL records are forwarded into the same Python logger once the JVM starts. + +## Compatibility + +| Component | Supported | +| --- | --- | +| Python | 3.11+ | +| Java | JDK 21+ | +| Packaging | `regi-python` wheel with bundled jars | +| Import name | `regi_python` | + +## Troubleshooting + +- If JVM startup fails immediately, verify `JAVA_HOME` points at a JDK installation and not just a JRE. +- If imports fail after installation, confirm the wheel includes `regi_python/lib/*.jar` and that the package was installed from the built wheel. +- If logs do not appear, lower `REGI_LOG_LEVEL` or override `REGI_LOG_FORMAT`. +- If you are calling the package from a larger application, make sure some other code is not starting and stopping the JVM out from under `regi_session()`. + diff --git a/regi-headless/src/main/python/regi_python/__init__.py b/regi-headless/src/main/python/regi_python/__init__.py index 0b4c1e6..9bc0c71 100644 --- a/regi-headless/src/main/python/regi_python/__init__.py +++ b/regi-headless/src/main/python/regi_python/__init__.py @@ -1,3 +1,5 @@ +"""Public package surface for the REGI Python bridge.""" + from .regi_python import regi_session, run_headless from importlib.metadata import version, PackageNotFoundError @@ -7,4 +9,4 @@ __version__ = version("regi_python") except PackageNotFoundError: # package is not installed - __version__ = "unknown" \ No newline at end of file + __version__ = "unknown" diff --git a/regi-headless/src/main/python/regi_python/regi_python.py b/regi-headless/src/main/python/regi_python/regi_python.py index c3694e8..4864b45 100644 --- a/regi-headless/src/main/python/regi_python/regi_python.py +++ b/regi-headless/src/main/python/regi_python/regi_python.py @@ -1,3 +1,5 @@ +"""Runtime bridge for executing REGI calculations from Python.""" + import os import jpype import jpype.imports @@ -16,10 +18,7 @@ @contextmanager def regi_session(): """ - Context manager to handle JVM lifecycle. - Usage: - with regi_session(): - run_headless(my_func) + Start the JVM on entry and shut it down when the context exits. """ if not jpype.isJVMStarted(): logger.info("Starting JVM...") @@ -38,7 +37,8 @@ def regi_session(): jpype.shutdownJVM() def run_headless(calculation_callback): - # We must import these inside the function or after JVM starts + """Run a callback against a headless REGI domain.""" + # Import these only after the JVM has started. from usace.rowcps.headless import HeadlessRegiDomainFactory, RegiCalcRegistry from usace.rowcps.regi.factories import RowcpsExecutorService from java.util.concurrent import TimeUnit @@ -61,10 +61,11 @@ def run_headless(calculation_callback): _shutdown_executor(manager_id) regi_domain.closing() + def _shutdown_executor(manager_id): from usace.rowcps.regi.factories import RowcpsExecutorService from java.util.concurrent import TimeUnit res = RowcpsExecutorService.getInstance(manager_id) res.shutdown() if not res.awaitTermination(3000, TimeUnit.MILLISECONDS): - res.shutdownNow() \ No newline at end of file + res.shutdownNow() diff --git a/regi-headless/src/main/python/regi_python/regi_python_logging.py b/regi-headless/src/main/python/regi_python/regi_python_logging.py index 3764731..e0b6099 100644 --- a/regi-headless/src/main/python/regi_python/regi_python_logging.py +++ b/regi-headless/src/main/python/regi_python/regi_python_logging.py @@ -1,3 +1,5 @@ +"""Logging helpers for the REGI Python bridge.""" + import os import logging from jpype import JImplements, JOverride @@ -15,6 +17,7 @@ def _get_log_level(): def configure_logging(): + """Configure the bridge logger.""" log_level, invalid_log_level, log_level_name = _get_log_level() log_format = os.environ.get( @@ -47,6 +50,7 @@ def filter(self, record): def configure_jul_to_python_logging(python_logger): + """Forward Java JUL records into Python logging.""" global _java_log_sink from java.util.logging import Logger @@ -122,4 +126,4 @@ def log(self, record, message): self._logger.log(level, "[%s] %s", name, message) - return PythonLogSink \ No newline at end of file + return PythonLogSink From bae10c2e0345d9e29ab0419fc82bee563456b759 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 12:56:50 -0700 Subject: [PATCH 23/26] add jython migration documentation --- README.md | 3 + docs/JYTHON_TO_JPYPE_MIGRATION.md | 122 ++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 docs/JYTHON_TO_JPYPE_MIGRATION.md diff --git a/README.md b/README.md index a18cf3e..f35a3ca 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ `regi-python` is the Python bridge over the REGI Java libraries. +The client-facing Python API is documented in [docs/PYTHON_API.md](docs/PYTHON_API.md). +For script migration guidance, see [docs/JYTHON_TO_JPYPE_MIGRATION.md](docs/JYTHON_TO_JPYPE_MIGRATION.md). + ## What Lives Where - `regi-headless/src/main/python/regi_python/` diff --git a/docs/JYTHON_TO_JPYPE_MIGRATION.md b/docs/JYTHON_TO_JPYPE_MIGRATION.md new file mode 100644 index 0000000..a1d10ce --- /dev/null +++ b/docs/JYTHON_TO_JPYPE_MIGRATION.md @@ -0,0 +1,122 @@ +# Migrating REGI Headless District Jython Scripts to `regi_python` + +This guide captures the script migration pattern used in the district-scripts history, +moving from old Python 2 Jython-style top-level scripts to the current JPype-based `regi_python` bridge. + +## Core Migration Pattern + +Old scripts typically: + +- imported Java classes at module import time +- accessed global `registry` and calculation objects at top level +- executed the calculation immediately when the file was loaded +- relied on shell wrappers such as `RunHeadlessJython.bat` or `.sh` + +New scripts should: + +- import `regi_session` and `run_headless` from `regi_python` +- move Java imports inside a callback that runs after the JVM starts +- wrap the calculation logic in a function such as `run_calculations(registry)` +- keep `registry.getCalculation(...)` and Java method calls unchanged +- end with `if __name__ == "__main__": with regi_session(): run_headless(run_calculations)` + +## Before And After + +### Before + +```python +from java.util import Calendar +from java.util import TimeZone + +gateCalc = registry.getCalculation(1.0, "Gate Flow") +timeZone = TimeZone.getTimeZone("US/Central") +startCal = Calendar.getInstance(timeZone) +endCal = Calendar.getInstance(timeZone) +gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total") +``` + +### After + +```python +from regi_python import regi_session, run_headless + + +def run_calculations(registry): + from java.util import Calendar + from java.util import TimeZone + + gateCalc = registry.getCalculation(1.0, "Gate Flow") + timeZone = TimeZone.getTimeZone("US/Central") + startCal = Calendar.getInstance(timeZone) + endCal = Calendar.getInstance(timeZone) + gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total") + + +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) +``` + +## Translation Rules + +### 1. Move Java imports inside the callback + +JPype-backed imports should happen after the JVM starts. +Put them inside `run_calculations(registry)` or a nested helper only called from that callback. + +This is the biggest behavioral difference from Jython scripts. + +### 2. Keep the registry lookup pattern + +The migration does not change the scriptable REGI API. Calls like these stay the same: + +- `registry.getNames(1.0)` +- `registry.getCalculation(1.0, "Inflow")` +- `registry.getCalculation(1.0, "Gate Flow")` + +The change is only the Python wrapper around those calls. + +### 3. Convert top-level execution into a callback + +Scripts must be converted from immediate execution to a `run_calculations()` function. +That keeps import side effects out of the module. + +### 4. Replace Python 2 `print` statements + +Old scripts often contain lines like: + +```python +print "Error Computing Flow Group" +``` + +Update these to Python 3 syntax: + +```python +print("Error Computing Flow Group") +``` + +### 5. Keep optional Java-side logging calls + +Calls such as `LoggingOptions.setDbMessageLevel(2)` and `LoggingOptions.setMetricsEnabled(True)` still belong in the script if the district workflow depends on them. They do not move to `regi_python`; they simply live inside the callback now. + +### 6. Remove the shell wrapper + +The old `RunHeadlessJython` launchers are no longer needed. The Python file itself becomes the entry point: + +```python +if __name__ == "__main__": + with regi_session(): + run_headless(run_calculations) +``` + +## Project-Specific Examples + +The current district scripts show the same migration shape across several script families: + +- `SWF/InflowCalcComputedInflow.py` +- `SWF/InflowCalcComputeEvapAsFlow.py` +- `SWF/GateSettings.py` +- `SWT/GateFlowGroup1.py` +- `SWL/Big3-GateFlow.py` + +The differences between them are the calculation names, location lists, and optional logging or flow-group loops. The migration pattern itself is the same. From 9e6e39d50a9c8323146f313b7df7562d28463a92 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 14:41:12 -0700 Subject: [PATCH 24/26] add check for required env variables --- .../src/main/python/regi_python/regi_python.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/regi-headless/src/main/python/regi_python/regi_python.py b/regi-headless/src/main/python/regi_python/regi_python.py index 4864b45..3c1fd25 100644 --- a/regi-headless/src/main/python/regi_python/regi_python.py +++ b/regi-headless/src/main/python/regi_python/regi_python.py @@ -38,6 +38,8 @@ def regi_session(): def run_headless(calculation_callback): """Run a callback against a headless REGI domain.""" + _require_environment_variables("CDA_URL", "CDA_API_KEY", "OFFICE_ID") + # Import these only after the JVM has started. from usace.rowcps.headless import HeadlessRegiDomainFactory, RegiCalcRegistry from usace.rowcps.regi.factories import RowcpsExecutorService @@ -62,6 +64,14 @@ def run_headless(calculation_callback): regi_domain.closing() +def _require_environment_variables(*variable_names): + missing = [name for name in variable_names if not os.environ.get(name)] + if missing: + raise RuntimeError( + "Missing required environment variables: " + ", ".join(missing) + ) + + def _shutdown_executor(manager_id): from usace.rowcps.regi.factories import RowcpsExecutorService from java.util.concurrent import TimeUnit From d7e2fe850645578d7f4412ff4c4b1b0c2b924c8d Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 14:50:36 -0700 Subject: [PATCH 25/26] add unit test for env var handling --- .../src/test/python/test_python_wheel.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/regi-headless/src/test/python/test_python_wheel.py b/regi-headless/src/test/python/test_python_wheel.py index 625b717..ef300e9 100644 --- a/regi-headless/src/test/python/test_python_wheel.py +++ b/regi-headless/src/test/python/test_python_wheel.py @@ -27,6 +27,23 @@ def test_public_api_is_exposed(): assert callable(regi_python.run_headless) +def test_run_headless_requires_cda_environment(monkeypatch): + import regi_python + + monkeypatch.delenv("CDA_URL", raising=False) + monkeypatch.delenv("CDA_API_KEY", raising=False) + monkeypatch.delenv("OFFICE_ID", raising=False) + + try: + regi_python.run_headless(lambda registry: None) + except RuntimeError as exc: + assert str(exc) == ( + "Missing required environment variables: CDA_URL, CDA_API_KEY, OFFICE_ID" + ) + else: + raise AssertionError("run_headless should fail when CDA env vars are missing") + + def test_bundled_java_libraries_are_present(): import regi_python package_dir = Path(regi_python.__file__).parent From 73cd24f91af308c7e0f89d1ab38cef378191b3cb Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Fri, 10 Jul 2026 15:00:48 -0700 Subject: [PATCH 26/26] code review updates to regi_python --- .../main/python/regi_python/regi_python.py | 46 +++++++++++-------- ...st_python_wheel.py => test_regi_python.py} | 31 +++++++++++++ 2 files changed, 58 insertions(+), 19 deletions(-) rename regi-headless/src/test/python/{test_python_wheel.py => test_regi_python.py} (62%) diff --git a/regi-headless/src/main/python/regi_python/regi_python.py b/regi-headless/src/main/python/regi_python/regi_python.py index 3c1fd25..f0a5ac3 100644 --- a/regi-headless/src/main/python/regi_python/regi_python.py +++ b/regi-headless/src/main/python/regi_python/regi_python.py @@ -10,17 +10,15 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__)) LIB_PATH = os.path.join(BASE_DIR, "lib", "*") -java_home = os.environ.get('JAVA_HOME') -java_bin = os.path.join(java_home, 'bin') -if java_bin not in os.environ['PATH']: - os.environ['PATH'] = java_bin + os.pathsep + os.environ['PATH'] @contextmanager def regi_session(): """ Start the JVM on entry and shut it down when the context exits. """ + started_jvm = False if not jpype.isJVMStarted(): + _prepend_java_home_to_path() logger.info("Starting JVM...") jpype.startJVM( jpype.getDefaultJVMPath(), @@ -28,11 +26,12 @@ def regi_session(): classpath=[LIB_PATH] ) configure_jul_to_python_logging(logger) + started_jvm = True try: yield finally: - if jpype.isJVMStarted(): + if started_jvm and jpype.isJVMStarted(): logger.info("Shutting down JVM...") jpype.shutdownJVM() @@ -47,21 +46,19 @@ def run_headless(calculation_callback): factory = HeadlessRegiDomainFactory() logger.info("Attempting to create RegiDomain...") regi_domain = factory.createDomain() + manager_id = factory.getManagerId() + registry = RegiCalcRegistry(regi_domain, manager_id) - if regi_domain is not None: - manager_id = factory.getManagerId() - registry = RegiCalcRegistry(regi_domain, manager_id) - - try: - logger.info("Executing callback...") - calculation_callback(registry) - regi_domain.commitData(manager_id) - except Exception as e: - logger.error("Execution failed.", exc_info=True) - raise - finally: - _shutdown_executor(manager_id) - regi_domain.closing() + try: + logger.info("Executing callback...") + calculation_callback(registry) + regi_domain.commitData(manager_id) + except Exception as e: + logger.error("Execution failed.", exc_info=True) + raise + finally: + _shutdown_executor(manager_id) + regi_domain.closing() def _require_environment_variables(*variable_names): @@ -72,6 +69,17 @@ def _require_environment_variables(*variable_names): ) +def _prepend_java_home_to_path(): + java_home = os.environ.get("JAVA_HOME") + if not java_home: + return + + java_bin = os.path.join(java_home, "bin") + path = os.environ.get("PATH", "") + if java_bin not in path: + os.environ["PATH"] = java_bin + os.pathsep + path + + def _shutdown_executor(manager_id): from usace.rowcps.regi.factories import RowcpsExecutorService from java.util.concurrent import TimeUnit diff --git a/regi-headless/src/test/python/test_python_wheel.py b/regi-headless/src/test/python/test_regi_python.py similarity index 62% rename from regi-headless/src/test/python/test_python_wheel.py rename to regi-headless/src/test/python/test_regi_python.py index ef300e9..81b9bb2 100644 --- a/regi-headless/src/test/python/test_python_wheel.py +++ b/regi-headless/src/test/python/test_regi_python.py @@ -4,6 +4,7 @@ # Source may not be released without written approval from HEC import importlib.metadata +import importlib from pathlib import Path @@ -51,3 +52,33 @@ def test_bundled_java_libraries_are_present(): assert lib_dir.is_dir() assert any(lib_dir.glob("*.jar")) + + +def test_bridge_import_does_not_require_java_home(monkeypatch): + import regi_python.regi_python as bridge + + monkeypatch.delenv("JAVA_HOME", raising=False) + + reloaded = importlib.reload(bridge) + + assert reloaded is bridge + + +def test_regi_session_only_shuts_down_jvm_it_started(monkeypatch): + import regi_python.regi_python as bridge + + started = [] + stopped = [] + jul_configured = [] + + monkeypatch.setattr(bridge.jpype, "isJVMStarted", lambda: True) + monkeypatch.setattr(bridge.jpype, "startJVM", lambda *args, **kwargs: started.append((args, kwargs))) + monkeypatch.setattr(bridge.jpype, "shutdownJVM", lambda: stopped.append(True)) + monkeypatch.setattr(bridge, "configure_jul_to_python_logging", lambda logger: jul_configured.append(logger)) + + with bridge.regi_session(): + pass + + assert started == [] + assert stopped == [] + assert jul_configured == []