DIY Zigbee weather station

Hi sloma
As I’ve mentioned in my previous post, I’ve programmed the CC2530 with PTVO using “Router” option as low consumption mode “PSM” was throwing errors at compilation (limited functionalities maybe due to non free license) . So maybe with “PSM” option, the power consumption would be drastically reduced.

In the HA MQTT sensors now require a different setup: MQTT Sensor - Home Assistant

# Example configuration.yaml entry
mqtt:
  sensor:
   
      - state_topic: "zigbee2mqtt/0x00124b000633d676"
        unit_of_measurement: "°C"
        value_template: "{{ value_json.temperature_l1| round(1) }}"
        availability_topic: "zigbee2mqtt/bridge/state"
        payload_available: "online"
        payload_not_available: "offline"
        json_attributes_topic: "zigbee2mqtt/0x00124b000633d676/attributes" 
        icon: mdi:thermometer-lines  
        name: "Temperature shed"
1 Like

Thanks Doublet for this excellent post and response.
I’ve tried your new code in my configuration.yaml. Still I’m getting “Temperature shed : Unavailable”.
When I try {{ value_json.temperature_l1| round(1) }} in Developers Tools → Template, I get the following error “UndefinedError: ‘value_json’ is undefined”.
I’ve checked that the weather station values are written in the file /config/zigbee2mqtt/state.json. If I replace “state_json.temperature_l1” by “state.temperature_l1” or “state.json.temperature_l1” I get “Temperature shed : Unavailable”
I’m lacking of ideas of where could be the issue

Did you check the output via the zigbee2mqtt add on?

Go the webgui of zigbee2mqtt
Search for your CC2530 device name like 0x00124b000fe64efd
Look at state, here you should see the actual values being transmitted from the CC2530

if not, then there is another challenge. :slight_smile:

under Zigbee2MQTT addon I can see values of humidity, temperature and pression being updated both in State of the CC2530 device and in Logs.
Example of State:

{
    "device_l1": "00",
    "device_l6": "00",
    "humidity_l1": 24.7,
    "humidity_l6": 45.2,
    "l1": 24.705,
    "l6": 0,
    "l8": 3.3,
    "last_seen": "2023-05-08T23:05:39+03:00",
    "linkquality": 94,
    "pressure_l1": 92788,
    "pressure_l6": 100785,
    "state_l1": "OFF",
    "state_l3": "OFF",
    "state_l5": "OFF",
    "state_l7": "ON",
    "temperature_l1": 28.1,
    "temperature_l6": 26.5,
    "voltage_l8": 3.3,
    "action": null,
    "l10": null,
    "l11": null,
    "l12": null,
    "l13": null,
    "l14": null,
    "l15": null,
    "l16": null,
    "l2": null,
    "l3": null,
    "l4": null,
    "l5": null,
    "l7": null,
    "l9": null,
    "state_l10": null,
    "state_l11": null,
    "state_l12": null,
    "state_l13": null,
    "state_l14": null,
    "state_l15": null,
    "state_l16": null,
    "state_l2": null,
    "state_l4": null,
    "state_l6": null,
    "state_l8": null,
    "state_l9": null
}

Example of Logs:

2023-05-08 23:06:12MQTT publish: topic 'zigbee2mqtt/weather_station_CC2531', payload '{"action":null,"device_l1":"00","device_l6":"00","humidity_l1":24.7,"humidity_l6":45.2,"l1":24.66,"l10":null,"l11":null,"l12":null,"l13":null,"l14":null,"l15":null,"l16":null,"l2":null,"l3":null,"l4":null,"l5":null,"l6":0,"l7":null,"l8":3.3,"l9":null,"last_seen":"2023-05-08T23:06:12+03:00","linkquality":92,"pressure_l1":92791,"pressure_l6":100785,"state_l1":"OFF","state_l10":null,"state_l11":null,"state_l12":null,"state_l13":null,"state_l14":null,"state_l15":null,"state_l16":null,"state_l2":null,"state_l3":"OFF","state_l4":null,"state_l5":"OFF","state_l6":null,"state_l7":"ON","state_l8":null,"state_l9":null,"temperature_l1":28.1,"temperature_l6":26.5,"voltage_l8":3.3}'

Somehow the dashboard is not able to read the values of humidity_l1, temparature_l1, pressure_l1.
But the dashboard is able to read the updated value of “l1” which randomly takes the value of either humidity or temperature or pressure

