Driveway Alarm Hack

I did this a while back, but I thought I would share. I initially bought a 433Mhz driveway alarm from Harbor Freight with the intention of using the rpi-rf module (I use it already for all sorts of 433 Mhz sensors)

https://www.harborfreight.com/wireless-security-alert-system-62447.html

The rf-sniffer could not decipher any codes coming from this device so I decided to hack an esp8266 into the receiver unit and when the alarm bell goes off (something in the driveway) it sends a high signal to an input on the ESP8266 which then publishes a message to my MQTT broker and then HA can have automations against it. It works quite well. Here is the Arduino code (which I cobbled together using code from various other people–so credit for a lot of the code is not mine). And I used this code on some door sensors too (that is why the odd variable names)


#include <ESP8266WiFi.h>      //ESP library from http://github.com/esp8266/Arduino
#include <ESP8266mDNS.h>
#include <PubSubClient.h>      // MQTT library from http://github.com/Imroy/pubsubclient
#include <ArduinoOTA.h>  //upload code over the network!
#include <WiFiUdp.h>

#define mqtt_server "192.168.1.185"


/**************************** FOR OTA **************************************************/
#define SENSORNAME "driveway" //change this to whatever you want to call your device
#define OTApassword "secret" //the password you will need to enter to upload remotely via the ArduinoIDE
//int OTAport = 8266;

const char *ssid =   "wifissid";      // cannot be longer than 32 characters!
const char *pass =   "password";      //


//long previousMillis = 0;      // Timer loop from http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

int previousdoor_reading = HIGH;

//IPAddress server( 192, 168, 1, 185 );    // Update these with values suitable for your network.
IPAddress server(192, 168, 1, 185);
WiFiClient espClient;
PubSubClient mqttClient(espClient);

