This post by Natalia Drault and T. Duncan Ellison is reprinted from ISO Focus+ magazine according to the reuse license. The authors are members of the ISO/TC 224.  I’m an expert member of ISO TC224/WG 09 which is writing the ISO standard for Water Event Detection system.

Access to water is a basic human right. So says the United Nations whose ambitious Millennium Development Goals aim to improve access to drinking water and wastewater services throughout the world by 2015. Supporting this endeavour, ISO has developed a series of standards on drinking water and wastewater services that provide a common methodology for assessing the services provided by water utilities of all types and sizes worldwide.

Developed by ISO technical committee ISO/TC 224 for quality water supply and wastewater services, ISO 24510 and its sister standards ISO 24511 and ISO 24512 are intended promote dialogue and continued improvement within the water service itself and among all its stakeholders – the owners, the regulators and the users.

The methodology works by linking the performance of the utility to its objectives, such as promoting public health, protecting the environment and providing services to its users.

With the service objectives set, the question then remains how to determine if these objectives are being met, in other words what service criteria would be applicable for this assessment to be made. The next challenge is how to measure the service provided by the utility within the criteria selected, or more specifically what numerical measures might be calculated to demonstrate that the objectives have been achieved. This is where the ISO 24510 series comes in, offering hands-on solutions to help water utilities through the process.

User successes

Plenty of positive feedback is sent by organizations worldwide about their experiences and the benefits of implementing these ISO standards. Following are a few examples:

Aguas de Santiago S.A., Argentina

Argentinian water utility Aguas de Santiago (AdeS) was an early adopter of the standard. Encouraged by the Argentine National Standardization Body (IRAM), AdeS used ISO 24510 to establish a set of templates that would help define its “service to users” objectives and to decide what service assessment criteria it would use to measure performance. The company developed criteria for performance indicators calculated over a finite period of time, and targets were set for performance improvements to be accomplished within that assessment period. AdeS published its first summary of the achievements, verified by IRAM, in its 2010 annual report.

Sebastián Paz Zavalía, General Manager of AdeS, said of the standard: “Its flexibility, specificity and user-oriented approach makes ISO 24510 the right tool for any public or private utility.”

In 2008, the company was strongly user-oriented, resolving one crisis at a time, as Marcela Paz, AdeS Project Coordinator for the implementation of ISO 24510, explained. “We worked really well,” she commented, “and we needed a tool to organize and systemize all the knowledge and procedures acquired over time. When these standards were published they seemed perfect for us because their orientation, especially ISO 24510, is focused on the user”.

Aguas de Corrientes S.A., Argentina

Aguas de Corrientes S.A. (AdeC) of Argentina was already familiar with management standards and thus able to build on existing procedures. The company established a baseline for key process and performance indicators: the number of user complaints about low water pressure and water quality, and the number of successful water quality control samples, are submitted to the Board in a monthly report. AdeC also extended its report on wastewater service customer satisfaction by measuring the number of user complaints received on flooding.

“The clarity and versatility of ISO 24510 was evident from the very beginning of our implementation. This was clearly shown in the successful implementation in 13 different cities, each with its own reality and characteristics,” said a company spokesperson.
“During the implementation process, it was very important to understand that defining specific objectives and performance indicators aligned with ISO 24510 would enable us to obtain results on which to base decision making, planning and continual improvement.”

Mei-Raanana Water Company, Israel

The Mei-Raanana Water Company is developing a national list of performance indicators for Israel, together with the regulator and a few other Israeli water companies. Its purpose is to create realistic performance indicators that will give the regulator a positive tool with which to assess the activities and processes of each water company, instead of simply comparing numbers. This involved adapting indicators to the function commonly referred to as benchmarking where the performance of individual utilities can be compared to others. However, this requires the indicators to be calculated from exactly the same data sets.

Mei-Raanana is using ISO 24510 to assess the efficiency of its customer service, taking into consideration the time it takes to respond to a complaint, start working on a leak and repair the leak, the time the customer is without water and, finally, the number of complaints lodged.

“Working with ISO 24510 is a process that involves teams of workers and managers,”says Nir Barlev, Manager at Mei-Raanana, adding that, “This mutual activity makes the workers feel much more involved and responsible, so it acts as a motivating force for all employees.”

Worldwide implementation

Uptake of the ISO 24510 series is gaining ground around the world, albeit at different paces. Europe and North America have been using performance measures for many years and most utilities are comfortable with these concepts, both on a management and technical level.

A few steps behind, water utilities in Latin America are fast coming to appreciate these standards and the Federal Council of Sanitation Services in Argentina is actively encouraging other water utilities in the country to follow in the footsteps of AdeS and AdeC. The ISO standards are part of a broader Latin American effort, led by the regional component of working group ISO/TC 224/WG 5 through the Latin American Association of Water and Wastewater Operators. The working group will continue to document implementation activities and hope to prepare a technical report on examples of applications of the ISO 24510 series.

