I wanted to share my open source, DIY, very low powered windows/door/mailbox/“whatever open and close” sensor (can also be used for other things).
Note1:
I have a active question on electronics.stackexchange were I try to get some help improving this circuit, but I’m not sure there is much to improve, but if you see something please give a comment here or there. You can also check that post for more in depth understanding of the circuit.
Link: https://electronics.stackexchange.com/questions/519758/improving-edge-detector-with-latching-circuit-for-esp8266/519912#519912
Note2:
Currently I’m using a Lipo battery directly connected to the esp8266-12e. By testing I see everything is ok, but at a full charge (4.2Vdc) it is more than recommended for the esp8266 (3.6Vdc). This might work for a long time, or it can break down. I have seen many discussion about this but none that have had problems when only going to 4.2Vdc (5Vdc yes, that is a problem).
You can buy your own circuit, almost 100% soldered, only missing the esp8266-12e and connectors, from jlcpcb. Link: https://easyeda.com/jakibsgaard/low-powered-rising-and-falling-power-on-circuit
I bought 30pcs for 18$ with parts and assembly (again not with the esp8266-12e, connectors and reed switch).
The device is quite small, 20mm wide, 31mm long and about 10mm thick. This is without the enclosure and reed switch.
The power consumption is quite good, since I’m not using the esp8266 deep sleep (~20uA), but with a latching circuit I get ~3uA in closed switch state and ~0.4uA in open switch state. On a 200mAh battery I get over 2 years calculated operating time, this includes 15% overhead in capacity.
You can use a reed switch or some other type of switch. But my circuit is not meant for a momentary switch, like a vibration sensor.
Picture of one side of the circuit:
Picture of the side where the esp8266-12f would be soldered:
Picture of my crudely put together for testing and power measurement:
PS.I have updated my schematics on easyeda so the resistor I have connected is not necessary.
This is the code I have flash on my esp8266-12e. In home assistant I have added a long lived token and a input_boolean.
code
// last tested on Arduino IDE 2.2.1 with esp8266 v3.1.2 (http://arduino.esp8266.com/stable/package_esp8266com_index.json)
// all libraries are included when you install the esp8266 board
// check this link to add unique id to your entity: https://community.home-assistant.io/t/ha-core-rest-api-post-unique-id-for-entities/216122/4
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#include <algorithm>
#include <string>
#include "secrets.h" // add this file in the same location as this ino sketch, in the file you write #define SECRET_SSID "yourSSID" etc
String ssid = SECRET_SSID;
String password = SECRET_PASS;
String haIP = SECRET_HAIP;
String apiKey = SECRET_HAKey;
// variables needed later in the code
String payload;
String macAddress;
// the name of the device on the network and in home assistant
String hostName = "esp12_reedsw"; // change this to your liking (uniqueness is added later in the code)
// PS!! A very long name could cause issues, I haven't found any good source that describes this, just be aware if you get a compile error or missing some characters in HA or on your network controller.
// IPaddress if static is needed/wanted, will speed things up with wifi connection
IPAddress ip(192,168,1,154); // change these, remember commas, not period between numbers
IPAddress gw(192,168,1,1);
IPAddress dns(192,168,1,2);
IPAddress subnet(255,255,255,0);
int sensorPin = 12; // ping to check if open or closed
int enablePin = 5; // pin to keep the power on until finnished
int sensor; // used to check if the switch is open or closed
int code; // used to check the http return code
//Enable getvcc
ADC_MODE(ADC_VCC);
void setup() {
//Enable power signal as soon as possible
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, HIGH);
pinMode(sensorPin,INPUT);
// Serial.begin(115200);
// Serial.println();
//Connect to WIFI
WiFi.mode(WIFI_STA);
// create a unique hostName from the last 3 octets of the mac address
macAddress = WiFi.macAddress();
macAddress = macAddress.substring(8);
std::replace( macAddress.begin(), macAddress.end(), ':', '_');
hostName = hostName + macAddress;
WiFi.hostname(hostName);
// uncomment to set static ip
//WiFi.config(ip, subnet, gw, dns);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password);
// Serial.println("WiFi failed, retrying.");
}
HTTPClient http;
WiFiClient client;
//Check if update is needed
http.begin(client, "http://" + haIP + ":8123/api/states/input_boolean.ota_update");
http.addHeader("Authorization", "Bearer "+apiKey);
http.addHeader("Content-Type", "application/json");
int httpCode = http.GET();
// Serial.println(httpCode);
if (httpCode > 0){
payload = http.getString();
// Serial.println(payload);
}
http.end();
if (payload.indexOf("\"state\":\"on\"") >= 0){
// go to http://deviceIP/update and update the firmware
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
MDNS.begin(hostName);
httpUpdater.setup(&httpServer);
httpServer.begin();
MDNS.addService("http", "tcp", 80);
//Turn off the update toggle
http.begin(client, "http://" + haIP + ":8123/api/services/input_boolean/turn_off");
http.addHeader("Authorization", "Bearer "+apiKey);
http.addHeader("Content-Type", "application/json");
http.POST("{\"entity_id\": \"input_boolean.ota_update\"}");
http.writeToStream(&Serial);
http.end();
//Handle the update, continue forever, after the update it will reboot, first time you will ever see me use while(true) and only since there is no state to actually check ;)
while (true){
httpServer.handleClient();
MDNS.update();
delay(10000);
}
}
//Get the battery voltage and send to HA
float vcc = ESP.getVcc();
vcc = vcc / 1000;
String svcc = String(vcc,3);
// Serial.println(svcc);
http.begin(client, "http://" + haIP + ":8123/api/states/sensor."+hostName+"_vcc_voltage");
http.addHeader("Authorization", "Bearer "+apiKey);
http.addHeader("Content-Type", "application/json");
code = http.POST("{\"state\": \""+svcc+"\", \"attributes\": {\"unit_of_measurement\": \"V\", \"icon\": \"mdi:flash\"}}");
// Serial.println(code);
http.writeToStream(&Serial);
// Serial.println();
http.end();
sensor = digitalRead(sensorPin);
//Send new data to HA
http.begin(client, "http://" + haIP + ":8123/api/states/sensor."+hostName+"_switch");
http.addHeader("Authorization", "Bearer "+apiKey);
http.addHeader("Content-Type", "application/json");
if (sensor == 0){
code = http.POST("{\"state\": \"on\", \"attributes\": {\"device_class\": \"opening\", \"icon\": \"mdi:electric-switch\"}}");
}
else if (sensor == 1) {
code = http.POST("{\"state\": \"off\", \"attributes\": {\"device_class\": \"opening\", \"icon\": \"mdi:electric-switch-closed\"}}");
}
// Serial.println(sensor);
// Serial.println(code);
http.writeToStream(&Serial);
// Serial.println();
payload = http.getString();
http.end();
//Turn of the latching circuit
digitalWrite(enablePin, LOW);
}
void loop() {
//Don't want to loop anything
}
Battery
I don’t want to post any links to ebay or aliexpress. But if you search for “200mah lipo” you will find a fitting battery. (They are probably not 200mah, just 140mah but the size is good for the box)
Update 21 June 2021
I have used this outside on my mailbox. Works quite good, the box has been almost 100% waterproof. Battery lasted around 6 months, but my mailbox has very poor wifi reception so the ESP uses sometimes up to a minute before transmitting the message.
Also the batteries I bought were not 200mah, only 140mah.
Box
I have modified the scad file from https://www.thingiverse.com/thing:1680291
From this I made this stl file: Box for esp8266 low powered window/door/mailbox sensor by johnarvid - Thingiverse
Enough room for the ESP and the battery.
Let me know if there are any questions and I will update this post.
Also if anyone want to use this in another low powered sensor and needs help, let me know and I can try to help. I would also like if you shared what you made with the community.