2 * Digitech XC0348 weather station
3 * Reports 1 row, 88 pulses
4 * Format: ff ID ?X XX YY ZZ ?? ?? ?? UU CC
6 * - ?X XX: temperature, likely in 0.1C steps (.1 e7 == 8.7C, .1 ef == 9.5C)
7 * - YY: percent in a single byte (for example 54 == 84%)
8 * - ZZ: wind speed (00 == 0, 01 == 1.1km/s, ...)
9 * - UU: wind direction: 00 is N, 02 is NE, 04 is E, etc. up to 0F is seems
12 * still unknown - rain, pressure
22 static const char* wind_directions[] = {
25 "SE", "SSE", "S", "SSW", "SW",
30 static float get_temperature(const uint8_t* br) {
31 const int temp_raw = (br[2] << 8) + br[3];
32 return ((temp_raw & 0x0fff) - 0x190) / 10.0;
35 static int get_humidity(const uint8_t* br) {
39 static const char* get_wind_direction(const uint8_t* br) {
40 return wind_directions[br[9] & 0x0f];
43 static float get_wind_speed(const uint8_t* br) {
47 static int digitech_ws_callback(bitbuffer_t *bitbuffer) {
49 char time_str[LOCAL_TIME_BUFLEN];
50 local_time_str(0, time_str);
52 if (bitbuffer->num_rows != 1) {
55 if (bitbuffer->bits_per_row[0] != 88) {
59 const uint8_t *br = bitbuffer->bb[0];
66 if (br[10] != crc8(br, 10, CRC_POLY, CRC_INIT)) {
71 const float temperature = get_temperature(br);
72 const int humidity = get_humidity(br);
73 const char* direction = get_wind_direction(br);
74 const float speed = get_wind_speed(br);
75 const char device_id = br[1];
77 data = data_make("time", "", DATA_STRING, time_str,
78 "model", "", DATA_STRING, "Digitech XC0348 weather station",
79 "id", "", DATA_INT, device_id,
80 "temperature_C", "Temperature", DATA_DOUBLE, temperature,
81 "humidity", "Humidity", DATA_INT, humidity,
82 "direction", "Wind direction", DATA_STRING, direction,
83 "speed", "Wind speed", DATA_DOUBLE, speed,
85 data_acquired_handler(data);
89 static char *output_fields[] = {
100 r_device digitech_ws = {
101 .name = "Digitech XC0348 Weather Station",
102 .modulation = OOK_PULSE_PWM_RAW,
105 .reset_limit = 10520,
106 .json_callback = &digitech_ws_callback,
109 .fields = output_fields,