@@ -34,15 +34,26 @@ I.e., data packet, wait 48 seconds, two data packets, wait 48 seconds, data pack
34
34
35
35
The 'Total rainfall' field is a cumulative counter, increased by 0.3 millimeters of rain each step.
36
36
37
- Message layout and example:
37
+ The station is also known as TFA STRATOS 35.1077
38
+ See the product page here: https://www.tfa-dostmann.de/en/product/wireless-weather-station-with-wind-and-rain-gauge-stratos-35-1077/
39
+ This model seems also capable to decode the DCF77 time signal sent by the time signal decoder (which is enclosed on the sensor tx):
40
+ around the minute 59 of the even hours the sensor's TX stops sending weather data, probably to receive (and sync with) DCF77 signals.
41
+ After around 3-4 minutes of silence it starts to send just time data for some minute, then it starts again with
42
+ weather data as usual.
43
+
44
+ To recognize which message is received (weather or time) you can use the 'msg_type' field on json output:
45
+ - msg_type 0 = weather data
46
+ - msg_type 1 = time data
47
+
48
+ Weather data - Message layout and example:
38
49
39
50
AA BC CD DD EE FF GG HH HH II
40
51
{80} ff 5f 51 93 48 00 00 12 46 aa
41
52
42
53
- A : 8 bits : Preamble 0xFF
43
- - B : 4 bits : ?? - always seems to be 0x5
54
+ - B : 4 bits : ?? - seems to be 0x5 for whether data, 0x6 for time data
44
55
- C : 8 bits : Id, changes when reset (e.g., 0xF5)
45
- - D : 1 bit : ?? - unknown, always seems to be 0
56
+ - D : 1 bit : msg_type - 0, for whether data
46
57
- D : 1 bit : Battery, 0 = ok, 1 = low (e.g, OK)
47
58
- D : 10 bits : Temperature in Celsius, offset 400, scaled by 10 (e.g., 0.3 degrees C)
48
59
- E : 8 bits : Relative humidity, percent (e.g., 72%)
@@ -51,6 +62,32 @@ Message layout and example:
51
62
- H : 16 bits : Total rainfall in units of 0.3mm, since reset (e.g., 1403.4 mm)
52
63
- I : 8 bits : CRC, poly 0x31, init 0x00 (excluding preamble)
53
64
65
+ Time data - Message layout and example:
66
+
67
+ AA BC CD DE FG HI JK LM NO PP
68
+ {80} ff 69 0a 96 02 41 23 43 27 df
69
+
70
+ - A : 8 bits : Preamble 0xFF
71
+ - B : 4 bits : ?? - seems to be 0x5 for whether data, seems 0x6 for time data
72
+ - C : 8 bits : Id, changes when reset (e.g., 0xF5)
73
+ - D : 1 bit : msg_type - 1, for time data
74
+ - D : 1 bit : Battery, 0 = ok, 1 = low (e.g, OK)
75
+ - D : 4 bits : ??
76
+ - D : 2 bits : hour BCD coded (*10)
77
+ - E : 4 bits : hour BCD coded (*1)
78
+ - F : 4 bits : minute BCD coded (*10)
79
+ - G : 4 bits : minute BCD coded (*1)
80
+ - H : 4 bits : second BCD coded (*10)
81
+ - I : 4 bits : second BCD coded (*1)
82
+ - J : 4 bits : year BCD coded (*10), counted from 2000
83
+ - K : 4 bits : year BCD coded (*1), counted from 2000
84
+ - L : 3 bits : ??
85
+ - L : 1 bits : month BCD coded (*10)
86
+ - M : 4 bits : month BCD coded (*1)
87
+ - N : 4 bits : day BCD coded (*10)
88
+ - O : 4 bits : day BCD coded (*1)
89
+ - P : 8 bits : CRC, poly 0x31, init 0x00 (excluding preamble)
90
+
54
91
*/
55
92
56
93
#include "decoder.h"
@@ -91,30 +128,62 @@ static int fineoffset_wh1050_callback(r_device *decoder, bitbuffer_t *bitbuffer)
91
128
return DECODE_FAIL_MIC ; // crc mismatch
92
129
}
93
130
94
- // GETTING WEATHER SENSORS DATA
95
- int temp_raw = ((br [1 ] & 0x03 ) << 8 ) | br [2 ];
96
- float temperature = (temp_raw - 400 ) * 0.1f ;
97
- int humidity = br [3 ];
98
- float speed = (br [4 ] * 0.34f ) * 3.6f ; // m/s -> km/h
99
- float gust = (br [5 ] * 0.34f ) * 3.6f ; // m/s -> km/h
100
- int rain_raw = (br [6 ] << 8 ) | br [7 ];
101
- float rain = rain_raw * 0.3f ;
102
- int device_id = (br [0 ] << 4 & 0xf0 ) | (br [1 ] >> 4 );
103
- int battery_low = br [1 ] & 0x04 ;
104
-
105
- /* clang-format off */
106
- data = data_make (
107
- "model" , "" , DATA_STRING , "Fineoffset-WH1050" ,
108
- "id" , "StationID" , DATA_FORMAT , "%04X" , DATA_INT , device_id ,
109
- "battery_ok" , "Battery" , DATA_INT , !battery_low ,
110
- "temperature_C" , "Temperature" , DATA_FORMAT , "%.01f C" , DATA_DOUBLE , temperature ,
111
- "humidity" , "Humidity" , DATA_FORMAT , "%u %%" , DATA_INT , humidity ,
112
- "wind_avg_km_h" , "Wind avg speed" , DATA_FORMAT , "%.02f" , DATA_DOUBLE , speed ,
113
- "wind_max_km_h" , "Wind gust" , DATA_FORMAT , "%.02f" , DATA_DOUBLE , gust ,
114
- "rain_mm" , "Total rainfall" , DATA_FORMAT , "%.01f" , DATA_DOUBLE , rain ,
115
- "mic" , "Integrity" , DATA_STRING , "CRC" ,
116
- NULL );
117
- /* clang-format on */
131
+ // GETTING MESSAGE TYPE
132
+ int msg_type = (br [1 ] & 0x08 ) >> 3 ;
133
+
134
+ if (msg_type == 0 ) {
135
+ // GETTING WEATHER SENSORS DATA
136
+ int temp_raw = ((br [1 ] & 0x03 ) << 8 ) | br [2 ];
137
+ float temperature = (temp_raw - 400 ) * 0.1f ;
138
+ int humidity = br [3 ];
139
+ float speed = (br [4 ] * 0.34f ) * 3.6f ; // m/s -> km/h
140
+ float gust = (br [5 ] * 0.34f ) * 3.6f ; // m/s -> km/h
141
+ int rain_raw = (br [6 ] << 8 ) | br [7 ];
142
+ float rain = rain_raw * 0.3f ;
143
+ int device_id = (br [0 ] << 4 & 0xf0 ) | (br [1 ] >> 4 );
144
+ int battery_low = br [1 ] & 0x04 ;
145
+
146
+ /* clang-format off */
147
+ data = data_make (
148
+ "model" , "" , DATA_STRING , "Fineoffset-WH1050" ,
149
+ "msg_type" , "Msg type" , DATA_INT , msg_type ,
150
+ "id" , "StationID" , DATA_FORMAT , "%04X" , DATA_INT , device_id ,
151
+ "battery_ok" , "Battery" , DATA_INT , !battery_low ,
152
+ "temperature_C" , "Temperature" , DATA_FORMAT , "%.01f C" , DATA_DOUBLE , temperature ,
153
+ "humidity" , "Humidity" , DATA_FORMAT , "%u %%" , DATA_INT , humidity ,
154
+ "wind_avg_km_h" , "Wind avg speed" , DATA_FORMAT , "%.02f" , DATA_DOUBLE , speed ,
155
+ "wind_max_km_h" , "Wind gust" , DATA_FORMAT , "%.02f" , DATA_DOUBLE , gust ,
156
+ "rain_mm" , "Total rainfall" , DATA_FORMAT , "%.01f" , DATA_DOUBLE , rain ,
157
+ "mic" , "Integrity" , DATA_STRING , "CRC" ,
158
+ NULL );
159
+ /* clang-format on */
160
+ }
161
+ else {
162
+ // GETTING TIME DATA
163
+ int device_id = (br [0 ] << 4 & 0xf0 ) | (br [1 ] >> 4 );
164
+ int battery_low = br [1 ] & 0x04 ;
165
+ int hours = ((br [2 ] & 0x30 ) >> 4 ) * 10 + (br [2 ] & 0x0F );
166
+ int minutes = ((br [3 ] & 0xF0 ) >> 4 ) * 10 + (br [3 ] & 0x0F );
167
+ int seconds = ((br [4 ] & 0xF0 ) >> 4 ) * 10 + (br [4 ] & 0x0F );
168
+ int year = ((br [5 ] & 0xF0 ) >> 4 ) * 10 + (br [5 ] & 0x0F ) + 2000 ;
169
+ int month = ((br [6 ] & 0x10 ) >> 4 ) * 10 + (br [6 ] & 0x0F );
170
+ int day = ((br [7 ] & 0xF0 ) >> 4 ) * 10 + (br [7 ] & 0x0F );
171
+
172
+ char clock_str [23 ];
173
+ sprintf (clock_str , "%04d-%02d-%02dT%02d:%02d:%02d" ,
174
+ year , month , day , hours , minutes , seconds );
175
+
176
+ /* clang-format off */
177
+ data = data_make (
178
+ "model" , "" , DATA_STRING , "Fineoffset-WH1050" ,
179
+ "msg_type" , "Msg type" , DATA_INT , msg_type ,
180
+ "id" , "Station ID" , DATA_INT , device_id ,
181
+ "battery_ok" , "Battery" , DATA_INT , !battery_low ,
182
+ "radio_clock" , "Radio Clock" , DATA_STRING , clock_str ,
183
+ "mic" , "Integrity" , DATA_STRING , "CRC" ,
184
+ NULL );
185
+ /* clang-format on */
186
+ }
118
187
119
188
decoder_output_data (decoder , data );
120
189
return 1 ;
@@ -123,12 +192,14 @@ static int fineoffset_wh1050_callback(r_device *decoder, bitbuffer_t *bitbuffer)
123
192
static char const * const output_fields [] = {
124
193
"model" ,
125
194
"id" ,
195
+ "msg_type" ,
126
196
"battery_ok" ,
127
197
"temperature_C" ,
128
198
"humidity" ,
129
199
"wind_avg_km_h" ,
130
200
"wind_max_km_h" ,
131
201
"rain_mm" ,
202
+ "radio_clock" ,
132
203
"mic" ,
133
204
NULL ,
134
205
};
0 commit comments