Worx Landroid Package (Deprecated)

I had the same issue: after upgrading to 0.117 I get the error message “Unable to prepare setup for platform landroid_cloud.sensor: Unable to set up component.”

Thanks Barmalej, that was just the right hint. I had already stowed away my Landroid for winter. So it was switched off when I did the update. I turned it back on and restarted HA. Worked instantly.

@Barmalej:
I need an advice on starting bordercut from home.

My research so far gave me the following to achieve it.
Via MQTT there are the following available commands:
cmd:1 = START
cmd:2 = PAUSE
cmd:3 = STOP
cmd:4 = ZONE TRAINING

And to get the border-cut from home it’s the following command-order:
Start Zone Training / Wait 3 Seconds / Pause / Wait 3 seconds / Stop

I also saw you writing here about MQTT-commands:

So I need this Start Zone Training command but I have no idea how to do it.

Hello,

i had an issue with “Landroid last update” and my timezone.
Solved by modify the template by adding false in timestamp_custom

      landroid_lastupdate:
        friendly_name: Landroid last update
        value_template: "{{ as_timestamp(strptime( state_attr('sensor.landroid_mower_status', 'last_update'), '%H:%M:%S %d/%m/%Y')) | timestamp_custom('%d.%m.%Y %H:%M:%S', False) }}"
        icon_template: mdi:clock

I setup my Landroid via MQTT before this stuff really picked up, so I’ve done a lot of manual work (template sensors) that’s eclipsed by these projects. I’ll share it here anyway, in case it’s useful to anyone else. I used https://github.com/orangutanoide/landroid_mosquitto_bridge to get the MQTT setup data, and bridged it to my own mosquitto instance.

mosquitto topic config (see elsewhere for full bridge info, my MAC address redacted):

# topic to subscribe in remote (aws) server
# move under 'landroid/' namespace locally for easier ACLs
topic PRM100/XXXXXXXXXXXX/commandOut in 0 landroid/ ""
topic PRM100/XXXXXXXXXXXX/commandIn out 0 landroid/ ""

sensors (MAC address redacted here, too):

## This is the base sensor that provides all the data from MQTT; everything
## else templates off of this one via the 'cfg' and 'dat' attributes.
## Timestamp is used as the base value to force this sensor to update
## whenever a new message is published, triggering all downstream templates.
## state_topic uses the landroid/ prefix as configured in the mosquitto bridge.
- platform: mqtt
  name: Landroid
  state_topic: landroid/PRM100/XXXXXXXXXXXX/commandOut
  value_template: >-
          {{ strptime(value_json["cfg"]["dt"] + " " + value_json["cfg"]["tm"], "%d/%m/%Y %H:%M:%S") }}
  json_attributes_topic: landroid/PRM100/XXXXXXXXXXXX/commandOut
  json_attributes_template: "{{ value_json | tojson }}"