After some investigation and reading the following post ’ Template variable error: 'value_json' is undefined - mqtt - #18 by TermeHansen’, it seems that the input json (State) is badly formatted for some entries, hence the lovelace dashboard is showing “unavailable” in some cases. The issue is that I can’t find where is the bad formatting in the json I’ve provided in my post above (couldn’t find additional space, return carriage…).
So still investigating

stupid question: did you use the latest PTVO firmware?

I’m using PTVO version of 7th of Feb 2023

I will see if I can find on the web an earlier version and test it

Today I’ve used PTVO version 2021-12-30 to generate the Hex. Same issue of “unavailable” sensor output in loveloace dashboard. So the issue doesn’t seem to be from the Sate json.

I have a Tuya temperature and humidity device. I’ve paired it with my CCS2531 zigbee coordinator. Lovelace dashboard is showing its default temperature and humidity values.
Related State json :

{
    "battery": 100,
    "humidity": 38.13,
    "last_seen": "2023-05-12T18:47:16+03:00",
    "linkquality": 86,
    "temperature": 23.84,
    "voltage": 3000
}

I’ve tried to configure a “manual” temparature sensor in configuration.yaml as follows:

mqtt:
  sensor:
      - state_topic: "zigbee2mqtt/weather_station_CC2531"
        unit_of_measurement: "°C"
        value_template: "{{ value_json.temperature_l1 | round(1) }}"
        availability_topic: "zigbee2mqtt/bridge/state"
        payload_available: "online"
        payload_not_available: "offline"
        json_attributes_topic: "zigbee2mqtt/weather_station_CC2531/attributes" 
        icon: mdi:thermometer-lines  
        name: "Temperature shed"
        unique_id: cc2530_temperature_l1
        
      - state_topic: "zigbee2mqtt/Tuya_T_H"
        unit_of_measurement: "°C"
        value_template: "{{ value_json.temperature | round(1) }}"
        availability_topic: "zigbee2mqtt/bridge/state"
        payload_available: "online"
        payload_not_available: "offline"
        json_attributes_topic: "zigbee2mqtt/Tuya_T_H/attributes" 
        icon: mdi:thermometer-lines  
        name: "Temperature tuya"
        unique_id: temp_tuya

Lovelace dashboard is showing Temperature tuya as Unavailable.
With both PTVO and Tuya State json it’s not working. So it doesn’t seem that the issue is related to bad formatting of json.
Back to square zero for investigations …

After giving up debugging why the value_json payload is not being parsed within mqtt sensor, I’ve decided to parse it using Node-Red then handle the separated outputs through yaml (not by Node-Red).
It is working now for BME280 Temp, Humidity and Pressure.

Below you may find the Node-Red export of the Flow:

