Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for VEVOR Wireless Weather Station 7-in-1 #3020

Closed
cipriancu opened this issue Aug 5, 2024 · 36 comments
Closed

Support for VEVOR Wireless Weather Station 7-in-1 #3020

cipriancu opened this issue Aug 5, 2024 · 36 comments

Comments

@cipriancu
Copy link

Hello,
I'm trying to decode the strings coming from a Vevor 7 in 1 yt60231 Weather Stations

https://www.amazon.com/VEVOR-Wireless-Stations-Forecast-Temperature/dp/B0CHFF77JS
I’m capturing the data with: rtl_433 -s 1000k -Y classic -f 868.3M -X "n=Vevor,m=FSK_PCM,s=87,l=87,r=89088"
And so far I have managed to figure out some measurements

The captured data looks like this :

time : 2024-08-05 09:02:56
model : Vevor count : 1 num_rows : 1 rows :
len : 963 data : fff8000aaaaaaaaaacaca54aa00f8f79d02e332010e03020b013802397a86e08721856ad008dafaab2f644ae30000fffff000155555555559594a95401f1ef3a05c664021c06041602700472f50dc10e430ad5a011b5f5565ec895c6000000000000000000000000000000000000000000000000000000000
codes : {963}fff8000aaaaaaaaaacaca54aa00f8f79d02e332010e03020b013802397a86e08721856ad008dafaab2f644ae30000fffff000155555555559594a95401f1ef3a05c664021c06041602700472f50dc10e430ad5a011b5f5565ec895c6000000000000000000000000000000000000000000000000000000000

breaking up the data I figure out this
fff8000aaaaaaaaaacaca54aa00f8f7 - this piece never changes
9d - this looks to have something to do with the battery - if the battery is low is 9d when it is good the value is 1d
02e3 - this is temperature, the formula to calculate it is Value in hex converted in decimals /10 minus 50
32 - humidity - Value in hex converted in decimals
010e - Unknown
030 - wind speed but I couldn't figure out the formula
20b - wind direction measured in degrees - Value in hex converted in decimals minus 257
01 - Unknown
38 - rain, the sensor is a tipping bucket rain gauge and it counts each tipping in hex i have no clue how it is converted in values displayed
02 - UVI index - the formula seems to be hex converted in decimals minus 1
397 - lux measurement Here i have a formula that works on small values but not o high-value
a86e087 - Unknown

21856ad008dafaab2f644ae30000fffff000155555555559594a95401f1e - this piece never changes
f - when the battery is 9d is f when battery is 1d is e
3a05c664021c06041602700472f50dc10e-Unknown
430ad5a011b5f5565ec895c6000000000000000000000000000000000000000000000000000000000 - this piece never changes

i can give more sample date

@zuckschwerdt
Copy link
Collaborator

Are you sure that you want -Y classic with FSK? Also 87 µs is a very uncommon value. Note that 8908 µs reset is far too long, that's why you see lots of 0's at the end. Reset should be maybe 20x (how many consecutive zeros you expect in the message) the bit length.
Best to look at a .cu8 sample.

@ProfBoc75
Copy link
Collaborator

Hi @cipriancu : Sounds like it's a Emax protocol but checksum failed can you try:

rtl_433 -R 215:vv -y ff8000aaaaaaaaaacaca54aa00f8f79d02e332010e03020b013802397a86e08721856ad008dafaab2f644ae30000

image

rtl_433 -R 215:vv -y fffff000155555555559594a95401f1ef3a05c664021c06041602700472f50dc10e430ad5a011b5f5565ec895c6000

image

And see the errors.

In your sample, your reset value is 10 x to big, so you have 2 messages in one.
For Emax, the pulse is 90 us and reset = 9000.

Try this flex:

 rtl_433 -s 1000k -f 868.3M -M level -X "n=Vevor,m=FSK_PCM,s=90,l=90,r=9000,preamble=caca54aa"

You may have 2 or more same messages for each signal transmit, it's normal.