- platform: template
  sensors:
    landroid_status:
      friendly_name: Landroid status
      icon_template: mdi:robot-mower-outline
      value_template: >-
              {% set mapper = {
                      0: "Idle",
                      1: "Home",
                      2: "Start sequence",
                      3: "Leaving home",
                      4: "Follow wire",
                      5: "Searching home",
                      6: "Searching wire",
                      7: "Mowing",
                      8: "Lifted",
                      9: "Trapped",
                      10: "Blade blocked",
                      11: "Debug",
                      12: "Remote control",
                      30: "Going home",
                      31: "Zone training",
                      32: "Border Cut",
                      33: "Searching zone",
                      34: "Pause" } %}
              {% set state = state_attr("sensor.landroid", "dat").ls %}
              {{ mapper[state] if state in mapper else 'Unknown: ' ~ state }}
      attribute_templates:
        statno: "{{ state_attr('sensor.landroid', 'dat').ls | int }}"
        locked: "{{ state_attr('sensor.landroid', 'dat').lk | int }}"
        fw_ver: "{{ state_attr('sensor.landroid', 'dat').fw }}"
        mac: "{{ state_attr('sensor.landroid', 'dat').mac }}"
        sn: "{{ state_attr('sensor.landroid', 'cfg').sn }}"
        pitch: "{{ state_attr('sensor.landroid', 'dat').dmp[0] }}"
        roll: "{{ state_attr('sensor.landroid', 'dat').dmp[1] }}"
        yaw: "{{ state_attr('sensor.landroid', 'dat').dmp[2] }}"
        updated: "{{ states('sensor.landroid') }}"
    landroid_error:
      friendly_name: Landroid error
      value_template: >-
              {% set mapper = {
                      0: "No error",
                      1: "Trapped",
                      2: "Lifted",
                      3: "Wire missing",
                      4: "Outside wire",
                      5: "Rain Delay",
                      6: "Close door to mow",
                      7: "Close door to go home",
                      8: "Blade motor blocked",
                      9: "Wheel motor blocked",
                      10: "Trapped timeout",
                      11: "Upside down",
                      12: "Battery low",
                      13: "Reverse wire",
                      14: "Charge error",
                      15: "Timeout finding home",
                      16: "Mower locked",
                      17: "Battery temperature too high/low" } %}
              {% set state = state_attr("sensor.landroid", "dat").le %}
              {{ mapper[state] if state in mapper else 'Unknown: ' ~ state }}
      attribute_templates:
        errno: "{{ state_attr('sensor.landroid', 'dat').le | int }}"
    landroid_battery_charge:
      friendly_name: Landroid charge
      unit_of_measurement: '%'
      value_template: "{{ state_attr('sensor.landroid', 'dat').bt.p | int }}"
      device_class: battery
    landroid_battery_voltage:
      friendly_name: Landroid battery voltage
      unit_of_measurement: 'V'
      value_template: "{{ state_attr('sensor.landroid', 'dat').bt.v | float(2) }}"
      device_class: voltage
    landroid_battery_temperature:
      friendly_name: Landroid battery temperature
      unit_of_measurement: '°C'
      value_template: "{{ state_attr('sensor.landroid', 'dat').bt.t | float(0) }}"
      device_class: temperature
    landroid_battery_cycle:
      friendly_name: Landroid battery cycle
      value_template: "{{ state_attr('sensor.landroid', 'dat').bt.nr | int }}"
      unit_of_measurement: 'cycles'
    landroid_total_distance:
      friendly_name: Landroid total distance
      value_template: "{{ state_attr('sensor.landroid', 'dat').st.d }}"
      unit_of_measurement: 'm'
    landroid_total_work_time:
      friendly_name: Landroid total work time
      value_template: "{{ state_attr('sensor.landroid', 'dat').st.wt }}"
      unit_of_measurement: 'min'
    landroid_total_blade_time:
      friendly_name: Landroid total blade time
      value_template: "{{ state_attr('sensor.landroid', 'dat').st.b }}"
      unit_of_measurement: 'min'
    landroid_wifi_rsi:
      friendly_name: Landroid WiFi RSI
      unit_of_measurement: 'dBm'
      value_template: "{{ state_attr('sensor.landroid', 'dat').rsi | int }}"
      device_class: signal_strength
    landroid_rain_delay:
      friendly_name: Landroid Rain Delay
      unit_of_measurement: 'min'
      value_template: "{{ state_attr('sensor.landroid', 'cfg').rd | int }}"
    landroid_rain_delay_countdown:
      friendly_name: Landroid Rain Countdown
      unit_of_measurement: 'min'
      value_template: "{{ state_attr('sensor.landroid', 'dat').rain.cnt | int }}"
      friendly_name: Landroid Rain estimated resume
      device_class: timestamp
      value_template: >-
              {% if states('sensor.landroid_rain_delay_countdown')|int > 0 %}
              {{ ( (as_timestamp(states('sensor.landroid'))/60)|int * 60 +
                   ( state_attr('sensor.landroid', 'dat').rain.cnt ) * 60
                 ) | timestamp_local }}
              {% else %}
              {{ states.sensor.landroid_rain_delay_countdown.last_changed }}
              {% endif %}
    landroid_zone_index:
      friendly_name: Landroid zone index
      value_template: "{{ state_attr('sensor.landroid', 'dat').lz|int }}"
    landroid_current_zone:
      friendly_name: Landroid current zone
      value_template: >-
              {% set mzv = state_attr('sensor.landroid', 'cfg').mzv %}
              {% set lz = states('sensor.landroid_zone_index')|int %}
              {{ mzv[lz]+1 }}
    landroid_next_zone:
      friendly_name: Landroid next zone
      value_template: >-
              {% set mzv = state_attr('sensor.landroid', 'cfg').mzv %}
              {% set mzv_mod = (mzv or [0]) | length %}
              {% set lz = (states('sensor.landroid_zone_index')|int + 1) % mzv_mod %}
              {{ mzv[lz]+1 }}
    landroid_pitch:
      friendly_name: Landroid pitch
      value_template: "{{ state_attr('sensor.landroid', 'dat').dmp[0] | float(1) }}"
      unit_of_measurement: '°'
    landroid_roll:
      friendly_name: Landroid roll
      value_template: "{{ state_attr('sensor.landroid', 'dat').dmp[1] | float(1)}}"
      unit_of_measurement: '°'
    landroid_yaw:
      friendly_name: Landroid yaw
      value_template: >-
              {% set yaw = state_attr('sensor.landroid', 'dat').dmp[2] %}
              {% if yaw > 180 %}{{ (yaw - 360)|round(1) }}{% else %}{{ yaw|round(1) }}{% endif %}
      unit_of_measurement: '°'
    landroid_next_start:
      friendly_name: Landroid next cycle start
      device_class: timestamp
      value_template: >-
              {%- set ns = namespace(done=false) %}
              {%- set earliest_start = [as_timestamp(now()), as_timestamp(states('sensor.landroid_rain_delay_resume'))] | max %}
              {%- for day_offset in range(0, 7) %}
              {%- set day = now().isoweekday()+day_offset %}
              {%- for sched in [state_attr('sensor.landroid', 'cfg').sc.d, state_attr('sensor.landroid', 'cfg').sc.dd] %}
              {%- if sched %}
              {%- set numdays = 7 %}
              {%- for pass in range(0, (sched|list|length/7)|int) %}
              {%- set current = sched[day % numdays + pass * 7] %}
              {%- set date = ((as_timestamp(now())+86400*day_offset)|timestamp_local).split()[0] %}
              {%- set start = strptime(date ~ " " ~ current[0], "%Y-%m-%d %H:%M") %}
              {%- set end = (as_timestamp(start)+current[1]*60)|timestamp_local %}
              {%- if not ns.done and current[1] != 0 %}
              {%- set cmp_time = end %}
              {%- if as_timestamp(cmp_time) > earliest_start %}
              {%- set ns.done = true %}
              {{ start }}
              {%- endif %}
              {%- endif %}
              {%- endfor %}
              {%- endif %}
              {%- endfor %}
              {%- endfor %}
    landroid_next_end:
      friendly_name: Landroid next cycle end
      device_class: timestamp
      value_template: >-
              {%- set ns = namespace(done=false) %}
              {%- set earliest_start = [as_timestamp(now()), as_timestamp(states('sensor.landroid_rain_delay_resume'))] | max %}
              {%- for day_offset in range(0, 7) %}
              {%- set day = now().isoweekday()+day_offset %}
              {%- for sched in [state_attr('sensor.landroid', 'cfg').sc.d, state_attr('sensor.landroid', 'cfg').sc.dd] %}
              {%- if sched %}
              {%- set numdays = 7 %}
              {%- for pass in range(0, (sched|list|length/7)|int) %}
              {%- set current = sched[day % numdays + pass * 7] %}
              {%- set date = ((as_timestamp(now())+86400*day_offset)|timestamp_local).split()[0] %}
              {%- set start = strptime(date ~ " " ~ current[0], "%Y-%m-%d %H:%M") %}
              {%- set end = (as_timestamp(start)+current[1]*60)|timestamp_local %}
              {%- if not ns.done and current[1] != 0 %}
              {%- set cmp_time = end %}
              {%- if as_timestamp(cmp_time) > earliest_start %}
              {%- set ns.done = true %}
              {{ end }}
              {%- endif %}
              {%- endif %}
              {%- endfor %}
              {%- endif %}
              {%- endfor %}
              {%- endfor %}
    landroid_next_edge:
      friendly_name: Landroid next border cut
      device_class: timestamp
      value_template: >-
              {%- set ns = namespace(done=false) %}
              {%- set earliest_start = [as_timestamp(now()), as_timestamp(states('sensor.landroid_rain_delay_resume'))] | max %}
              {%- for day_offset in range(0, 7) %}
              {%- set day = now().isoweekday()+day_offset %}
              {%- for sched in [state_attr('sensor.landroid', 'cfg').sc.d, state_attr('sensor.landroid', 'cfg').sc.dd] %}
              {%- if sched %}
              {%- set numdays = 7 %}
              {%- for pass in range(0, (sched|list|length/7)|int) %}
              {%- set current = sched[day % numdays + pass * 7] %}
              {%- set date = ((as_timestamp(now())+86400*day_offset)|timestamp_local).split()[0] %}
              {%- set start = strptime(date ~ " " ~ current[0], "%Y-%m-%d %H:%M") %}
              {%- set end = (as_timestamp(start)+current[1]*60)|timestamp_local %}
              {%- if not ns.done and current[2] > 0 %}
              {%- set cmp_time = end %}
              {%- if as_timestamp(cmp_time) > earliest_start %}
              {%- set ns.done = true %}
              {{ start }}
              {%- endif %}
              {%- endif %}
              {%- endfor %}
              {%- endif %}
              {%- endfor %}
              {%- endfor %}

