Water System Monitoring Update
Learnings applied to a cloud based monitoring solution for a neighborhood water system

A man of genius makes no mistakes. His errors are volitional and are the portals of discovery
~James Joyce (Ulysses)
When I first set out on the design of this water monitoring solution my main assumption was that it was only water. What could be more benign and forgiving than water? I didn’t put as much stock into my understanding of the tank environment. This turned out to be a costly mistake that incurred my time and effort into troubleshooting and replacing sensors. Ultimately, I arrived at the conclusion that I needed to rethink the design, and select a more industrial and robust sensor, while still keeping in the mold of connecting to IoT.
When I first selected the level sensor there were a few key attributes that led to the decision. The first, was that the sensor was IP68 rated and could be mounted outside which is where this sensor was to be located. Secondly, the sensor could connect directly to the wireless network, bypassing the need to run power and communication cable out to the sensor on the top of the tank. I was able to mount the sensor by drilling a hole on the access latch and wiring it directly to an antenna that connected back to the AWS gateway. This hummed along for about 3 months until I noticed I was getting intermittent errors (by default the sensor returns a value of 9999 when no target is detected in the field of view).
The first time I went to inspect the sensor I noticed there was some mineral build up on the transducer itself. Looking at the anatomy of the sensor the transducer is aluminum and the body is polycarbonate. When I checked with NCD they had me wipe down the sensor with a mild alcohol and lint free towel. After performing this maintenance task the sensor performed well for a week until it started returning the same 9999 error values. When I contacted NCD they instructed me there is a rebuild option to add a caustic/PF protection to the transducer that would work for my application. I went with it and shipped the sensor back which NCD quickly had back to me within 2 weeks. I installed the sensor and was hunky dory for another 3 months when I had the same issue. Ultimately, we could not prevent water splash and/or evaporated residue drying on the sensor and creating the mineral build up and pitting.
This required me to do an engineering deep dive and rethink the design. My new goal was to source a sensor that did not have any metallic components and only polycarbonate surfaces exposed to the inside of the tank. In addition, I needed the sensor to work on my existing wireless mesh network so it would need options for outputs that I could pick up from a radio gateway device. After reviewing multiple types of sensors including, capacitance, float, pressure and other optical sensors I arrived at a radar sensor provided by Emerson Rosemount. It was also by no mistake that I have an affinity for Rosemount since I started my career in power plants and there was something reassuring seeing all of the blue sensors mounted all over the piping throughout every plant I walked. The Rosemount 1208 Non Contacting Radar checked all the boxes. It has Polyvinylidene fluoride (PVDF) housing and is rated IP68 that allows it to be mounted outside in the elements and can even be submerged in water. There is not a single metallic part on the outside of the sensor except where the M12 connector mounts on the very top. In addition, the sensor has multiple output options where I opted for 4-20ma. This allowed me to connect the sensor back to a Dual Channel 4-20 mA Receiver. I actually needed to source another current receiver, as I used both channels with the ultrasonic flow meters. NCD was kind of enough to replace my damaged level sensor and ship me the receiver free of charge. Luckily, I had space in my enclosure to mount the second receiver. The only other pain was that I needed to run M12 cable from the enclosure in the pump house out to the top of the tank. I used 1/2 inch Schedule 40 PVC to run underground and up the side of the tank. While this was not optimum it at least removed the constant need for maintenance.
The biggest pain point on the sensor upgrade was the lead time on Rosemount. Once I placed the order it took 4 months to receive. I also needed to purchase IO Link Communicator with USB and Software. This allowed me to configure the sensor outputs and default offsets for level. All in, this was about twice the cost of the previous Ultrasonic sensor but is much more robust and is worth the time and effort. These are the main components for the new level monitoring:
Meter Type | Total | Order Notes |
---|---|---|
Rosemount 1208AN Level and Flow Transmitter | ~$900 | 1208AN Level and Flow Transmitter, NPT11⁄2-in, IO-Link, M12 |
Rosemount IO Link Communicator | ~$600 | FB-5301:Rosemount IO-Link USB Communicator |
Rosemount IO Link Assistant | ~$300 | FB-5401:Rosemount IO Link Assistant |
M12 Cable Assembly | ~$100 | 4P A-CODE, M12 FEMALE ANGLED - UNTERMINATED |
I also needed to make a small change in my Lambda code for reading the sensors and a few minor changes in Sitewise to accomodate the new calculated level percentage from mA. This was fairly easy as I was already ingesting some similar code for the ultrasonic meters. I just needed to add a new alias id from Sitewise and write the data.
import json
import math
import boto3
import os
#sitewise alias id's are defined as environmental variables in lambda
def lambda_handler(event, context):
mytime = time.time()
mysec = math.floor(mytime)
entryID = 'Entry_' + str(mysec)
propValList=[]
propValDict={}
if 'mA_1' in event['data']: #flow #1
doubVal=event['data']['mA_1']
alliasID=os.environ['flow_in_alias_id']
propValDict['value']={'doubleValue': doubVal}
propValDict['timestamp']={'timeInSeconds': mysec}
propValList.append(propValDict)
write_sitewise_values(entryID,alliasID,propValList)
propValList=[]
propValDict={}
if 'mA_2' in event['data']: #flow #2
doubVal=event['data']['mA_2']
alliasID=os.environ['flow_out_alias_id']
propValDict['value']={'doubleValue': doubVal}
propValDict['timestamp']={'timeInSeconds': mysec}
propValList.append(propValDict)
write_sitewise_values(entryID,alliasID,propValList)
propValList=[]
propValDict={}
elif 'level' in event['data']: #level
doubVal=event['data']['mA_1']
alliasID = os.environ['level_alias_id']
propValDict['value']={'doubleValue': doubVal}
propValDict['timestamp']={'timeInSeconds': mysec}
propValList.append(propValDict)
write_sitewise_values(entryID,alliasID,propValList)
I’m hoping this is not the end of my water project. Despite the challenges we now have a fairly robust and reliable design that meets the intent. We also have a much better handle on what is coming out of the ground and into our tank, and have a working system that monitors and alerts on water tank level. While we have stable monitoring of level and flow there is still features I would like to add regarding maintenance and detection of water loss. In addition, there will need to be upgrades in the future for chemical monitoring and cleaning.
comments powered by Disqus