Try also to capture .cu8 samples. rtl_433 -s 1000k -f 868.3M -S all

Bitbench Based on your data layout explanation, and my assumption

Notice that the rain gauge is probably on 2 bytes, ie 0x0138. This is a cumulative value, each time you have a tilt into the rain gauge this value is incremented. To know the corresponding mm/m² you need to do some tests and calculations, or you can trust your weather station and see the gap in mm for each tilt.

To calculate yourself:

  • Take the internal diameter of the rain gauge: for example diameter = 10 cm, radius = 5 cm --> surface = pi x radius² = 78.5398 cm²
  • Compare this surface to 1 m² = 10 000 cm² (100x100 cm) = 10000 / 78.5398 = 127.324, so each time the water is going into the gauge you need to multiply by 127.324 to get the 1 m² value.
  • With a 100 ml glass of water (0.1 L) => 0.1 * 127.324 = 12.7324 L/m² = 12.7324 mm/m²
  • Then, with this 0.1 L water, run gently, drop by drop, and count the number of tilts, for example = 64 tilts
  • The final result is: 12.7324 / Number of tilts = 12.7324/64 = 0.1989 mm/tilt , round to 0.2 mm/tilt.

The raw rain value must be multiplied by 0.2 to get the final rain value in mm/m².

The LUX values can coded like that (it's the case for Emax) : 1b + 15 bits, if first bit = 0 then LUX = 15 bits, if first bit = 1, LUX = 10 x 15 bits. UV and LUX are linked, so you may have to look at bit level into the UV data to get the figures. Check also the range from the user guide: LUX value from xx to yy could help to define the require number of bits.

Share more samples, note the temp / hum / rain / lux / uv / wind information from the weather station and we'll find/confirm the data layout and probably able to update the current Emax decoder.

@cipriancu
Copy link
Author

Hi Christian,

I chose -Y classic because the beginning of the code resembles the Universal Radio Hacker result. Since I managed to decode some measurements, it seemed like a good starting point.

The values 87 and 8908 came from rtl_433 guidance: -A g001_868.3M_1000k.cu8 "Use a flex decoder with -X 'n=name,m=FSK_PCM,s=87,l=87,r=89088'".

Here's the .cu8 sample:
g001_868.3M_1000k.zip

Bruno I'll try your guidance

Thanks both for your help!

@ProfBoc75
Copy link
Collaborator

@cipriancu : thanks, based on your cu8 sample, reset value is 1400 to get the 2 messages.

rtl_433 -M level -X "n=Vevor,m=FSK_PCM,s=90,l=90,r=1400,preamble=caca54aa" g001_868.3M_1000k.cu8

image

So try with:

 rtl_433 -s 1000k -f 868.3M -M level -X "n=Vevor,m=FSK_PCM,s=90,l=90,r=1400,preamble=caca54aa"

bitbench updated

@cipriancu
Copy link
Author

Bruno
sometimes times it breaks the data into two pieces other times dont
image
here's my Excel with sample data for wind speed and formulas for temperature humidity wind direction and UVI
Decode.xlsx

@ProfBoc75
Copy link
Collaborator

Thanks for the excel file ! I'll check and back later.

So reduce the reset to 1000 or 900 not less to get the 2 messages.

@ProfBoc75
Copy link
Collaborator

Hi @cipriancu

I drafted a decoder but I need more samples to decode properly the values, the ratio between the raw hexa value and the real values.

I confirm that same behavior as with Emax decoder, some data are coded with 0x0101 = 0 (offset 257) or 0x01 = 0 (offset 1)

Please test and share samples with the values you have on the weather display station.

@cipriancu
Copy link
Author

cipriancu commented Aug 7, 2024

Bruno, I think i made some progress
1 Breaking into pieces didn’t work despite adjusting the reset. Using -Y classic was the only way to get consistent results. Now, my command is: rtl_433 -s 1000k -Y classic -M level -f 868M -X "n=Vevor,m=FSK_PCM,s=90,l=90,r=1400,preamble=caca54aa" The results now break into two equal pieces.
2 I changed my Excel to read the new format
3. I made some adjustments in bitbench https://triq.net/bitbench#c=00f8f71d02f5370101000210015d010101a902aa21856ad008dafaab2f644ae30000&f=TYPE%204h%20CHANNEL%204h%20ID%2016h%20FLAGS_BAT%208h%20TEMP_C%2016d%20HUM%208d%20%20WIND_SPEED%3F%2016d%20WIND_GUST%2012d%20WIND_DIR%2012d%20RAIN%2016d%20UVI%20d%20LUX_MSB%20b%20LUX_LSB%2015d%20CTR%208h%20CHECK_SUM%208h%20CTR%2BONE%208h%20%3F%20112h&z=1&cw=4
4. The LUX formula for low values seems to be ROUND(((BitBench decimal - 257)/1007), 2), but I need to test with higher values.
5. For wind, there are two measurements: wind speed (strings 15-18) and wind gust (strings 19-21).
6. Wind speed formula: =ROUND(((HEX2DEC(strings 15,16,17,18) / 34) - 7.63), 1).
7. Wind gust formula: =ROUND((HEX2DEC(strings 19,20,21) / 86) - 0.06, 1).

I need higher values to verify the formulas, but up to 2 m/s they seem accurate (except for 0).

For rain, I will test with 100 ml poured at once to see the indicator. The display resets to 0 after inactivity, but the string retains the same value.

Thanks for your help!

Decode.xlsx

@ProfBoc75
Copy link
Collaborator

ProfBoc75 commented Aug 8, 2024

Hi @cipriancu

Thanks a lot, with your last decode.xlsx I found useful information that confirm some assumption and I need to correct few things in my drafted decoder, but I'm very close to the solution.

1- Ok, and in fact, for the decoder, I keep one row and looking the 2 preambles into the row, so not an issue if you still have one row instead of two, with bitbench we can easily split it and add the caca54aa preamble, but I understand for your excel file, it's easier to get directly the 2 rows.
2- Ok, good.
3- My last update with your codes : bitbench

4- LUX value is based on 16 bits (4 nibbles, 31/32/33/34), and first bit + 15 bits, in fact you just need to offset 257 to get LUX value, you don't need to convert the result in KLUX value, so you don't need to divide by 1007, this let us have a better precision than the weather display in KLUX, if the first bit is = 1 (so the 16 bits > 33025) , then x 10 the 15 bits decimal value . ( 33025 = 32768 + 257)

=IF(HEX2DEC(LUX_16bits)>33025;(HEX2DEC(LUX_16bits)-33025)*10;HEX2DEC(LUX_16bits)-257)
Result is in LUX (not KLUX)

5- Ok for wind speed, not ok for wind gust, the nibble 21 is always = 0, so you just need 19 & 20 for wind gust.

6- Wind speed, (km/h = 3.6 x m/s)

m/s formula =ROUND(((HEX2DEC(strings 15,16,17,18) - 257) / 36), 1). 
kmh formula =ROUND(((HEX2DEC(strings 15,16,17,18) - 257) / 10), 1).

7- Wind gust

m/s formula: =ROUND((HEX2DEC(strings 19,20) / 1.5 / 3.6), 1).
kmh formula: =ROUND((HEX2DEC(strings 19,20) / 1.5), 1).

Notice that we prefer to get km_h as it is handle by the -C option to convert to customary mi_h, the m/s is not cover by convert feature, this is the subject of another opened issue, but I put here the both formula.

I will update your excel file accordingly tomorrow.

@cipriancu
Copy link
Author

Bruno
I’ve confirmed the LUX formula works for higher values:

00f8f79d031d2a0113050201015d04987378817921856ad008dafaab2f644ae30000 (LUX value = 60)
00f8f79d03282e0101020205016d059b810c350d21856ad008dafaab2f644ae30000 (LUX value = 67.8)
00f8f71d03182f012a080203017e069d5d5c135d21856ad008dafaab2f644ae30000 (LUX value = 72.6)

I also tested the rain sensor by pouring 100 ml of water:

15 tips: Rain rate = 20.6 mm/h
16 tips: Rain rate = 21.9 mm/h
17 tips: Rain rate = 23.3 mm/h
Each tip adds 1.3 mm ish (I think is something more than 1.3) to the rain measurement. The rain rate remains steady for 10 minutes and then resets to 0 if no more rain is detected.
Thanks

@ProfBoc75
Copy link
Collaborator

Good.

For the rain value, you should change the weather display to cumulative or total value and not rain rate mm/h, because this one is an average and each hour the value is reset to 0, so not possible to get the figures, i.e how many mm / tips.

And about the rain test, you must pour slowly drip by drip, like the real rain. What is the diameter of the rain gauge ?

Here your excel updated, I keep 1 tips = 1 mm for the moment into the formula. (with the offset 257 too)

Decode_ProfBoc75_reviewed.xlsx

@cipriancu
Copy link
Author

ok
Today's cumulative rain is 14.8 mm with 65 tips, with a total 400 ml of water. This gives about 6 ml per tip. The rain gauge has a diameter of 13.5 cm, which means the area is approximately 143.1 cm².
400ml = 400 cm3 in theory measured quanity shoud be (400/143.38 )*10 = 27.94490084 mm

This is significantly different from the 14.8 mm displayed.
Any thoughts on this discrepancy? but to be honest this is the last thing that i'm interested in if i know that each tip is 6 ml i'm more than happy

My goal is to read this vevor wheather station with and ESP32 that have OpenMQTTGateway on it and to push measurents in home assistant

@ProfBoc75
Copy link
Collaborator

ProfBoc75 commented Aug 8, 2024

I'm answering to myself, as I found the FCC ID of the device (915MHz version) 2AQBD-R56.

The original manufacturer is Fujian Youtong Industries Co., Ltd. rebrand under Vevor name.

If I'm not wrong the diameter is around 15 cm external photos

From your test, I understood a total of 17 tips for 0.1 L glass ( 100ml )

The result is 0.33 mm/tips

Diameter cm Radius cm Surface cm² Ratio m² / Surface Glass Liter Glass mm/m² Glass Num of tips mm/m²/tips
15.00 7.50 176.71 56.59 0.10 5.66 17.00 0.33

The result may be refined if you test 2 or 3 times more, and if you confirm the funnel diameter (the widest internal part at the top of the funnel ).

In another hand, from the user guide, the Rain range is from 0-12999 mm/m². And based on 2 bytes values, we have 65536 tips which give : 12999 / 65536 = 0.198 mm/tips, could be round to 0.2 mm , so not exactly 0.33 mm, the reason why it needs to be refined/confirmed. Notice that for other Emax Weather station using the same protocol, it's 0.2 mm/tips.

Edit: I did not see your previous answer while writing this comment 😄 So, the 14.8 mm for 65 tips = 14.8 / 65 = 0.227 mm/tips

But if I calculate from your values we have 0.4 mm/m²/tips

Diameter Radius Surface cm² Ratio m² / Surface Glass ( Liter ) Glass ( mm/m² ) Glass ( Num of tips ) mm/m²/tips
13.50 6.75 143.14 69.86 0.10 6.99 17.00 0.41
13.50 6.75 143.14 69.86 0.40 27.94 65.00 0.43

Edit 2: the 6 ml/tips must be converted into mm/m² so 0.006 L x 69.86 = 0.43 mm/m²/tips

@ProfBoc75
Copy link
Collaborator

@cipriancu

I just updated the decoder accordingly, can you try to test the rtl_433 version from branch feat-vevor_7in1 , see PR #3023

My test with your last lux code (just added the preamble in front of the code to get a result):

rtl_433 -y aaaacaca54aa00f8f71d03182f012a080203017e069d5d5c135d21856ad008dafaab2f644ae30000

image

@cipriancu
Copy link
Author

Bruno
I installed the decoder, and the results look great! I adjusted the display to show km/h to match the readings from rtl_433.

Observations:

A simple rtl_433 -f 868M command works, but some measurements aren’t captured. When I use -Y classic, all measurements are captured correctly. It seems that without -Y classic, the string isn’t properly split into two pieces.
Wind max speed: The display value is usually 0.1 km/h higher than the readings. I'll try to get more readings and to see if I can refine the formula
Rain total: The display shows 78 mm, while the readings show a total rainfall of 67.5 mm.

Thank you for your time and help with this

@ProfBoc75
Copy link
Collaborator

ProfBoc75 commented Aug 9, 2024

Hi @cipriancu:

the string isn’t properly split into two pieces

Into the decoder, we don't care as I keep one row, (reset = 9000), and within a loop, I'm searching the first preamble, then extract the first 21 bytes, decode the data, if it's ok, then show the values, if not ok, search for the second preamble, extract the next 21 bytes and decode and so on.

May be add -M level option to get the central frequency of the signal and adjust to it may help also, and you will see the signal quality too, if you have a bad reception or a bad antenna, check rssi / snr / noise dB values.

Wind max speed: The display value is usually 0.1 km/h higher than the readings

Probably a round value, we can add 0.1f to final value.

float gust_kmh    = 0.1f + gust_raw / 1.5f ;

Rain total: The display shows 78 mm, while the readings show a total rainfall of 67.5 mm.

We need to change the 0.43 ratio to 0.5 (line 112):

67.5 / 0.43 =  157   --> + 257 = 0x19E in the original message
78 / 157 = 0.5 (rounded value)

float rain_mm     = rain_raw * 0.5f; // calculation is 0.43f ratio

@cipriancu
Copy link
Author

Bruno.
I ran a few more tests and think I’ve nailed it. I reset both the external and internal units to start from 0 with the rain measurements, manually tipping the sensor to generate values. Here’s what I discovered:

float rain_mm = rain_raw * 0.233f;
I compiled the build with this new formula, and it’s working perfectly!

The only issue I’m noticing is with rounding. The display doesn’t round numbers; it just takes digits as they come, while rtl_433 rounds the values. This affects the conversion for lux to klux and wind gust as well.

Thanks again for your time and help with this!

@ProfBoc75
Copy link
Collaborator

@cipriancu

Good job ! As you reset all, did you notice if the sensor changed ID ?

@ProfBoc75
Copy link
Collaborator

Ciprian

I merged the PR with your updates. Enjoy !

Thanks for your contribution. If there is any error, do not hesitate and share here your findings, we'll update accordingly.

@cipriancu
Copy link
Author

@cipriancu

Good job ! As you reset all, did you notice if the sensor changed ID ?

nope nothing was changed after reset other than string for rain which went to 0101
the ID f8f7 is still the same
and the end of the string too 21856ad008dafaab2f644ae30000

@JV16Bar
Copy link

JV16Bar commented Aug 15, 2024

Hi, I'm successfully running rtl_433 with the new decoder, and it gives me good results. My unit is a wifi version (YT60234), but it's almost sure that the outdoor units are identical, hence the protocol is the same. Do you guys know, if the pressure sensor values can be decoded?

@zuckschwerdt
Copy link
Collaborator

Ambient pressure sensors are always mounted in the display units. There is no pressure difference to outside ;)