binary_sensors:

- platform: template
  sensors:
    landroid_battery_charging:
      friendly_name: Landroid battery charging
      value_template: "{{ state_attr('sensor.landroid', 'dat').bt.c | int == 1 }}"
      device_class: battery_charging
    landroid_rain_sensed:
      friendly_name: Landroid Rain sensor
      value_template: "{{ state_attr('sensor.landroid', 'dat').rain.s | int > 0 }}"
      device_class: moisture

edit: battery charging (dat.bt.c) is 0 for not charging, 1 for charging, and 2 for not charging because battery temperature is out of range, so only check against 1.

3 Likes

Hello,

I had an issue with landoroid WR130E. “S300i”
can some body help me please? what is wrong?

Thanks a lot!

Written here:

NOTE: you will require the “fold-entity-row” plugin. This can be found using HACS or via the repository https://github.com/thomasloven/lovelace-fold-entity-row

1 Like

Hi,

Thanks for the amazing job done, it’s one of the neetest integrations I have in Hass, so I’m actually redisigning all my cards in order to have the same stacking efect used in halandroid.
Also I’ve translated the files to Portuguese, so if anyone interested, please reply.

I’m not a programmer, and all I do is by entuition, learning from others amazing work.
I’ve been trying to understand the schedulle function inbeded in the code, but I came into the conclusion that I need your profecional help.
Could someone explain me how can I make use of this part of the code:

# Input Boolean ###
    input_boolean.landroid_0_sched_enable:
      friendly_name: Sonntag
    input_boolean.landroid_1_sched_enable:
      friendly_name: Montag
    input_boolean.landroid_2_sched_enable:
      friendly_name: Dienstag
    input_boolean.landroid_3_sched_enable:
      friendly_name: Mittwoch
    input_boolean.landroid_4_sched_enable:
      friendly_name: Donnerstag
    input_boolean.landroid_5_sched_enable:
      friendly_name: Freitag
    input_boolean.landroid_6_sched_enable:
      friendly_name: Samstag

    input_boolean.landroid_0_cuttoedge:
      friendly_name: Cut to edge
    input_boolean.landroid_1_cuttoedge:
      friendly_name: Cut to edge
    input_boolean.landroid_2_cuttoedge:
      friendly_name: Cut to edge
    input_boolean.landroid_3_cuttoedge:
      friendly_name: Cut to edge
    input_boolean.landroid_4_cuttoedge:
      friendly_name: Cut to edge
    input_boolean.landroid_5_cuttoedge:
      friendly_name: Cut to edge
    input_boolean.landroid_6_cuttoedge:
      friendly_name: Cut to edge

    input_boolean.landroid_sched_settings:
      friendly_name: Mähplan
    input_boolean.landroid_info_toggle:
      friendly_name: Information
    input_boolean.landroid_view_0:
      friendly_name: So.
    input_boolean.landroid_view_1:
      friendly_name: Mo.
    input_boolean.landroid_view_2:
      friendly_name: Di.
    input_boolean.landroid_view_3:
      friendly_name: Mi.
    input_boolean.landroid_view_4:
      friendly_name: Do.
    input_boolean.landroid_view_5:
      friendly_name: Fr.
    input_boolean.landroid_view_6:
      friendly_name: Sa.
    input_boolean.landroid_view_config:
      friendly_name: Konf.

