X-Git-Url: https://git.rvb.name/rtl-433.git/blobdiff_plain/ca13278b24eb61443559bcb61e64627fba3d8823..6d15c6f967221af825cf84e3ed12b96c763b127b:/src/devices/hideki.c diff --git a/src/devices/hideki.c b/src/devices/hideki.c new file mode 100644 index 0000000..00457dc --- /dev/null +++ b/src/devices/hideki.c @@ -0,0 +1,149 @@ +#include "rtl_433.h" +#include "pulse_demod.h" +#include "util.h" +#include "data.h" + +#define HIDEKI_BYTES_PER_ROW 14 + +// 11111001 0 11110101 0 01110011 1 01111010 1 11001100 0 01000011 1 01000110 1 00111111 0 00001001 0 00010111 0 +// SYNC+HEAD P RC cha P P Nr.? P .1° 1° P 10° BV P 1% 10% P ????SYNC -------Check?------- P + +//TS04: +// 00000000 11111111 22222222 33333333 44444444 55555555 66666666 77777777 88888888 99999999 +// SYNC+HEAD cha RC Nr.? 1° .1° VB 10° 10% 1% SYNC???? -----Check?------ + +//Wind: +// 00000000 11111111 22222222 33333333 44444444 55555555 66666666 77777777 88888888 99999999 AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD +// SYNC+HEAD cha RC Nr.? 1° .1° VB 10° 1° .1° VB 10° .1mh 1mh ?? 10mh ???? w° ?? ???? ???? + +enum sensortypes { HIDEKI_UNKNOWN, HIDEKI_TS04, HIDEKI_WIND, HIDEKI_RAIN }; + +static int hideki_ts04_callback(bitbuffer_t *bitbuffer) { + bitrow_t *bb = bitbuffer->bb; + uint8_t *b = bb[0];//TODO: handle the 3 row, need change in PULSE_CLOCK decoding + + char time_str[LOCAL_TIME_BUFLEN]; + data_t *data; + local_time_str(0, time_str); + + uint8_t packet[HIDEKI_BYTES_PER_ROW]; + int sensortype = HIDEKI_WIND; // default for 14 valid bytes + uint8_t channel, humidity, rc, battery_ok; + int temp, wind_strength, wind_direction, rain_units; + + // Transform the incoming data: + // * change endianness + // * toggle each bits + // * Remove (and check) parity bit + // TODO this may be factorise as a bitbuffer method (as for bitbuffer_manchester_decode) + for(int i=0; i> (8 - i%8); + // reverse as it is litle endian... + packet[i] = reverse8(packet[i]); + // toggle each bit + packet[i] ^= 0xFF; + // check parity + uint8_t parity = ((b[i+offset+1] >> (7 - i%8)) ^ 0xFF) & 0x01; + if(parity != byteParity(packet[i])) + { + if (i == 10) { + sensortype = HIDEKI_TS04; + break; + } + if (i == 9) { + sensortype = HIDEKI_RAIN; + break; + } + return 0; + } + } + + // Read data + if(packet[0] == 0x9f){ //Note: it may exist other valid id + channel = (packet[1] >> 5) & 0x0F; + if(channel >= 5) channel -= 1; + rc = packet[1] & 0x0F; + temp = (packet[5] & 0x0F) * 100 + ((packet[4] & 0xF0) >> 4) * 10 + (packet[4] & 0x0F); + if(((packet[5]>>7) & 0x01) == 0){ + temp = -temp; + } + battery_ok = (packet[5]>>6) & 0x01; + if (sensortype == HIDEKI_TS04) { + humidity = ((packet[6] & 0xF0) >> 4) * 10 + (packet[6] & 0x0F); + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "HIDEKI TS04 sensor", + "rc", "Rolling Code", DATA_INT, rc, + "channel", "Channel", DATA_INT, channel, + "battery", "Battery", DATA_STRING, battery_ok ? "OK": "LOW", + "temperature_C", "Temperature", DATA_FORMAT, "%.01f C", DATA_DOUBLE, temp/10.f, + "humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity, + NULL); + data_acquired_handler(data); + return 1; + } + if (sensortype == HIDEKI_WIND) { + const uint8_t wd[] = { 0, 15, 13, 14, 9, 10, 12, 11, 1, 2, 4, 3, 8, 7, 5, 6 }; + wind_direction = wd[((packet[11] & 0xF0) >> 4)] * 225; + wind_strength = (packet[9] & 0x0F) * 100 + ((packet[8] & 0xF0) >> 4) * 10 + (packet[8] & 0x0F); + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "HIDEKI Wind sensor", + "rc", "Rolling Code", DATA_INT, rc, + "channel", "Channel", DATA_INT, channel, + "battery", "Battery", DATA_STRING, battery_ok ? "OK": "LOW", + "temperature_C", "Temperature", DATA_FORMAT, "%.01f C", DATA_DOUBLE, temp/10.f, + "windstrength", "Wind Strength", DATA_FORMAT, "%.02f km/h", DATA_DOUBLE, wind_strength*0.160934f, + "winddirection", "Direction", DATA_FORMAT, "%.01f °", DATA_DOUBLE, wind_direction/10.f, + NULL); + data_acquired_handler(data); + return 1; + } + if (sensortype == HIDEKI_RAIN) { + rain_units = (packet[5] << 8) + packet[4]; + battery_ok = (packet[2]>>6) & 0x01; + data = data_make("time", "", DATA_STRING, time_str, + "model", "", DATA_STRING, "HIDEKI Rain sensor", + "rc", "Rolling Code", DATA_INT, rc, + "channel", "Channel", DATA_INT, channel, + "battery", "Battery", DATA_STRING, battery_ok ? "OK": "LOW", + "rain", "Rain", DATA_FORMAT, "%.01f mm", DATA_DOUBLE, rain_units*0.7f, + NULL); + data_acquired_handler(data); + return 1; + } + return 0; + } + return 0; +} + +PWM_Precise_Parameters hideki_ts04_clock_bits_parameters = { + .pulse_tolerance = 60, + .pulse_sync_width = 0, // No sync bit used +}; + +static char *output_fields[] = { + "time", + "model", + "rc", + "channel", + "battery", + "temperature_C", + "humidity", + "windstrength", + "winddirection", + "rain", + NULL +}; + +r_device hideki_ts04 = { + .name = "HIDEKI TS04 Temperature, Humidity, Wind and Rain Sensor", + .modulation = OOK_PULSE_CLOCK_BITS, + .short_limit = 520, + .long_limit = 1040, // not used + .reset_limit = 4000, + .json_callback = &hideki_ts04_callback, + .disabled = 0, + .demod_arg = (uintptr_t)&hideki_ts04_clock_bits_parameters, + .fields = output_fields, +};