@JV16Bar
Copy link

JV16Bar commented Aug 15, 2024

You're absolutely right :)
OT: does anybody accidentally knows if the outdoor unit is available somewhere for sale separately? The outdoor unit with rtl_433 would be a good weather station and could be integrated in home automation/nodered/etc.

@cipriancu
Copy link
Author

I asked that already buy they dont
image

@ProfBoc75
Copy link
Collaborator

ProfBoc75 commented Aug 15, 2024

Hi, I'm successfully running rtl_433 with the new decoder, and it gives me good results. My unit is a wifi version (YT60234), but it's almost sure that the outdoor units are identical, hence the protocol is the same. Do you guys know, if the pressure sensor values can be decoded?

Hi @JV16Bar , since it's a wifi version, this means that the data is probably sent to the cloud if you have this information in the application and here you may be able to analyze and get the figures. If your are able to capture the wifi frame with Wireshark you may be able to get the data. This needs some knowledge and work ...

Edit: from https://fccid.io/2AQBD-60234 internal photos show a nice Ai-Thinker-WB2-12F, another possibility here to deep dive the weather station.

@vlovmx
Copy link

vlovmx commented Aug 28, 2024

Hi, I'm successfully running rtl_433 with the new decoder, and it gives me good results. My unit is a wifi version (YT60234), but it's almost sure that the outdoor units are identical, hence the protocol is the same. Do you guys know, if the pressure sensor values can be decoded?

