Worx Landroid Binding

The api offers a http request to get product items, perhaps these are the supported mowers. This is the response of the query:
https://github.com/nibi79/worxlandroid/blob/master/doc/products.json

So your mower is listed:

{
	"id": 19,
	"product_family_id": 3,
	"default_name": "Landroid L",
	"code": "WG797E.1",
	"product_year": 2016,
	"features": {
		"unrestricted_mowing_time": true,
		"multi_zone": true,
		"wifi_connection": "manual_display",
		"display_type": "lcd",
		"pin": true,
		"rain_delay": true,
		"chassis": "l_2016"
	},
	"board_id": 2,
	"meters": 2000,
	"iot_enabled": true,
	"registration_enabled": true,
	"mowing_runtime": 60,
	"charge_time": 120,
	"mow_speed": 0.41887902,
	"wire_speed": 0.293215314,
	"cutting_width": 220,
	"region": "eu",
	"accessories": null,
	"maximum_weekly_scheduled_time": 5550,
	"onboard_accessories": null,
	"created_at": "2017-03-13 19:25:50",
	"updated_at": "2020-03-12 00:00:56"
},

No. It works with the previous-gen app (which was current by the time I got my Landroid) which was working locally only. I had sniffed that protocol (it’s just HTTP) and use HTTP commands to control my Landroid.
But the current app just does not find my mower, and it’s even too intelligent to allow the user to enter the mower’s IP manually.

Thanks for your effort in writing this binding. It works intuitive and really well, good job! Thank you so much!

1 Like

I have installed this binding, i used the THINGS and ITEMS text file examples from Github, it took me less than 30min to have a working solution.
Last year my mower was connected via the Landroid brigde software, this worked perfectly but was more complicated to install and configure.

1 Like

My Landroid S still in the garage. The installation went well after configuring the bridge the Landroid S appeared in the Inbox.
I had my landroid bridge running in a docker container. This solution for sure better.
Thanks in advance.
My feedback will be in few weeks.

1 Like

The Binding is running with the Landroid S Offline (still in the garage).
I got this error in the log this morning:

2020-03-27 07:10:00.046 [ERROR] [id.internal.WorxLandroidMowerHandler] - RefreshStatusRunnable 2018301909020029945B: Unknown error

org.openhab.binding.worxlandroid.internal.webapi.WebApiException: java.io.EOFException: HttpConnectionOverHTTP@a4ec0f::DecryptedEndPoint@10a98b2{api.worxlandroid.com/34.248.123.187:443<->/192.168.3.145:49524,OPEN,fill=-,flush=W,to=60021/0}

	at org.openhab.binding.worxlandroid.internal.webapi.request.WebApiRequest.callWebApi(WebApiRequest.java:122) ~[bundleFile:?]

	at org.openhab.binding.worxlandroid.internal.webapi.request.WebApiRequest.callWebApiGet(WebApiRequest.java:79) ~[bundleFile:?]

	at org.openhab.binding.worxlandroid.internal.webapi.request.ProductItemsRequest.call(ProductItemsRequest.java:46) ~[bundleFile:?]

	at org.openhab.binding.worxlandroid.internal.webapi.WorxLandroidWebApiImpl.retrieveUserDevices(WorxLandroidWebApiImpl.java:101) ~[bundleFile:?]

	at org.openhab.binding.worxlandroid.internal.WorxLandroidMowerHandler$1.run(WorxLandroidMowerHandler.java:102) [bundleFile:?]

	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_232]

	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_232]

	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_232]

	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_232]

	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_232]

	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_232]

	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_232]

Caused by: java.util.concurrent.ExecutionException: java.io.EOFException: HttpConnectionOverHTTP@a4ec0f::DecryptedEndPoint@10a98b2{api.worxlandroid.com/34.248.123.187:443<->/192.168.3.145:49524,OPEN,fill=-,flush=W,to=60021/0}

	at org.eclipse.jetty.client.util.FutureResponseListener.getResult(FutureResponseListener.java:118) ~[bundleFile:9.4.20.v20190813]

	at org.eclipse.jetty.client.util.FutureResponseListener.get(FutureResponseListener.java:101) ~[bundleFile:9.4.20.v20190813]

	at org.eclipse.jetty.client.HttpRequest.send(HttpRequest.java:685) ~[bundleFile:9.4.20.v20190813]

	at org.openhab.binding.worxlandroid.internal.webapi.request.WebApiRequest.callWebApi(WebApiRequest.java:92) ~[bundleFile:?]

	... 11 more

