[APP][Pro] MQTT Hub - Community version

Well, it depends :grinning_face_with_smiling_eyes:

It’s like HA entities. You can perhaps have a Mqtt device that has ‘min’, ‘medium’, ‘max’ or 0..100%.

You can chabge your fan and check the topic in MqttExplorer.

Then you can add an export template as JavaScript to map the values. Just ask if you have some example values and need help.

I have a MQTT topic that returns a JSON:

{
  "state": {
    "reported": {
      "ts": 1759810164000,
      "239": 1,
      "240": 1,
      "80": 5,
      "21": 4,
      "200": 0,
      "69": 1,
      "383": 3,
      "30": 0,
      "31": 0,
      "32": 71,
      "37": 76,
      "50": 101,
      "53": 11,
      "181": 9,
      "182": 6,
      "66": 14750,
      "24": 75,
      "206": 4210,
      "67": 3944,
      "68": 0,
      "17": 2,
      "18": -60,
      "19": 39,
      "15": 1000,
      "36": 1462,
      "42": 834,
      "43": 0,
      "49": 53266,
      "51": 14640,
      "241": 24491,
      "199": 9006,
      "16": 7859331,
      "449": 0,
      "636": 36734486,
      "389": 352056,
      "390": 442,
    }
  }
}

I can read paramter “390” and get the raw 442 value which is Fuel remaining, but it needs to be divided by 10 to get it into 44.2 liters.

This is the configuration for the capability

  "measure_content_volume": {
    "capability": "measure_content_volume",
    "stateTopic": "car/data",
    "setTopic": "",
    "valueTemplate": " (value) => { return value.state.reported[\"390\"]/10) }",
    "outputTemplate": "",
    "displayName": "Fuel remaining"
  }

$.state.reported["390"]" returns the raw value fine, but doing MathJS on that directly fails and returns always 0.

Then I tried
(value) => { return (JSON.parse(value).state.reported[\"390\"] / 10 ) }
but that also always returns 0

and now I tried also
(value) => { return value.state.reported[\"390\"]/10) }
and that too returns 0.

What should be the proper way to do the math on the value?

Please try single quotes ‘ instead of \”. The string is used as function without without unescaping.

I think this should work:

(value) => { return value.state.reported['390']/10 }

Hi All,

I’m having some difficulties with the MQTT Hub app in thermostat mode.

{
  "measure_temperature": {
    "capability": "measure_temperature",
    "stateTopic": "thermostat1/status/number:201",
    "setTopic": "",
    "valueTemplate": "$.value",
    "outputTemplate": "",
    "displayName": "temperature"
  },
"target_temperature": {
    "capability": "target_temperature",
    "stateTopic": "thermostat1/status/number:202",
    "setTopic": "thermostat1/rpc",
    "valueTemplate": "$.value",
    "outputTemplate": "21.2", 
    "displayName": "temperature"
  },
  "measure_humidity": {
    "capability": "measure_humidity",
    "stateTopic": "thermostat1/status/number:200",
    "setTopic": "",
    "valueTemplate": "$.value",
    "outputTemplate": "",
    "displayName": "Humidity"
  },
  "onoff": {
    "capability": "onoff",
    "stateTopic": "thermostat1/status/boolean:202",
    "setTopic": "",
    "valueTemplate": "$.value",
    "outputTemplate": "",
    "displayName": ""
  }

}

Is this a bug in the Hub app? Or do I do something wrong here?

Thanks, will test that next time that car moves.

Second question, for:

  "measure_number.2": {
    "capability": "measure_number",
    "stateTopic": "ajovalo/fmc003/864275078490771/data",
    "setTopic": "",
    "valueTemplate": "$.state.reported['389']",
    "outputTemplate": "",
    "displayName": "Odometer km",
    "units": "km"
  },

I’m trying to display the last known value for Odometer, when the attribute is missing from the JSON. Is there a way to retain the last good value instead of reseting to 0?

The Json changes (other fields), but sometimes, the Odo is empty/missing?

I would try the JS function template. Read the field and return it. If the field is empty/missing, throw an error. That should prevent an update in this case.

It’s just a guess, but should work I think :grinning_face_with_smiling_eyes:

Throwing and error seems to result in null value and the capability value is set to null. So when null value is received, maybe have an option in the capability config to either allow null value, or keep last known good value.

It seems the device registers capability listeners only at start up, not after settings changes.
An app restart should fix the issue for you. I will check if I can add a this for settings, too.

New test version 4.5.2:

  • Fixed capability registration after settings changed. Capability listener should be added now (untested)
  • Exception in JS template skips value.

@OH2TH I changed the logic a bit. An exception in a JS function skips the capability update now.

Hi RonnyW,

great the APP reset was already sufficient :slight_smile:

I would like to send this payload:

 {"method":"number.set","params":{"value": 20.2, "id":202, "source":"homey"}
 

With the thermostat target as value (20.2). How should I handle this? Is that like?

"outputTemplate"=‘{"method":"number.set","params":{"value": value, "id":202, "source":"homey"}’

Best regards

I got it to work with:

{
  "measure_temperature": {
    "capability": "measure_temperature",
    "stateTopic": "thermostat1/status/number:201",
    "setTopic": "",
    "valueTemplate": "$.value",
    "outputTemplate": "",
    "displayName": "temperature"
  },
"target_temperature": {
    "capability": "target_temperature",
    "stateTopic": "thermostat1/status/number:202",
    "setTopic": "thermostat1/rpc",
    "valueTemplate": "$.value",
    "outputTemplate": "{\"method\":\"number.set\", \"params\":{\"id\":202, \"value\":value} }", 
    "displayName": "temperature"
  },
  "measure_humidity": {
    "capability": "measure_humidity",
    "stateTopic": "thermostat1/status/number:200",
    "setTopic": "",
    "valueTemplate": "$.value",
    "outputTemplate": "",
    "displayName": "Humidity"
  },
  "onoff": {
    "capability": "onoff",
    "stateTopic": "thermostat1/status/boolean:202",
    "setTopic": "",
    "valueTemplate": "$.value",
    "outputTemplate": "",
    "displayName": ""
  }

}

Thanks fot the update. Haven’t used this myself yet :grinning_face_with_smiling_eyes:

Is there a way receiving a boolean and convert to a (capability) state?

(value) => { return (value.output == false)?”heat”:"cool” }

Hehe, youd should create a Wiki post with examples :smiley:

Thanks will try that, so something like this should work?

"valueTemplate": "(value) => { if (value.state.reported['389'] === undefined) throw Error(); return value.state.reported['389'] }",

Could be useful for $.state.reported['256'] JSONpath also.

in the JS template, is it possible to use Date() ?

(value) => new Date(value.state.reported['ts']).toLocaleString('sv-SE', { timeZone: 'Europe/Helsinki' })

Would be nice if I could convert timestamps to human readable.

The JS function is executed in app context. You can use everything that’s also possible in apps (all existing Homey NodeJS modules).

And Date does work correctly, my capability was number and not string.

New test version 4.5.3:

  • Undefined result of JSON path, MathJS or JS function skips value. Capability keeps unchanged in this case.
2 Likes