Hi @JV16Bar , since it's a wifi version, this means that the data is probably sent to the cloud if you have this information in the application and here you may be able to analyze and get the figures. If your are able to capture the wifi frame with Wireshark you may be able to get the data. This needs some knowledge and work ...

Edit: from https://fccid.io/2AQBD-60234 internal photos show a nice Ai-Thinker-WB2-12F, another possibility here to deep dive the weather station.

I did this and currently have Home Assistant ingesting sensor values. I bought the wifi version and didn't want to dedicate a full SDR dongle to just capture this information all of the time.

I performed a packet capture and found the URL the station calls containing sensor values. I then used that to write a PHP script that parses sensor data, it then formats a JSON payload that ultimately gets sent to Home Assistant via the Hassio REST API.

Luckily, the base station sends the data unencrypted to weather cloud services. This is what I initially suspected and it was what drove me to even attempt this. I thought such an affordable device would not have an advanced enough SoC to deal with cryptographic handshakes like SSL/TLS.

The way I redirected station traffic to my script was via DNS record. I run Pi-Hole as DNS server in my IoT vLAN. I just created a DNS record for rtupdate.wunderground.com to resolve to my local docker container which is where I have an NGINX and PHP stack running along with my custom PHP page. If anyone is interested I can share it here as long it's allowed in this forum since it's not rtl_433 related.