void setup(){
  // Setup console
  Serial.begin(115200);
  mqttClient.setServer(server, 1883);
//  mqttClient.setCallback(callback);
  pinMode(5, INPUT_PULLUP);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  //int retries = 0;
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

 //OTA SETUP
 // ArduinoOTA.setPort(OTAport);
  // Hostname defaults to esp8266-[ChipID]
  ArduinoOTA.setHostname("driveway");

  // No authentication by default
  //ArduinoOTA.setPassword((const char *)OTApassword);
//mqttClient.connect("garage");
ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}
void reconnect() {
  // Loop until we're reconnected
  while (!mqttClient.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (mqttClient.connect("driveway")) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop(){
  ArduinoOTA.handle();
  if (!mqttClient.connected()) {
    reconnect();
  }
  mqttClient.loop();
  int door_reading = digitalRead(5);
  // Serial.println(reading);
  if (previousdoor_reading == HIGH && door_reading == LOW ) {
    // counter++;
    mqttClient.publish("driveway/motion", "detected"); 
  } 
  if (previousdoor_reading == HIGH && door_reading == LOW ) {
    // counter++;
    mqttClient.publish("driveway/motion", "none");
  }
    delay(1000);
 
  previousdoor_reading = door_reading;
}
2 Likes

Nice project. Have you looked at Tzapu wiFi manager ( https://github.com/tzapu/WiFiManager ) to avoid hardcoding the credentials, mqtt parameters in the ESP sketch?

1 Like

I have not seen this. Pretty cool. I do use a lot of ESP8266 devices on my network. Thanks for the link.

Just purchased one of these HF motion sensor systems today with the intention of adding WiFi and found your post here. Please consider recording a basic, tutorial video for YouTube and share the knowledge with those of us who don’t understand how to apply the code for a project like this.
Cheers

I have one of this in my driveway and I am just starting to mess with HA.
I have a Sonoff RF Bridge on its way hopefully it will be able to detect the signal from it!

Have anyone tried this sensor with Sonoff RF Bridge?

@chils41 Were you able to get teh Sonoff RF Bridge working?

I can confirm these work with the sonoff RF bridge flashed with Tasmota. Just need to make an automation to reset the state since they are only one code transmitters. The range is actual better than my cheap Alixpress 433 mhz motion sensors and they’ve survived outside for well over a year in the Florida sun.

1 Like

FWIW, I got a different model of driveway alarm working. The brand is either hosmart or emacros.

I used rtl_433. See the guidelines for Contributing on the github, which give a few tips for reverse engineering devices that aren’t yet supported. In short, you can capture messages like this:

rtl_433 -S unknown

Then you can have it guess a decoding with

rtl_433 -r [the file name of the captured message] -A

which will give you a line like “Use a flex decoder with -X […]”.

In my case, I got:

-X n=name,m=FSK_PWM,s=412,l=1240,r=14224,g=1252,t=328,y=0

And then you can run rtl_433 like this to decode packets:

rtl_433 -X n=name,m=FSK_PWM,s=412,l=1240,r=14224,g=1252,t=328,y=0

The data for the hosmart, only one byte ever changes as far as I can tell - that gives you the channel number (there is a switch to choose A, B, or C on the device).

This device has no “house code” which would be nice to prevent you receiving alerts if your neighbor has the same system - so that’s a shortcoming. (They should have done it like those Oregon Scientific weather devices, which have a “house code” distinct from the channel, which I believe changes randomly when you press the reset button (?), to stop conflicting with your neighbor. That adds a step for the user, of “syncing” the base to recognize the house code of the sensors, but I would rather have that.)

There is also a “battery OK” signal, but I haven’t figured out what bit it is.

1 Like

I’m having more success following the discussion on GitHub for the rtl_433 project:

Thanks for this tip @mepster88 . I see a similar flex suggestion from rtl_433 to you but sadly when using this and my InkBird ITH-20R temperature sensors transmit they seem to clash. There is no motion at the driveway sensor during this capture:

rtl_433 -X 'n=hosmart,m=FSK_PWM,s=412,l=1240,r=14184,g=1250,t=320,y=12' -A
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2022-02-14 19:02:27
model     : hossmart     count     : 5             num_rows  : 5             rows      : 
len       : 612          data      : fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 
len       : 8            data      : ff, 
len       : 2            data      : c, 
len       : 10           data      : ffc, 
len       : 0            data      : 
codes     : {612}fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, {8}ff, {2}c, {10}ffc, {0}
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2022-02-14 19:02:27
model     : Inkbird ITH-20R                        id        : 32598
Battery   : 100          sensor_num: 2             Integrity : CRC
Temperature: 21.2 C      Temperature2: 27.6 C      Humidity  : 51.7 %

Any pointers would be appreciated!
Thanks a lot
Ian

1 Like

This is the output when motion detected:

time      : 2022-02-14 19:35:06
model     : hosmart      count     : 6             num_rows  : 6             rows      : 
len       : 25           data      : 3a46de8, 
len       : 25           data      : 3a46de8, 
len       : 25           data      : 3a46de8, 
len       : 25           data      : 455aae8, 
len       : 25           data      : 455aae8, 
len       : 25           data      : 455aae8
codes     : {25}3a46de8, {25}3a46de8, {25}3a46de8, {25}455aae8, {25}455aae8, {25}455aae8
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
1 Like

OK folks sorry for the multiple postings but think I figured it out - I wrote a .conf file like this and got the output I needed which is great! I need to do some more testing but so far so good. Not quite sure why the flex decoder was picking up signals from the InkBird but hey ho.

decoder {
    name=hosmart,
    modulation=FSK_PWM,
    short=412,
    long=1236,
    reset=14196,
    gap=1248,
    tolerance=330,
    sync=0,
    match={25}0x3a46de8,
    bits=25,
    unique,
}
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2022-02-14 20:27:48
model     : hosmart      count     : 3             num_rows  : 6             len       : 25            data      : 3a46de8
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
1 Like

I think I reversed engineered this one. Need to confirm battery status bit (waiting for it to deplete) but it works reliably with 2 different Hosmart HS002 sensors (branded as eMacros)
Decoder is -X "n=Hosmart-HS002,m=FSK_PWM,s=416,l=1248,r=14240,g=1252,t=332,y=0,bits=25,invert,repeats>=3,unique,get=id:@0:{12},get=model_id:@12:{8},get=channel:@20:{4},get=battery_ok:@24:{1}:[0:1 1:0]"

This flows to MQTT.

Sample HA config:

mqtt:
  binary_sensor:
    - name: Driveway Motion
      device_class: motion
      value_template: '{{ "ON" if value_json.id else "OFF" }}'
      state_topic: rtl_433/Hosmart-HS002/123
      off_delay: 300
      expire_after: 432000
    - name: Driveway Motion Battery
      device_class: battery
      value_template: '{{ value_json.battery_ok }}'
      payload_on: '0'
      payload_off: '1'
      state_topic: rtl_433/Hosmart-HS002/123
      expire_after: 432000
2 Likes

Should we be concerned that our configs are all a bit different?

I can’t seem to sync my eMacros sensors to either of those configs. Using the discovery process (credit/props @mepster88 post from Sep '20), the best I can do is with this one:

-X 'n=eMacros,m=FSK_PWM,s=408,l=1236,r=14172,g=1256,t=331,y=0'

Even with this one, I seem to have a slight variation in decodes - most often I get something fairly consistent like this (just a difference in a count of 6 vs 7 messages)

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2023-01-03 10:47:30
model     : eMacros      count     : 7             num_rows  : 7             rows      :
len       : 25           data      : 60fb9b8,
len       : 25           data      : 60fb9b8,
len       : 25           data      : 60fb9b8,
len       : 25           data      : 455aab8,
len       : 25           data      : 455aab8,
len       : 25           data      : 455aab8,
len       : 0            data      :
codes     : {25}60fb9b8, {25}60fb9b8, {25}60fb9b8, {25}455aab8, {25}455aab8, {25}455aab8, {0}
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time      : 2023-01-03 10:47:44
model     : eMacros      count     : 6             num_rows  : 6             rows      :
len       : 25           data      : 60fb9b8,
len       : 25           data      : 60fb9b8,
len       : 25           data      : 60fb9b8,
len       : 25           data      : 455aab8,
len       : 25           data      : 455aab8,
len       : 25           data      : 455aab8
codes     : {25}60fb9b8, {25}60fb9b8, {25}60fb9b8, {25}455aab8, {25}455aab8, {25}455aab8
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

But sometimes it goes off the rails (I need to dig deeper into how the hardware works and how to leverage the software to get a better decode).

In any case… Wouldn’t different configs for similar hardware get in the way of developing a common solution that works for everyone?

@sbalabanov - I learned a ton from this example (thanks!), but I haven’t been able to get my 2 sensors to sync with this config (still working on a reliable config myself).

Did you ever find the battery depleted bit? I’ve tried to deplete my sensors by covering the solar panels, but have never seen the receiver illuminate the “Low Battery” LED. It may be an unimplemented feature, or the battery capacity could be “overkill” for this application (I might not have enough patience for it to deplete).

I came up with almost the same config, but had the id being the first 16 bits for lack of additional context. How did you make the determination that the id was the first 12 bits and model was the next 8? Do you have more than one transmitter? edit: I see above that you do have more than one transmitter. nice. I’ll submit a config PR incorporating your analysis if you haven’t already.