1 /* Prologue sensor protocol
2 * also FreeTec NC-7104 sensor for FreeTec Weatherstation NC-7102.
4 * the sensor sends 36 bits 7 times, before the first packet there is a sync pulse
5 * the packets are ppm modulated (distance coding) with a pulse of ~500 us
6 * followed by a short gap of ~2000 us for a 0 bit or a long ~4000 us gap for a
7 * 1 bit, the sync gap is ~9000 us.
9 * the data is grouped in 9 nibbles
10 * [model] [id0] [id1] [flags] [temp0] [temp1] [temp2] [humi0] [humi1]
12 * model is 1001 (9) or 0110 (5)
13 * id is a random id that is generated when the sensor starts, could include battery status
14 * the same batteries often generate the same id
15 * flags(3) is 0 the battery status, 1 ok, 0 low, first reading always say low
16 * flags(2) is 1 when the sensor sends a reading when pressing the button on the sensor
17 * flags(1,0)+1 forms the channel number that can be set by the sensor (1-3)
18 * temp is 12 bit signed scaled by 10
19 * humi0 is always 1100 (0x0C) if no humidity sensor is available
20 * humi1 is always 1100 (0x0C) if no humidity sensor is available
22 * The sensor can be bought at Clas Ohlson
29 static int prologue_callback(bitbuffer_t *bitbuffer) {
30 bitrow_t *bb = bitbuffer->bb;
33 char time_str[LOCAL_TIME_BUFLEN];
42 int r = bitbuffer_find_repeated_row(bitbuffer, 3, 36);
45 bitbuffer->bits_per_row[r] <= 37 && // we expect 36 bits but there might be a trailing 0 bit
46 ((bb[r][0]&0xF0) == 0x90 ||
47 (bb[r][0]&0xF0) == 0x50)) {
50 local_time_str(0, time_str);
53 model = bb[r][0] >> 4;
54 id = ((bb[r][0]&0x0F)<<4) | ((bb[r][1]&0xF0)>>4);
55 battery = bb[r][1]&0x08;
56 button = (bb[r][1]&0x04) >> 2;
57 channel = (bb[r][1]&0x03) + 1;
58 temp = (int16_t)((uint16_t)(bb[r][2] << 8) | (bb[r][3]&0xF0));
60 humidity = ((bb[r][3]&0x0F) << 4) | (bb[r][4] >> 4);
62 data = data_make("time", "", DATA_STRING, time_str,
63 "model", "", DATA_STRING, "Prologue sensor",
64 "id", "", DATA_INT, model, // this should be named "type"
65 "rid", "", DATA_INT, id, // this should be named "id"
66 "channel", "Channel", DATA_INT, channel,
67 "battery", "Battery", DATA_STRING, battery ? "OK" : "LOW",
68 "button", "Button", DATA_INT, button,
69 "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, temp/10.0,
70 "humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
72 data_acquired_handler(data);
79 static char *output_fields[] = {
93 .name = "Prologue Temperature Sensor",
94 .modulation = OOK_PULSE_PPM_RAW,
98 .json_callback = &prologue_callback,
101 .fields = output_fields