Builders · 5 min read

How to make an ESP32, Arduino or Raspberry Pi ring your phone

To make an ESP32, an Arduino with Wi-Fi or a Raspberry Pi ring your phone, have it send one HTTP POST to the private link of an anything alarm in LFG Alarm. LFG Alarm is a social alarm clock for iPhone and Android, and lfg.gm in a desktop browser. The board notices something (a door left open, water on the floor, a print finished) and the request rings your phone like an alarm, plus the phones of anyone you shared the alarm with. No library, no account on the device, no key: the link is the whole integration.

Also called: esp32 phone alarm · raspberry pi phone notification · arduino webhook alarm · octoprint print done alarm

Get it on Google PlayDownload on the App Store

Before you start

  • The LFG Alarm app on your phone, signed in. Your board sends the request; the app is what rings.
  • A board on Wi-Fi: an ESP32, an Arduino with Wi-Fi (such as an Uno R4 WiFi or a Nano 33 IoT), or a Raspberry Pi. It needs to reach the internet over HTTPS.
  • An anything alarm. In the app, on Alarms, tap 🔮 Anything, pick a Cooldown, keep it private or share it with friends, and tap Arm it. Copy the link from the link card. More on how the link works: How to make any app, script or feed ring your phone.

The link looks like https://api.lfg.gm/horn/<token>. Treat it like a password: anyone who has it can ring the alarm. Keep it out of public repositories (a secrets.h or an environment variable you do not commit), and tap New URL on the alarm's page if it leaks.

The code

Each snippet sends an empty POST. LFG Alarm ignores the body, so there is nothing to format.

ESP32 with MicroPython

import network, urequests, time

RING_URL = "https://api.lfg.gm/horn/your-token"

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("your-wifi", "your-wifi-password")
while not wlan.isconnected():
    time.sleep(0.5)

def ring():
    r = urequests.post(RING_URL)
    print(r.status_code)  # 200 rang, 429 in quiet time, 409 switched off
    r.close()

ESP32 or Arduino with the Arduino core

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>

const char* RING_URL = "https://api.lfg.gm/horn/your-token";

void ring() {
  WiFiClientSecure client;
  client.setInsecure();  // skips certificate checks; fine for a ring
  HTTPClient http;
  http.begin(client, RING_URL);
  int code = http.POST("");
  Serial.println(code);
  http.end();
}

Call WiFi.begin(...) in setup() first. Other Wi-Fi boards use their own libraries (for example WiFiS3.h with ArduinoHttpClient on an Uno R4 WiFi); the request is the same empty POST over HTTPS.

Raspberry Pi with Python

import requests
requests.post("https://api.lfg.gm/horn/your-token", timeout=10)

Raspberry Pi with curl, for a shell script or a cron job:

curl -s -X POST "$LFG_RING_URL"

Call ring() when your condition turns true, not on every loop. After a ring, the alarm stays quiet for its Cooldown (1 minute to 1 hour), so a sensor that flickers rings once, but keeping your own "already rang" flag means fewer wasted requests.

Ideas that earn a ring

Door left open. Lena's back gate has a reed switch on an ESP32. If it stays open for ten minutes after 22:00, the board rings an alarm called "Gate open". A one hour Cooldown means one ring per night, not one per minute.

Fridge, freezer or leak. Theo's chest freezer in the garage has a temperature probe on a Pi. Above minus 10 degrees for half an hour, it rings him and his partner. A water sensor under the washing machine does the same for a leak, and rings the whole house.

3D print finished. Sam starts eight hour prints at night and wants to pull the part before it cools onto the bed. Two ways to do it with no code:

  • OctoPrint: the OctoPrint-Webhooks plugin calls a URL on events such as Print Done and Print Failed. Paste the link, set the HTTP method to POST, and tick the events you want.
  • Klipper with Moonraker: add a [notifier] section to moonraker.conf. Moonraker sends notifications through Apprise, whose jsons:// address makes an HTTPS POST:
[notifier print_done]
url: jsons://api.lfg.gm/horn/your-token
events: complete, error

Restart Moonraker after editing. Check the current Moonraker and Apprise docs if your version differs.

Plant dry. Priya's greenhouse has a soil moisture sensor on an ESP32. A dry plant is rarely a 3am emergency, so she makes the alarm private and lets the board ring only between 08:00 and 20:00. For things that can wait, a ring is too much; use it for the ones that cannot.

Your robot can wake you. Jun's rover patrols the shed on a Pi. When its battery runs low or it gets stuck, it rings "Rover needs you". A robot that can ring a phone is also a fine alarm clock: his rings him at sunrise on build days.

Running Home Assistant already?

If your sensors already report to Home Assistant, let it do the ringing with a rest_command instead of adding code to each board. See Ring your phone from Home Assistant.

How it rings

On Android an anything alarm rings full screen like an alarm. On iPhone it arrives as a time-sensitive alert with the alarm's sound, so the ringer should be on. Everyone who joined the alarm is rung at once. LFG Alarm is not a monitored safety service: keep real smoke and CO alarms, and emergency numbers.

If it does not work

  • Status 200 but no ring: check the app is signed in on your phone, and on iPhone that the ringer is on.
  • Status 429: the alarm is in its Cooldown after a recent ring. Wait, or use a shorter Cooldown while testing.
  • Status 409: the alarm is switched off. Turn it on in the app.
  • Status 404: the token is wrong, or you made a New URL and the board still has the old one.
  • A negative status or a TLS error on an ESP32: the board could not open the HTTPS connection. Check Wi-Fi, the clock (some TLS setups need the time set), and that you used WiFiClientSecure.
  • Nothing happens when you open the link in a browser: that is a GET, which does nothing. Use POST, or Test fire in the app.

Learn more

Sources and further reading

LFG Alarm is not affiliated with Espressif, Arduino, Raspberry Pi, OctoPrint, Klipper, Moonraker or Apprise.

questions people ask
Does the board need my LFG Alarm sign-in?

No. Only the link. It never sees your account.

Can one sensor ring several people?

Yes. Share the anything alarm with them as a friends alarm. Anything alarms are private or friends, never public.

Can I tell which sensor rang?

Give each sensor its own anything alarm with a clear name and its own sound. Whatever you put in the request body is not shown.

keep exploring

One use case opens another.

Never miss the moment.

Free on Android and iPhone.

Get it on Google PlayDownload on the App Store