simplified Gardena smart mower status & control
Based on https://flows.nodered.org/user/chmuck flow but simplified without websockets. Without websockets its more limited but simpler. One downside is limitation for querying status and commands.
[{"id":"8603c38cd8dca9a1","type":"tab","label":"Gardena smart mower","disabled":false,"info":""},{"id":"11a48f4217f434a4","type":"inject","z":"8603c38cd8dca9a1","name":"InitialToken","props":[],"repeat":"","crontab":"*/15 9-15 * * *","once":false,"onceDelay":0.1,"topic":"","x":140,"y":100,"wires":[["d84f8676ba9212fc"]]},{"id":"dcf64b1356151361","type":"http request","z":"8603c38cd8dca9a1","name":"http request","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":640,"y":130,"wires":[["01230423b9a7a105","5604ef05215e521e"]]},{"id":"886acde701e555a0","type":"function","z":"8603c38cd8dca9a1","name":"GetLocation","func":"global.set(\"access_token\", msg.oauth2Response.access_token);\nglobal.set(\"refresh_token\", msg.oauth2Response.refresh_token);\nglobal.set(\"user_id\", msg.oauth2Response.user_id)\n\nvar mytoken = global.get(\"access_token\"); \nvar myapi = global.get(\"api_key\"); \nvar url= \"https://api.smart.gardena.dev/v1/locations\";\n\nmsg.headers = {\n\t'Authorization': 'Bearer '+mytoken,\n\t'Authorization-Provider': 'husqvarna',\n\t'X-Api-Key': myapi,\n\t'Content-Type': 'application/vnd.api+json',\n};\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":130,"wires":[["dcf64b1356151361"]]},{"id":"a4c36ffc5541a4a2","type":"http request","z":"8603c38cd8dca9a1","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":640,"y":180,"wires":[["fa69dd3123599178","76afbbe3d6bf407f"]]},{"id":"01230423b9a7a105","type":"function","z":"8603c38cd8dca9a1","name":"GetServiceIDs","func":"global.set(\"location\", msg.payload[\"data\"][\"0\"][\"id\"]);\n\nvar mytoken = global.get(\"access_token\"); \nvar myapi = global.get(\"api_key\"); \nvar mylocation = global.get(\"location\"); \nvar url= \"https://api.smart.gardena.dev/v1/locations/\"+mylocation;\n\nmsg.headers = {\n\t'Authorization': 'Bearer '+mytoken,\n\t'Authorization-Provider': 'husqvarna',\n\t'X-Api-Key': myapi,\n\t'Content-Type': 'application/vnd.api+json'\n};\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":180,"wires":[["a4c36ffc5541a4a2"]],"info":"Location coule be d8a1faef-2ee3-421d-a3f8-f8ed577c2ad3:suffix\n\nvar url= \"https://api.smart.gardena.dev/v1/locations/\"+mylocation;\nvar url= \"https://api.smart.gardena.dev/v1/locations/d8a1faef-2ee3-421d-a3f8-f8ed577c2ad3\";"},{"id":"fa69dd3123599178","type":"debug","z":"8603c38cd8dca9a1","name":"Debug service-ID","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1180,"y":130,"wires":[]},{"id":"5604ef05215e521e","type":"debug","z":"8603c38cd8dca9a1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1170,"y":90,"wires":[]},{"id":"64883fca333bab5c","type":"function","z":"8603c38cd8dca9a1","name":"MowNowFor3h","func":"var mytoken = global.get(\"access_token\"); \nvar myapi = global.get(\"api_key\"); \nvar myservice = \"xxxxxxxx-xxxxxxxxxx-xxxxxxxxx\"; \n\nmsg.payload = {\n 'data': {\n 'type': 'MOWER_CONTROL', \n\t\t'id': 'request-4', \n\t\t'attributes': {\n\t\t\t'command': 'START_SECONDS_TO_OVERRIDE',\n\t\t\t'seconds': 10800\n\t\t}\n\t}\n};\n\nmsg.headers = {\n\t'Authorization': 'Bearer '+mytoken,\n\t'Authorization-Provider': 'husqvarna',\n\t'X-Api-Key': myapi,\n\t'Content-Type': 'application/vnd.api+json'\n};\n\n\nvar url= \"https://api.smart.gardena.dev/v1/command/\"+myservice;\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":600,"wires":[["1057884222fa40ca"]]},{"id":"8e1ff7ff57d4d2f3","type":"function","z":"8603c38cd8dca9a1","name":"StopMowing","func":"var mytoken = global.get(\"access_token\"); \nvar myapi = global.get(\"api_key\"); \nvar myservice = \"xxxxxxxx-xxxxxxxxxx-xxxxxxxxx\"; \n\nmsg.payload = {\n 'data': {\n 'id': 'request-5', \n 'type': 'MOWER_CONTROL', \n\t\t'attributes': {\n\t\t\t'command': 'PARK_UNTIL_FURTHER_NOTICE'\n\t\t}\n\t}\n};\n\nmsg.headers = {\n\t'Authorization': 'Bearer '+mytoken,\n\t'Authorization-Provider': 'husqvarna',\n\t'X-Api-Key': myapi,\n\t'Content-Type': 'application/vnd.api+json'\n};\n\n\nvar url= \"https://api.smart.gardena.dev/v1/command/\"+myservice;\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":640,"wires":[["1057884222fa40ca"]]},{"id":"1057884222fa40ca","type":"http request","z":"8603c38cd8dca9a1","name":"","method":"PUT","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":990,"y":560,"wires":[["38e5038e75b4e434"]]},{"id":"816a3a4ec0a87d09","type":"function","z":"8603c38cd8dca9a1","name":"MowToSchedule","func":"var mytoken = global.get(\"access_token\"); \nvar myapi = global.get(\"api_key\"); \nvar myservice = \"xxxxxxxx-xxxxxxxxxx-xxxxxxxxx\"; \n\nmsg.payload = {\n 'data': {\n 'type': 'MOWER_CONTROL', \n\t\t'id': 'request-2', \n\t\t'attributes': {\n\t\t\t'command': 'START_DONT_OVERRIDE'\n\t\t}\n\t}\n};\n\nmsg.headers = {\n\t'Authorization': 'Bearer '+mytoken,\n\t'Authorization-Provider': 'husqvarna',\n\t'X-Api-Key': myapi,\n\t'Content-Type': 'application/vnd.api+json'\n};\n\n\nvar url= \"https://api.smart.gardena.dev/v1/command/\"+myservice;\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":520,"wires":[["1057884222fa40ca"]]},{"id":"81aa290feb78341e","type":"function","z":"8603c38cd8dca9a1","name":"StopMowTillSchedule","func":"var mytoken = global.get(\"access_token\"); \nvar myapi = global.get(\"api_key\"); \nvar myservice = \"xxxxxxxx-xxxxxxxxxx-xxxxxxxxx\"; \n\nmsg.payload = {\n 'data': {\n 'type': 'MOWER_CONTROL', \n\t\t'id': 'request-3', \n\t\t'attributes': {\n\t\t\t'command': 'PARK_UNTIL_NEXT_TASK'\n\t\t}\n\t}\n};\n\nmsg.headers = {\n\t'Authorization': 'Bearer '+mytoken,\n\t'Authorization-Provider': 'husqvarna',\n\t'X-Api-Key': myapi,\n\t'Content-Type': 'application/vnd.api+json'\n};\n\n\nvar url= \"https://api.smart.gardena.dev/v1/command/\"+myservice;\n\nmsg.url = url;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":560,"wires":[["1057884222fa40ca"]]},{"id":"38e5038e75b4e434","type":"debug","z":"8603c38cd8dca9a1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1160,"y":560,"wires":[]},{"id":"4c38a7ef4515f10c","type":"debug","z":"8603c38cd8dca9a1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"oauth2Response","targetType":"msg","statusVal":"","statusType":"auto","x":1200,"y":50,"wires":[]},{"id":"b2bfd2f0fcc39ee5","type":"comment","z":"8603c38cd8dca9a1","name":"Input your credentials","info":"","x":400,"y":40,"wires":[]},{"id":"9060e85deda3b90e","type":"comment","z":"8603c38cd8dca9a1","name":"Input your appliances' service-IDs from debug","info":"","x":800,"y":480,"wires":[]},{"id":"d84f8676ba9212fc","type":"function","z":"8603c38cd8dca9a1","name":"Client Credentials","func":"msg.oauth2Request = { \n \"access_token_url\": \"https://api.authentication.husqvarnagroup.dev/v1/oauth2/token\",\n \"credentials\": {\n \"grant_type\": \"client_credentials\",\n \"client_id\": \"xxxxxxxx-xxxxxxxxxx-xxxxxxxxx\",\n \"client_secret\": \"xxxxxxxx-xxxxxxxxx-xxxxxxxx\",\n \"scope\": \"*\"\n },\n};\nreturn msg;\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":80,"wires":[["abbb2b57bd02cfb1"]]},{"id":"abbb2b57bd02cfb1","type":"oauth2","z":"8603c38cd8dca9a1","name":"Set by msg.oauth2Request","container":"oauth2Response","access_token_url":"http://localhost:3000/oauth/token ","grant_type":"set_by_credentials","username":"pedroet","password":"","client_id":"confidentialApplication","client_secret":"topSecret","scope":"*","headers":{},"x":690,"y":60,"wires":[["4c38a7ef4515f10c","886acde701e555a0"]]},{"id":"cc1ff004ded7c396","type":"inject","z":"8603c38cd8dca9a1","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":640,"wires":[["9520fc0e86f6f3b8"]]},{"id":"15f53175bc220ea5","type":"inject","z":"8603c38cd8dca9a1","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":600,"wires":[["61dbe7ab2a5c0fa5"]]},{"id":"8f0a932a599ee9b0","type":"inject","z":"8603c38cd8dca9a1","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":560,"wires":[["59257bf70a8453cd"]]},{"id":"a55d00259bf5aec6","type":"inject","z":"8603c38cd8dca9a1","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":520,"wires":[["d937f8d7dd6dc36a"]]},{"id":"a31c060c0acd71ac","type":"debug","z":"8603c38cd8dca9a1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1170,"y":170,"wires":[]},{"id":"ef984fb0b1b82041","type":"ui_text","z":"8603c38cd8dca9a1","group":"9852e93e7fb4fe70","order":7,"width":0,"height":0,"name":"","label":"Drift timer:","format":"{{msg.payload.ophours}} h","layout":"row-spread","className":"","x":1160,"y":360,"wires":[]},{"id":"76afbbe3d6bf407f","type":"function","z":"8603c38cd8dca9a1","name":"","func":"var ophours = msg.payload.included[\"1\"].attributes.operatingHours.value;\nvar status = msg.payload.included[\"1\"].attributes.state.value;\nvar activity = msg.payload.included[\"1\"].attributes.activity.value;\nvar batlevel = msg.payload.included[\"2\"].attributes.batteryLevel.value;\nvar batstate = msg.payload.included[\"2\"].attributes.batteryState.value;\nvar rfstate = msg.payload.included[\"2\"].attributes.rfLinkState.value;\nvar rflevel = msg.payload.included[\"2\"].attributes.rfLinkLevel.value;\n\n\n\n\n\nmsg.payload.ophours = ophours;\nmsg.payload.status = status;\nif (activity == \"PAUSED\") \n {activity = \"Sat på pause\";}\n \nif (activity == \"OK_CUTTING\") \n {activity = \"Klipper græs (auto)\";}\n \nif (activity == \"OK_CUTTING_TIMER_OVERRIDDEN\")\n {activity = \"Klipper græs (manuelt)\";}\n \nif (activity == \"OK_SEARCHING\") \n {activity = \"Søger ladestation\";}\n \nif (activity == \"OK_CHARGING\") \n {activity = \"Lader op\";}\n\nif (activity == \"PARKED_TIMER\") \n {activity = \"Parkeret indtil næste tidsplan\";}\n \nif (activity == \"PARKED_PARK_SELECTED\") \n {activity = \"Parkeret indtil videre\";}\n \nif (activity == \"PARKED_AUTOTIMER\") \n {activity = \"Parkeret græs for lavt\";}\n\nif (activity == \"NONE\") \n {activity = \"Fejl?\";}\n\nmsg.payload.activity = activity;\n\nmsg.payload.batlevel = batlevel;\nmsg.payload.batstate = batstate;\nmsg.payload.rfstate = rfstate;\nmsg.payload.rflevel = rflevel;\n \n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":790,"y":270,"wires":[["ef984fb0b1b82041","a31c060c0acd71ac","dd30458e28ae882f","da73ee28f589dd4f","efe73c1de614c8c4","3bba98cb54525256"]]},{"id":"dd30458e28ae882f","type":"ui_text","z":"8603c38cd8dca9a1","group":"9852e93e7fb4fe70","order":2,"width":"6","height":"2","name":"","label":"","format":"{{msg.payload.activity}}","layout":"row-center","className":"","x":1140,"y":320,"wires":[]},{"id":"da73ee28f589dd4f","type":"ui_text","z":"8603c38cd8dca9a1","group":"9852e93e7fb4fe70","order":1,"width":0,"height":0,"name":"","label":"Status:","format":"{{msg.payload.status}}","layout":"row-spread","className":"","x":1150,"y":280,"wires":[]},{"id":"6728b088f8ad73f3","type":"delay","z":"8603c38cd8dca9a1","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":140,"y":280,"wires":[["d84f8676ba9212fc"]]},{"id":"d937f8d7dd6dc36a","type":"ui_button","z":"8603c38cd8dca9a1","name":"","group":"9852e93e7fb4fe70","order":3,"width":0,"height":0,"passthru":true,"label":"Klip efter tidsplan","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":440,"y":520,"wires":[["816a3a4ec0a87d09","6728b088f8ad73f3"]]},{"id":"59257bf70a8453cd","type":"ui_button","z":"8603c38cd8dca9a1","name":"","group":"9852e93e7fb4fe70","order":5,"width":0,"height":0,"passthru":true,"label":"Parker til næste tidsplan","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":420,"y":560,"wires":[["81aa290feb78341e","6728b088f8ad73f3"]]},{"id":"61dbe7ab2a5c0fa5","type":"ui_button","z":"8603c38cd8dca9a1","name":"","group":"9852e93e7fb4fe70","order":4,"width":0,"height":0,"passthru":true,"label":"Manuelt klip i 3 timer","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":430,"y":600,"wires":[["64883fca333bab5c","6728b088f8ad73f3"]]},{"id":"9520fc0e86f6f3b8","type":"ui_button","z":"8603c38cd8dca9a1","name":"","group":"9852e93e7fb4fe70","order":6,"width":0,"height":0,"passthru":true,"label":"Parker og pause tidsplan","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":410,"y":640,"wires":[["8e1ff7ff57d4d2f3","6728b088f8ad73f3"]]},{"id":"efe73c1de614c8c4","type":"ui_text","z":"8603c38cd8dca9a1","group":"9852e93e7fb4fe70","order":8,"width":"0","height":"0","name":"","label":"Batteri:","format":"{{msg.payload.batlevel}}% - {{msg.payload.batstate}}","layout":"row-spread","className":"","x":1150,"y":400,"wires":[]},{"id":"3bba98cb54525256","type":"ui_text","z":"8603c38cd8dca9a1","group":"9852e93e7fb4fe70","order":9,"width":"0","height":"0","name":"","label":"Signal:","format":"{{msg.payload.rflevel}}% - {{msg.payload.rfstate}}","layout":"row-spread","className":"","x":1150,"y":440,"wires":[]},{"id":"8e21207179d17289","type":"comment","z":"8603c38cd8dca9a1","name":"Dashboard text","info":"","x":1170,"y":240,"wires":[]},{"id":"ef28f8558ff145e1","type":"comment","z":"8603c38cd8dca9a1","name":"Dashboard buttons","info":"","x":440,"y":480,"wires":[]},{"id":"a7d88f8bde00cb2a","type":"comment","z":"8603c38cd8dca9a1","name":"If sending commands & read status often it will \"limit exceeded\" and lock communication for a while.","info":"","x":710,"y":700,"wires":[]},{"id":"9852e93e7fb4fe70","type":"ui_group","name":"Mower","tab":"cfc2786282105f1c","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"cfc2786282105f1c","type":"ui_tab","name":"Mower","icon":"mi-grass","order":7,"disabled":false,"hidden":false}]