Download as PDF (5MB)

Tagged with: ,

During the blackhat europe 2013 convention, Kyle Wilhoit of Trend Micro  gave a talk about “Who’s Really Attacking Your ICS Devices?“.  Kyle has set up a test decoy web server which mimics the operation of control station for water pumps.

decoy-network

According to the report (pdf file) it took only 18 hours for the first attack to start:

It took only 18 hours to find the first signs of attack on one of the honeypots. While the honeypots ran and continued to collect attack statistics, the findings concerning the deployments proved disturbing. The statistics of this report contain data for 28 days with a total of 39 attacks from 11 different countries. Out of these 25 attacks, 12 were unique and could be classified as “targeted” while 13 were repeated by several of the same actors over a period of several days and could be considered “targeted” and/or “automated.” All of these attacks were prefaced by port scans performed by the same IP address or an IP address in the same /27 netblock. In sum, China accounted for the majority of the attack attempts at 35%, followed by the United States at 19% and Lao at 12%.

The attacks aimed to modify Modbus traffic, modify CPU fan speed (which mimics the pump speed), access information and diagnostics pages and malware exploitation (including via email phishing).

Kyle recommendations are:

  • Disable Internet access to your trusted resources, where possible.
  • Make sure your trusted resources have the latest patches and that you diligently monitor when new patches/fixes are released.
  • Use real-time anti-malware protection and real-time network scanning locally on trusted hosts and where applicable. (Some PLC systems cannot support anti-malware products because of the fragile nature of ICS protocols.)
  • Require user name/password combinations for all systems, including those that are not deemed “trustworthy.”
  • Set appropriately secure login credentials. Do not rely on defaults.
  • Implement two-factor authentication on all trusted systems for any user account.
  • Disable remote protocols that are insecure like Telnet.
  • Disable all protocols that communicate inbound to your trusted resources but are not critical to business functionality.
  • Control contractor access. Many ICS/SCADA networks utilize remote contractors, and controlling how they access trusted resources is imperative.
  • Utilize SSL/TLS for all communications to web-based ICS/SCADA systems.
  • Utilize network segmentation to secure resources like VES systems, ICS, and SCADA devices.
  • Control access to trusted devices. For instance, for access to a segmented network, use a bastion host with access control lists (ACLs) for ingress/egress access.
  • Improve logging in on trusted environments in addition to passing logs to SIEM devices for third-party backup/analysis.
  • Develop a threat modeling system for your organization. Understand who’s attacking you and why.

The White paper, presentation slides and video are available here.

Hat tip Eyal Sela

Tagged with: , , ,

A Russian and Ukrainian version of EPANet is available at www.epanet.com.ua

epanet-ru

The entire user manual was also translated.  Download from here or here.

Tagged with: , ,

During an ISO meeting one of the members said that toilets should be called “user interface”. This led to a somewhat funny discussion about toilets around the world. While talking about the heated toilets in Japan it was pointed that these facilities use a lot of energy. So I looked it up and found a post on the Washington Post saying that these heated toilets take about 4% of household energy consumption.

Japanese toilets can warm and wash one’s bottom, whisk away odors with built-in fans and play water noises that drown out potty sounds. They play relaxation music, too. “Ave Maria” is a favorite.

An imported note is that, according to the World Bank, the per-capita energy consumption in Japan is about 60% of the one in the US (home of the Washington Post).

Looking at some of these devices I found an amazing image of a wireless remote control with 38 (!) buttons. See the translation of the buttons here.

Wireless_toilet_control_panel_w._open_lid

Image by Chris 73 / Wikimedia Commons.

Tagged with: , ,

Earlier this month there were reports that the city of Haifa (a northern city in Israel) water supply SCADA system was attacked by a group named the Syrian Electronic Army (SEA). The source of these reports was the Iranian Ahlul Bayt News Agency who posted on May 8th the following news feed:

The Syrian Electronic Army (SEA) launched a successful cyberattack on the main infrastructure system of Haifa, one of the most important ports in Israel, disrupting the operation of the servers in charge of urban management systems and public utilities in the city. (Full statement here.)

They also added:

The SEA warned that it could cause a major blast by continuing the attack on the servers of the Haifa infrastructural systems, but avoided further move due to inescapable human casualties as it did not want a story like the recent accident in Texas which claimed the lives of dozens of the people.

To “prove” their actions the SEA posted many screen shots of the so-called Haifa SCADA (PDF file):

cdn.anonfiles.com1367855605244.pdf

A few remarks:

  1. For the non-Hebrew speaking readers let me translate a few words for the above image. The headers are for “Avocado orchard” and “Hen house line”  – this is not Haifa 🙂 
  2. The screen shot is dated April 28th, 2012 (see the bottom of the image).
  3. This screen shot is from the ICC software (see the upper right corner). A few years back a have managed part of Haifa’s SCADA system upgrade. It is not ICC!
  4. Not that it proves anything but the SEA posted on their Twitter account that they did not attack the Israeli system:

TwitterOfficial_SEA12AndnowedidntattackIsraeli

 

Update 11/06/2013: the Fars News Agency reported again on this issue. According to the report the Haifa hack was successful and the “prove” is a new set of screenshots. None of these images are from the Haifa control system. If one looks at the following screenshot it is clear that this is from some system of Kibbutz Sa’ar (this is a translation from Hebrew):

saar

Tagged with: , ,

The review process over at the Water Resources Planning and Management (ASCE) is finally over and the Battle of the Water Networks II (BWN-II) summary paper is published. There are 50 (!) authors to this paper led by Dr Angela Marchi.

Abstract:

The Battle of the Water Networks II (BWN-II) is the latest of a series of competitions related to the design and operation of water distribution systems (WDSs) undertaken within the Water Distribution Systems Analysis (WDSA) Symposium series. The BWN-II problem specification involved a broadly defined design and operation problem for an existing network that has to be upgraded for increased future demands, and the addition of a new development area. The design decisions involved addition of new and parallel pipes, storage, operational controls for pumps and valves, and sizing of backup power supply. Design criteria involved hydraulic, water quality, reliability, and environmental performance measures. Fourteen teams participated in the Battle and presented their results at the 14th Water Distribution Systems Analysis (WDSA 2012) conference in Adelaide, Australia, September 2012. This paper summarizes the approaches used by the participants and the results they obtained. Given the complexity of the BWN-II problem and the innovative methods required to deal with the multi-objective, high dimensional and computationally demanding nature of the problem, this paper represents a snap-shot of state of the art methods for the design and operation of water distribution systems. A general finding of this paper is that there is benefit in using a combination of heuristic engineering experience and sophisticated optimization algorithms when tackling complex real-world water distribution system design problems.

Paper’s permalink: http://dx.doi.org/10.1061/(ASCE)WR.1943-5452.0000378

Tagged with: ,

Last year I posted about the Water Canary and since I have not heard any news about the project. Recently a short interview published with Sonaar Luthra who “explains his role in developing a device to prevent people from using water contaminated by deadly bacteria”.

Water Canary

Water Canary

Interview video link

Tagged with: , ,

Update 24/02/2014: there is new EPANET C# class here.

Thanks to abcprogramlama (site in Turkish) I finally got the EPANet Toolkit working in C# (C-sharp). First the EpanetCSharpLibrary should be added to the solution (click to expend or download here):

[code language=”csharp” collapse=”true”]
using System;
using System.Runtime.InteropServices;