I think this should be used in some kind of Schedulle Card, but I do not have enough programing knowled to figure it out. Can someone explain me how can I add the day schedulle an edge routine to my UI?

Everithing else works great.

1 Like

Also,

Is there a way to translate the inforrmation on the main screen that says the currente state of the mower “Home, Mowing,… No error…”

Thanks.

Also I’ve translated the files to Portuguese, so if anyone interested, please reply.

Thank you. Post here please

Could someone explain me how can I make use of this part of the code:

This is rest from the old Landroid integration. It supported the Scheduler

Hi I also want my landroid on my HA. my problem is I am very new to Home Assistant :slight_smile: and do not understand much of your talk, I have spent an incredible amount of time on nothing :slight_smile: is there anyone who has made a setup video?

has then come so far that I can see my landroid in my HA :smile:

Welcome to the world of Home Assistant @enggaard10

Refering to my previous post (#63):
Install the landroid_cloud component by @BlackChart (MTrab). Full details at https://github.com/MTrab/landroid_cloud. It is recommended to have the Home Assistant Community Store (HACS) component installed beforehand at https://hacs.xyz .

After that, recommend adding the beautiful lovelace card (for the User Interface) by @Barmalej https://github.com/Barma-lej/halandroid/ (manual install but good documentation there)

hi and thanks.
have got my landroid integrated in HA but where it goes wrong for me when writing in configuration.yaml, secrets.yaml and Copy folders www and packages.

have maybe 20 maybe 30 hours of experience in HA

All I can say is keep trying and you’ll get there!

You’ll know it’s working when you see around 15 entries in “Developer Tools” (http://nas.local:8123/developer-tools/state), all listed as “sensor.landroid_*******”

Make sure you’ve called your Landroid the default “mower” in your Landroid App as well.

Unless you’ve figured out the concept of secrets.yaml and its purpose, maybe hold off until you’re comfortable with it.

If you’re still running into difficulty, maybe post your issue at https://github.com/MTrab/landroid_cloud/issues and give specific details of your issue (EG: hardware, version of HASSIO, confirmation that its working in the Landroid App, manual install or via HACS (recommended))

Hello everyone, can anyone give me some advice on how to have the mower display distance in …dare I say it… Miles?

I know, I know, my educational system failed me blah blah blah. Thanks!

File packages/landroid.yaml
Change line 152 to:

value_template: "{{ ((state_attr('sensor.landroid_mower_status', 'distance') | float) / 1609) | round(3) }}"

and line 154 to:

unit_of_measurement: "mi"

So far so good, thank you! Only now it’s giving me 15 decimal places EG: 8.286513362336855
Can you please tell me how I’d round to two decimal places?

value_template: "{{ ((state_attr('sensor.landroid_mower_status', 'distance') | float) / 1609) | round(2) }}"

Easy enough, thank you again!

Hi there,
Finally get to test out this great integration. Works like a charm. Thanks for the great work an effort.

But I just stumbled upon a small problem. Yesterday I changed my blades an in the Landroid App there is an option to reset blade working time. This seems to have no effect on the integration what so ever because it still keeps counting up.
Blade woklrking time in App 2h
Blade working time in your integration 5258 min.

Is there a way to reset the blade working time or show the time since last resetting?

Thanks in advance and keep up the good work.

Cheers

I can confirm the issue, but this is an integration issue, not a package. I opened an issue on the integration page here