Decode radio transmissions from devices on the ISM bands in OCaml
at main 109 lines 3.1 kB view raw
1(* Hierarchical data structure *) 2 3type value = 4 | Int of int 5 | Float of float 6 | String of string 7 | Data of t 8 | Array of value array 9 10and field = { 11 key : string; 12 pretty_key : string option; 13 format : string option; 14 value : value; 15} 16 17and t = field list 18 19let make items = 20 List.map 21 (fun (key, pretty_key, value) -> { key; pretty_key; format = None; value }) 22 items 23 24let int key ?pretty ?format value = 25 { key; pretty_key = pretty; format; value = Int value } 26 27let float key ?pretty ?format value = 28 { key; pretty_key = pretty; format; value = Float value } 29 30let string key ?pretty ?format value = 31 { key; pretty_key = pretty; format; value = String value } 32 33let data key ?pretty value = 34 { key; pretty_key = pretty; format = None; value = Data value } 35 36let array key ?pretty value = 37 { key; pretty_key = pretty; format = None; value = Array value } 38 39let hex key ?pretty bytes len = 40 let s = Rtl433_util.bytes_to_hex bytes len in 41 { key; pretty_key = pretty; format = None; value = String s } 42 43let find key data = List.find_opt (fun f -> f.key = key) data 44 45let get_int key data = 46 match find key data with Some { value = Int i; _ } -> Some i | _ -> None 47 48let get_float key data = 49 match find key data with Some { value = Float f; _ } -> Some f | _ -> None 50 51let get_string key data = 52 match find key data with Some { value = String s; _ } -> Some s | _ -> None 53 54let rec pp_value fmt = function 55 | Int i -> Format.fprintf fmt "%d" i 56 | Float f -> Format.fprintf fmt "%g" f 57 | String s -> Format.fprintf fmt "%S" s 58 | Data d -> pp fmt d 59 | Array a -> 60 Format.fprintf fmt "[%a]" 61 (Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ", ") pp_value) 62 (Array.to_list a) 63 64and pp fmt data = 65 Format.fprintf fmt "{%a}" 66 (Format.pp_print_list 67 ~pp_sep:(fun fmt () -> Format.fprintf fmt ", ") 68 (fun fmt f -> Format.fprintf fmt "%s: %a" f.key pp_value f.value)) 69 data 70 71let to_json data = 72 let buf = Buffer.create 256 in 73 let rec emit_value = function 74 | Int i -> Buffer.add_string buf (string_of_int i) 75 | Float f -> Buffer.add_string buf (string_of_float f) 76 | String s -> 77 Buffer.add_char buf '"'; 78 Buffer.add_string buf (String.escaped s); 79 Buffer.add_char buf '"' 80 | Data d -> emit_data d 81 | Array a -> 82 Buffer.add_char buf '['; 83 Array.iteri 84 (fun i v -> 85 if i > 0 then Buffer.add_char buf ','; 86 emit_value v) 87 a; 88 Buffer.add_char buf ']' 89 and emit_data fields = 90 Buffer.add_char buf '{'; 91 List.iteri 92 (fun i f -> 93 if i > 0 then Buffer.add_char buf ','; 94 Buffer.add_char buf '"'; 95 Buffer.add_string buf f.key; 96 Buffer.add_string buf "\":"; 97 emit_value f.value) 98 fields; 99 Buffer.add_char buf '}' 100 in 101 emit_data data; 102 Buffer.contents buf 103 104(* Mutable storage for last decoded output *) 105let last_output : t option ref = ref None 106 107let set_last_output data = last_output := Some data 108let get_last_output () = !last_output 109let clear_last_output () = last_output := None