# 💧EPANET-JS

![](https://github.com/modelcreate/epanet-js/workflows/CI/badge.svg) [![codecov](https://codecov.io/gh/modelcreate/epanet-js/branch/master/graph/badge.svg)](https://codecov.io/gh/modelcreate/epanet-js) ![npm](https://img.shields.io/npm/v/epanet-js) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) [![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest)

Water distribution network modelling, either in the browser or Node. Uses the Open Water Analytics EPANET v2.2 toolkit compiled to Javascript.

> **Note**: All version before 1.0.0 should be considered beta with potential breaking changes between releases, use in production with caution.

## Install

To install the stable version with npm:

```
$ npm install epanet-js
```

or with yarn:

```
$ yarn add epanet-js
```

For those without a module bundler, the epanet-js package will soon also be available on unpkg as a precompiled UMD builds. This will allow you to drop a UMD build in a `<script>` tag on your page and access it on the window.epanetJs global variable.

## Usage

### Load and run an existing inp File

```js
import { Project, Workspace } from "epanet-js";
import fs from "fs";

// Read an existing inp file from the disk
const net1 = fs.readFileSync("net1.inp");

// Initialise a new Workspace and Project object
// Requires top-level await support or execution within an async function
const ws = new Workspace();
await ws.loadModule(); // Asynchronous
const model = new Project(ws);

// Write a copy of the inp file to the workspace
ws.writeFile("net1.inp", net1);

// Runs toolkit methods: EN_open, EN_solveH & EN_close
model.open("net1.inp", "report.rpt", "out.bin");
model.solveH();
model.close();
```

**_More Examples_**

- [Step through the hydraulic simulation](https://github.com/modelcreate/epanet-js/wiki/Examples#step-through-the-hydraulic-simulation)
- [New model builder API](https://github.com/modelcreate/epanet-js/wiki/Examples#new-model-builder-api)

## About

Engineers use hydraulic modelling software to simulate water networks. A model will represent a network consisting of pipes, pumps, valves and storage tanks. The modelling software tracks the flow of water in each pipe, the pressure at each node, the height of water in each tank throughout the network during a multi-period simulation.

EPANET is an industry-standard program, initially developed by the USEPA, to simulate water distribution networks, its source code was released in the public domain. An open-source fork by the OWA (Open Water Analytics) community has been released extending its original capabilities. Read more about EPANET on Wikipedia and the OWA community on their website.

The EPANET Toolkit is an API written in C that allows developers to embed the EPANET's engine in their own applications. Ports of the toolkit exist in Python and Matlab; however, there are limited options to use the EPANET engine in JavaScript.

Epanet-js is a full port of version 2.2 OWA-EPANET Toolkit in Typescript, providing access to all 120 functions within the toolkit.

The JavaScript library is for engineers, developers and academics to quickly run and share hydraulic analyses or create custom front end or server-side applications.

### Roadmap

Reaching version 1.0.0 is the current focus, the first non-beta version will have API stability and have mirrored functions of each method in the EPANET Toolkit.

Also planned are helper classes and an object-oriented wrapper to allow simpler development of applications using the EPANET engine.

See the remaining task on the [Version 1.0.0 Project](https://github.com/modelcreate/epanet-js/projects/1).

## Build

epanet-js is split into two packages, the epanet-engine package which compiles the original C code into WASM using Emscripten. And epanet-js is a TypeScript library which wraps over the generated module from Emscripten and manages memory allocation, error handling and returning of varaible.

**Building epanet-engine**

Run the command `pnpm run build` to creates a docker container of Emscripten and the compiled OWA-EPANET source code and generate types.

```sh
cd packages/epanet-engine
pnpm run build
```

**Building epanet-js**

You must first build epanet-engine before you can test or build epanet-js.

```sh
cd packages/epanet-js
pnpm run test
pnpm run build
```

## API

> [The full API is on the GitHub Wiki](https://github.com/modelcreate/epanet-js/wiki/Project-Class)

epanet-js contains two classes, Workspace & Project. A Workspace represents a virtual file system where you can store and read files that are consumed by the tool kit, such as [INP Files](https://github.com/OpenWaterAnalytics/EPANET/wiki/Input-File-Format) or generated by it, such as [RPT](https://github.com/OpenWaterAnalytics/EPANET/wiki/Report-File) or [OUT files](https://github.com/OpenWaterAnalytics/EPANET/wiki/Output-File-Format).

A Project is a single instance of the EN_Project wrapper object and a singleton with all 120+ toolkit methods attached. A [full list of all methods](https://github.com/modelcreate/epanet-js/wiki/Project-Class#class-methods) can be found on the wiki. All method names have been converted to camelCase to keep with javascript convention.

Create a `Project` object by instancing the <a href="https://github.com/modelcreate/epanet-js/wiki/Project-Class"><code>Project</code></a> class with a <a href="https://github.com/modelcreate/epanet-js/wiki/Workspace-Class"><code>Workspace</code></a> object.

```javascript
import { Project, Workspace } from `epanet-js`

const ws = new Workspace()
const model = new Project(ws)
```

If you are not familiar with the OWA-EPANET Toolkit API or EPANET it is worthwhile reading the [OWA-EPANET Toolkit API documentation](http://wateranalytics.org/EPANET/) and [OWA-EPANET wiki](https://github.com/openwateranalytics/epanet/wiki).

## License

The epanet-js and @model-create/epanet-engine are [MIT licenced](https://github.com/modelcreate/epanet-js/blob/master/LICENSE).

The hydraulic engine used within the epanet-js library is [OWA-EPANET](https://github.com/OpenWaterAnalytics/EPANET), which is [MIT licenced](https://github.com/OpenWaterAnalytics/EPANET/blob/dev/LICENSE), with contributed by the following [authors](https://github.com/OpenWaterAnalytics/EPANET/blob/dev/AUTHORS).