image

Edit: Typo

@zuckschwerdt
Copy link
Collaborator

I can share it here as long it's allowed in this forum since it's not rtl_443 related.

Any knowledge, discussion or hacks interesting to rtl_433 users or the the wider community is fine with us.

@vlovmx
Copy link

vlovmx commented Aug 28, 2024

Thank you @zuckschwerdt.

This is in "work in progress" but it works so far.

This script redirects weather information uploaded to Weather Underground by the VEVOR 7-in-1 Wi-Fi Solar Self-Charging Weather Station (Model YT60234) into Home Assistant.
The base station sends weather data to Weather Underground service as the URL format below.
x represent values

http://rtupdate.wunderground.com/weatherstation/updateweatherstation.php?ID=XXXXX&PASSWORD=XXXXX&dateutc=xxxx-x-xx&baromin=x&tempf=x&humidity=x&dewptf=x&rainin=x&dailyrainin=x&winddir=x&windspeedmph=x&windgustmph=x&UV=x&solarRadiation=x

How to deploy

  1. You will need a local web server in your network, you can create an instance of apache, nginx or any other web server that is configured to interpret PHP. Using docker should make it quick and painless to set it up, make sure the server runs on port 80. Once installed, create a directory called "weatherstation" under /var/www/html and copy this script to it. The full path should look something like this. /var/www/html/weatherstation/updateweatherstation.php . You can now start this web server instance, take note of the IP address.

  2. We can redirect the base station's traffic to the web server by creating a DNS record in your router if supported but an easier way to do this is by using Pi-Hole. The record should resolve as shown below.