namespace EpanetCSharpLibrary
{
public static class Epanet
{
public const string EPANETDLL = "epanet2.dll";
public const int EN_ELEVATION = 0;
public const int EN_BASEDEMAND = 1;
public const int EN_PATTERN = 2;
public const int EN_EMITTER = 3;
public const int EN_INITQUAL = 4;
public const int EN_SOURCEQUAL = 5;
public const int EN_SOURCEPAT = 6;
public const int EN_SOURCETYPE = 7;
public const int EN_TANKLEVEL = 8;
public const int EN_DEMAND = 9;
public const int EN_HEAD = 10;
public const int EN_PRESSURE = 11;
public const int EN_QUALITY = 12;
public const int EN_SOURCEMASS = 13;
public const int EN_INITVOLUME = 14;
public const int EN_MIXMODEL = 15;
public const int EN_MIXZONEVOL = 16;
public const int EN_TANKDIAM = 17;
public const int EN_MINVOLUME = 18;
public const int EN_VOLCURVE = 19;
public const int EN_MINLEVEL = 20;
public const int EN_MAXLEVEL = 21;
public const int EN_MIXFRACTION = 22;
public const int EN_TANK_KBULK = 23;
public const int EN_DIAMETER = 0;
public const int EN_LENGTH = 1;
public const int EN_ROUGHNESS = 2;
public const int EN_MINORLOSS = 3;
public const int EN_INITSTATUS = 4;
public const int EN_INITSETTING = 5;
public const int EN_KBULK = 6;
public const int EN_KWALL = 7;
public const int EN_FLOW = 8;
public const int EN_VELOCITY = 9;
public const int EN_HEADLOSS = 10;
public const int EN_STATUS = 11;
public const int EN_SETTING = 12;
public const int EN_ENERGY = 13;
public const int EN_DURATION = 0;
public const int EN_HYDSTEP = 1;
public const int EN_QUALSTEP = 2;
public const int EN_PATTERNSTEP = 3;
public const int EN_PATTERNSTART = 4;
public const int EN_REPORTSTEP = 5;
public const int EN_REPORTSTART = 6;
public const int EN_RULESTEP = 7;
public const int EN_STATISTIC = 8;
public const int EN_PERIODS = 9;
public const int EN_NODECOUNT = 0;
public const int EN_TANKCOUNT = 1;
public const int EN_LINKCOUNT = 2;
public const int EN_PATCOUNT = 3;
public const int EN_CURVECOUNT = 4;
public const int EN_CONTROLCOUNT = 5;
public const int EN_JUNCTION = 0;
public const int EN_RESERVOIR = 1;
public const int EN_TANK = 2;
public const int EN_CVPIPE = 0;
public const int EN_PIPE = 1;
public const int EN_PUMP = 2;
public const int EN_PRV = 3;
public const int EN_PSV = 4;
public const int EN_PBV = 5;
public const int EN_FCV = 6;
public const int EN_TCV = 7;
public const int EN_GPV = 8;
public const int EN_NONE = 0;
public const int EN_CHEM = 1;
public const int EN_AGE = 2;
public const int EN_TRACE = 3;
public const int EN_CONCEN = 0;
public const int EN_MASS = 1;
public const int EN_SETPOINT = 2;
public const int EN_FLOWPACED = 3;
public const int EN_CFS = 0;
public const int EN_GPM = 1;
public const int EN_MGD = 2;
public const int EN_IMGD = 3;
public const int EN_AFD = 4;
public const int EN_LPS = 5;
public const int EN_LPM = 6;
public const int EN_MLD = 7;
public const int EN_CMH = 8;
public const int EN_CMD = 9;
public const int EN_TRIALS = 0;
public const int EN_ACCURACY = 1;
public const int EN_TOLERANCE = 2;
public const int EN_EMITEXPON = 3;
public const int EN_DEMANDMULT = 4;
public const int EN_LOWLEVEL = 0;
public const int EN_HILEVEL = 1;
public const int EN_TIMER = 2;
public const int EN_TIMEOFDAY = 3;
public const int EN_AVERAGE = 1;
public const int EN_MINIMUM = 2;
public const int EN_MAXIMUM = 3;
public const int EN_RANGE = 4;
public const int EN_MIX1 = 0;
public const int EN_MIX2 = 1;
public const int EN_FIFO = 2;
public const int EN_LIFO = 3;
public const int EN_NOSAVE = 0;
public const int EN_SAVE = 1;
public const int EN_INITFLOW = 10;

#region Epanet Imports
public delegate void UserSuppliedFunction(string param0);
/// <summary>
/// Runs a complete EPANET simulation.
/// </summary>
/// <param name="f1">name of the input file</param>
/// <param name="f2">name of an output report file</param>
/// <param name="f3">name of an output output file </param>
/// <param name="vfunc">pointer to a user-supplied function which accepts a character string as its argument</param>
/// <returns>Returns an error code.</returns>
[DllImport(EPANETDLL, EntryPoint = "ENepanet")]
public static extern int ENepanet(string f1, string f2, string f3, UserSuppliedFunction vfunc);

/// <summary>
/// Opens the Toolkit to analyze a particular distribution system.
/// </summary>
/// <param name="param0">name of the input file</param>
/// <param name="param1">name of an output report file</param>
/// <param name="param2">name of an output output file</param>
/// <returns>Returns an error code.</returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENopen")]
public static extern int ENopen(string param0, string param1, string param2);

/// <summary>
/// Writes all current network input data to a file using the format of an EPANET input file.
/// </summary>
/// <param name="filename">name of the file where data is saved.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsaveinpfile")]
public static extern int ENsaveinpfile(string filename);

/// <summary>
/// Closes down the Toolkit system (including all files being processed).
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENclose")]
public static extern int ENclose();

/// <summary>
/// Runs a complete hydraulic simulation with results
/// for all time periods written to the binary Hydraulics file.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsolveH")]
public static extern int ENsolveH();

/// <summary>
/// Transfers results of a hydraulic simulation from the binary Hydraulics file to the binary Output file,
/// where results are only reported at uniform reporting intervals.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsaveH")]
public static extern int ENsaveH();

/// <summary>
/// Opens the hydraulics analysis system.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENopenH")]
public static extern int ENopenH();

/// <summary>
/// Initializes storage tank levels, link status and settings,
/// and the simulation clock time prior to running a hydraulic analysis.
/// </summary>
/// <param name="saveflag">0-1 flag indicating if hydraulic results will be saved to the hydraulics file.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENinitH")]
public static extern int ENinitH(int saveflag);

/// <summary>
/// Runs a single period hydraulic analysis, retrieving the current simulation clock time t.
/// </summary>
/// <param name="t">current simulation clock time in seconds.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENrunH")]
public static extern int ENrunH(ref long t);

/// <summary>
/// Determines the length of time until the next hydraulic event occurs in an extended period simulation.
/// </summary>
/// <param name="tstep">time (in seconds) until next hydraulic event occurs or
/// 0 if at the end of the simulation period.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENnextH")]
public static extern int ENnextH(ref long tstep);

/// <summary>
/// Closes the hydraulic analysis system, freeing all allocated memory.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENcloseH")]
public static extern int ENcloseH();

/// <summary>
/// Saves the current contents of the binary hydraulics file to a file.
/// </summary>
/// <param name="fname">name of the file where the hydraulics results should be saved.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsavehydfile")]
public static extern int ENsavehydfile(string fname);

/// <summary>
/// Uses the contents of the specified file as the current binary hydraulics file.
/// </summary>
/// <param name="fname">name of the file containing hydraulic analysis results for the current network.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENusehydfile")]
public static extern int ENusehydfile(string fname);

/// <summary>
/// Runs a complete water quality simulation with results at uniform reporting
/// intervals written to EPANET’s binary Output file.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsolveQ")]
public static extern int ENsolveQ();

/// <summary>
/// Opens the water quality analysis system.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENopenQ")]
public static extern int ENopenQ();

/// <summary>
/// Initializes water quality and the simulation clock time prior to running a water quality analysis.
/// </summary>
/// <param name="saveflag">0-1 flag indicating if analysis results
/// should be saved to EPANET’s binary output file at uniform reporting periods.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = " ENinitQ")]
public static extern int ENinitQ(int saveflag);

/// <summary>
/// Makes available the hydraulic and water quality results that occur
/// at the start of the next time period of a water quality analysis,
/// where the start of the period is returned in t.
/// </summary>
/// <param name="t">current simulation clock time in seconds.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENrunQ")]
public static extern int ENrunQ(ref long t);

/// <summary>
/// Advances the water quality simulation to the start of the next hydraulic time period.
/// </summary>
/// <param name="tstep">time (in seconds) until next hydraulic event occurs or
/// 0 if at the end of the simulation period.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENnextQ")]
public static extern int ENnextQ(ref long tstep);

/// <summary>
/// Advances the water quality simulation one water quality time step.
/// The time remaining in the overall simulation is returned in tleft.
/// </summary>
/// <param name="tleft">seconds remaining in the overall simulation duration.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENstepQ")]
public static extern int ENstepQ(ref long tleft);

/// <summary>
/// Closes the water quality analysis system, freeing all allocated memory.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENcloseQ")]
public static extern int ENcloseQ();

/// <summary>
/// Writes a line of text to the EPANET report file.
/// </summary>
/// <param name="line">text to be written to file.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENwriteline")]
public static extern int ENwriteline(string line);

/// <summary>
/// Writes a formatted text report on simulation results to the Report file.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENreport")]
public static extern int ENreport();

/// <summary>
/// Clears any report formatting commands that either appeared in the
/// [REPORT] section of the EPANET Input file or were issued with the ENsetreport function.
/// </summary>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENresetreport")]
public static extern int ENresetreport();

/// <summary>
/// Issues a report formatting command.
/// Formatting commands are the same as used in the
/// [REPORT] section of the EPANET Input file.
/// </summary>
/// <param name="command">text of a report formatting command.</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetreport")]
public static extern int ENsetreport(string command);

/// <summary>
/// Retrieves the parameters of a simple control statement.
/// The index of the control is specified in cindex and
/// the remaining arguments return the control’s parameters.
/// </summary>
/// <param name="cindex">control statement index</param>
/// <param name="ctype">control type code</param>
/// <param name="lindex">index of link being controlled</param>
/// <param name="setting">value of the control setting</param>
/// <param name="nindex">index of controlling node</param>
/// <param name="level">value of controlling water level or
/// pressure for level controls or of time of control action (in seconds)
/// for time-based controls</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetcontrol")]
public static extern int ENgetcontrol(int cindex, ref int ctype, ref int lindex,
ref float setting, ref int nindex, ref float level);

/// <summary>
/// Retrieves the number of network components of a specified type.
/// </summary>
/// <param name="countcode">component code</param>
/// <param name="count">number of countcode components in the network</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetcount")]
public static extern int ENgetcount(int countcode, ref int count);

/// <summary>
/// Retrieves the value of a particular analysis option.
/// </summary>
/// <param name="optioncode">an option code</param>
/// <param name="value">an option value</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetoption")]
public static extern int ENgetoption(int optioncode, ref float value);

/// <summary>
/// Retrieves the value of a specific analysis time parameter.
/// </summary>
/// <param name="paramcode">time parameter code</param>
/// <param name="timevalue">value of time parameter in seconds</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgettimeparam")]
public static extern int ENgettimeparam(int paramcode, ref int timevalue);

/// <summary>
/// Retrieves a code number indicating the units used to express all flow rates.
/// </summary>
/// <param name="unitscode">value of a flow units code number</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetflowunits")]
public static extern int ENgetflowunits(ref int unitscode);

/// <summary>
/// Retrieves the index of a particular time pattern.
/// </summary>
/// <param name="id">pattern ID label</param>
/// <param name="index">pattern index</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetpatternindex")]
public static extern int ENgetpatternindex(string id, ref int index);

/// <summary>
/// Retrieves the ID label of a particular time pattern.
/// </summary>
/// <param name="index">pattern index</param>
/// <param name="id">ID label of pattern</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetpatternid")]
public static extern int ENgetpatternid(int index, string id);

/// <summary>
/// Retrieves the number of time periods in a specific time pattern.
/// </summary>
/// <param name="index">pattern index</param>
/// <param name="len">number of time periods in the pattern</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetpatternlen")]
public static extern int ENgetpatternlen(int index, ref int len);

/// <summary>
/// Retrieves the multiplier factor for a specific time period in a time pattern.
/// </summary>
/// <param name="index">time pattern index</param>
/// <param name="period">period within time pattern</param>
/// <param name="value">multiplier factor for the period</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetpatternvalue")]
public static extern int ENgetpatternvalue(int index, int period, ref float value);

/// <summary>
/// Retrieves the type of water quality analysis called for.
/// </summary>
/// <param name="qualcode">water quality analysis code</param>
/// <param name="tracenode">index of node traced in a source tracing analysis</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetqualtype")]
public static extern int ENgetqualtype(ref int qualcode, ref int tracenode);

/// <summary>
/// Retrieves the text of the message associated with a particular error or warning code.
/// </summary>
/// <param name="errcode">error or warning code</param>
/// <param name="errmsg">text of the error or warning message for errcode</param>
/// <param name="nchar">maximum number of characters that errmsg can hold</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgeterror")]
public static extern int ENgeterror(int errcode, string errmsg, int nchar);

/// <summary>
/// Retrieves the index of a node with a specified ID.
/// </summary>
/// <param name="id">node ID label</param>
/// <param name="index">node index</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetnodeindex")]
public static extern int ENgetnodeindex(string id, ref int index);

/// <summary>
/// Retrieves the ID label of a node with a specified index
/// </summary>
/// <param name="index">node index</param>
/// <param name="id">ID label of node</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetnodeid")]
public static extern int ENgetnodeid(int index, string id);

/// <summary>
/// Retrieves the node-type code for a specific node.
/// </summary>
/// <param name="index">node index</param>
/// <param name="typecode">node-type code</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetnodetype")]
public static extern int ENgetnodetype(int index, ref int typecode);

/// <summary>
/// Retrieves the value of a specific link parameter.
/// </summary>
/// <param name="index">node index</param>
/// <param name="paramcode">parameter code</param>
/// <param name="value">parameter value</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetnodevalue")]
public static extern int ENgetnodevalue(int index, int paramcode, ref float value);

/// <summary>
/// Retrieves the index of a link with a specified ID.
/// </summary>
/// <param name="id">link ID label</param>
/// <param name="index">link index</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetlinkindex")]
public static extern int ENgetlinkindex(string id, ref int index);

/// <summary>
/// Retrieves the ID label of a link with a specified index.
/// </summary>
/// <param name="index">link index</param>
/// <param name="id">ID label of link</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetlinkid")]
public static extern int ENgetlinkid(int index, string id);

/// <summary>
/// Retrieves the link-type code for a specific link.
/// </summary>
/// <param name="index">link index</param>
/// <param name="typecode">link-type code</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetlinktype")]
public static extern int ENgetlinktype(int index, ref int typecode);

/// <summary>
/// Retrieves the indexes of the end nodes of a specified link.
/// </summary>
/// <param name="index">link index</param>
/// <param name="fromnode">index of node at start of link</param>
/// <param name="tonode">index of node at end of link</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetlinknodes")]
public static extern int ENgetlinknodes(int index, ref int fromnode, ref int tonode);

/// <summary>
/// Retrieves the value of a specific link parameter.
/// </summary>
/// <param name="index">link index</param>
/// <param name="paramcode">parameter code</param>
/// <param name="value">parameter value</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetlinkvalue")]
public static extern int ENgetlinkvalue(int index, int paramcode, ref float value);

/// <summary>
/// Retrieves version.
/// </summary>
/// <param name="version">Version</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENgetversion")]
public static extern int ENgetversion(ref int version);

/// <summary>
/// Sets the parameters of a simple control statement.
/// </summary>
/// <param name="cindex">control statement index</param>
/// <param name="ctype">control type code</param>
/// <param name="lindex">index of link being controlled</param>
/// <param name="setting">value of the control setting</param>
/// <param name="nindex">index of controlling node</param>
/// <param name="level">value of controlling water level or pressure
/// for level controls or of time of control action (in seconds)
/// for time-based controls</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetcontrol")]
public static extern int ENsetcontrol(int cindex, int ctype, int lindex,
float setting, int nindex, float level);

/// <summary>
/// Sets the value of a parameter for a specific node.
/// </summary>
/// <param name="index">node index</param>
/// <param name="paramcode">parameter code</param>
/// <param name="value">parameter value</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetnodevalue")]
public static extern int ENsetnodevalue(int index, int paramcode, float value);

/// <summary>
/// Sets the value of a parameter for a specific link.
/// </summary>
/// <param name="index">link index</param>
/// <param name="paramcode">parameter code</param>
/// <param name="value">parameter value</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetlinkvalue")]
public static extern int ENsetlinkvalue(int index, int paramcode, float value);

/// <summary>
/// Adds a new time pattern to the network.
/// </summary>
/// <param name="id">ID label of pattern</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENaddpattern")]
public static extern int ENaddpattern(string id);

/// <summary>
/// Sets all of the multiplier factors for a specific time pattern.
/// </summary>
/// <param name="index">time pattern index</param>
/// <param name="factors">multiplier factors for the entire pattern</param>
/// <param name="nfactors">number of factors in the pattern</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetpattern")]
public static extern int ENsetpattern(int index, float[] factors, int nfactors);

/// <summary>
/// Sets the multiplier factor for a specific period within a time pattern.
/// </summary>
/// <param name="index">time pattern index</param>
/// <param name="period">period within time pattern</param>
/// <param name="value">multiplier factor for the period</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetpatternvalue")]
public static extern int ENsetpatternvalue(int index, int period, float value);

/// <summary>
/// Sets the value of a time parameter.
/// </summary>
/// <param name="paramcode">time parameter code</param>
/// <param name="timevalue">value of time parameter in seconds</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsettimeparam")]
public static extern int ENsettimeparam(int paramcode, long timevalue);

/// <summary>
/// Sets the value of a particular analysis option.
/// </summary>
/// <param name="optioncode">an option code</param>
/// <param name="value">an option value</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetoption")]
public static extern int ENsetoption(int optioncode, float value);

/// <summary>
/// Sets the level of hydraulic status reporting.
/// </summary>
/// <param name="statuslevel">level of status reporting</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetstatusreport")]
public static extern int ENsetstatusreport(int statuslevel);

/// <summary>
/// Sets the type of water quality analysis called for.
/// </summary>
/// <param name="qualcode">water quality analysis code</param>
/// <param name="chemname">name of the chemical being analyzed</param>
/// <param name="chemunits">units that the chemical is measured in</param>
/// <param name="tracenode">ID of node traced in a source tracing analysis</param>
/// <returns></returns>
[DllImportAttribute(EPANETDLL, EntryPoint = "ENsetqualtype")]
public static extern int ENsetqualtype(int qualcode, string chemname, string chemunits, string tracenode);

#endregion
}
}
[/code]

