Reading a Kapadokya Guesthouse Water Tank from Istanbul

这篇内容暂时只有 English 版本,以下是原文。

The guesthouse has eight rooms in Mustafakemalpaşa-ish hill country outside Ürgüp, and the water comes from a tank on the roof fed by a well pump. Twice last spring guests got cold showers because the pump had run dry and nobody noticed until someone complained at breakfast. The owner asked me, from Istanbul, whether I could make the tank tell him when it was low. No new hardware budget, so I used what was already there: a Raspberry Pi 3 that had been running a guest Wi-Fi captive portal, and a cheap float switch he had bought and never installed.

The float switch is a mechanical reed contact, normally open, that closes when the water drops below the arm’s set point. I wired it between GPIO4 and ground with the Pi’s internal pull-up enabled. That is all the electronics. The part that took thought was not reading the pin but not lying about it.

import time, json, urllib.request
from gpiozero import Button

SENSOR = Button(4, pull_up=True, bounce_time=2.0)
STATE_FILE = "/var/lib/tank/state.json"

def read_stable(samples=5, gap=1.0):
    votes = [SENSOR.is_pressed for _ in range(samples)]
    return sum(votes) >= 4

low = read_stable()
state = {"low": low, "ts": int(time.time())}
with open(STATE_FILE, "w") as f:
    json.dump(state, f)

if low:
    msg = "tank low at %s" % time.strftime("%Y-%m-%d %H:%M")
    req = urllib.request.Request(
        "https://ntfy.sh/guesthouse-tank-alerts",
        data=msg.encode(), method="POST")
    urllib.request.urlopen(req, timeout=10)

A cron entry runs this every five minutes. The five-sample vote matters because the float arm swings in the tank when the pump cycles; a single read flaps. Two seconds of bounce time plus majority voting over roughly five seconds means a genuine drop is still caught within one cron interval, but sloshing does not page anyone.

Why push instead of poll? The Pi sits behind a guest router that gets a new WAN address every time the power blinks, which in that village is often. A local script that pushes outward survives that; a dashboard I query from Istanbul does not, unless I add a tunnel and then maintain it. The cost is that I am trusting a public push service with nothing sensitive and no delivery guarantee. If ntfy is down, the event sits in the state file and I find it the next time I look, which is not good enough for a real alarm but is fine for a water tank.

Where this breaks: the float switch itself. The first one corroded at the contact after about seven months because the tank breathes humid air and the switch was not sealed. I replaced it with a sealed reed type and added a rubber gasket at the cable entry. The second failure mode is the Pi’s SD card, which I have already had die once after a power cut took the filesystem with it. The state file is written every five minutes, so I moved it to a tmpfs and only log transitions to disk. That means a reboot forgets whether it was already low, so the first run after boot may send a duplicate alert. I decided duplicates are cheaper than missed alerts.

The open question: how do you handle the case where the sensor is fine but the pump is the thing failing? A low tank alarm fires after the fact. I keep wondering whether the more useful signal is pump run-time per fill cycle, and whether anyone here has measured that on a well pump without adding a flow meter.

0
赞同度 100% · 0 条评论 · 2 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。