rtupdate.wunderground.com = (web server IP address)

  1. Activate pairing mode in the base station by pressing the BARO key for 5 seconds, connect to the WiFi network called WWS_XXXXX, navigate to http://192.168.1.1, under the WeatherUnderground section enter any value for Station ID and Station Key, then enable the "Upload wunderground.com" checkbox. Click Apply and wait for it to connect to your previously configured WiFi network.

  2. Replace the relevant details in this script such as Home Assistant IP, token and time zone. Allow 1 to 2 minutes for the base station to upload sensor data, you should now have multiple sensors with entity prefix "sensor.weather_station_..."

<?php
//Author: @vlovmx
//This script redirects weather information uploaded to Weather Underground by the VEVOR 7-in-1 Wi-Fi Solar Self-Charging Weather Station (Model YT60234) into Home Assistant. 
// The base station sends weather data to Weather Underground service as the URL format below. 
// x represent values

//http://rtupdate.wunderground.com/weatherstation/updateweatherstation.php?ID=XXXXX&PASSWORD=XXXXX&dateutc=xxxx-x-xx&baromin=x&tempf=x&humidity=x&dewptf=x&rainin=x&dailyrainin=x&winddir=x&windspeedmph=x&windgustmph=x&UV=x&solarRadiation=x

// How to deploy