[{"id":"edec0f840215002e","type":"tab","label":"Weather Station Zigbee CC2530","disabled":false,"info":"","env":[]},{"id":"f186a88e563dd4b4","type":"mqtt in","z":"edec0f840215002e","name":"","topic":"zigbee2mqtt/CC2530_Weather_Station/#","qos":"2","datatype":"auto-detect","broker":"12edb785fb5ab57c","nl":false,"rap":true,"rh":0,"inputs":0,"x":220,"y":460,"wires":[["1c0255251db1567f","6d7279bde2905cba","60f49c16166f59e9","f2f73106f88a90cb","ca7d346a5e84fbf4"]]},{"id":"9fbe852074ce5ced","type":"debug","z":"edec0f840215002e","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":360,"wires":[]},{"id":"b32f6a1ccb113f77","type":"debug","z":"edec0f840215002e","name":"debug 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":460,"wires":[]},{"id":"159da52485cd1702","type":"debug","z":"edec0f840215002e","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":560,"wires":[]},{"id":"1c0255251db1567f","type":"debug","z":"edec0f840215002e","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":280,"y":400,"wires":[]},{"id":"6d7279bde2905cba","type":"function","z":"edec0f840215002e","name":"function 1","func":"var p = msg.payload\nvar temp = p.temperature_l1\nvar hum = p.humidity_l1\nvar pres = p.pressure_l1\nmsg.payload=temp\n//msg.payload = hum\n//msg.payload=pres\n//msg.temp = temp\n//msg.hum= hum\n//msg.pres = pres\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":400,"wires":[["9fbe852074ce5ced","c2db247511ff6ccb"]]},{"id":"60f49c16166f59e9","type":"function","z":"edec0f840215002e","name":"function 2","func":"var p=msg.payload\nvar temp = p.temperature_l1\nvar hum = p.humidity_l1\nvar pres = p.pressure_l1\n//msg.payload=temp\nmsg.payload=hum\n//msg.payload=pres\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":500,"wires":[["b32f6a1ccb113f77","c914e17f344a640d"]]},{"id":"f2f73106f88a90cb","type":"function","z":"edec0f840215002e","name":"function 3","func":"var p = msg.payload\nvar temp = p.temperature_l1\nvar hum = p.humidity_l1\nvar pres = p.pressure_l1\n//msg.payload=temp\n//msg.payload = hum\nmsg.payload=pres\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":600,"wires":[["159da52485cd1702","febdf43d819adf59"]]},{"id":"eb1d27c9b2a62ffa","type":"debug","z":"edec0f840215002e","name":"debug 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":240,"y":600,"wires":[]},{"id":"c2db247511ff6ccb","type":"mqtt out","z":"edec0f840215002e","name":"Weather_Station_T","topic":"zigbee2mqtt/Weather_Station_T","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"12edb785fb5ab57c","x":670,"y":400,"wires":[]},{"id":"a49b6ce0e1b94e0b","type":"mqtt in","z":"edec0f840215002e","name":"","topic":"zigbee2mqtt/Weather_Station/#","qos":"2","datatype":"auto-detect","broker":"12edb785fb5ab57c","nl":false,"rap":true,"rh":0,"inputs":0,"x":210,"y":540,"wires":[["eb1d27c9b2a62ffa"]]},{"id":"c914e17f344a640d","type":"mqtt out","z":"edec0f840215002e","name":"Weather_Station_H","topic":"zigbee2mqtt/Weather_Station_H","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"12edb785fb5ab57c","x":670,"y":500,"wires":[]},{"id":"febdf43d819adf59","type":"mqtt out","z":"edec0f840215002e","name":"Weather_Station_P","topic":"zigbee2mqtt/Weather_Station_P","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"12edb785fb5ab57c","x":670,"y":600,"wires":[]},{"id":"ca7d346a5e84fbf4","type":"function","z":"edec0f840215002e","name":"function 4","func":"var p = msg.payload\nvar wind_v = p.l8\nmsg.payload = wind_v\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":700,"wires":[["b932c3beca88dbdb","37f511bc4ede0b1a"]]},{"id":"37f511bc4ede0b1a","type":"mqtt out","z":"edec0f840215002e","name":"Weather_Station_Wind_V","topic":"zigbee2mqtt/Weather_Station_Wind_V","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"12edb785fb5ab57c","x":690,"y":700,"wires":[]},{"id":"b932c3beca88dbdb","type":"debug","z":"edec0f840215002e","name":"debug 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":640,"y":660,"wires":[]},{"id":"12edb785fb5ab57c","type":"mqtt-broker","name":"","broker":"localhost","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

and the configuration.yaml:

homeassistant:
  packages: !include_dir_named packages

# Loads default set of integrations. Do not remove.
default_config:

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

# Text to speech
tts:
  - platform: google_translate

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
#sensor: !include_dir_merge_list sensors


mqtt:
  sensor:
      - name: "Temperature shed"
        state_topic: 'zigbee2mqtt/Weather_Station_T'
        unit_of_measurement: "°C"
        icon: mdi:thermometer-lines
        value_template: "{{value_json | round(2)}}"
        
      - name: "Humidity shed"
        state_topic: 'zigbee2mqtt/Weather_Station_H'
        unit_of_measurement: "%"
        icon: mdi:water-percent
        value_template: "{{value_json | round(2)}}"
        
      - name: "Pressure"
        state_topic: 'zigbee2mqtt/Weather_Station_P'
        unit_of_measurement: "hpa"
        icon: mdi:weight
        value_template: "{{value_json | round(0)}}"

      - name: "Wind voltage"
        state_topic: 'zigbee2mqtt/Weather_Station_Wind_V'
        unit_of_measurement: "V"
        icon: mdi:call-made
        value_template: "{{value_json | round(2)}}"

sensor:
  - platform: history_stats
    name: Daily rain clicks
    entity_id: switch.CC2530_Weather_Station_l5
    state: 'off'
    type: count
    start: '{{ now().replace(hour=0, minute=0, second=0) }}'
    end: '{{ now() }}'


template:
  - sensor:
      - name: "Rainfall today"
        unit_of_measurement: "mm"
        icon: mdi:water
        state: >-
          {% set count = states('sensor.daily_rain_clicks') | int %}
          {% set mm_per_pulse = 0.30303 %}
          {% set mm = count * mm_per_pulse %}
          {{ mm|round(1, 'floor') }} 

      - name: "Absolute Humidity shed"
        unit_of_measurement: "g/m³"
        icon: mdi:water
        state: >-
          {% set h, t = states('sensor.humidity_shed') | float, states('sensor.temperature_shed') %}
          {% if not h or t == 'unknown' -%}
            'unknown'
          {%- else %}
            {% set t = t | float %}
            {{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(1) }}
          {% endif %}

      - name: "Dewpoint shed"
        unit_of_measurement: "°C"
        icon: mdi:coolant-temperature
        state: >-
          {{ (log( states('sensor.humidity_shed')|int / 100 ) + 18.678 * states('sensor.temperature_shed')|float / (257.14 + states('sensor.temperature_shed')|float ) )| round (1) }}  

      - name: "WindSpeed"
        unit_of_measurement: "m/s"
        icon: mdi:weather-windy
        # m_per_pulse = (r * 2 * Pi)/2 = (0.09 * 2 * 3.14)/2 = 0.2862 m
        state: >-
          {% set count = states('sensor.CC2530_Weather_Station_l6') | int %}
          {% set m_per_pulse = 0.2826 %} 
          {% set mps = count * m_per_pulse %}
          {{ mps|round(1) }}
          
      - name: "WindForce"
        icon: mdi:wind-power
        # m_per_pulse = (r * 2 * Pi)/2 = (0.09 * 2 * 3.14)/2 = 0.2862 m
        state: "{% set wind = states('sensor.WindSpeed')|float %}
        {% set wind_round = wind|round(1) %}
        {% if wind <= 1 %}Bft: 0, Wind stil, {{wind_round}} km/h
        {% elif wind <= 5 %}Bft: 1
        , Zwak: flauwe wind, {{wind_round}} km/h
        {% elif wind <= 11 %}Bft: 2, Zwak, {{wind_round}} km/h
        {% elif wind <= 20 %}Bft: 3, Matig: lichte bries, {{wind_round}} km/h
        {% elif wind <= 28 %}Bft: 4, Matig: flauwe bries, {{wind_round}} km/h
        {% elif wind <= 39 %}Bft: 5, Vrij krachtig, {{wind_round}} km/h
        {% elif wind <= 50 %}Bft: 6, Krachtig, {{wind_round}} km/h
        {% elif wind <= 62 %}Bft: 7, Hard, {{wind_round}} km/h
        {% elif wind <= 75 %}Bft: 8, Stormachting, {{wind_round}} km/h
        {% elif wind <= 89 %}Bft: 9, Storm, {{wind_round}} km/h
        {% elif wind <= 103 %}Bft: 10, Zware storm, {{wind_round}} km/h
        {% elif wind <= 117 %}Bft: 11, Zeer zware storm, {{wind_round}} km/h
        {% else %} > 117 %}Bft: 12, Orkaan, {{wind_round}} km/h
        {%- endif %}"
        
      - name: "Beaufort"
        state: "{% set wind = states('sensor.WindSpeed')|float %}
        {% if wind <= 1 %} 0
        {% elif wind <= 5 %} 1
        {% elif wind <= 11 %} 2
        {% elif wind <= 20 %} 3
        {% elif wind <= 28 %} 4
        {% elif wind <= 39 %} 5
        {% elif wind <= 50 %} 6
        {% elif wind <= 62 %} 7
        {% elif wind <= 75 %} 8
        {% elif wind <= 89 %} 9
        {% elif wind <= 103 %} 10
        {% elif wind <= 117 %} 11
        {% else %} > 117 %} 12
        {%- endif %}"
#        entity_picture_template: "
#        {% set state = states('sensor.Beaufort') %}
#        {% set path = '/local/Beaufort/' %}
#        {% set ext = '.jpg'%}
#        {{[path,state,ext]|join('')|lower}}" 

      - name: "WindAzimuth"
        icon: mdi:windsock
        unit_of_measurement: "°"
        state: >-
          {% set wind = states('sensor.wind_voltage')|float %}
          {% if wind <= 0.21 %} 112.5
          {% elif wind <= 0.27 %} 67.5
          {% elif wind <= 0.30 %} 90.0
          {% elif wind <= 0.41 %} 157.5
          {% elif wind <= 0.60 %} 135.0
          {% elif wind <= 0.79 %} 202.5
          {% elif wind <= 0.93 %} 180.0
          {% elif wind <= 1.31 %} 22.5
          {% elif wind <= 1.49 %} 45.0
          {% elif wind <= 1.93 %} 247.5
          {% elif wind <= 2.03 %} 225.0
          {% elif wind <= 2.26 %} 337.5
          {% elif wind <= 2.53 %} 0.0
          {% elif wind <= 2.67 %} 292.5
          {% elif wind <= 2.86 %} 315.0
          {% elif wind <= 3.05 %} 270
          {% else %} 295.5
          {% endif %}
        
      - name: "Wind direction"
        icon: mdi:windsock
        state: >-
          {% set degrees = states('sensor.WindAzimuth')|float %}
          {% set abbr = ['N','NNE','NE','ENE','E','ESE','SE',
          'SSE','S','SSW','SW','WSW','W','WNW','NW','NNW' ] %}
          {%- set i = ((degrees / 22.25) | round(0)) | int %}
          {%- set i = 0 if i == 16 else i %}
          {{ abbr[i] }}

Next step is to connect the rain and wind sensors to check if it’s working.

edit ===================

Finally, by luck, I found how to parse value_json within mqtt sensor : just comment or delete availability_topic:

mqtt:
  sensor:
      - state_topic: "zigbee2mqtt/weather_station_CC2531"
        unit_of_measurement: "°C"
        value_template: "{{ value_json.temperature_l1 | round(1) }}"
#        availability_topic: "zigbee2mqtt/bridge/state"
#        payload_available: "online"
#        payload_not_available: "offline"
        json_attributes_topic: "zigbee2mqtt/weather_station_CC2531/attributes" 
        icon: mdi:thermometer-lines  
        name: "Temperature shed"
        unique_id: cc2530_temperature_l1

et voilà no need to go through node-red intermediate step.
I don’t have an explanation why it works like this

======================

I would like to add to this great zigbee weather station AS3935 module : lightning sensor. It has an external interruption pin when a lightning is very near. It works with I2C and SPI. If it interests you, you may vote for an enhancement I’ve raised to PTVO to support it https://github.com/ptvoinfo/zigbee-configurable-firmware/issues/202

1 Like

I have the same. I can’t login at TI. I have no business-e-mail.

did you find a solution to obtain the program?

I was able to download the TI program by using a .co.uk email. However, I’m using Linux so although PTVO runs ok and creates the .hex files fine and I can load the TI programmer in wine (Linux windows emulator) it can’t see the hardware as Linux struggles to allow USB port access. A simple solution is to use cc-tools cc-tool download | SourceForge.net to program the device via RF04EB. If you have access to a Linux box or a virtual machine this may work for you.

I can now program my cc2530 perfectly!

1 Like

Has anyone else come across this problem? I can program the CC2530 and join to HA through ZHA and all the sensors show up the BME data (temp/hum/press), does not update - it only uploads once on startup/reset of the CC2530. The switches (rain gauge) and anemometer work ok and the RSSI updates ok. I’ve tried 2 BME280 and a SHT3x with the same result. The BME280 data is accurate, just not updating. I can’t work out from ZHA if the problem is from the CC2530 not transmitting the data or HA not finding it. If anyone can point me in the right direction I’d be grateful. Thank you.

Here is a an overview of the flashing options: Flashing the CC2531 USB stick | Zigbee2MQTT

After spending some time debugging, the solution is the following:

mqtt:
  sensor:
    - name: "garden 5 psi voltage"
      unique_id: garden5psivoltage
      state_topic: 'zigbee2mqtt/ZIGBEE_PTVO_NAME'
      unit_of_measurement: "V"
      icon: mdi:call-made
      value_template: "{{value_json.l1 | round(3)}}" 
      availability: 
        - topic: "zigbee2mqtt/ZIGBEE_PTVO_NAME/availability"
          value_template: "{{ value_json.state }}"
          payload_available: "online"
          payload_not_available: "offline"
1 Like

I’ve finally managed to crack this. I’m not sure why, but setting the send report frequency to 30 seconds (in the advanced tab) in the PTVO software has fixed this. The default is 60s but for whatever reason it wasn’t working for me. I now have a very nice fully working unit! I may try and add a Lux/UV sensor at some point…

Hi.I built this circuit, but unfortunately I can’t read the sensor values in zigbee2mqtt. I did everything according to the description and checked several times. The pairing was successful in z2m, but after that the reading of the data is no longer unsuccessful. I get this error message:

2024-02-21 12:27:51Exception while calling fromZigbee converter: Definition 'wethear station' has not endpoint defined}

Error 2024-02-21 12:27:51Publish 'get' 'temperature' to '0x00124b0009693a1c' failed: 'Error: Read 0x00124b0009693a1c/1 msTemperatureMeasurement(["measuredValue"], {"timeout":10000,"disableResponse":false,"disableRecovery":false,"disableDefaultResponse":true,"direction":0,"srcEndpoint":null,"reservedBits":0,"manufacturerCode":null,"transactionSequenceNumber":null,"writeUndiv":false}) failed (Status 'WRITE_ONLY')'

I tried to find information, but I didn’t come across this error message anywhere.
Anyone have any ideas?
Thank you in advance for your help!
Thom

Please find here my latest config files:

BME280 & wind data, this is the updated MQTT Sensor format.

Put this in your configuration.yaml:

mqtt: 
  sensor: !include_dir_merge_list mqtt_sensors 
  switch: !include_dir_merge_list mqtt_switches  

and create the two directories

/homeassistant/mqtt_sensors/
/homeassistant/mqtt_switches/

And put the file below in the Mqtt sensor directory: weatherstation.yaml

#########################################################
#                                                       #
#      BME280 DATA                                      #
#                                                       #
######################################################### 

  - state_topic: "zigbee2mqtt/0x00124b000633d676"
    unit_of_measurement: "%"
    value_template: "{{ value_json.humidity_l1| round(0) }}"
    availability_topic: "zigbee2mqtt/bridge/state"
    payload_available: "online"
    payload_not_available: "offline"
    json_attributes_topic: "zigbee2mqtt/0x00124b000633d676/attributes" 
    icon: mdi:water-percent 
    name: "Humidity shed"
    unique_id: humshed
    
  - state_topic: "zigbee2mqtt/0x00124b000633d676"
    unit_of_measurement: "hpa"
    value_template: "{{ ((value_json.pressure_l1| float ) | round (0)) }}"
    availability_topic: "zigbee2mqtt/bridge/state"
    payload_available: "online"
    payload_not_available: "offline"
    json_attributes_topic: "zigbee2mqtt/0x00124b000633d676/attributes" 
    icon: mdi:weight  
    name: "Pressure shed"
    unique_id: preshed
    
  - state_topic: "zigbee2mqtt/0x00124b000633d676"
    unit_of_measurement: "°C"
    value_template: "{{ value_json.temperature_l1| round(1) }}"
    availability_topic: "zigbee2mqtt/bridge/state"
    payload_available: "online"
    payload_not_available: "offline"
    json_attributes_topic: "zigbee2mqtt/0x00124b000633d676/attributes" 
    icon: mdi:thermometer-lines  
    name: "Temperature shed"
    unique_id: tempshed

#########################################################
#                                                       #
#      WIND                                             #
#                                                       #
#########################################################

  - state_topic: "zigbee2mqtt/0x00124b000633d676"
    unit_of_measurement: "v"
    value_template: "{{ value_json.l8| round(2) }}"
    availability_topic: "zigbee2mqtt/bridge/state"
    payload_available: "online"
    payload_not_available: "offline"
    json_attributes_topic: "zigbee2mqtt/0x00124b000633d676/attributes" 
    icon: mdi:call-made
    name: "Wind voltage"
    unique_id: windvoltage

  - state_topic: "zigbee2mqtt/0x00124b000633d676"
    unit_of_measurement: "rpm"
    value_template: "{{ value_json.l6 }}"
    availability_topic: "zigbee2mqtt/bridge/state"
    payload_available: "online"
    payload_not_available: "offline"
    json_attributes_topic: "zigbee2mqtt/0x00124b000633d676/attributes" 
    icon: mdi:call-made
    name: "Windpulse"
    unique_id: windpulse

   


#########################################################
#                                                       #
#            END OF CONFIGURATION FILE                  # 
#                                                       # 
#########################################################   

The other sensor configuration file can be put in the usual place:

In my case; I have created a sensor directory in configuration.yaml

sensor: !include_dir_merge_list sensors

and put all my sensor files in:

/homeassistant/sensors
#########################################################
#                                                       #
#      BME280 DATA                                      #
#                                                       #
######################################################### 

  - platform: template
    sensors:
      humidity_abs_shed:
        value_template: >-
          {% set h, t = states('sensor.humidity_shed') | float, states('sensor.temperature_shed') %}
          {% if not h or t == 'unknown' -%}
            'unknown'
          {%- else %}
            {% set t = t | float %}
            {{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(1) }}
          {% endif %}
        unit_of_measurement: g/m³
        friendly_name: Absolute Humidity shed

  - platform: template
    sensors:
      dewpoint_shed:
        friendly_name: "Dewpoint shed"
        value_template: >-
          {{ (log( states('sensor.humidity_shed')|int / 100 ) + 18.678 * states('sensor.temperature_shed')|float / (257.14 + states('sensor.temperature_shed')|float ) )| round (1) }}  
        unit_of_measurement: °C

#########################################################
#                                                       #
#      RAIN METER                                       #
#                                                       #
#########################################################  

  - platform: history_stats
    name: Daily rain clicks
    entity_id: switch.0x00124b000633d676_l5
    state: 'off'
    type: count
    start: '{{ now().replace(hour=0, minute=0, second=0) }}'
    end: '{{ now() }}'
    
  - platform: template
    sensors:
      rainfall_today:
        friendly_name: Rainfall today
        unit_of_measurement: mm
        value_template: >-
          {% set count = states('sensor.daily_rain_clicks') | int(0)  %}
          {% set mm_per_pulse = 0.30303 %}
          {% set mm = count * mm_per_pulse %}
          {{ mm|round(1, 'floor') }}    
          
#########################################################
#                                                       #
#      ANEMOMETER                                       #
#                                                       #
#########################################################

  - platform: template
    sensors:
      windspeed:
        friendly_name: Wind speed
        unit_of_measurement: m/s
        # m_per_pulse = (r * 2 * Pi)/2 = (0.09 * 2 * 3.14)/2 = 0.2862 m
        value_template: >-
          {% set count = states('sensor.wind_pulse') | int %}
          {% set m_per_pulse = 0.2826 %} 
          {% set mps = count * m_per_pulse %}
          {{ mps|round(0) }}    
          
  - platform: template
    sensors:
      windkmh:
        friendly_name: Wind speed
        unit_of_measurement: km/h
        value_template: >-
          {% set count = states('sensor.windspeed') | int %}
          {% set conversion =  0.2777778 %} 
          {% set mps = count * conversion %}
          {{ mps|round(0) }}      

  - platform: template
    sensors:
      windforce:
        friendly_name: Wind force
        icon_template: "mdi:weather-windy"
        value_template: "{% set wind = states('sensor.windspeed')|float %}
        {% set wind_round = wind|round(1) %}
        {% if wind <= 0.2 %}Bft: 0, Wind stil, {{wind_round}} m/s
        {% elif wind <= 1.5 %}Bft: 1, Zwak: flauwe wind, {{wind_round}} m/s
        {% elif wind <= 3.3 %}Bft: 2, Zwak, {{wind_round}} m/s
        {% elif wind <= 5.4 %}Bft: 3, Matig: lichte bries, {{wind_round}} m/s
        {% elif wind <= 7.9 %}Bft: 4, Matig: flauwe bries, {{wind_round}} m/s
        {% elif wind <= 10.7 %}Bft: 5, Vrij krachtig, {{wind_round}} m/s
        {% elif wind <= 13.8 %}Bft: 6, Krachtig, {{wind_round}} m/s
        {% elif wind <= 17.1 %}Bft: 7, Hard, {{wind_round}} m/s
        {% elif wind <= 20.7 %}Bft: 8, Stormachting, {{wind_round}} m/s
        {% elif wind <= 24.4 %}Bft: 9, Storm, {{wind_round}} m/s
        {% elif wind <= 28.4 %}Bft: 10, Zware storm, {{wind_round}} m/s
        {% elif wind <= 32.6 %}Bft: 11, Zeer zware storm, {{wind_round}} m/s
        {% else %}Bft: 12, Orkaan, {{wind_round}} m/s
        {%- endif %}"


  - platform: template
    sensors:
      beaufort: 
        friendly_name: Wind force
        icon_template: " mdi:weather-windy" 
        unit_of_measurement: Bft
        value_template: "{% set wind = states('sensor.windspeed')|float %} 
        {% if wind <= 0.2 %}0
        {% elif wind <= 1.5 %}1
        {% elif wind <= 3.3 %}2
        {% elif wind <= 5.4 %}3
        {% elif wind <= 7.9 %}4
        {% elif wind <= 10.7 %}5
        {% elif wind <= 13.8 %}6
        {% elif wind <= 17.1 %}7
        {% elif wind <= 20.7 %}8
        {% elif wind <= 24.4 %}9
        {% elif wind <= 28.4 %}10
        {% elif wind <= 32.6 %}11
        {% else %} > 32.6 %}12
        {%- endif %}"
             