Now the EPANet class can be used:

[code language=”csharp” collapse=”false”]
public static void Main()
{
int i = 0;
int v = 0;
string f1="", f2="", f3="";
//get the DLL’s version
i = Epanet.ENgetversion(ref v);

f1 = "Net1.inp";
f2 = "out.txt";
f3 = "rep.txt";
//run an EPANet simulation
i = Epanet.ENepanet(f1, f2, f3, null);
}
[/code]

Turns out to be simple…

Tagged with: ,

This is a guest post by Marcelino Rodríguez from Transparent Blue.

WatDis in short

WatDis 1.3 is a system for the analysis of water pressure distributions networks. The software allows engineers to evaluate the behavior of the pipe network and to evaluate its performance.

WatDis is able to model several hydraulic elements. Starting with simple components like demand nodes and pipes, it goes to more sophisticate ones like pumps, pumping stations, valves and tanks. Users can work with demands patterns to analyze the behavior of hydraulic properties (pressure, flow) in a given time period.

WatDis has two methods of hydraulic analysis: steady state regime and EPS (extended period simulation). Also is able to work with several head loss formulas.

In summary, it’s  a software like EPANet, but with many enhancements in his graphical interface, and includes modules that are not present in epanet, like the module to construct the network from shapes file, DXF or even excel.

Why should anyone use WatDis?

Well, several reasons:

  • It’s Free to the current version (1.3).
  • Has a very powerful graphical interface. Only comparable to high end software on the market. You can zoom and pan with the mouse wheel, customizable floating panes, easy creation of links and nodes, split links, reconnect links etc.
  • It has many appealing features like a specific editor for demands, tools to create a model from external data like Excel, SHP files Access and more.
  • It’s an alive project. Expect more to come soon.
  • It’s free. Really, no limitations on how many pipes you can use or something like that.
  • You can migrate easily from EPANet to WatDis and viceversa. Just go to File > Import > EPANet’s .INP

 When asked us for a guest post, Elad had a question “Why to develop new software in such a strong market like water distribution systems?”

The answer is simple: WaterCAD , KyPipes and others has a lot of features, but cost a lot of money. In the other hand is EPANet, which is free, is very stable (stable is GOOD) and it has the almighty EPA on its back. Unfortunately EPANet has a few drawbacks, mainly on the graphical interface, almost twenty years old. Also, EPA has no statement about carrying on with the project.

At this point we thought it would be nice to have software that doesn’t cost so much money, have a good user interface and lots of features.

Lots of features you said? Well it’s not that simple; you need to be a financially strong entity to fund such development. Or… perhaps not, we have a proven secret weapon: The plug-in architecture.