// 1. You will need a local web server in your network, you can create an instance of apache, nginx or any other web server that is configured to interpret PHP. Using docker should make it quick and painless to set it up, make sure the server runs on port 80. Once installed, create a directory called "weatherstation" under /var/www/html and copy this script to it. The full path should look something like this. /var/www/html/weatherstation/updateweatherstation.php . You can now start this web server instance, take note of the IP address. 

// 2. We can redirect the base station's traffic to the web server by creating a DNS record in your router if supported but an easier way to do this is by using Pi-Hole. The record should resolve as shown below. 
// rtupdate.wunderground.com = (web server IP address)

// 3. Activate pairing mode in the base station by pressing the BARO key for 5 seconds, connect to the WiFi network called WWS_XXXXX, navigate to http://192.168.1.1, under the WeatherUnderground section enter any value for Station ID and Station Key, then enable the "Upload wunderground.com" checkbox. Click Apply and wait for it to connect to your previously configured WiFi network. 

// 4. Replace the relevant details in this script such as Home Assistant IP, token and time zone. Allow 1 to 2 minutes for the base station to upload sensor datwe, you should now have multiple sensors with entity prefix "sensor.weather_station_..."


$attributes = array(
    "Barometric Pressure" => array(
        "value" => isset($_GET['baromin']) ? $_GET['baromin'] : '',
        "unit" => "inHg",
        "device_class" => "atmospheric_pressure" 
    ),
    "Temperature" => array(
        "value" => isset($_GET['tempf']) ? $_GET['tempf'] : '',
        "unit" => "°F",
        "device_class" => "temperature" 
    ),
    "Humidity" => array(
        "value" => isset($_GET['humidity']) ? $_GET['humidity'] : '',
        "unit" => "%",
        "device_class" => "humidity" 
    ),
    "Dew Point" => array(
        "value" => isset($_GET['dewptf']) ? $_GET['dewptf'] : '',
        "unit" => "°F",
        "device_class" => "temperature" 
    ),
    "Rainfall" => array(
        "value" => isset($_GET['rainin']) ? $_GET['rainin'] : '',
        "unit" => "in",
        "device_class" => "precipitation" 
    ),
    "Daily Rainfall" => array(
        "value" => isset($_GET['dailyrainin']) ? $_GET['dailyrainin'] : '',
        "unit" => "in",
        "device_class" => "precipitation" 
    ),
    "Wind Direction" => array(
        "value" => isset($_GET['winddir']) ? $_GET['winddir'] : '',
        "unit" => "°",
        "device_class" => "none" 
    ),
    "Wind Speed" => array(
        "value" => isset($_GET['windspeedmph']) ? $_GET['windspeedmph'] : '',
        "unit" => "mph",
        "device_class" => "wind_speed" 
    ),
    "Wind Gust Speed" => array(
        "value" => isset($_GET['windgustmph']) ? $_GET['windgustmph'] : '',
        "unit" => "mph",
        "device_class" => "wind_speed" 
    ),
    "UV Index" => array(
        "value" => isset($_GET['UV']) ? $_GET['UV'] : '',
        "unit" => "index",
        "device_class" => "none" 
    ),
    "Solar Radiation" => array(
        "value" => isset($_GET['solarRadiation']) ? $_GET['solarRadiation'] : '',
        "unit" => "W/m²",
        "device_class" => "irradiance" 
    )
);

