{"id":828,"date":"2021-02-18T17:18:45","date_gmt":"2021-02-18T16:18:45","guid":{"rendered":"https:\/\/www.chaosgeordend.nl\/wordpress\/?p=828"},"modified":"2022-03-11T09:39:08","modified_gmt":"2022-03-11T08:39:08","slug":"fanju-temperature-sensor-transmission-protocol","status":"publish","type":"post","link":"https:\/\/www.chaosgeordend.nl\/wordpress\/2021\/02\/18\/fanju-temperature-sensor-transmission-protocol\/","title":{"rendered":"Fanju Temperature sensor transmission protocol"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.chaosgeordend.nl\/mt-blog-cg\/images\/RF433TemperatureHumiditySensor.jpeg\" alt=\"Fanju temperature sensor\" \/><br \/>\nOn AliExpress you find cheap wireless (RF433) weather stations compatible with the &#8216;Fanju&#8217; weather station model FJ3378\/74\/79C\/65\/89 (according to AE). Following is the description of the data transmission protocol.<\/p>\n<p><!--more--><\/p>\n<p><strong>Details<\/strong><br \/>\nFirst the RF signal was analysed to determine the physical layer, OOK using e.g. Manchester encoding or pulse-width modulation.<\/p>\n<p>Helpful in reverse engineering a checksum is data differing one bit only. The sensor uses a rolling-code for its identification. That means, when powered off, c.q. batteries are changed, it generates a new id.<br \/>\nWith help of the ATTiny and a FET, the sensor is switched off and on for a few hours. The data sent was logged using a Python script. With the thus collected dataset the &#8216;attack&#8217; started.<\/p>\n<p>To make a long story short, the physical layer uses on-off keying and pulse-width modulation. Pulse durations (mark\/space in &micro;s) are as follows (pilight-debug timings between parenthesis):<br \/>\nSync: 1000\/1000 (936\/936),<br \/>\nHead: 600\/7900 (468\/7956)<br \/>\nData 0: 600\/1900 (468\/1872)<br \/>\nData 1: 600\/3800 (468\/3744-4212)<br \/>\nTail: 600\/16000 (468\/15912)<br \/>\nA message comprises 4xSYNC, 1xHEAD, 40xDATA 0\/1, 1xTAIL.<br \/>\nEvery \u00b180s the station transmits a burst of six messages.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.chaosgeordend.nl\/mt-blog-cg\/images\/RF433Sync.bmp\" alt=\"Physical layer\" \/><\/p>\n<p>The checksum turns out to be a Linear-feedback Shift Register (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Linear-feedback_shift_register\">LFSR<\/a>) hash with seed 0xC and feedback 0x9. The following script calculates the masks used for generating the checksum:<\/p>\n<p><a href=\"https:\/\/www.chaosgeordend.nl\/documents\/generate_hash_mask.py\">Generate_hash_mask.py<\/a>:<\/p>\n<pre>  mask = 0xC\r\n  print(\"0\")\r\n  for i in range(40):\r\n      lsb = (mask &amp; 0x1 == 0x1)\r\n      mask &gt;&gt;= 1\r\n      if lsb:\r\n          mask ^= 0x9\r\n      print(\"Mask: {:2x} {:04b}\".format(mask, mask))\r\n      if ((i + 1) % 4) == 0:\r\n          print(i + 1)\r\n<\/pre>\n<p><strong>Hardware used<\/strong><br \/>\nRaspberry Pi 4<br \/>\nRF 433MHz superheterodyne receiver *)<br \/>\nATTiny85 development board *)<br \/>\nA FET and two resistors lying around here<br \/>\n*) AliExpress<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.chaosgeordend.nl\/mt-blog-cg\/images\/RF433TkGui.png\" alt=\"Python Tk GUI\" \/><br \/>\n<strong>Software<\/strong><br \/>\nA <a href=\"https:\/\/www.chaosgeordend.nl\/documents\/analyse_rf433.py\">Python script<\/a> for data analysis and checksum verification<br \/>\nProtocol code has been submitted to the <a href=\"https:\/\/www.pilight.org\/\">PiLight<\/a> project and is under review. <a href=\"https:\/\/github.com\/pilight\/pilight\">PiLight GitHub repo<\/a><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.chaosgeordend.nl\/mt-blog-cg\/images\/RF433PilightWebserver.png\" alt=\"Pilight Webserver\" \/><br \/>\n<strong>Software<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>On AliExpress you find cheap wireless (RF433) weather stations compatible with the &#8216;Fanju&#8217; weather station model FJ3378\/74\/79C\/65\/89 (according to AE). Following is the description of the data transmission protocol.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43,31,49],"tags":[],"class_list":["post-828","post","type-post","status-publish","format-standard","hentry","category-arduino","category-electronicaelectronics","category-raspberrypi"],"_links":{"self":[{"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/posts\/828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/comments?post=828"}],"version-history":[{"count":33,"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/posts\/828\/revisions"}],"predecessor-version":[{"id":949,"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/posts\/828\/revisions\/949"}],"wp:attachment":[{"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/media?parent=828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/categories?post=828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.chaosgeordend.nl\/wordpress\/wp-json\/wp\/v2\/tags?post=828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}