Skip to content

custom device: 433 MHz weather station

Marco Sillano edited this page Aug 21, 2023 · 2 revisions

433 MHz Weather station

For some time I have wanted to include meteorological probes in the tuyaDAEMON project: in particular, the rain gauge data can be integrated with the irrigation system, and the anemometer is useful for wind turbine testing (next project).

The problem is the probes. There are (yet) no weather probes in the Tuya system. The best solution I have found is not to select separate, very expensive probes, but to use a medium-quality standalone wireless (433 MHz) weather station: the "Auriol IAN-114435"(https://www.manua.ls/auriol/ian-114435/manual) offered some time ago by Lidl for € 50. (https://fandilidl.it/volantino/2019.01.21.caldo.inverno/17080,Stazione-meteorologica). Good quality/price factor.

The weather station consists of the main interface (H13716a), of a probe (H13716b) which transmits on two channels: one for temperature and humidity, the other for wind and direction, and we also have the rain gauge (H13716c). Googling for comments, it is considered an excellent entry level product, though some criticisms has been leveled at the position of the temperature probe: alternative DIY solutions can be found.

With this choice, the problem is generalized: finding a valid connection with tuyaDEAMON for devices using the ISM bands: 433.92 MHz, 868 MHz, 315 MHz, 345 MHz and 915 MHz. Examples of such devices include weather stations, sensors alarm, utility monitor, tire pressure monitor and more.

1. exploring

I am not an RF expert, so my first step is to investigate the problem, before starting with RX circuits and Arduino microprocessor to decode the signals and transmit them via WIFI (example: https://www.instructables.com/Decoding-and-sending-433MHz-RF-codes-with-Arduino-/).

Here my experience:

As HW, I used the RTL-SDR, a very cheap USB dongle, around $ 30 with an antenna, that can be used as a computer-based radio scanner to receive live radio signals on Pc, Raspberry, and Android. more...

As software there is the brink of choice, see list. I chose SDRsharp (SDR#) due to the presence of a specialized 433 plugin.

  1. I downloaded "SRD# with Community Plugins" from https://airspy.com/download/ for its easy installation.
  2. After installing SRD# (see instructions at https://www.rtl-sdr.com/rtl-sdr-quick-start-guide) I also installed NET 5.0 SDK.
  3. Then I followed these instructions https://www.rtl-sdr.com/rtl433-plugin-for-sdr-now-available/ to install in SRD# the RTL_433 plugin from https://github.com/marco402/Rtl_433_dll-for-plugin-SdrSharp.
  4. Finally I installed the driver as indicated in https//www.rtl-sdr.com/getting-the-rtl-sdr-to-work-on-windows-10/. The Zadig.exe file is present in the bin dir of SRD#.

For the analysis of signals, you can refer to: https://www.sigidwiki.com/wiki/SignalIdentificationGuide.

This is a signal:

To my surprise the plugin has decoded all the weather devices providing this output in clear text.

All three channels of the weather station use the same protocol #16, called 'Alecto V1': see here for protocol details.

2. node-red test

The good result obtained made me change plans: instead of building a DIY gateway, I decided to permanently use the RLT_SDR as receiver and RTL_433 as converter. Moreover: "One comment about the cc1101 transceiver module, I have found that the receiver is not as sensitive as a rtl_sdr and I get about 1/2 the range (by NorthernMan54) ".

I need now the rtl_433.exe standalone from https://github.com/merbanan/rtl_433 The following operations were necessary:

  1. I downloaded the rtl_433-win-msvc-x64-21.12.zip file from https://github.com/merbanan/rtl_433/releases
  2. I created a directory (d:\usrbin) and added it to the windows PATH (pop-up system properties then environment variables) and unzipped here rtl_433-win-msvc-x64- 21.12.zip.
  3. Using the RTL_SDR, we can't use the default rtl_433.exe. So I renamed the file "D:\userbin\rtl_433.exe" to "D:\userbin\rtl_433_base.exe" and I make a copy of the file "D:\userbin\rtl_433-rtlsdr.exe" as "D:\userbin\rtl_433.exe".
  4. note: you can test all exe in d:\usrbin simply using a command line terminal (cmd.exe): the dir is in the PATH, so it works from anywhere.

Time now to use node-red.

  1. I installed the node-red-contrib-rtl_433 then I build a minimal test flow:

Just with the default settings, it worked the first time: as you can see in the debug pad, it returns all data in an object. Perfect!.

So this is a fast and easy solution for all 433 MHz (and 868 MHz, 315 MHz, 345 MHz and 915 MHz) RF devices. There are currently over 200 protocols available: it is likely (as in my case) that you will find the one required.

At this point it is possible to continue either by creating your own standalone weather application (example: https://www.rtl-sdr.com/tag/weather-station/, or by integrating the data in 'tuyaDAEMON', creating a 'fake weather station device'. Note: the original interface (Auriol H13716a) continues to function as before.

note (04/04/2023): If you get 'error -12' in the console, re-install the driver using Zadig as in 1.3 up. (see https://www.rtl-sdr.com/forum/viewtopic.php?f=7&t=1797).

3. weather station device

Time to make some design choices:

  1. The new flow will be a general purpose 433 gateway, which manages (for now) two devices: _Auriol_IAN_114435 for the meteo data and _extra_temperature for other temperature probes, using device nodes.
  1. General characteristics

    • Random ID user configuration for all handled devices (when changing the battery).
    • Uses the RT/AVG filter subflow to average device data (optional, e.g. every 5 min). note: the user can select which dp to record in the toyathome DB for subsequent processing (see hide).
    • Send any extra data captured as a warning message.
    • As usual, user runtime configuration data are grouped for easy access in a Global 433 gateway config node.
    • Some useful meteorological functions are implemented in a singleton object context.global.meteoUtils to allow easy reuse in any flow/node.
  2. the custom device "_Auriol_IAN_114435" groups three probes (temperature, wind, rain) and follows the rules:

4_extra_temperature device

This device simply groups 2 spare temperature probes, from old time+temperature clocks.

5. last version

The last version of 433 gateway can be downloaded from https://github.com/msillano/tuyaDAEMON/tree/main/extra/433_gateway.

Code includes also the devices:

6. customization: how to add more 433 devices

If you are receiving signals from other probes in a stable way, you can add a custom tuyaDAEMON device to the '433 gateway'. Here's how to proceed:

  1. Define a new fake device in alldevices: with the device id (e.g. _newDevice) and all the dps received plus other optional dps calculated by the device driver (you can use tuyaDAEMON-toolkit for this phase).
  2. In the 'global 433 gateway config' node add
    • flow.RND_XXX the probe random ID (if used by probe)
    • flow._newDevice_AVERAGE = true to use the average feature (optional)
  3. Add a new output to the 'RX data selector' node, and update the code to select only the new device data objects.
  4. Add a new function node 'newDevice process' to
    • map probe data to defined tuyaDAEMON dps.
    • calculate the added 'dps' (optional).
  5. If required, add also an 'AVG _newDevice' input node with average definitions.

In production, you can reduce the computational load by selecting only the useful protocols in the 'rtl_a33' node.

7. 'Weather station' view

To extract weather data from the 'messages' table in a more useful format you can create a 'view' with a record every 5 minutes:

using this MYSQL query:

SELECT `timestamp`,
MAX(CASE WHEN messages.dps ="_day" THEN messages.value END) "day",
MAX(CASE WHEN messages.dps ="_temperature" THEN messages.value END) "temp",
MAX(CASE WHEN messages.dps ="_humidity" THEN messages.value END) "hum",
MAX(CASE WHEN messages.dps ="_rain_day_mm" THEN messages.value END) "rain",
MAX(CASE WHEN messages.dps ="_wind_avg_m_s" THEN messages.value END) "wind",
MAX(CASE WHEN messages.dps ="_heat_index" THEN messages.value END) "HI",
MAX(CASE WHEN messages.dps ="_dew_point" THEN messages.value END) "DP",
MAX(CASE WHEN messages.dps ="_wind_chill" THEN messages.value END) "WC",
MAX(CASE WHEN messages.dps ="_wind_max_m_s" THEN messages.value END) "WM",
MAX(CASE WHEN messages.dps ="_wind_dir_deg" THEN messages.value END) "dir"
FROM messages
WHERE `device-id`='_Auriol_IAN_114435' 
GROUP BY `timestamp`
ORDER BY `timestamp` ASC

Update (2023): For an in-depth analysis and alternative options for using the data in the DB, see the application notes:

8. notes about RT/AVG filter subflow

use sample

This subflow filter for tuyaDAEMON allows the processing of individual messages in real time, or the creation of an averaged sampling. This subflow is a generic node that can be used with data messages from any tuyaDAEMON device.

For devices in 'RT' mode, all messages go directly to the output (no filter action).

For devices in 'AVG' mode, all input messages are stored. A special "trigger" message in input provokes the output.

This message fires the output message with averaged data and causes the reset of the internal storage.

    msg:{
        topic    = 'average'           '        (mandatory)
        }

The simplest way to generate trigger messages at fixed time intervals is to use a standard 'input' node, setting interval to the required value.

Details

This subflow can handle messages from one device, with a user-defined strategy, and it is designed to allow for a simple upgrade of any existing tuyaDAEMON module or device.

Condition to enable the AVG mode for a device:

This global variable is used as flag:

    global.<deviceid>_AVERAGE = true|false     (mandatory)

The simplest and user-convenient way to set this value is to add it to the Global MODULE config node, present in all tuyaDEAMON modules: it acts as a switch to enable or disable the 'average' function.

Processing dps rules in AVG mode

  • The dps full list is taken, for any device, from the global.alldevices object (see the CORE.Global CORE config node).
  • Only dps with at least one value in stored inputs are in the output.
  • If the dp value 'isNaN()' (i.e. not numeric) automatically the last value is used in output.
  • If the dp value is numeric, we get the average of all stored input values as output (default).
  • The average is rounded to an integer if 'dp' is in the dp_round trigger list, else it is with user-defined decimal digits.
  • If a 'dp' is in dp_max or dp_min trigger lists, we get the maximum or the minimum stored value instead of the average.

Limits
This node only works with atomic values. In the case of dp whose value is a data structure, the user can:

  • default: the last value is used in triggered output.
  • put the dp in the dp_exclude list, it is sent as-is immediately.
  • add an explode node in input to generate atomic values from the structure.

9. notes about explode subflow

Using the RT/AVG filter subflow alone does not get the expected result in the case of Objects (structures). Example: see BreakerDIN where a dP (6) uses a structure to send 4 RT values.

The subflow Explode early decodes (using a decode user function) one data structure and adds the atomic values to the payload. It is recursive, and, of course, the new values must be defined also in alldevices, as _<dp>.<path> (e.g. _6.V or _6.Leack ), as PUSH (user can't GET/SET them).

Details

Not all JSON structures are handled as expected by 'explode'. It does not work with arrays.
The following structures will not be exploded correctly (from TRV device):

      dp 110 = [18,18,18,18,0,0,0]            // fixed size, week data

      dp 123 = {"count":4,
                "changes": [                          // variable size
                       {"time":"06:00","temp":16},
                       {"time":"10:00","temp":21},
                       {"time":"13:00","temp":21},
                       {"time":"23:00","temp":16}  ] }

Workaround: If it is required an 'explode' for such data, make a custom version of 'explode', or change the DECODE/ENCODE functions to avoid the arrays. Example:

   dp 110 = {
            "Mon":18,
            "Tue":18,
            "Wed":18,
            "Thu":18,
            "Fri":0,
            "Sat":0,
            "Sun":0 }

10. Functions library meteoUtils

This collection of functions is general enough to be useful in other weather projects as well. In node-red, in order to use it in every flow/node, it is implemented as a global singleton, built by the code 'On Start' in the 433 gateway startup node, see details.
In your function nodes, you can use it like so (from weather station process function node):

         ...
         if (context.global.meteoUtils.isDayChanged(RAINDAY)){
         ...
method parameters description
getDOY (aDate= null) returns the meteorological day-of-year. If aDate is missed or null, use now
isDayChanged (nowDay) returns true the first time and if the meteorological day is changed, else false; param (flow.)nowDay: a local unique name where it stores DOY
toFahrenheit (tc) converts a temperature from [°Celsius] to [°Fahrenheit]
toCelsius (tf) converts a temperature from [°Fahrenheit] to [°Celsius]
toKmHr (v) converts a speed from [m/s] to [Km/h]
evalHeatIndex (tc, RH) Returns the NOAA Heat Index [°C] (see here)
evalDewPoint (tc, RH) Returns the Dew Point [°C] (see here)
evalWindChill (tc, v, hi) Returns the Wind Chill [°C] (see here)
Clone this wiki locally