$dateutc = isset($_GET['dateutc']) ? $_GET['dateutc'] : '';

if ($dateutc) {
    $datetime = new DateTime($dateutc, new DateTimeZone('UTC'));
    $datetime->setTimezone(new DateTimeZone('America/New_York')); // <---- Replace with local timezone 
    $local_time = $datetime->format('Y-m-d H:i:s');
} else {
    $local_time = '';
}

$home_assistant_url_base = 'http://xx.xx.xx.xx:8123/api/states/'; // <---- Replace with Home Assistant IP
$access_token = 'xxxxxxxxxxxx'; // <---- Replace with your long-lived access token

foreach ($attributes as $attribute_name => $attribute_data) {
    $sensor_name = 'sensor.weather_station_' . strtolower(str_replace(' ', '_', $attribute_name));
    $data = array(
        "state" => $attribute_data['value'],
        "attributes" => array(
            "friendly_name" => $attribute_name,
            "unit_of_measurement" => $attribute_data['unit'],
            "device_class" => $attribute_data['device_class'],
            "measured on" => $local_time
        )
    );

    $json_data = json_encode($data);
    $home_assistant_url = $home_assistant_url_base . $sensor_name;
    $ch = curl_init($home_assistant_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer ' . $access_token,
        'Content-Type: application/json'
    ));
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
    $response = curl_exec($ch);
    if ($response === false) {
        echo 'cURL Error: ' . curl_error($ch);
    }
}

// The VEVOR base station expects a "success" string after submitting sensor values. If this is not returned the base station performs 2 more attempts consecutively. 
echo "success";

curl_close($ch);
?>

@zenguru84
Copy link

ne. Allow 1 to 2 minutes for the base station to upload sensor datwe, you should now have multiple sensors

hey @vlovmx!
thanks for sharing!
I'm about to buy a Vevor weather station, but I'm curious: how often do the sensors update?

@JV16Bar
Copy link

JV16Bar commented Sep 30, 2024

If you're asking the external sensor unit, it sends update to the base station every 20 seconds.

@zenguru84
Copy link

If you're asking the external sensor unit, it sends update to the base station every 20 seconds.

good to know, thanks, but I was asking about the request that sends the data to rtupdate.wunderground.com.

@vlovmx
Copy link

vlovmx commented Sep 30, 2024

@JV16Bar, the base station pushes sensor data to rtupdate.wunderground.com every 60 seconds.

@hash6iron
Copy link

hash6iron commented Oct 29, 2024

I'd like to use your script. Could you help me to run it?

@zuckschwerdt
Copy link
Collaborator

@hash6iron please don't full-quote. Read http://www.catb.org/esr/faqs/smart-questions.html on how to write a good question, esp. the "Be precise and informative about your problem" section.

@drew442
Copy link

drew442 commented Nov 21, 2024

for compatibility with home assistant using what's discussed above, should I buy YT60234 or YT60231?

I'm confused because Vevor says yt60231 doesn't have wifi but @cipriancu says that's what they're using?

@zenguru84
Copy link

@drew442
both models use RF to send data to indoor display.
the one with wifi only sends data to weather underground. you want this if you gonna use @vlovmx method.
you can use any of them with rtl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants