{"id":3516,"date":"2018-12-31T14:00:05","date_gmt":"2018-12-31T22:00:05","guid":{"rendered":"http:\/\/192.168.3.4\/?p=3516"},"modified":"2018-12-31T13:36:07","modified_gmt":"2018-12-31T21:36:07","slug":"monitoring-wireless-sensors","status":"publish","type":"post","link":"https:\/\/www.cloudacm.com\/?p=3516","title":{"rendered":"Monitoring Wireless Sensors"},"content":{"rendered":"<p>In this post we&#8217;ll cover how to monitor inexpensive wireless security sensors. There are two types of wireless sensors that we&#8217;ll be working with, door reed switches and passive infra red motion detectors. Each of these sensors transmit a broadcast radio message on the 433Mhz frequency. We&#8217;ll be expanding on earlier work with RTL_433. This post will cover how to identify a specific sensor and take appropriate action as needed, all that with a single bash script, let&#8217;s begin.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2018\/12\/Sensors.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-3517\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2018\/12\/Sensors-300x171.jpg\" alt=\"\" width=\"300\" height=\"171\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2018\/12\/Sensors-300x171.jpg 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2018\/12\/Sensors-768x437.jpg 768w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2018\/12\/Sensors-1024x583.jpg 1024w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2018\/12\/Sensors-475x270.jpg 475w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2018\/12\/Sensors.jpg 1160w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>The first thing will be the command to run the RTL_433 command. The path to the command is included in the bash script. CRON might be able to know the path, but it&#8217;s better to include it just in case. If the path isn&#8217;t known, type &#8220;whereis <command>&#8221; in a terminal window and it will display the path. RTL_433 will only need to monitor protocol 86 (&#8220;Wireless Smoke and Heat Detector GS 558&#8221;). The sensors we&#8217;ll be working with use this protocol exclusively, so we don&#8217;t need to bother detecting other devices. The output of the results will be formated in JSON, which contains all of the data on a single line. This will make it easier to parse and process the results. Since RTL_433 will be running in a loop condition, we want to interrupt it when a device is detected. Here is the command we&#8217;ll be using.<\/command><\/p>\n<pre>\/usr\/local\/bin\/rtl_433 -R 86 -F json:\"$JsonOutput\" -E<\/pre>\n<p>Since the above command is saving its output to a variable, we will define all of the variables at the beginning of the script.<\/p>\n<pre>DoorSensorEmail=\"\/home\/local\/Tasks\/DoorSensorEmail.txt\"\nJsonOutput=\"\/home\/local\/Tasks\/A_JsonOutput.txt\"\nMessage=\"\/home\/local\/Tasks\/A_Message.txt\"\nMessageOutside=\"\/home\/local\/Tasks\/A_MessageOutside.txt\"\n\nPIRCounter=\"\/home\/local\/Tasks\/BasementPIRCounter.txt\"\nCounter=$(cat \"$PIRCounter\")\n\nCactiHost='cacti.host.local'\nMate1FTPUser=''\nMate1FTPPass=''<\/pre>\n<p>This script will be called from CRON on bootup. I like to add a 2 minute delay before staring the rest of the script. This is done with this command.<\/p>\n<pre>sleep 120<\/pre>\n<p>After this period of time, the variables will be loaded into memory and our main loop function will begin by starting RTL_433. It will continue running RTL_433 until one of a sensor transmits. When data is decoded by RTL_433, that process will end and we will enter into a series of if else conditions.<\/p>\n<p>The first condition will check if the JSON output contains the identifier for a door sensor. If it doesn&#8217;t, it will continue on with the next check of another identifier and so on. However, if the JSON output does contain the identifier then a series of commands will execute.<\/p>\n<pre># Door Sensor ID = #####\nif grep -q ##### \"$JsonOutput\" ; then\n  echo \"Door Sensor Tripped\" &gt; $Message\n  # Process paths need to be included for CRON, use whereis \"command\" to find path.\n  cat \"$JsonOutput\" | \/usr\/bin\/logger -n syslog.host.local\n  rm \"$JsonOutput\"\n  # Process paths need to be included for CRON, use whereis \"command\" to find path.\n  \/usr\/sbin\/ssmtp admin@email.local &lt; \"$DoorSensorEmail\" &gt;\/dev\/null 2&gt;&amp;1<\/pre>\n<p>The above if condition will log the results to a syslog server named &#8220;syslog.host.local&#8221;. It then removes the JSON file for housekeeping. Finally, it sends an email notifying admin@email.local with a pre-formatted email message. Certain sensors merit immediate attention, while others can simply be logged to the syslog server.<\/p>\n<p>In the next if condition, we&#8217;ll log the JSON result to our syslog server. In addition to that, we&#8217;ll also tally a counter of the occurrence of the event. This value will then be uploaded to a FTP host that runs Cacti. I won&#8217;t cover the configuration of Cacti here, see earlier posts for that. If you have a number, Cacti will graph it.<\/p>\n<p><a href=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2018\/12\/CactiGraph.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3518\" src=\"http:\/\/192.168.3.4\/wp-content\/uploads\/2018\/12\/CactiGraph.png\" alt=\"\" width=\"595\" height=\"196\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2018\/12\/CactiGraph.png 595w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2018\/12\/CactiGraph-300x99.png 300w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/a><\/p>\n<pre># PIR Sensor ID = #####\nelif grep -q ##### \"$JsonOutput\" ; then\n  echo \"PIR Tripped\" &gt; $Message\n  # Process paths need to be included for CRON, use whereis \"command\" to find path.\n  cat \"$JsonOutput\" | \/usr\/bin\/logger -n syslog.host.local\n  Counter=$((Counter+1))\n  echo \"$Counter\" &gt; \"$PIRCounter\"\n\n  echo \"\n  verbose\n  open $CactiHost\n  user $Mate1FTPUser $Mate1FTPPass\n  cd Tasks\n  bin\n  put \"$PIRCounter\"\n  bye\n  \" | ftp -n \n\n  rm \"$JsonOutput\"<\/pre>\n<p>The last condition we&#8217;ll check is a catch all. If none of our devices were found in earlier conditions, then some unknown device transmitted data. This condition will take action based on that. Since I covered email, syslog, and cacti, we could use any or all of these in this catch all condition. At the conclusion of this, we return to the start of our loop and run the RTL_433 command again.<\/p>\n<p>Using a single bash script and some inexpensive hardware, we can monitor security sensors and take action based on their activity. Here is the complete code for the script, names have been changed to protect the innocent.<\/p>\n<pre>#!\/bin\/sh\n# \/home\/local\/Tasks\/DoorSensor.sh\n# Version 6.0 (12312018)\n# Purpose - Run SDR scan of Door and PIR Sensors, log readings to Syslog \/ Cacti, and send email alert\n# Author - Patrick Gilfeather - CloudACM\n\n\n# Delay the start of the script for 2 minutes so system has time to boot\nsleep 120\n\n# Set variables for work files\nDoorSensorEmail=\"\/home\/local\/Tasks\/DoorSensorEmail.txt\"\nJsonOutput=\"\/home\/local\/Tasks\/A_JsonOutput.txt\"\nMessage=\"\/home\/local\/Tasks\/A_Message.txt\"\nMessageOutside=\"\/home\/local\/Tasks\/A_MessageOutside.txt\"\n\nPIRCounter=\"\/home\/local\/Tasks\/BasementPIRCounter.txt\"\nCounter=$(cat \"$PIRCounter\")\n\nCactiHost='**********'\nMate1FTPUser='**********'\nMate1FTPPass='**********'\n\n\n# Run the process in a loop endlessly\nwhile :\ndo\n\n# Run RTL_433 process to detect door sensor with SDR and capture results to a JSON formatted file.\n# Process paths need to be included for CRON, use whereis \"command\" to find path.\n\/usr\/local\/bin\/rtl_433 -R 86 -F json:\"$JsonOutput\" -E \n\n# Door Sensor ID = **********\nif grep -q ********** \"$JsonOutput\" ; then\n  echo \"********** Sensor Tripped\" &gt; $Message\n  # Process paths need to be included for CRON, use whereis \"command\" to find path.\n  cat \"$JsonOutput\" | \/usr\/bin\/logger -n **********\n  rm \"$JsonOutput\"\n  # Process paths need to be included for CRON, use whereis \"command\" to find path.\n  \/usr\/sbin\/ssmtp ********** &lt; \"$DoorSensorEmail\" &gt;\/dev\/null 2&gt;&amp;1\n\n# Door Sensor ID = **********\nelif grep -q ********** \"$JsonOutput\" ; then\n  echo \"********** Sensor Tripped\" &gt; $Message\n  # Process paths need to be included for CRON, use whereis \"command\" to find path.\n  cat \"$JsonOutput\" | \/usr\/bin\/logger -n **********\n  rm \"$JsonOutput\"\n\n# PIR Sensor ID = **********\nelif grep -q ********** \"$JsonOutput\" ; then\n  echo \"********** Sensor Tripped\" &gt; $Message\n  # Process paths need to be included for CRON, use whereis \"command\" to find path.\n  cat \"$JsonOutput\" | \/usr\/bin\/logger -n **********\n  Counter=$((Counter+1))\n  echo \"$Counter\" &gt; \"$PIRCounter\"\n\n  echo \"\n  verbose\n  open $CactiHost\n  user $Mate1FTPUser $Mate1FTPPass\n  cd Tasks\n  bin\n  put \"$PIRCounter\"\n  bye\n  \" | ftp -n \n\n  rm \"$JsonOutput\"\n\n# Undefined Sensor\nelse\n  echo \"Foreign Sensor Tripped\" &gt;&gt; $MessageOutside\n  rm \"$JsonOutput\"\nfi\n\ndone\n\nexit<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In this post we&#8217;ll cover how to monitor inexpensive wireless security sensors. There are two types of wireless sensors that we&#8217;ll be working with, door reed switches and passive infra red motion detectors. Each of these sensors transmit a broadcast radio message on the 433Mhz frequency. We&#8217;ll be expanding on earlier work with RTL_433. This post will cover how to identify a specific sensor and take appropriate action as needed, all that with a single bash script, let&#8217;s begin. The&#8230;<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.cloudacm.com\/?p=3516\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-3516","post","type-post","status-publish","format-standard","hentry","category-rd"],"_links":{"self":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/3516","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3516"}],"version-history":[{"count":2,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/3516\/revisions"}],"predecessor-version":[{"id":3520,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/3516\/revisions\/3520"}],"wp:attachment":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3516"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3516"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3516"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}