Water Meter with Shelly Uni

Hi there!

I want to show you an easy way to integrate your water meter into Home Assistant.
If you have the inductive type with the little, rotating metal plate, then this is probably for you.

Here’s mine and you can see the plate on the left site.

You need the following hardware:

  • An inductive sensor like the LJ12A3-4-Z/BX
    It should work between 6V and 36V so you dont’t need a power converter. As far as I saw the most of these sensors work inside this voltage range.

  • A Shelly Uni
    There is only one so far.

  • A power adapter
    Can be an old one as long as it provides something between 12V and 32V.
    This is what the Shelly needs and the sensor can handle.
    I got mine from an old electronic cat door which my predecessor had installed in the basement :slight_smile:

  • Something to fixate your sensor on top of the watermeter
    I was lucky and had an unused water pipe cap lying around which fitted perfectly after I cut out some pices. In German it’s called Muffenstopfen and looks like that:
    ht rohr muffenstopfen - Google Search
    This was simply perfect as it holds the sensor and has enough room to put the Shelly and all the cables inside.

Thats more or less everything besides some tools.

I do not explain every step of my construction now because everone will find a different way to mount the sensor onto the watermeter anyway. But maybe you’re lucky and you can also use a Muffenstopfen (love this word :smiley: )

Place the Sensor
Firstly you need to find the right place where the sensor should sit. It has to be on top of the rotating metal plate but not in the center. The plate should move under the sensor and then again away from it. This produces a voltage drop or rise depending on your sensor. Both will work. I then drilled a hole into the cap and fixated the sensor with the two nuts. The sensor needs to stand directly ontop of the plastic or glass. Mine has a range of 4mm to detect an object. If it’s further away it wont work. Two other holes let the sensor and the power cable in.

Place the Shelly
I then prepared the Shelly UNI. We don’t need the 4 cables for the switches so I desoldered them. From the other bunch we only need the red, black and white cable. I separeted them from the others and isolated the rest with tape. There’s a hole to fixate the Shelly somewhere. I had some bolt and a screw lying around which fortunately fitted perfectly. So I just glued the bolt to the cap and screwed the shelly onto it. I’m sure you will also find a practical solution. And don’t forget the wifi antenna which needs to go somewhere. Mine is inside with all the cables and I have enough connectivity.

Wires
Now you only need to bring in the sensor and power cable and wire everything together. You can solder it or crimp it as you like. The wiring itself is very easy. The sensor has 3 cables. Mine had Brown, Blue and Black. Brown needs positive, Blue negative and Black gives us the voltage depending on how much of the metal plate is under the sensor. The Shelly has Red, Black and White. So Brown goes together with Red to the positive of the power adapter. Blue goes with Black to the negative. Then there is the Shelly White and the sensor Black which needs to be connected. That’s all. No step down module or separate 5V power adapters for Arduinos.

Test
If everything is correct and you plug in the power then the Shelly should boot and a red light flashes. There’s also a light ontop of the sensor, at least mine has one, which shines red if some metal is in front of the sensor. That’s also how you can test it.

Integrate
The Shelly Uni is perfectly integrated into Home Assistant, you can just add it with the integration. I don’t use the cloud so I had to setup the wifi and CoIOT first. Also on the Shelly interface, set the ADC RANGE under Settings depending on your power adapter. It has to be 12V for a 12V adapter or 30V if you use 24V or higher.
After the Shelly is added you get an entity called ADC which we gonna use to detect the rotating metal plate.

Now you need some YAML, this is what I came up with:

automation:
  - alias: Generate Watermeter Pulse
    description: "Takes the ADC reading from the Shelly Uni and converts it to a pulse if the value is above 5V."
    trigger:
      - platform: numeric_state
        entity_id: sensor.basement_watermeter_reading
        above: 5
    action:
      - service: input_boolean.toggle
        target:
          entity_id: input_boolean.basement_watermeter_pulse
      - delay:
          milliseconds: 100
      - service: input_boolean.toggle
        target:
          entity_id: input_boolean.basement_watermeter_pulse
    mode: single

# Stores the generated pulses.
input_boolean:
  basement_watermeter_pulse:
    name: Watermeter Pulse
    icon: mdi:pulse

sensor:
  # Counts the pulses of the current hour.
  - platform: history_stats
    name: "Basement Watermeter Pulses Hourly"
    entity_id: input_boolean.basement_watermeter_pulse
    state: "on"
    type: count
    start: "{{now().replace(minute=0).replace(second=0)}}"
    end: "{{now()}}"

template:
  # Converts the unitless count to liters.
  - sensor:
      - name: "Basement Watermeter Liters Hourly"
        unique_id: "712b918e-ee27-4e93-91cd-dada5fbd91e7"
        unit_of_measurement: L
        device_class: water
        state_class: total_increasing
        state: >
          {{ states('sensor.basement_watermeter_pulses_hourly')|float(0) }}

I packed everything inside a package to group it together but you can also create the automation and the input_boolean helper over the wizard. The two sensors although you have to create manually.

Explanation
So now the following happens. The metal plate rotates under the sensor for every liter of water measured by the watermeter. This rises or drops the sensor voltage between 0V and 12V or 0V and 32V or whatever voltage your power adapter has. The automation triggers if the voltage is over about half of the max. Maybe you can use 0 or the actual max value but I thought maybe the sensor reading was to slow and then skips some liters. My 12V power adapter works fine with 5V as trigger. The automation sets an input_boolean on and after 100ms off again. This gives us a pulse for every liter. The reason for this is that there is a 50/50 chance that the metal plate stops right under the sensor and it stays on. This wont work with the following history stats counter because then it counts the ON state every time again if a new time period starts. With pulses there is no such problem.
The history stats counter counts every pulse in the range of the current hour and then resets. The sensor template takes this unitless counts and makes liters out of it. The liters can then be used to feed the Energy Dashboard.

That’s all. If everything works you won’t miss a liter of used water and even detect some in the middle of the night when the sneaky toilet suddenly refills it’s slowly dripping losses :slight_smile:

d.k

8 Likes

Hi, thnx for sharing your project. I am preparing to do it the same way with Shelly Uni cause i have one laying arround… One question i cant figure… I have 24V AC near the outside water meter from the automatic gate control box… So i plan to use it to power the Shelly Uni, but i´m not sure how to power the inductive sensor cause i see most of them use DC power? Can you please advise me… should i use ac / dc converter…
Thnx…

Hey
Yeah I think I would because the Shelly Uni needs a sensor which works between 6-36V DC. So an AC wouldn‘t work anyway. You could convert the 24V AC and then power the Sensor and the Uni both with DC.

Thanks to share, i am in the same configuration but need somme understanding .
My shelly uni gives this sensor.shellyuni_adc (as yours i suppose)
Could you tell me how you come to the >>> sensor.basement_watermeter_reading
or is it just a rename of it ?

forgot on thing , could you also share the settings of your shelly uni. eg what parms are defined (my adc range is 12v) and i currently use +12v of the shelly uni on the wire 1 of the sensor and orange wire of the shelly uni on the second wire of the sensor. the water meter as only 2 cables)
I may be wrong but i thought data entry was the way to get the info .
any help welcome

That’s right, I just renamed it so it honors my naming convention.

I also have 12V ADC range because of the power adapter. Other than that I’ve not configured anything special, just normal Shelly stuff.
Could you post the sensor model you use? If it works like a switch the orange cable could be right. But then you don’t need the ADC range, there is only on or off. In Home Assistant you should have a entity called Channel 1 input or something like that. It’s maybe disabled but when you enable it it should go on or off depending und your sensor.

Good guess . I tried your code and it works just fine

Exactly , i got an old power adapter for the 12v too. nothing happened with the orange cable , i tried the blank one and tada… the sensor started to record my sensor is the
[GIOANOLA - Compteur d’eau avec sortie contact sec pour comptage d’impulsion (1 imp/litre) - 3/4p]
image
Once again thank you for posting.
just a recap for those who may be interrested, i connected the shelly uni black and red to the power adapter, the the red and the white to the cable of the sensor

1 Like

The setup works great with a Shelly Plus Uni, which has the advantage of using the ‘COUNT IN’ signal on Pin 8 to read impulses from an inductive sensor.

For my Sensus 620 water meter, I used a 3D-printed adapter (see here) to install it.


(Not the cleanest, but a quick setup. I also added a temperature sensor!)


EDIT:
By the way, I just remembered that I had to patch the Shelly integration, since the COUNT IN feature is only supported in the dev version of the integration (see here).

--- /usr/src/homeassistant/homeassistant/components/shelly/sensor.py.original
+++ /usr/src/homeassistant/homeassistant/components/shelly/sensor.py
@@ -960,6 +960,30 @@
         native_unit_of_measurement=PERCENTAGE,
         state_class=SensorStateClass.MEASUREMENT,
     ),
+    "analoginput_xpercent": RpcSensorDescription(
+        key="input",
+        sub_key="xpercent",
+        name="Analog value",
+    ),
+    "pulse_counter": RpcSensorDescription(
+        key="input",
+        sub_key="counts",
+        name="Pulse counter",
+        native_unit_of_measurement="pulse",
+        state_class=SensorStateClass.TOTAL,
+        value=lambda status, _: status["total"],
+        removal_condition=lambda config, _status, key: (config[key]["enable"] is False),
+    ),
+    "counter_value": RpcSensorDescription(
+        key="input",
+        sub_key="counts",
+        name="Counter value",
+        value=lambda status, _: status["xtotal"],
+        removal_condition=lambda config, status, key: (
+            config[key]["enable"] is False
+            or status[key]["counts"].get("xtotal") is None
+        ),
+    ),
 }
1 Like

oh the new one has a counter!? that’s nice. what sensor do you use that gives you directly pulses?