Caused by: java.io.EOFException: HttpConnectionOverHTTP@a4ec0f::DecryptedEndPoint@10a98b2{api.worxlandroid.com/34.248.123.187:443<->/192.168.3.145:49524,OPEN,fill=-,flush=W,to=60021/0}

	at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.earlyEOF(HttpReceiverOverHTTP.java:335) ~[?:?]

	at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1526) ~[?:?]

	at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.shutdown(HttpReceiverOverHTTP.java:209) ~[?:?]

	at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:147) ~[?:?]

	at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:73) ~[?:?]

	at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:133) ~[?:?]

	at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:154) ~[?:?]

	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) ~[?:?]

	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) ~[?:?]

	at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:426) ~[?:?]

	at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:320) ~[?:?]

	at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:158) ~[?:?]

	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) ~[?:?]

	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117) ~[?:?]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336) ~[?:?]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313) ~[?:?]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171) ~[?:?]

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129) ~[?:?]

	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:367) ~[?:?]

	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:782) ~[?:?]

	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:918) ~[?:?]

	... 1 more

Did you get error once or permanently? Is the Bridge online at the moment? Can you restart oh and check the log again. Perhaps it was a temporary HTTP problem.

I just witnessed once, not repeating, though should not throw an exception.

Thanks a lot
I’ve been waiting for this binding since new API version of worx. The landroid bridge was always having lots of problem on my raspberry and I didn’t use it anymore.

I just install the binding and everything goes well for the moment:

  • Installation with Karaf Console
  • Restart OpenHab
  • Add API Things and use discovery to add my mower
  • Copy/Paste all provinding items and sitemaps

Perfect !

1 Like

Hi everybody!
Thank you for that wonderful binding which solves many problems with the prevoius used bridge. But I do also have a problem, my Mower does not accept the commands, but it has also a problem with the Worx Android App:

2020-03-28 12:29:33.558 [vent.ItemStateChangedEvent] - Landroid_Status_dateTimeS changed from 2020-03-28T12:28:33.232+0100 to 2020-03-28T12:29:33.557+0100
2020-03-28 12:29:57.685 [ome.event.ItemCommandEvent] - Item 'Landroid_Command' received command START
2020-03-28 12:29:57.686 [nt.ItemStatePredictedEvent] - Landroid_Command predicted to become START
2020-03-28 12:29:57.688 [vent.ItemStateChangedEvent] - Landroid_Command changed from 1970-01-01T00:00:00.000+0000 to START
2020-03-28 12:33:24.846 [DEBUG] [d.internal.WorxLandroidBridgeHandler] - publish topic -> DB510/F0FE6B831BC2/commandIn
2020-03-28 12:33:24.847 [DEBUG] [d.internal.WorxLandroidBridgeHandler] - publish message -> {}
2020-03-28 12:33:24.851 [INFO ] [orxlandroid.internal.mqtt.AWSMessage] - onSuccess
2020-03-28 12:33:25.297 [INFO ] [.worxlandroid.internal.mqtt.AWSTopic] - onMessage: {"cfg":{"id":1,"lg":"it","tm":"12:34:27","dt":"28/03/2020","sc":{"m":1,"p":0,"d":[["00:00",0,0],["11:00",300,1],["11:00",300,1],["11:00",300,1],["11:00",300,1],["11:00",300,1],["11:00",300,1]]},"cmd":0,"mz":[0,0,0,0],"mzv":[0,0,0,0,0,0,0,0,0,0],"rd":0,"sn":"201830190902001711FE"},"dat":{"mac":"F0FE6B831BC2","fw":3.52,"bt":{"t":27.2,"v":20.25,"p":94,"nr":1385,"c":1,"m":0},"dmp":[-1.1,-0.5,345.8],"st":{"b":33231,"d":559051,"wt":34700},"ls":1,"le":0,"lz":0,"rsi":-66,"lk":1}}
2020-03-28 12:33:25.299 [INFO ] [id.internal.WorxLandroidMowerHandler] - HOME | StatusCode: 1 - Home

==> /var/log/openhab2/events.log <==

2020-03-28 12:33:25.305 [vent.ItemStateChangedEvent] - Landroid_Command changed from START to 1970-01-01T00:00:00.000+0000

==> /var/log/openhab2/openhab.log <==

