Water meter monitoring
Hardware
Using a ESP32 with QMC5883L compass module. TBD
Accuracy
Quite accurate, each interval (max to min to max) from the water meter appears to be 32.5ml, this was confirmed over the course of a few days and about 1.6 m³ of water (about 49 thousand intervals).
ESPhome yaml
This is still a work in progress, and will need some customization for your specific installation (such as defining which magnetic axis to monitor and thresholds).
- watermeter.yaml
esphome: name: WaterMeter friendly_name: water project: name: "photonicsguy.Water Meter Sensor" version: "0.1.2" on_boot: priority: 300 then: - lambda: |- id(sample)=id(total_pulses); esp32: board: esp32dev framework: type: arduino version: recommended # Don't use VERBOSE or DEBUG logging when Hall sensor has fast updates logger: level: WARN # Enable Home Assistant API api: encryption: key: !secret ha_key ota: password: !secret ota_passwd wifi: ssid: !secret wifi_ssid password: !secret wifi_password i2c: - id: bus_a sda: 4 scl: 15 frequency: 800kHz scan: true text_sensor: - platform: wifi_info ip_address: name: IP Address entity_category: "diagnostic" switch: - platform: restart name: "Reboot" - platform: template name: "Reset usage" id: resetusage optimistic: false icon: mdi:water-sync restore_mode: ALWAYS_OFF turn_on_action: then: - lambda: |- id(sample)=id(total_pulses); id(wateruse).publish_state((id(total_pulses)-id(sample)) * 0.01 * id(offset)); number: - platform: template name: "Threshold Minimum" id: minVal optimistic: true restore_value: true entity_category: config initial_value: 70 min_value: -200 max_value: 200 step: 5 unit_of_measurement: "µT" set_action: - lambda: id(pulse).set_lower_threshold(x); - platform: template name: "Threshold Maximum" id: maxVal optimistic: true restore_value: true entity_category: config initial_value: 90 min_value: -200 max_value: 200 unit_of_measurement: "µT" step: 5 set_action: - lambda: id(pulse).set_upper_threshold(x); - platform: template name: "Threshold Minimum alt" id: minVal2 optimistic: true restore_value: true entity_category: config initial_value: 40 min_value: -200 max_value: 200 step: 5 unit_of_measurement: "µT" set_action: - lambda: id(pulse2).set_lower_threshold(x); - platform: template name: "Threshold Maximum alt" id: maxVal2 optimistic: true restore_value: true entity_category: config initial_value: 60 min_value: -200 max_value: 200 unit_of_measurement: "µT" step: 5 set_action: - lambda: id(pulse2).set_upper_threshold(x); globals: - id: total_pulses type: int restore_value: True initial_value: '0' - id: sample type: int restore_value: False initial_value: '0' - id: offset type: float restore_value: False initial_value: '3.25' sensor: - platform: wifi_signal name: "RSSI" id: rssi_db filters: - delta: 2 - throttle: 300s entity_category: "diagnostic" - platform: qmc5883l i2c_id: bus_a address: 0x0D field_strength_x: name: "Field Strength X" id: fsx internal: true range: 200uT oversampling: 64x update_interval: 0.005s - platform: template name: "Water Consumption new" id: waterconsumption3 device_class: water unit_of_measurement: "m³" state_class: "total_increasing" icon: "mdi:water" accuracy_decimals: 4 lambda: |- return id(total_pulses) * 0.00001 * id(offset); - platform: template name: "Water usage" id: wateruse device_class: water unit_of_measurement: "L" state_class: "measurement" icon: "mdi:hand-water" accuracy_decimals: 2 lambda: |- return (id(total_pulses)-id(sample)) * 0.01 * id(offset); - platform: template name: "Counter" unit_of_measurement: pulses id: watercounter lambda: |- return id(total_pulses); binary_sensor: - platform: analog_threshold name: "Pulse" # Cover closed id: pulse #internal: True sensor_id: fsx threshold: upper: 90 lower: 80 on_state: then: - lambda: |- id(total_pulses) += 1; id(waterconsumption3).publish_state(id(total_pulses) * 0.00001 * id(offset)); id(wateruse).publish_state((id(total_pulses)-id(sample)) * 0.01 * id(offset)); id(watercounter).publish_state(id(total_pulses)); - platform: analog_threshold name: "Pulse2" #Cover open id: pulse2 sensor_id: fsx threshold: upper: 60 lower: 40 on_state: then: - lambda: |- id(total_pulses) += 1; id(waterconsumption3).publish_state(id(total_pulses) * 0.00001 * id(offset)); id(wateruse).publish_state((id(total_pulses)-id(sample)) * 0.01 * id(offset)); id(watercounter).publish_state(id(total_pulses));