The plug-in architecture

We decided to go for a successful software design pattern known as Plug-in / Framework architecture. This pattern allows us to change over time easily. Adding new features that will not compromise what we already have. Time prove this to be the right choice as WatDis has evolved smoothly since its creation. In fact, from the graphic user interface to the calculation engine, everything in WatDis is a plug-in. Our systems allow even to add even new types of extensions. A “hot thing” we were inspired from successful software like Eclipse.

WatDis allows not only extensions (SIMPLE), but even new types of extensions (EXTENDED). This highly increase the possibilities and power of the system.

 But sharing is the real power of it. How about if this architecture would be released to many people around the world? Have you noticed how many epanet modifications exist out there? There are a lot. From simple language translations to genetic algorithms implementations. If we could gather all this modifications into one piece of software it would be a very powerful one. Unfortunately, this is very difficult to do, when not impossible. The reason is that while EPANet has a toolkit, it is designed to be modified, not to be extended.

Here is when our plug-in architecture comes to play part. WatDis is designed to be extended. We at Transparent Blue extend it every day as the normal development process. To add a new functionality, we simply add a new plug-in.

Think of this architecture in the hands of all the research centers and companies around the world. Sum up and you will end up with lots of features I told you so.

There are many examples of software that use plug-ins architecture. Wekka, 3DStudio Max, AutoCAD and Eclipse are success histories, just to mention a few.

