Mobile app update breaking changes?

Yeah would definitely be nice to streamline this process.

My workflow was:

Woken up last night by a very loud tts message from my phone: “please set a title for text to speech…”

Google that phrase having no idea what’s just happened or why my phone is shouting at me.

Thankfully find this thread and all the helpful responses here.

Refactor 20+ automations and scripts for the new syntax.

Inwardly moan whilst I read the other comments on this thread.

Test.

Feel better.

I think the workflow could definitely be optimised

1 Like

Given there has been so much problems with the update and release notes I made a Node red sequence that will send you a notification with the breaking changes when the app updates.

- but I don't have Node red, it's just unnecessary overhead and my CPU and....

Too bad. This is for Node red, if you want to make something similar in HA then go ahead.
The reason I did this in Node red is because it’s easier to get data from dynamic sources, but it’s probably doable in HA.

This is a quick and dirty solution, it will look at the first three pages of releases and find the version you have, extract the breaking changes and send them to your phone as a notification.
You could easily just copy paste then nodes to make it look at more pages if you want.

[{"id":"f45b950aa1ab8fc8","type":"api-current-state","z":"ebaa69a9.649708","name":"","server":"4bbca37b.1700ec","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.andreas_current_version","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"version","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":380,"y":1200,"wires":[["c83873a7bbfa9b43"]]},{"id":"286ad732f3e943f1","type":"inject","z":"ebaa69a9.649708","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":120,"y":1200,"wires":[["f45b950aa1ab8fc8"]]},{"id":"c83873a7bbfa9b43","type":"http request","z":"ebaa69a9.649708","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://github.com/home-assistant/android/releases","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":690,"y":1200,"wires":[["b90d81dbfbdd93a4"]]},{"id":"21df4cebb637e8ef","type":"server-state-changed","z":"ebaa69a9.649708","name":"","server":"4bbca37b.1700ec","version":4,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.andreas_current_version","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"outputProperties":[{"property":"version","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":260,"y":1340,"wires":[["c83873a7bbfa9b43"]]},{"id":"b90d81dbfbdd93a4","type":"function","z":"ebaa69a9.649708","name":"","func":"\nmsg.version = msg.version.split(\"-\")[0];\nvar splitstr = '<a href=\"/home-assistant/android/releases/tag/VERSION\" data-view-component=\"true\" class=\"Link--primary\">VERSION</a>'.replaceAll(\"VERSION\", msg.version);\n\nif (msg.payload.includes(splitstr)){\n    var release = msg.payload.split(splitstr)[1].split('</ul>')[0];\n\n    if (release !== null){\n        var changes = [];\n        changes = release.match(/(Breaking Change:.*?<\\/a>)/gms);\n    }else{\n        return [null,msg]\n    }\n\n    msg.breaking = \"\"\n    changes.forEach(function (value,index) {\n        msg.breaking = msg.breaking + \"<br>\" + value.replace(/<\\/?[^>]+(>|$)/g, \"\");\n    });\n    msg.changes = changes;\n    return [msg,null];\n}else{\n    return [null,msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":1200,"wires":[["c503b73eb3434e9d","ead2bde3f5cc61af"],["11df3ae016a1583d"]]},{"id":"c503b73eb3434e9d","type":"debug","z":"ebaa69a9.649708","name":"debug 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1280,"y":1220,"wires":[]},{"id":"11df3ae016a1583d","type":"http request","z":"ebaa69a9.649708","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://github.com/home-assistant/android/releases?page=2","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":830,"y":1280,"wires":[["de747fc05c1d292e"]]},{"id":"ead2bde3f5cc61af","type":"api-call-service","z":"ebaa69a9.649708","name":"","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_andreas","areaId":[],"deviceId":[],"entityId":[],"data":"{\t    \"title\": \"New version of companion app\",\t    \"message\": msg.breaking\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1380,"y":1320,"wires":[[]]},{"id":"de747fc05c1d292e","type":"function","z":"ebaa69a9.649708","name":"","func":"\nmsg.version = msg.version.split(\"-\")[0];\nvar splitstr = '<a href=\"/home-assistant/android/releases/tag/VERSION\" data-view-component=\"true\" class=\"Link--primary\">VERSION</a>'.replaceAll(\"VERSION\", msg.version);\n\nif (msg.payload.includes(splitstr)){\n    var release = msg.payload.split(splitstr)[1].split('</ul>')[0];\n\n    if (release !== null){\n        var changes = [];\n        changes = release.match(/(Breaking Change:.*?<\\/a>)/gms);\n    }else{\n        return [null,msg]\n    }\n\n\n    msg.breaking = \"\"\n    changes.forEach(function (value,index) {\n        msg.breaking = msg.breaking + \"<br>\" + value.replace(/<\\/?[^>]+(>|$)/g, \"\");\n    });\n    msg.changes = changes;\n    return [msg,null];\n}else{\n    return [null,msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":900,"y":1340,"wires":[["c503b73eb3434e9d","ead2bde3f5cc61af"],["77943c36beb9398b"]]},{"id":"3432389388f2eead","type":"function","z":"ebaa69a9.649708","name":"","func":"\nmsg.version = msg.version.split(\"-\")[0];\nvar splitstr = '<a href=\"/home-assistant/android/releases/tag/VERSION\" data-view-component=\"true\" class=\"Link--primary\">VERSION</a>'.replaceAll(\"VERSION\", msg.version);\n\nif (msg.payload.includes(splitstr)){\n    var release = msg.payload.split(splitstr)[1].split('</ul>')[0];\n\n    if (release !== null){\n        var changes = [];\n        changes = release.match(/(Breaking Change:.*?<\\/a>)/gms);\n    }else{\n        return [null,msg]\n    }\n\n    msg.breaking = \"\"\n    changes.forEach(function (value,index) {\n        msg.breaking = msg.breaking + \"<br>\" + value.replace(/<\\/?[^>]+(>|$)/g, \"\");\n    });\n    msg.changes = changes;\n    return [msg,null];\n}else{\n    return [null,msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1160,"y":1480,"wires":[["c503b73eb3434e9d","ead2bde3f5cc61af"],[]]},{"id":"77943c36beb9398b","type":"http request","z":"ebaa69a9.649708","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://github.com/home-assistant/android/releases?page=3","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":1010,"y":1420,"wires":[["3432389388f2eead"]]},{"id":"4bbca37b.1700ec","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

3 Likes

And if you want to scan for breaking changes before you update you can use this sequence:

I didn’t know there was a latest URL but that made it very easy. Easy enough that it’s probably very much doable in HA.

Anyways this looks at the latest page, and if it’s a new version then it sends you release name and breaking changes.
The first time you run it then it will message you of the current version. But from then on it should only give you latest version.

Just set the inject node to run at an appropriate interval.

[{"id":"23eade4a7d71d3c1","type":"html","z":"ebaa69a9.649708","name":"","property":"payload","outproperty":"title","tag":"title","ret":"html","as":"single","x":530,"y":1560,"wires":[["3f6f208546c7955b"]]},{"id":"da4d913f62c248e8","type":"http request","z":"ebaa69a9.649708","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"https://github.com/home-assistant/android/releases/latest","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":350,"y":1560,"wires":[["23eade4a7d71d3c1"]]},{"id":"3f6f208546c7955b","type":"html","z":"ebaa69a9.649708","name":"What's Changed","property":"payload","outproperty":"changes","tag":"#repo-content-pjax-container > div > div > div > div.Box-body > div.markdown-body.my-3 > ul:nth-child(2)","ret":"html","as":"single","x":740,"y":1560,"wires":[["b2b3040e4f5a400f"]]},{"id":"69119ff305774878","type":"inject","z":"ebaa69a9.649708","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":180,"y":1560,"wires":[["da4d913f62c248e8"]]},{"id":"b2b3040e4f5a400f","type":"function","z":"ebaa69a9.649708","name":"","func":"msg.title = msg.title[0].substring(0,16) + \" of companion app is available\"\n\nvar changes = [];\nchanges = msg.changes[0].match(/(Breaking Change:.*?<\\/a>)/gms);\n\nmsg.breaking = \"\"\nchanges.forEach(function (value,index) {\n    msg.breaking = msg.breaking + \"<br>\" + value.replace(/<\\/?[^>]+(>|$)/g, \"\");\n});\nmsg.changes = changes;\n\nreturn msg;\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":920,"y":1560,"wires":[["813d13fd1a0124ed"],[]]},{"id":"813d13fd1a0124ed","type":"switch","z":"ebaa69a9.649708","name":"","property":"title","propertyType":"msg","rules":[{"t":"neq","v":"title","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":1050,"y":1560,"wires":[["fc72bd76ec5f55a3"]]},{"id":"fc72bd76ec5f55a3","type":"change","z":"ebaa69a9.649708","name":"","rules":[{"t":"set","p":"title","pt":"flow","to":"title","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1190,"y":1560,"wires":[["465389aad2ac207c","bdf59d5f0e8d7f00"]]},{"id":"465389aad2ac207c","type":"debug","z":"ebaa69a9.649708","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1340,"y":1540,"wires":[]},{"id":"bdf59d5f0e8d7f00","type":"api-call-service","z":"ebaa69a9.649708","name":"","server":"4bbca37b.1700ec","version":5,"debugenabled":false,"domain":"notify","service":"mobile_app_andreas","areaId":[],"deviceId":[],"entityId":[],"data":"{\t    \"title\": msg.title,\t    \"message\": msg.breaking\t}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1420,"y":1580,"wires":[[]]},{"id":"4bbca37b.1700ec","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

3 Likes

Just found this thread after my Sleep automation kept failing.
For anyone else who doesn’t want to scroll through here’s the breakdown

Breaking Change: Switch notification command parameters

The biggest change is going to be that title will no longer be used for any command including TTS, this means all additional command data will need to be in the data element underneath message. In most cases title was switched to command.

Broadcast Intent

change channel to intent_package_name
change title to intent_action
change group to intent_extras

Volume Level

change title to command
change channel to media_stream

Media

change title to media_command
change channel to media_package_name

Activity

change channel to intent_package_name
change tag to intent_action
change title to intent_uri
change subject to intent_type
change group to intent_extras

So in NodeRED I had to change my service call from:

{
    "message": "command_broadcast_intent",
    "title": "com.urbandroid.sleep.alarmclock.START_SLEEP_TRACK",
    "data": {
        "channel": "com.urbandroid.sleep"
    }
}

To:

{
    "message": "command_broadcast_intent",
    "data": {
        "intent_package_name": "com.urbandroid.sleep",
        "intent_action": "com.urbandroid.sleep.alarmclock.START_SLEEP_TRACK"
    }
}
2 Likes

So, funny story… I didn’t have anything break from this change, but I am now trying to set up my first Text to Speech notification…

I also use NodeRED and am trying to get TTS to work…
I get speech but it always says “Please set a title for text to speech to process”

I’ve looked through all the docs, and this thread to find anything that might work and have been used as “title” but nothing is working

Has anyone managed to get TTS on Android to work with NodeRed since this update? If so can they please share the code?

Thanks!

{"message": "TTS", "data": {

    message: TTS,

    media_command: "The house is on Fire and the cat is stuck in the dryer!",

    intent_type: "The house is on Fire and the cat is stuck in the dryer!",

    command: "The house is on Fire and the cat is stuck in the dryer!",

    intent_action: "The house is on Fire and the cat is stuck in the dryer!",

    intent_uri: "The house is on Fire and the cat is stuck in the dryer!",

    tts_text: "The house is on Fire and the cat is stuck in the dryer!",

    ttl: 0,

    priority: high,

    media_stream: alarm_stream_max

    }

}

always good to check the docs for the updated format

https://companion.home-assistant.io/docs/notifications/notifications-basic/#text-to-speech-notifications

I’m using the updated format and copying directly from the docs…
You can’t put message under data as you get an error…

"Call-service error. required key not provided @ data['message']"

If I put it in both it still doesn’t work

I’ve literally tried every combination that I can

{
  "message": "TTS",
  "data":{
    "tts_text": "Motion has been detected"
  }
}

keep in mind it’s easier if you post what you have tried so that we can help you correct it.

1 Like

Thank you…
Really appreciated