# Telegraf as MQTT consumer - handling string and float values

**URL:** <https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257>\
**Category:** Telegraf\
**Tags:** telegraf, kapacitor, iot\
**Created:** [September 5, 2017, 9:53pm UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257 "2017-09-05T21:53:04Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![DavidA](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/davida/32/1796_2.png) [@DavidA](https://community.influxdata.com/u/DavidA)\
**Post date:** [September 5, 2017, 9:53pm UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/1 "2017-09-05T21:53:04Z")

</div>

I have a device that publishes both floating-point sensor values and “status” strings via MQTT. I have configured Telegraf to subscribe to these topics, however I’ve had to add two separate instances of the MQTT Consumer plugin in order to handle the different types of data formats:

```auto
[[inputs.mqtt_consumer]]
  servers = ["mosquitto:1883"]
  qos = 0
  topics = ["mydevice/#"]
  data_format = "value"
  data_type = "float"

[[inputs.mqtt_consumer]]
  name_override = "mqtt_consumer_string"
  servers = ["mosquitto:1883"]
  qos = 0
  topics = ["mydevice/#"]
  data_format = "value"
  data_type = "string"

```

This results in duplicate data in InfluxDB, because some topics are caught by both consumers and written to the database. The topics for values that are actual strings never appear in the mqtt\_consumer measurement, but the topics for float values do appear in the mqtt\_consumer\_string measurement, as strings.

Apart from creating a list of explicit topics, is there a better way to do this? Or does the data agnostic nature of MQTT mean that there’s no way for Telegraf to know whether a topic is a float or a string (does MQTT not have a data type field?), and having two consumers (one for float topics, one for string topics) is the only way to deal with this?

Alternatively, what if I collected all my data as strings? Will InfluxDB (and downstream services like Grafana) interpret those values as numerical, or will I need to convert them (e.g. Kapacitor TICKscript)?

---

<div class="post-metadata">

**Author:** ![daniel](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/daniel/32/142_2.png) [@daniel](https://community.influxdata.com/u/daniel)\
**Post date:** [September 5, 2017, 10:53pm UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/2 "2017-09-05T22:53:03Z")

</div>

Is it possible to modify the format of the message in MQTT? If so you could send Line Protocol and use the influx data\_format which is much more powerful.

> Alternatively, what if I collected all my data as strings? Will InfluxDB (and downstream services like Grafana) interpret those values as numerical, or will I need to convert them (e.g. Kapacitor TICKscript)?

You will need to convert them.

---

<div class="post-metadata">

**Author:** ![DavidA](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/davida/32/1796_2.png) [@DavidA](https://community.influxdata.com/u/DavidA)\
**Post date:** [September 6, 2017, 12:34am UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/3 "2017-09-06T00:34:47Z")

</div>

Sending Line Protocol sounds like it could work, at the cost of the published data being less friendly to non-InfluxDB subscribers (no longer a simple value). I’ll think about whether it will work in my application.

Do you know if there’s a way to convert a string to a float in a Grafana query? The query will know that the string is meant to be a float (so that’s the explicit conversion that is required), but I can’t find a way to actually make the conversion. Is there a hidden “cast” or “convert” function, either in Grafana or in the InfluxDB query language? Aggregators like Mode still work on string representations of floats because they treat each value as a member of a set of arbitrary values, but Mean does not work because it needs numerical values to calculate the mean, and if given strings it doesn’t automatically convert.

---

<div class="post-metadata">

**Author:** ![daniel](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/daniel/32/142_2.png) [@daniel](https://community.influxdata.com/u/daniel)\
**Post date:** [September 6, 2017, 1:22am UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/4 "2017-09-06T01:22:25Z")

</div>

I’m not aware of anything like this.

---

<div class="post-metadata">

**Author:** ![DavidA](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/davida/32/1796_2.png) [@DavidA](https://community.influxdata.com/u/DavidA)\
**Post date:** [September 6, 2017, 1:44am UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/5 "2017-09-06T01:44:11Z")

</div>

I tried sending Line Protocol to a single MQTT topic, using the `data_format = "influx"` setting for `[[inputs.mqtt_consumer]]` and it does work, but I did notice that the “measurement” part of the Line Protocol seems to be ignored, such that all tags and fields end up under the single “mqtt\_consumer” measurement. However by filtering on publisher-supplied tags (rather than MQTT topics with the “value” method) I’m able to extract the right data, as string or float as needed, if I tag it sensibly.

It does feel a bit like an extra hoop to jump through though, and it does mean any other MQTT subscribers (like a mobile app or websocket app) don’t see nice per-topic values coming in, as everything arrives via a single topic. I’ll do some more testing and consider it as a possible solution though.

It’s a shame that the measurement _name_ isn’t used by Telegraf when sending the data to InfluxDB. That would have been a really nice solution to another problem I have where everything via MQTT ends up in one “mqtt\_consumer” measurement and certain operations are not possible unless they are split between measurements. The workaround for that is currently multiple instances of the mqtt\_consumer input plugin, with `name_override` to set each measurement’s name.

---

<div class="post-metadata">

**Author:** ![daniel](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/daniel/32/142_2.png) [@daniel](https://community.influxdata.com/u/daniel)\
**Post date:** [September 6, 2017, 5:27pm UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/6 "2017-09-06T17:27:55Z")

</div>

This seems like a bug/mistake to me as well, do you want to open a [new issue](https://github.com/influxdata/telegraf/issues/new)?

---

<div class="post-metadata">

**Author:** ![DavidA](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/davida/32/1796_2.png) [@DavidA](https://community.influxdata.com/u/DavidA)\
**Post date:** [September 6, 2017, 9:56pm UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/7 "2017-09-06T21:56:47Z")

</div>

I’ve narrowed it down to use of the `name_override` directive, which I need to use as I have multiple instances of the MQTT input plugin. It seems that this override also overrides the Line Protocol measurement names, which doesn’t seem right to me:

> <https://github.com/influxdata/telegraf/issues/3205>
>
> \## Bug report
> 
> \### Relevant telegraf.conf:
> 
> \`\`\`
> \[\[inputs.mqtt\_consumer\]\]
> … name\_override = "foo"
> servers = \["mosquitto:1883"\]
> qos = 0
> topics = \[
> "test",
> \]
> data\_format = "influx"
> \`\`\`
> 
> \### System info:
> 
> \* Raspbian Jessie (Raspberry Pi)
> \* Docker 17.05.0-ce
> \* Mosquitto 1.4.14
> \* Telegraf 1.3.5
> \* InfluxDB 1.3.3
> 
> Note: I expect this issue to appear on a non-Raspberry Pi system however I don't have one I can use at the moment. I do not have any reason to think it is Raspberry Pi specific - it's just the system that I have right now.
> 
> \### Steps to reproduce:
> 
> 1. Configure Mosquitto to provide MQTT broker services (no security).
> 2. Configure Telegraf with default configuration.
> 3. Add \`inputs.mqtt\_consumer\` section as above, and set "servers" to the name of the Mosquitto service.
> 4. Start all the services.
> 5. Using an MQTT client (such as mqtt-spy) send the following string to the "test" topic:
> 
> weather,location=us-midwest temperature=82 
> 
> \### Expected behavior:
> 
> Given the measurement name "weather" in the Line Protocol I'd expect a new measurement called "weather" to be created in the telegraf.autogen database, with the tag location, tag value "us-midwest", and a field called "temperature" with the value 82.
> 
> If the "weather" measurement already exists, I'd expect the data point to be added to it.
>  
> \### Actual behavior:
> 
> A measurement named "weather" is \*\*not\*\* created, or added to if it already exists.
> 
> Instead, specified tags and fields are added to the measurement named "foo" which is the name specified by the "name\_override" directive. If it does not exist, it is created.
> 
> While I would expect the name\_override to change the default name of the measurement when none is provided elsewhere, for example when using \`data\_format="value"\`, I wouldn't expect it to override the measurement name for every Line Protocol message.
> 
> Line Protocol \_requires\_ that the measurement name be specified, so there's no need for a default measurement name in this case. If the intention is to direct all incoming LP data to a \_single\_ measurement regardless of the source's intention, perhaps there's a case for a new influx-format-only parameter called "redirect\_measurement", "override\_measurement", "merge" or some such?
> 
> The specific use case I have is that I have defined multiple \`\[\[inputs.mqtt\_consumer\]\]\` instances, and have specified different names for each (using the same name for all of them seems unwise). However the side-effect of this is that it overrides the measurement name, meaning that I can't combine \`name\_override\` with \`data\_format="influx"\` and this limits my use of multiple instances.
> 
> \### Additional info:
> 
> A docker-compose.yml to help reproduce this issue (Raspberry Pi only):
> 
> https://github.com/DavidAntliff/poolmon/tree/master/services

If I don’t use the `name_override` directive the measurement name is correctly handled. I can work around this by using the default instance for any LP handling, but it doesn’t seem quite right to me.

---

<div class="post-metadata">

**Author:** ![daniel](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/daniel/32/142_2.png) [@daniel](https://community.influxdata.com/u/daniel)\
**Post date:** [September 7, 2017, 12:22am UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/8 "2017-09-07T00:22:57Z")

</div>

That’s actually the only thing the `name_override` option does, you don’t need to set it even with multiple MQTT inputs.

---

<div class="post-metadata">

**Author:** ![DavidA](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/davida/32/1796_2.png) [@DavidA](https://community.influxdata.com/u/DavidA)\
**Post date:** [September 7, 2017, 7:39am UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/9 "2017-09-07T07:39:16Z")

</div>

Ok, thanks, I was under the impression I needed distinct names for each instance of the plugin, but if they can happily co-exist then I can omit the `name_override` whenever I’m using the `influx` data format. Thanks for the pointers.

---

<div class="post-metadata">

**Author:** ![i\_code](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/i_code/32/8479_2.png) [@i\_code](https://community.influxdata.com/u/i_code)\
**Post date:** [October 5, 2021, 10:21pm UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/10 "2021-10-05T22:21:29Z")

</div>

> [@DavidA](#):
>
> ent name is correctly handled. I can work around this by using the default instance for any LP handling, but it doesn’t

DavidA, could you show us how you structured your mqtt message and post your Telegraf config file. I’d love to start from there.

---

<div class="post-metadata">

**Author:** ![DavidA](https://sea1.discourse-cdn.com/flex023/user_avatar/community.influxdata.com/davida/32/1796_2.png) [@DavidA](https://community.influxdata.com/u/DavidA)\
**Post date:** [October 10, 2021, 8:57pm UTC](https://community.influxdata.com/t/telegraf-as-mqtt-consumer-handling-string-and-float-values/2257/11 "2021-10-10T20:57:13Z")

</div>

It’s been a long time, so this is all I can offer I’m afraid: [poolmon/telegraf.conf at master · DavidAntliff/poolmon · GitHub](https://github.com/DavidAntliff/poolmon/blob/master/services/srv/telegraf/config/telegraf.conf)

Re-reading this thread, I’m pretty sure I ended up using different topics for different MQTT message types (string vs numeric).