I’m just puzzled that it hasn’t happened in this field.

WatDis as a business opportunity/Research platform

Let me carry on with plug-ins. This time we are going to look at this from the developer’s perspective. Suppose you are a small company / research center. Small companies don’t have enough funds to go against the big ones (we know it well, when the idea first came up, everybody said we were crazy). Research centers usually have a very small windows of time in which to research (usually time given by governmental project, a Ph.D thesis or similar) not to mention going into prototype and final product.

By having an already made platform on which to base your work the research-prototype-final product cycle would be shortened extremely. Also by joining your product with a bigger package the added value would increase extremely.

We haven’t still decided how to do the release of the architecture. It will depend manly on license legal stuff and what kind of funding we can get to carry on with the project. But it’s definitively a go.

Others ideas we have in mind is a Python embedded scripting. This will allow users to play with the network and experiment with it new ideas in a very dynamic fashion before going deep into plug-in development. This is a feature we have implemented and would be release only if we have positive feedback for it.

The graphical user interface

We have put a lot of effort in making this a functional an easy interface to use. We have received a lot of positive feedback regarding this topic. We made the software in close contact with engineers using it and it has been an enormous advance.

I would like to share some of our favorite features of WatDis interface:

  • You can pan and zoom with the mouse wheel while you are placing a link (video)
  • Connections can be split / reconnected with ease (video)
  • Selection is powerful (video)
  • You can edit every property´s unit (video)
  • Simple and powerful color schemas (video)

The In-House Engine. Quality tests

We develop the calculations engine ourselves. We will start looking for a partner to validate our engine eventually. For now, it´s tested against the old faithful friend, EPANet. Our test data base consists in over one hundred (100) .INP files. Many of them where actually real cases the hydraulic engineers of Transparent Blue have worked on. Other sources where public .INP files, also feedback from our users where used. The engine was tested by comparing our results to EPANets results.  Test included, but where not limited to: network validation, calculation’s result, control rules and extended and steady modes.

Where we are?

We are very happy with the results of our work. Now we are working intensely on the WatDis stability by increasing the number of automatic tests we do to the software and by seeking validation partners to help us in actually exploiting the product. Unfortunately, not all the parts of the software are as stable as we should like them to be as we add too many features too fast. Nevertheless, this is a work in continuous evolution and every version will gain in features and stability.

The future

The main features we want to add to WatDis include to make the software interact with the cloud; include a module for calibration and keeping enhancing the stability and functionality.

We would like to bring community software into the hydraulics fields. Maintain the project alive and bring new versions every couple month or so. We need funds thou. Future strategies will be conditioned by that. Perhaps going open source and getting fund by development / governmental projects. We will seek partners to achieve this. Personally I´m quite optimistic about the future of WatDis. Time will say.

 

Tagged with:

Are your Fire Hydrant maps updated? Can Firefighters access them in real time? Read this report by wspa:

Firefighters say a mistake on a map did not give them the information they needed to fight a fire over the weekend in Anderson County.

A home caught fire early Saturday morning on Hopewell Ridge off Highway 81.

Firefighters found a fire hydrant on the other side of the street, but the hydrant did not show up on Anderson County’s electronic map that is used by 9-1-1 dispatchers to inform firefighters of the nearest hydrant.

Anderson County Assistant Fire Chief Jimmy Sutherland says the fire department collects information about hydrant locations from water companies and then passes that information on so that it can be entered into the county’s computer mapping system.

Sutherland says there’s not enough manpower for firefighters to keep up with new hydrants that are added, so the fire department relies on water companies to tell fire crews when those additions are made, so that updates can be put into the system.

How do your utility keep the records updated?

Tagged with: ,