2020-03-28 12:33:25.308 [INFO ] [id.internal.WorxLandroidMowerHandler] - NO_ERROR | ErrorCode: 0 - No error
2020-03-28 12:33:35.388 [DEBUG] [nternal.webapi.request.WebApiRequest] - URI: https://api.worxlandroid.com/api/v2/product-items
2020-03-28 12:33:35.658 [DEBUG] [nternal.webapi.request.WebApiRequest] - Worx Landroid WebApi Response: [{"id":239984,"product_id":37,"user_id":77143,"serial_number":"xxxxx","mac_address":"xxxxx","name":"Robby","setup_location":{"latitude":xxxx,"longitude"xxxx},"locked":true,"firmware_version":3.52,"firmware_auto_upgrade":false,"distance_covered":558302,"mower_work_time":34654,"blade_work_time":33187,"battery_charge_cycles":1385,"messages_in":630,"messages_out":28925,"push_notifications":true,"city":{"id":2887175,"country_id":276,"name":"xxxx","latitude":xxxx,"longitude":xxxx,"created_at":"2018-02-15 22:23:54","updated_at":"2018-02-15 22:23:54"},"sim":null,"push_notifications_level":"notice","lawn_size":0,"lawn_perimeter":null,"raw_messages_in":34393,"raw_messages_out":28925,"test":0,"iot_registered":true,"warranty_registered":true,"pin_code":null,"time_zone":"Europe\/Berlin","purchased_at":"2018-06-02 00:00:00","warranty_expires_at":"2020-06-02 00:00:00","registered_at":"2018-07-09 00:00:00","online":true,"app_settings":null,"accessories":null,"features":{"unrestricted_mowing_time":true,"multi_zone":true,"wifi_connection":"smartlink_no_display","display_type":"led","lock":true,"rain_delay":true,"chassis":"s_2017","mqtt":true,"wifi_pairing":"smartlink","tracking_firmware":true,"provisoning_replaceable":true},"auto_schedule_settings":null,"auto_schedule":false,"pending_radio_link_validation":null,"mqtt_topics":{"command_in":"DB510\/F0FE6B831BC2\/commandIn","command_out":"DB510\/F0FE6B831BC2\/commandOut"},"created_at":"2018-06-22 15:25:57","updated_at":"2020-03-28 01:12:04"}]

==> /var/log/openhab2/events.log <==

2020-03-28 12:33:35.659 [vent.ItemStateChangedEvent] - Landroid_Status_dateTimeS changed from 2020-03-28T12:32:35.388+0100 to 2020-03-28T12:33:35.659+0100

To me, it seems like the channel is bound to wrong information, or is there a problem with my configuration?
landroid.items:

DateTime Landroid_Status_dateTimeS "Letztes Update [%1$td.%1$tm.%1$ty %1$tH:%1$tM:%1$tS]" <kalender>  {channel="worxlandroid:mower:99e526be:201830190902001711FE:common#lastUpdateOnlineStatus"}
String Landroid_Command "Befehl [%s]" <movecontrol> {channel="worxlandroid:mower:99e526be:201830190902001711FE:cfgCommon#command"}

landroid.sitemap:

Default item=Landroid_Status_dateTimeS
Switch item=Landroid_Command mappings=[START="Start",STOP="Stop",HOME="Go Home"]

Hi Stefan,

your channel is wrong:

String Landroid_Command "Befehl [%s]" <movecontrol> {channel="worxlandroid:mower:99e526be:201830190902001711FE:cfgCommon#command"}

to control the mower you need ‘common#action

String Landroid_Command "Befehl [%s]" <movecontrol> {channel="worxlandroid:mower:99e526be:201830190902001711FE:common#action"}
1 Like

Hi Nils!

This is a great binding! I was waiting for this for a long time as the landroid bridge was not working stable for me! Great job, thanks a lot!

One question:
What are the commands that can be transmitted via “common#action” channel?
I could not find any info about this. I remember it was documented somewhere in the API.

Thanks in advance!

1 Like

you are right!

These are the commands you can use for “common#action” channel:

  • START
  • STOP
  • HOME

I just added the info to the README.

Hi… Is it possible to add a command that forces the mower to a specific zone?

Regards Mads

There are some options regarding zones but I don’t know exactly which one yet.
I’ll take a look at that.

I’ve just seen that @INT5749 created an issue regarding zones: https://github.com/nibi79/worxlandroid/issues/5

Hi,

ja, und Enhencement trifft es gut :wink: Braucht man nicht häufig, aber ich finde die Lösung der Desktop App klasse, da können die Zonen direkt geschrieben werden, ohne die mühsam immer wieder abzufahren. Hat mir geholfen Shaun an der richtigen stelle vom Kabel ins Feld zu schicken.

VG

Hi Mads,

there is no specific command, mower always start with next zone.
e.g. if you have 3 Zones which are all in scope it will be
1
2
3
1
2
etc

I’m not aware how to send mower to start with a specific zone

Is there already a channel to read information for
“id”: 34,
“product_family_id”: 1,
“default_name”: “Landroid S”,
“code”: “WR102SI.1”,
“product_year”: 2018,

Etc. and probably MAC address also??

Regards
int5479

Hi Jörg,

not at the moment. I was thinking about it and in principle it is not a problem. But I asked myself for what I need this information.

Can you please create an issue for this topic?

Hi Nibi,
sure, but shall be Enhancement as well. Sure thing this information can easily add by label, but would be nice to capure them :wink: