mqtt-tools / mqttwarn

A highly configurable MQTT message router, where the routing targets are notification plugins, primarily written in Python.
https://mqttwarn.readthedocs.io/
Eclipse Public License 2.0
955 stars 183 forks source link

Republish part of json to influxdb or mqtt #696

Open martinlindjarv opened 5 months ago

martinlindjarv commented 5 months ago

Good day!

First of all - thank you for great software!

For last few days i have been struggling with idea to get ecowitt weather station data to influxdb. I'm seem to be missing logic or understanding ...

When one value comes in and needs to go to influx it seems doable.

[ecowitt/#]
targets = influxdb:ecowitt

But once i have one json topic i have no idea how to do it :(

Received json is quite simple:

2024-04-14 16:28:48 weather/ecowitt {"runtime": 194556.0, "tempin": 77.18, "humidityin": 30.0, "baromrel": 29.179, "baromabs": 29.179, "temp": 44.78, "humidity": 86.0, "winddir": 263.0, "windspeed": 1.198, "windgust": 3.098, "maxdailygust": 6.701, "solarradiation": 156.59, "uv": 1.0, "rrain_piezo": 0.0, "erain_piezo": 12.7, "hrain_piezo": 0.0, "drain_piezo": 10.592, "wrain_piezo": 10.592, "mrain_piezo": 13.589, "yrain_piezo": 13.589, "ws90cap_volt": 3.4, "ws90_ver": 138.0, "wh90batt": 3.18, "interval": 60.0, "beaufortscale": 1, "dewpoint": 40.856, "feelslike": 44.78, "frostpoint": 39.277, "frostrisk": "No risk", "heatindex": 43.0, "humidex": 6, "humidex_perception": "Comfortable", "humidityabs": 6.706, "humidityabsin": 6.706, "relative_strain_index": null, "relative_strain_index_perception": null, "safe_exposure_time_skin_type_1": 166.7, "safe_exposure_time_skin_type_2": 200.0, "safe_exposure_time_skin_type_3": 266.7, "safe_exposure_time_skin_type_4": 333.3, "safe_exposure_time_skin_type_5": 533.3, "safe_exposure_time_skin_type_6": 866.7, "simmerindex": null, "simmerzone": null, "solarradiation_perceived": 85.943, "thermalperception": "Dry", "windchill": null}

Now i would like to get winddir and windspeed and insert them directly to influx ... but have no idea how to do it ... With python func i have found it is possible to extract and formutale the message again ... but i have not found any example how to solve "one topic, multiple values to different places" - is it even possible?

Any hints or directions are welcome.

martinlindjarv commented 5 months ago

Ok, it seems i have found a solution that suits my needs. Used url as base for info and made modifications.

samplefuncs.py:

def ecowitt_fields(data, srv=None):
    """Extract fields from JSON payload of messages on topic
    ecowitt and publish the fields on separate
    MQTT topics ecowitt/[Field]."""

    if type(data) == dict and "winddir" in data and "windspeed" in data:
        base_topic = "ecowitt"
        republish_fields = ['winddir', 'windspeed']
        if type(data) == dict and srv is not None:
            for field, value in data.items():
                if field in republish_fields:
                  srv.mqttc.publish("/".join([base_topic, field]), value, qos=0, retain=False)
    return None

and into mqttwarn.ini i added:

[ecowitt]
targets=log:info
format=ecowitt_fields()

[ecowitt/+]
targets = influxdb:ecowitt

It all seems to work ... maybe there are some simplier solutions but this seems to finally serve the purpose for me.

amotl commented 4 months ago

Hi Martin,

excellent. Thanks for sharing your procedures.

So, effectively you are doing some JSON attribute filtering and MQTT topic rewriting in your custom code, right? I wonder if mqttwarn would offer a corresponding plugin out of the box, at least for the re-publishing part?

In any case, we are happy that you managed to find a solution using mqttwarn with custom code.

With kind regards, Andreas.

martinlindjarv commented 4 months ago

Good day,

What i wanted was simple - incoming json republished to mqtt as separate topics under one base. That filtering is there with case "it's possible" but not mandatory.

But as my solution seemed quite hacky i asked maybe it can be solved with existing code ...

But if not i will continue with my solution as it works :)

Regards, Martin