Nishi Daak: an Arduino UNO Q that calls your name twice when you come home late (local Gemma, no cloud) A developer built Nishi Daak, an Arduino UNO Q project that detects a resident's return via a Bluetooth presence scanner and then spells the person's name twice on an LED matrix, mimicking the Bengali Nishi spirit that calls only twice. The board runs Gemma 3 1B locally through llama.cpp's llama-server as a systemd service, generating short folk-horror tales at roughly 4.7 tokens per second with no cloud, accounts or API keys, and logs each event with timings in a web page served from the board on port 7000. This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine https://dev.to/challenges/hacktoberfest-week4-2026-10-26 In Bengal they say that late at night, someone may call your name from outside in the voice of a person you love. Do not answer. Not the first time, not the second. The Nishi নিশি, "the night one" only ever calls twice, and whoever answers follows it into the dark and is never seen again. A real person, the story goes, will always call a third time. Nishi Daak "the night call" puts that spirit on a shelf. It is an Arduino UNO Q that: No cloud, no accounts, no API keys. Nothing leaves the house. The night call: the name, letter by letter, twice. Never a third time. 🎬 Watch the 74-second demo video Google Drive https://drive.google.com/file/d/1u8dVJ5TkOvXM-yOYtAKwM5j3VuGyJZYs/view?usp=sharing The human scenes in the video are free stock footage from Pexels a Kolkata evening, a walk home, a door at night . The board's behaviour, the timings and the numbers come from the real build. The tale typed out in the video is the few-shot example from the prompt; real ones from the board's night log are below. This is the board's own web page, screenshotted live from the UNO Q on my home Wi-Fi. The eyes and the "2" show the spirit energy 5 Bluetooth devices nearby , the night log holds real tales Gemma wrote on the board, and the footer is the board's health check: presence ok, Gemma 3 1B ok, last reply 15 s at 4.7 tokens/s. Three real entries from night log.json , written by Gemma 3 1B on the board: A single, crimson leaf drifted down the path, landing softly beside his feet. It mirrored a forgotten melody, a scent of rain and old roses. The Nishi smiles, a fleeting glimmer in the gloom. 10.0 s, 4.7 tokens/s A single jasmine flower, bruised and drooping, drifted past the doorway. The rain smelled of dust and regret, a faint, silver light reflecting on it. It paused, a single tear falling: a beautiful sorrow, like a forgotten song. 15.0 s, 4.7 tokens/s A single, pale moonbeam traced a path down the stairs. It watched a small, worn book open. A faded map, perhaps? The Nishi smiles, a fleeting shadow. 12.6 s, 4.7 tokens/s Each log entry records the time the board caught the phone. Tap the small red icon next to a name a flask for a test call, Wi-Fi for a real one and a card shows how it was caught, how long the person was away, and how fast Gemma wrote the tale. It calls your name twice. Never answer. An Arduino UNO Q that lives on a shelf and behaves like a Nishi, the night spirit of Bengali folklore. Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 4 "Ghost in the Machine" , Arduino category. In Bengal they say the Nishi comes late at night and calls your name in the voice of someone you love. It calls only twice. If you answer, you follow it into the dark and are never seen again. So if you hear your name at night, wait for the third call: a real person will always call a third time. | Part | File | Runs on | |---|---|---| | Matrix eyes and planchette | sketch/sketch.ino | the UNO Q's STM32 microcontroller | | App logic and web API | python/main.py | App Lab container on the Linux side | | Web page séance, night log | assets/index.html | App Lab web ui brick, port 7000 | | Presence scanner | host/presence service.py | Debian host, systemd | | The spirit's voice | llama.cpp llama-server + gemma-3-1b-it Q4 K M | Debian host, systemd | The UNO Q is two computers on one board: an STM32 microcontroller that drives the LED matrix, and a quad-core Linux side 4 GB of RAM on mine running Debian. App Lab connects them with a Bridge, so Python on the Linux side can call Bridge.call "spell", "TUSHAR TUSHAR" and the sketch fades the letters in and out on the matrix. llama.cpp builds on the board itself 47 minutes with -j2 ; 3.6 GB of RAM was enough . llama-server runs as a systemd service with Gemma 3 1B instruct, Q4 K M a 769 MB file : | What | Measured on the board | |---|---| | Generation speed | 4.7 to 4.9 tokens/s, 4 threads | | One séance answer | 8.5 to 9.1 s | | A night tale | 10 to 15 s | | First reply after a restart | 38.8 s it processes the persona once | A 1B model does not follow rules well, but it copies examples beautifully. So instead of a long list of "never do X", the prompt is a short persona plus two few-shot turns: one night tale and one dodged request for advice. A small tidy pass then strips markdown, emojis and any "as an AI" talk, and keeps at most three sentences, so whatever Gemma says always fits the spirit. If Gemma is down, the Nishi falls back to a canned line, so the call never fails. From the demo video: the moment the phone rejoins the home Wi-Fi and the board decides to call. The footage is stock and the times are illustrative; the decision logic is the real code below. The Nishi needs to know who came home, but I did not want cameras or an app on anyone's phone. Phones randomize their Bluetooth addresses constantly, so Bluetooth only feeds the "energy" count. Wi-Fi is different: Android and iOS keep one stable private MAC per network. A small root service on the host runs arp-scan on the home network and serves the result as JSON, and the app turns it into arrivals: python def arrivals macs, now : """ name, seconds away for known people whose phone reappeared after being away.""" back = for p in CFG "people" : mac = p "mac" .lower if mac not in macs: continue prev = last seen.get mac if prev is not None and now - prev away seconds : back.append p "name" , now - prev last seen mac = now first sighting after app start never counts as an arrival return back Then reality got in the way, twice. Locked phones vanish. A locked phone in Wi-Fi power save answers ARP after up to 2 seconds, and the default arp-scan gives up after 500 ms. With --retry=4 --timeout=1500 it went from 4 of 6 scans to 6 of 6. But during a 30-minute test with the phone locked on the table, it was seen once in 62 polls : a sleeping phone drops off Wi-Fi entirely, and no scan can see a disconnected phone. So the "away" threshold is 3 hours, not 20 minutes. Otherwise the Nishi would call my name every time my phone took a nap next to me. The board kept dying after about 15 hours. Ping worked, SSH refused, and only a power cycle brought it back. The journal of the dead boot had the answer: The maximum number of active connections for UID 0 has been reached max connections per user=256 . Each BLE scan used asyncio.run , a fresh event loop every time, and bleak opened a new system D-Bus connection for each loop without closing the old one. The connections piled up until root hit the limit, and from then on nothing running as root could talk to D-Bus. The fix is one event loop for every scan: BLE LOOP = asyncio.new event loop one loop for every scan: bleak keeps a D-Bus connection per loop def scan ble : found = BLE LOOP.run until complete BleakScanner.discover timeout=BLE SECONDS, return adv=True Before the fix, the service's socket count grew by one with every scan. After it, the count stayed flat at 6. This project only makes sense with an open model running locally: config.json , and nothing depends on a hosted model's mood that week. I built this with Claude Code as a pair, running the board over SSH from my laptop. The session below is a curated slice of the real build: the board setup, the locked-phone tests, the crash that turned out to be a D-Bus leak, and the night log's details card. The spookiest moment wasn't a ghost story. It was the board going silent after 15 hours: it still answered a ping, but nothing else. Something was still home, but it wouldn't come to the door. It turned out to be 256 D-Bus connections that never closed, which is a very modern kind of haunting. It is an old story, living in a small board, made out of open pieces anyone can read and change.