adding Oil Ultrasonic Standard protocol

This commit is contained in:
Christian W. Zuckschwerdt
2017-05-21 13:55:15 +02:00
committed by Benjamin Larsson
parent 58f2973bcb
commit d2fd99aba1
5 changed files with 142 additions and 3 deletions

View File

@@ -93,6 +93,7 @@ add_executable(rtl_433
devices/lacrosse_tx35.c
devices/vaillant_vrt340f.c
devices/ibis_beacon.c
devices/oil_standard.c
)

View File

@@ -78,6 +78,7 @@ rtl_433_SOURCES = baseband.c \
devices/rftech.c \
devices/vaillant_vrt340f.c \
devices/wg_pb12v1.c \
devices/ibis_beacon.c
devices/ibis_beacon.c \
devices/oil_standard.c
rtl_433_LDADD = $(LIBRTLSDR) $(LIBM)

136
src/devices/oil_standard.c Normal file
View File

@@ -0,0 +1,136 @@
/* Oil tank monitor using manchester encoded FSK protocol
*
* Tested devices:
* APOLLO ULTRASONIC STANDARD (maybe also VISUAL but not SMART)
* Should apply to similar Watchman and Beckett devices too.
*
* Copyright (C) 2017 Christian W. Zuckschwerdt <zany@triq.net>
* based on code Copyright (C) 2015 David Woodhouse
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include "rtl_433.h"
#include "util.h"
// The sensor sends a single packet once every hour or twice a second
// for 11 minutes when in pairing/test mode (pairing needs 35 sec).
// depth reading is in cm, lowest reading is ~3, highest is ~305, 0 is invalid
//
// IIII IIII IIII IIII 0FFF L0OP DDDD DDDD
//
// example packets are:
// 010101 01010101 01010111 01101001 10011010 10101001 10100101 10011010 01101010 10011001 10011010 0000
// 010101 01010101 01011000 10011010 01010110 01101010 10101010 10100101 01101010 10100110 10101001 1111
// Start of frame full preamble is depending on first data bit either
// 01 0101 0101 0101 0101 0111 01
// 01 0101 0101 0101 0101 1000 10
static const unsigned char preamble_pattern0[2] = { 0x55, 0x5D };
static const unsigned char preamble_pattern1[2] = { 0x55, 0x62 };
// End of frame is the last half-bit repeated additional 4 times
static int oil_standard_decode(bitbuffer_t *bitbuffer, unsigned row, unsigned bitpos) {
char time_str[LOCAL_TIME_BUFLEN];
data_t *data;
uint8_t *b;
uint16_t unit_id;
uint16_t depth = 0;
uint16_t binding_countdown = 0;
uint8_t flags;
uint8_t alarm;
bitbuffer_t databits = {0};
local_time_str(0, time_str);
bitpos = bitbuffer_manchester_decode(bitbuffer, row, bitpos, &databits, 33);
if (databits.bits_per_row[0] != 32)
return 0;
b = databits.bb[0];
// The unit ID changes when you rebind by holding a magnet to the
// sensor for long enough.
unit_id = (b[0] << 8) | b[1];
// 0x01: Rebinding (magnet held to sensor)
// 0x02: High-bit for depth
// 0x04: (always zero?)
// 0x08: Leak/theft alarm
// 0x10: (unkown toggle)
// 0x40: (unkown toggle)
// 0x10: (unkown toggle)
// 0x80: (always zero?)
flags = b[2] & ~0x0A;
alarm = (b[2] & 0x08) >> 3;
if (flags & 1)
// When binding, the countdown counts up from 0x40 to 0x4a
// (as long as you hold the magnet to it for long enough)
// before the device ID changes. The receiver unit needs
// to receive this *strongly* in order to change its
// allegiance.
binding_countdown = b[3];
else
// A depth reading of zero indicates no reading.
depth = ((b[2] & 0x02) << 7) | b[3];
data = data_make(
"time", "", DATA_STRING, time_str,
"model", "", DATA_STRING, "Oil Ultrasonic STANDARD",
"id", "", DATA_FORMAT, "%04x", DATA_INT, unit_id,
"flags", "", DATA_FORMAT, "%02x", DATA_INT, flags,
"alarm", "", DATA_INT, alarm,
"binding_countdown", "", DATA_INT, binding_countdown,
"depth_cm", "", DATA_INT, depth,
NULL);
data_acquired_handler(data);
return 1;
};
static int oil_standard_callback(bitbuffer_t *bitbuffer) {
unsigned bitpos = 0;
int events = 0;
// Find a preamble with enough bits after it that it could be a complete packet
while ((bitpos = bitbuffer_search(bitbuffer, 0, bitpos, (uint8_t *)&preamble_pattern0, 16)) + 78 <=
bitbuffer->bits_per_row[0]) {
events += oil_standard_decode(bitbuffer, 0, bitpos + 14);
bitpos += 2;
}
bitpos = 0;
while ((bitpos = bitbuffer_search(bitbuffer, 0, bitpos, (uint8_t *)&preamble_pattern1, 16)) + 78 <=
bitbuffer->bits_per_row[0]) {
events += oil_standard_decode(bitbuffer, 0, bitpos + 14);
bitpos += 2;
}
return events;
}
static char *output_fields[] = {
"time",
"model",
"id",
"flags",
"alarm",
"binding_countdown",
"depth_cm",
NULL
};
r_device oil_standard = {
.name = "Oil Ultrasonic STANDARD",
.modulation = FSK_PULSE_PCM,
.short_limit = 500,
.long_limit = 500,
.reset_limit = 2000,
.json_callback = &oil_standard_callback,
.disabled = 0,
.fields = output_fields,
};