Decode radio transmissions from devices on the ISM bands in OCaml
at main 154 lines 4.9 kB view raw
1(* Tests for rtl433 library *) 2 3module Util = Rtl433.Util 4module Bitbuffer = Rtl433.Bitbuffer 5module Data = Rtl433.Data 6module Device = Rtl433.Device 7 8(* Test CRC-8 calculation *) 9let test_crc8 () = 10 let data = Bytes.of_string "\x51\x12\x34\x56\x05\x32\x01\x00\x00\x05\x00\x00" in 11 let crc = Util.crc8 ~poly:0x31 ~init:0x00 data 12 in 12 Printf.printf "CRC-8 of test data: 0x%02x\n" crc; 13 assert (crc >= 0 && crc <= 255) 14 15(* Test add_bytes checksum *) 16let test_add_bytes () = 17 let data = Bytes.of_string "\x01\x02\x03\x04\x05" in 18 let sum = Util.add_bytes data 5 in 19 Printf.printf "Sum of bytes 1+2+3+4+5: %d (expected 15)\n" sum; 20 assert (sum = 15) 21 22(* Test bitbuffer operations *) 23let test_bitbuffer () = 24 let bb = Bitbuffer.create () in 25 (* Add 8 bits to create a row *) 26 for i = 0 to 7 do 27 Bitbuffer.add_bit bb (if i mod 2 = 0 then 1 else 0) 28 done; 29 Printf.printf "Bitbuffer test: created buffer with %d rows, %d bits in row 0\n" 30 (Bitbuffer.num_rows bb) 31 (Bitbuffer.bits_per_row bb 0); 32 assert (Bitbuffer.num_rows bb > 0); 33 assert (Bitbuffer.bits_per_row bb 0 = 8) 34 35(* Add a byte to the bitbuffer, MSB first *) 36let add_byte_to_bitbuffer bb byte = 37 for j = 7 downto 0 do 38 Bitbuffer.add_bit bb ((byte lsr j) land 1) 39 done 40 41(* Create a valid WH51 packet for testing *) 42let create_wh51_packet ~device_id ~moisture ~battery_mv = 43 let data = Bytes.create 14 in 44 (* Family code *) 45 Bytes.set_uint8 data 0 0x51; 46 (* Device ID (24 bits) *) 47 Bytes.set_uint8 data 1 ((device_id lsr 16) land 0xff); 48 Bytes.set_uint8 data 2 ((device_id lsr 8) land 0xff); 49 Bytes.set_uint8 data 3 (device_id land 0xff); 50 (* Battery status (OK) + counter *) 51 Bytes.set_uint8 data 4 0x05; 52 (* Moisture *) 53 Bytes.set_uint8 data 5 moisture; 54 (* AD raw value *) 55 Bytes.set_uint8 data 6 0x01; 56 Bytes.set_uint8 data 7 0x00; 57 (* Boost *) 58 Bytes.set_uint8 data 8 0x00; 59 (* Battery voltage raw *) 60 let battery_raw = battery_mv / 2 in 61 Bytes.set_uint8 data 9 ((battery_raw lsr 8) land 0xff); 62 Bytes.set_uint8 data 10 (battery_raw land 0xff); 63 (* Sequence *) 64 Bytes.set_uint8 data 11 0x00; 65 (* CRC-8 *) 66 let crc = Util.crc8 ~poly:0x31 ~init:0x00 data 12 in 67 Bytes.set_uint8 data 12 crc; 68 (* Checksum *) 69 let sum = Util.add_bytes data 13 in 70 Bytes.set_uint8 data 13 sum; 71 data 72 73(* Test WH51 decoder with synthetic packet *) 74let test_wh51_decoder () = 75 Printf.printf "\n=== Testing WH51 decoder ===\n"; 76 77 (* Create a valid WH51 packet *) 78 let packet = create_wh51_packet ~device_id:0x123456 ~moisture:50 ~battery_mv:3000 in 79 80 Printf.printf "Created WH51 packet: "; 81 for i = 0 to 13 do 82 Printf.printf "%02x " (Bytes.get_uint8 packet i) 83 done; 84 Printf.printf "\n"; 85 86 (* Create bitbuffer with preamble + packet *) 87 let bb = Bitbuffer.create () in 88 89 (* Add preamble: 0xAA 0x2D 0xD4 *) 90 add_byte_to_bitbuffer bb 0xAA; 91 add_byte_to_bitbuffer bb 0x2D; 92 add_byte_to_bitbuffer bb 0xD4; 93 94 (* Add packet data *) 95 for i = 0 to 13 do 96 add_byte_to_bitbuffer bb (Bytes.get_uint8 packet i) 97 done; 98 99 Printf.printf "Created bitbuffer with %d rows, %d bits in row 0\n" 100 (Bitbuffer.num_rows bb) 101 (Bitbuffer.bits_per_row bb 0); 102 103 (* Create decoder and run it *) 104 let decoders = Rtl433.builtin_decoders () in 105 let wh51_decoder = List.hd decoders in 106 Printf.printf "Running decoder: %s\n" wh51_decoder.Device.name; 107 108 let result = wh51_decoder.Device.decode () bb in 109 110 (match result with 111 | Device.Decoded n -> 112 Printf.printf "SUCCESS: Decoded %d message(s)\n" n; 113 (match Data.get_last_output () with 114 | Some data -> 115 Printf.printf "Output JSON: %s\n" (Data.to_json data); 116 Data.clear_last_output () 117 | None -> 118 Printf.printf "WARNING: No output data captured\n") 119 | Device.Abort_length -> 120 Printf.printf "FAILED: Abort_length (not enough bits)\n" 121 | Device.Abort_early -> 122 Printf.printf "FAILED: Abort_early (no preamble found)\n" 123 | Device.Fail_sanity -> 124 Printf.printf "FAILED: Fail_sanity (invalid family code)\n" 125 | Device.Fail_mic -> 126 Printf.printf "FAILED: Fail_mic (CRC or checksum error)\n"); 127 128 Printf.printf "=== WH51 decoder test complete ===\n" 129 130(* Test JSON output *) 131let test_json_output () = 132 Printf.printf "\n=== Testing JSON output ===\n"; 133 let data = Data.make [ 134 ("model", None, Data.String "Test-Device"); 135 ("id", None, Data.String "abc123"); 136 ("temperature_C", Some "Temperature", Data.Float 23.5); 137 ("humidity", Some "Humidity", Data.Int 65); 138 ] in 139 let json = Data.to_json data in 140 Printf.printf "JSON output: %s\n" json; 141 assert (String.length json > 0); 142 Printf.printf "=== JSON output test complete ===\n" 143 144let () = 145 Printf.printf "rtl433 library tests\n"; 146 Printf.printf "====================\n\n"; 147 148 test_crc8 (); 149 test_add_bytes (); 150 test_bitbuffer (); 151 test_json_output (); 152 test_wh51_decoder (); 153 154 Printf.printf "\nAll tests passed!\n"