#########################################################
#                                                       #
#      WIND DIRECTION                                   #
#                                                       #
#########################################################

  - platform: template
    sensors:
      wind_azimuth: 
        friendly_name: Wind azimuth
        unit_of_measurement: '°'
        value_template: "{% set wind = states('sensor.wind_voltage')|float %}
        {% if wind <= 0.21 %}112.5
        {% elif wind <= 0.27 %}67.5
        {% elif wind <= 0.30 %}90.0
        {% elif wind <= 0.41 %}157.5
        {% elif wind <= 0.60 %}135.0
        {% elif wind <= 0.79 %}202.5
        {% elif wind <= 0.93 %}180.0
        {% elif wind <= 1.31 %}22.5
        {% elif wind <= 1.49 %}45.0
        {% elif wind <= 1.93 %}247.5
        {% elif wind <= 2.03 %}225.0
        {% elif wind <= 2.26 %}337.5
        {% elif wind <= 2.53 %}0.0
        {% elif wind <= 2.67 %}292.5
        {% elif wind <= 2.86 %}315.0
        {% elif wind <= 3.05 %}270
        {% else %} > 3.05 %}295.5
        {%- endif %}"

  - platform: template
    sensors:
      wind_direction:
        friendly_name: Wind direction
        icon_template: "mdi:compass-outline"
        value_template: >
          {% set degrees = states('sensor.wind_azimuth')|float %}
          {% set abbr = ['N','NNE','NE','ENE','E','ESE','SE',
          'SSE','S','SSW','SW','WSW','W','WNW','NW','NNW' ] %}
          {%- set i = ((degrees / 22.25) | round(0)) | int %}
          {%- set i = 0 if i == 16 else i %}
          {{ abbr[i] }}

#########################################################
#                                                       #
#            END OF CONFIGURATION FILE                  # 
#                                                       # 
#########################################################   

Trust this helps

Hi Doublet!
I really appreciate your answer, it was extremely useful, because I was not aware of this configuration either. Unfortunately, it didn’t solve my problem, the error is still the same. I get the same error message in the log file. Maybe the BME280 is not communicating with the CC2530 for some reason

Debug 2024-02-22 09:53:11Received MQTT message on 'zigbee2mqtt/wethear station/1/set' with data '{"read":{"attributes":["measuredValue"],"cluster":"msTemperatureMeasurement","options":{}}}'

Debug 2024-02-22 09:53:11Publishing 'set' 'read' to 'wethear station'

Debug 2024-02-22 09:53:11Received Zigbee message from 'wethear station', type 'readResponse', cluster 'msTemperatureMeasurement', data '{}' from endpoint 1 with groupID 0

Error 2024-02-22 09:53:11Exception while calling fromZigbee converter: Definition 'wethear station' has not endpoint defined}

Debug 2024-02-22 09:53:11Error: Definition 'wethear station' has not endpoint defined at getEndpointName (/app/node_modules/zigbee-herdsman-converters/src/lib/utils.ts:129:15) at /app/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:459:72 at Array.find (<anonymous>) at Object.convert (/app/node_modules/zigbee-herdsman-converters/src/lib/modernExtend.ts:459:45) at Receive.onDeviceMessage (/app/lib/extension/receive.ts:153:51) at EventEmitter.wrappedCallback (/app/lib/eventBus.ts:174:23) at EventEmitter.emit (node:events:529:35) at EventBus.emitDeviceMessage (/app/lib/eventBus.ts:108:22) at Controller.<anonymous> (/app/lib/zigbee.ts:115:27)