5 * Magnetic door & window sensor
7 * From http://elektronikforumet.com/wiki/index.php/RF_Protokoll_-_Proove_self_learning
8 * Proove packet structure (32 bits):
9 * HHHH HHHH HHHH HHHH HHHH HHHH HHGO CCEE
10 * H = The first 26 bits are transmitter unique codes, and it is this code that the reciever “learns” to recognize.
11 * G = Group code. Set to 0 for on, 1 for off.
12 * O = On/Off bit. Set to 0 for on, 1 for off.
14 * E = Unit bits. Device to be turned on or off. Unit #1 = 00, #2 = 01, #3 = 10.
16 * Every bit in the packets structure is sent as two physical bits.
17 * Where the second bit is the inverse of the first, i.e. 0 -> 01 and 1 -> 10.
18 * Example: 10101110 is sent as 1001100110101001
19 * The sent packet length is thus 64 bits.
20 * A message is made up by a Sync bit followed by the Packet bits and ended by a Pause bit.
21 * Every message is repeated four times.
23 * Copyright (C) 2016 Ask Jakobsen
24 * This program is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU General Public License as published by
26 * the Free Software Foundation; either version 2 of the License, or
27 * (at your option) any later version.
33 static int proove_callback(bitbuffer_t *bitbuffer) {
35 char time_str[LOCAL_TIME_BUFLEN];
37 /* Reject codes of wrong length */
38 if (bitbuffer->bits_per_row[1] != 64)
41 bitbuffer_t databits = {0};
42 unsigned pos = bitbuffer_manchester_decode(bitbuffer, 1, 0, &databits, 64);
44 /* Reject codes when Manchester decoding fails */
48 /* bitbuffer_print(&databits); */
50 bitrow_t *bb = databits.bb;
53 uint32_t sensor_id = (b[0] << 18) | (b[1] << 10) | (b[2] << 2) | (b[3]>>6); // ID 26 bits
54 uint32_t group_code = (b[3] >> 5) & 1;
55 uint32_t on_bit = (b[3] >> 4) & 1;
56 uint32_t channel_code = (b[3] >> 2) & 0x03;
57 uint32_t unit_bit = (b[3] & 0x03);
60 local_time_str(0, time_str);
62 data = data_make("time", "", DATA_STRING, time_str,
63 "model", "", DATA_STRING, "Proove",
64 "id", "House Code", DATA_INT, sensor_id,
65 "channel", "Channel", DATA_INT, channel_code,
66 "state", "State", DATA_STRING, on_bit ? "OFF" : "ON",
67 "unit", "Unit", DATA_INT, unit_bit,
70 data_acquired_handler(data);
75 static char *output_fields[] = {
87 .modulation = OOK_PULSE_PPM_RAW,
91 .json_callback = &proove_callback,
94 .fields = output_fields