Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] Landroid v4 #87

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open

[wip] Landroid v4 #87

wants to merge 23 commits into from

Conversation

clinique
Copy link

@clinique clinique commented Jun 7, 2023

Checklist :

  • Passed mvn spotless:apply (sorry this changed many files probably from tab indentation to space indentation)
  • Corrected some IDE complains for potential NPE
  • Initiated the addition of an IconProvider
  • Initiated the creation of a proper i18 file.
  • Switch to use the core oAuth factory
  • NonNullByDefault enforcement and impacts on code
  • Implement quantity type channels where it applies
  • Implement system type channels when they are available
    - [ ] use the mqtt transport provided by openhab core

Added addon.xml
Seeded i18n file
Adressed potential NPE detected by IDE.

Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
Enforcing usage of @NonNullByDefault

Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
Identified the serial number as a specific configuration element of the mower

Signed-off-by: clinique <gael@lhopital.org>
@clinique
Copy link
Author

clinique commented Jun 9, 2023

@nibi79 : do you prefer I push to your repo or should I go directly to openhab/addons ?

@nibi79
Copy link
Owner

nibi79 commented Jun 9, 2023

@clinique thanks for your work, but please push it only to my repo. I hope I can check it next week.

Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
@nibi79
Copy link
Owner

nibi79 commented Jun 16, 2023

Does this version work for you? Because I have connection problems.

@nibi79
Copy link
Owner

nibi79 commented Jun 16, 2023

use the mqtt transport provided by openhab core

If I'm right, openhab uses HiveMQ version 1.2.2, but this version doesn't support custom headers for MQTT. The newer version 1.3.1 does.

@clinique
Copy link
Author

Does this version work for you? Because I have connection problems.

Not fully tested, consider it as of now as an ongoing work.
I will setup my landroid this week-end, so I will be able to move on.

I’m at bridge initialization right now. I’m stuck in my tests line 121 of bridge handler because my mower is not setup and the api call answers with an empty array.

If I'm right, openhab uses HiveMQ version 1.2.2, but this version doesn't support custom headers for MQTT. The newer version 1.3.1 does.

Ok, so keep as it is for now and in a second time see if there is no show-stopper on upgrading core version of HiveMQ

Signed-off-by: clinique <gael@lhopital.org>
Usage of system defined channel types
Usage of UoM channels

Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
Data push to channels controlled.

Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
@clinique
Copy link
Author

clinique commented Jul 2, 2023

@nibi79 : I think I nearly finished reviewing your code. It now needs testing. We could publish it on the Marketplace, this would let people give feedback while we refine it. Your thoughts ?

The README.md still needs a complete review.

Signed-off-by: clinique <gael@lhopital.org>
Adding valid example of .things file in README.md
Some SAT corrections for mvn

Signed-off-by: clinique <gael@lhopital.org>
@ilumie802
Copy link

@clinique , @nibi79 I could help you testing if you could provide me a *.jar file

@sihui62
Copy link

sihui62 commented Jul 24, 2023

if you could provide me a *.jar file

https://community.openhab.org/t/worx-landroid-binding/95246/289?u=sihui

@ilumie802
Copy link

ilumie802 commented Jul 24, 2023

I get the following error during initialization of the bridge thing:

COMMUNICATION_ERROR Unexpected error deserializing '[{"id":669878,"uuid":"96c53178-25db-4002-83e2-ba004ec7a4b7","product_id":70,"user_id":621168,"serial_number":"XXX","mac_address":"XXX","name":"M","locked":false,"firmware_version":3.3,"firmware_auto_upgrade":true,"push_notifications":true,"sim":null,"push_notifications_level":"warning","test":false,"iot_registered":true,"mqtt_registered":true,"pin_code":null,"registered_at":"2022-07-08 00:00:00","online":true,"app_settings":null,"protocol":0,"pending_radio_link_validation":null,"capabilities":["auto_lock","bluetooth_control","bluetooth_pairing","border_cut","digital_fence_settings","follow_border","lock","mqtt","multi_zone","multi_zone_percentage","one_time_scheduler","pairing_smartconfig","pause_over_wire","rain_delay","rain_delay_start","safe_go_home","scheduler_two_slots","unrestricted_mowing_time","zone_keeper"],"capabilities_available":[],"features":{"auto_lock":3.25,"bluetooth_control":3.2,"bluetooth_pairing":true,"chassis":"m_2021","digital_fence_settings":3.25,"display_type":"lcd","input_type":"keyboard_push_knob","lock":true,"mqtt":true,"multi_zone":true,"multi_zone_percentage":true,"multi_zone_zones":4,"one_time_scheduler":3.15,"pause_over_wire":3.26,"rain_delay":true,"rain_delay_start":3.08,"safe_go_home":3.25,"scheduler_two_slots":3.15,"unrestricted_mowing_time":true,"wifi_pairing":"smartconfig"},"accessories":{"ultrasonic":true},"mqtt_endpoint":"iot.eu-west-1.worxlandroid.com","mqtt_topics":{"command_in":"PRM100\/1C9DC2DCE064\/commandIn","command_out":"PRM100\/1C9DC2DCE064\/commandOut"},"warranty_registered":true,"purchased_at":"2022-05-31 00:00:00","warranty_expires_at":"2024-05-31 00:00:00","setup_location":{"latitude":49.20071752,"longitude":8.29588249},"city":{"id":2951206,"country_id":276,"name":"XXX","latitude":XXX,"longitude":XXX",created_at":"2018-02-15 22:21:32","updated_at":"2018-02-15 22:21:32"},"time_zone":"Europe\/Berlin","lawn_size":120,"lawn_perimeter":60,"auto_schedule_settings":{"boost":2,"exclusion_scheduler":{"days":[{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false}],"exclude_nights":false},"grass_type":"mixed_species","irrigation":true,"nutrition":{"k":8,"n":17,"p":23},"soil_type":"sand"},"auto_schedule":false,"improvement":true,"diagnostic":true,"distance_covered":335830,"mower_work_time":22507,"blade_work_time":21405,"blade_work_time_reset":18282,"blade_work_time_reset_at":"2023-06-19 16:59:53","battery_charge_cycles":318,"battery_charge_cycles_reset":0,"battery_charge_cycles_reset_at":null,"created_at":"2021-12-16 12:16:15","updated_at":"2023-07-24 02:01:17","last_status":{"timestamp":"2023-07-24 13:59:15","payload":{"cfg":{"id":2,"sn":"2021302672090085435A","dt":"24\/07\/2023","tm":"15:59:16","lg":"de","cmd":0,"sc":{"m":2,"d":[["17:00",180,1],["17:00",180,0],["17:00",180,0],["17:00",180,1],["17:00",180,0],["17:00",180,0],["17:00",180,0]],"dd":[["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0]],"distm":0,"p":0,"ots":{"wtm":0,"bc":0}},"mz":[0,0,0,0],"mzv":[0,0,0,0,0,0,0,0,0,0],"mzk":0,"rd":0,"al":{"lvl":1,"t":300},"tq":0,"modules":{"US":{"enabled":1}}},"dat":{"mac":"1C9DC2DCE064","fw":3.3,"fwb":1,"ls":1,"le":0,"conn":"wifi","bt":{"t":26.2,"v":20.08,"p":100,"nr":318,"c":0,"m":1},"dmp":[-0.8,1.8,337.3],"st":{"b":21405,"d":335830,"wt":22507,"bl":60},"act":1,"rsi":-58,"lk":0,"tr":0,"lz":0,"rain":{"s":0,"cnt":0},"modules":{"US":{"stat":"ok"}}}}}}]'

@clinique
Copy link
Author

[{"id":669878,"uuid":"96c53178-25db-4002-83e2-ba004ec7a4b7","product_id":70,"user_id":621168,"serial_number":"XXX","mac_address":"XXX","name":"M","locked":false,"firmware_version":3.3,"firmware_auto_upgrade":true,"push_notifications":true,"sim":null,"push_notifications_level":"warning","test":false,"iot_registered":true,"mqtt_registered":true,"pin_code":null,"registered_at":"2022-07-08 00:00:00","online":true,"app_settings":null,"protocol":0,"pending_radio_link_validation":null,"capabilities":["auto_lock","bluetooth_control","bluetooth_pairing","border_cut","digital_fence_settings","follow_border","lock","mqtt","multi_zone","multi_zone_percentage","one_time_scheduler","pairing_smartconfig","pause_over_wire","rain_delay","rain_delay_start","safe_go_home","scheduler_two_slots","unrestricted_mowing_time","zone_keeper"],"capabilities_available":[],"features":{"auto_lock":3.25,"bluetooth_control":3.2,"bluetooth_pairing":true,"chassis":"m_2021","digital_fence_settings":3.25,"display_type":"lcd","input_type":"keyboard_push_knob","lock":true,"mqtt":true,"multi_zone":true,"multi_zone_percentage":true,"multi_zone_zones":4,"one_time_scheduler":3.15,"pause_over_wire":3.26,"rain_delay":true,"rain_delay_start":3.08,"safe_go_home":3.25,"scheduler_two_slots":3.15,"unrestricted_mowing_time":true,"wifi_pairing":"smartconfig"},"accessories":{"ultrasonic":true},"mqtt_endpoint":"iot.eu-west-1.worxlandroid.com","mqtt_topics":{"command_in":"PRM100/1C9DC2DCE064/commandIn","command_out":"PRM100/1C9DC2DCE064/commandOut"},"warranty_registered":true,"purchased_at":"2022-05-31 00:00:00","warranty_expires_at":"2024-05-31 00:00:00","setup_location":{"latitude":49.20071752,"longitude":8.29588249},"city":{"id":2951206,"country_id":276,"name":"XXX","latitude":XXX,"longitude":XXX"created_at":"2018-02-15 22:21:32","updated_at":"2018-02-15 22:21:32"},"time_zone":"Europe/Berlin","lawn_size":120,"lawn_perimeter":60,"auto_schedule_settings":{"boost":2,"exclusion_scheduler":{"days":[{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false},{"slots":[{"reason":"generic","duration":780,"start_time":540}],"exclude_day":false}],"exclude_nights":false},"grass_type":"mixed_species","irrigation":true,"nutrition":{"k":8,"n":17,"p":23},"soil_type":"sand"},"auto_schedule":false,"improvement":true,"diagnostic":true,"distance_covered":335830,"mower_work_time":22507,"blade_work_time":21405,"blade_work_time_reset":18282,"blade_work_time_reset_at":"2023-06-19 16:59:53","battery_charge_cycles":318,"battery_charge_cycles_reset":0,"battery_charge_cycles_reset_at":null,"created_at":"2021-12-16 12:16:15","updated_at":"2023-07-24 02:01:17","last_status":{"timestamp":"2023-07-24 13:59:15","payload":{"cfg":{"id":2,"sn":"2021302672090085435A","dt":"24/07/2023","tm":"15:59:16","lg":"de","cmd":0,"sc":{"m":2,"d":[["17:00",180,1],["17:00",180,0],["17:00",180,0],["17:00",180,1],["17:00",180,0],["17:00",180,0],["17:00",180,0]],"dd":[["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0],["00:00",0,0]],"distm":0,"p":0,"ots":{"wtm":0,"bc":0}},"mz":[0,0,0,0],"mzv":[0,0,0,0,0,0,0,0,0,0],"mzk":0,"rd":0,"al":{"lvl":1,"t":300},"tq":0,"modules":{"US":{"enabled":1}}},"dat":{"mac":"1C9DC2DCE064","fw":3.3,"fwb":1,"ls":1,"le":0,"conn":"wifi","bt":{"t":26.2,"v":20.08,"p":100,"nr":318,"c":0,"m":1},"dmp":[-0.8,1.8,337.3],"st":{"b":21405,"d":335830,"wt":22507,"bl":60},"act":1,"rsi":-58,"lk":0,"tr":0,"lz":0,"rain":{"s":0,"cnt":0},"modules":{"US":{"stat":"ok"}}}}}}]

Yes, there's obviously something wrong with this json response. I'll have to find where is the error in it.

@clinique
Copy link
Author

clinique commented Jul 24, 2023

Ok, I think the error does not lie in the json. It is wrong because you anonimized your location. Correct ?
Would you have another error line point the erroneous data in the json ?

@ilumie802
Copy link

ilumie802 commented Jul 24, 2023

Ok, I think the error does not lie in the json. It is wrong because you anonimized your location. Correct ? Would you have another error line point the erroneous data in the json ?

I exchanged the exact location as well as the serial number and mac with the XXX. Yes, there was an error in the json due to my manual edit. I fixed that. The json seems to be at least in a correct format.

The app is telling me also that there is a connection issue. Maybe I am blocked at the moment and need to check it again tomorrow.

In the logs I also see the same error message as well as:
2023-07-24 18:18:20.409 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'worxlandroid:mower:MyWorxBridge:mymower' changed from OFFLINE (BRIDGE_OFFLINE) to UNINITIALIZED 2023-07-24 18:18:20.414 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'worxlandroid:mower:MyWorxBridge:mymower' changed from UNINITIALIZED to UNINITIALIZED (HANDLER_MISSING_ERROR)

But this is mainly due to the problem with the bridge as I would understand this.

@cinadr
Copy link

cinadr commented Jul 25, 2023

Hi @clinique!
I have the same issue like @ilumie802. I have validated the JSON that I've got back from the binding and it is valid. I have my Android App working correctly and connected. Also the JSON response from the AWS servers do seem correct and filled with actual data. My modified JSON can be found in the forum.

Thank you.

@clinique
Copy link
Author

clinique commented Jul 25, 2023

I'm going to take a look and try to find the origin of the deserialization error.
Ok. Got it. I need to expand the deserialization model. You're using auto schedule setting that are currently not present.

Signed-off-by: clinique <gael@lhopital.org>
@ilumie802
Copy link

ilumie802 commented Jul 25, 2023

I got it up and running with this new version. There are still some errors in the readme regarding the channel names, but I did not have time to come up with a full correct version to share at the moment.

Current status:
``
Switch LandroidEnable "Mowing enabled" {channel="worxlandroid:mower:MyWorxBridge:mymower:common#enable"}

String LandroidAction "Action []" {channel="worxlandroid:mower:MyWorxBridge:mymower:common#action"}
String LandroidLastUpdate "Last Update [%1$td.%1$tm.%1$ty / %1$tH:%1$tM:%1$tS]" {channel="worxlandroid:mower:MyWorxBridge:mymower:common#online-timestamp"}
Switch LandroidPoll "Poll []" oh:worxlandroid:refresh {channel="worxlandroid:mower:MyWorxBridge:mymower:common#poll"}
Switch LandroidLock "Lock" oh:worxlandroid:lock {channel="worxlandroid:mower:MyWorxBridge:mymower:common#lock"}
Number LandroidScheduleMode "Schedule Mode []" {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgSc#scheduleMode"}

String LandroidMacAdress "MAC [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datCommon#macAdress"}
String LandroidSerialNumber "Serial Number [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgCommon#serialNumber"}
Number LandroidFirmware "Firmware [v%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datCommon#firmware"}
Switch LandroidOnline "Onlinestatus [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:common#online"}
Number LandroidId "Id []" {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgCommon#id"}

String LandroidLastUpdateOnlineStatus "Last Update Online Status [%1$td.%1$tm.%1$ty / %1$tH:%1$tM:%1$tS]" {channel="worxlandroid:mower:MyWorxBridge:mymower:config#timestamp"}

// Multizone
Switch LandroidMultizoneEnable "Multizone enable []" {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#enable"}
Number LandroidLastZone "Start Zone []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:datCommon#lastZone"}

// Zone Meters
Number LandroidMeterZone1 "Meters Zone 1 [%d]" oh:worxlandroid:distance {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#zone1Meter"}
Number LandroidMeterZone2 "Meters Zone 2 [%d]" oh:worxlandroid:distance {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#zone2Meter"}
Number LandroidMeterZone3 "Meters Zone 3 [%d]" oh:worxlandroid:distance {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#zone3Meter"}
Number LandroidMeterZone4 "Meters Zone 4 [%d]" oh:worxlandroid:distance {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#zone4Meter"}

// Allocation Zones
Number LandroidAllocation0 "Allocation 0 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation0"}
Number LandroidAllocation1 "Allocation 1 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation1"}
Number LandroidAllocation2 "Allocation 2 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation2"}
Number LandroidAllocation3 "Allocation 3 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation3"}
Number LandroidAllocation4 "Allocation 4 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation4"}
Number LandroidAllocation5 "Allocation 5 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation5"}
Number LandroidAllocation6 "Allocation 6 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation6"}
Number LandroidAllocation7 "Allocation 7 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation7"}
Number LandroidAllocation8 "Allocation 8 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation8"}
Number LandroidAllocation9 "Allocation 9 []" oh:worxlandroid:zones {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgMultiZones#allocation9"}

// Status
Number LandroidWifiQuality "Wifi Quality [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datCommon#wifiQuality"}
Switch LandroidBatteryCharging "Battery charging [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:battery#charging"}
Number LandroidStatusCode "Status Code [%d]" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:common#status"}
String LandroidStatusDescription "[%s]" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:datCommon#statusDescription"}
Number LandroidErrorCode "Error Code [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:common#error"}
String LandroidErrorDescription "Error: [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datCommon#errorDescription"}

// Rain
Switch LandroidRainState "Rain State []" {channel="worxlandroid:mower:MyWorxBridge:mymower:datRain#state"}
Number LandroidRainCounter "Rain Counter [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datRain#counter"}

// Move
Number LandroidPitch "Pitch [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datDmp#pitch"}
Number LandroidRoll "Roll [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datDmp#roll"}
Number LandroidYaw "Yaw [%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datDmp#yaw"}

// Battery
Number LandroidBatteryLevel "Battery Level [%d %%]" (MowerBat, MowerBatStatus_Chart) {channel="worxlandroid:mower:MyWorxBridge:mymower:battery#level"}
Number LandroidBatteryVoltage "Battery Voltage [%.2f V]" (MowerBat, MowerBat_Chart) {channel="worxlandroid:mower:MyWorxBridge:mymower:battery#voltage"}
Number LandroidBatteryTemperature "Battery Temperature [%.1f °C]" (MowerBat, MowerBatTemp_Chart) {channel="worxlandroid:mower:MyWorxBridge:mymower:datBattery#batteryTemperature"}
Number LandroidBatteryChargeCycle "Battery ChargeCycle [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:battery#charge-cycle"}
Number LandroidBatteryChargeCycleCurrent "Battery ChargeCycle Current [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:battery#charge-cycle-current"}

// Settings
Number LandroidRainDelay "Rain Delay [%d min]" {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgCommon#rainDelay"}
Number LandroidScheduleTimeExtension "Schedule Time Extension [%d %%]" {channel="worxlandroid:mower:MyWorxBridge:mymower:cfgSc#scheduleTimeExtension"}

// Statistics
Number LandroidTotalTime "Total Time [JS(minstohours.js):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datSt#totalTime"}
Number:Length LandroidTotalDistance "Total Distance [%s m]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datSt#totalDistance"}
Number LandroidTotalBladeTime "Total Bladetime [JS(minstohours.js):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datSt#totalBladeTime"}
Number LandroidCurrentBladeTime "Current Bladetime [JS(minstohours.js):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:datSt#currentBladeTime"}

//Schedule
// OneTime Schedule
Switch LandroidOneTimeScheduleEdgecut "OneTime Edgecut" {channel="worxlandroid:mower:MyWorxBridge:mymower:one-time#edgecut"}
Number LandroidOneTimeScheduleDuration "OneTime Duration" {channel="worxlandroid:mower:MyWorxBridge:mymower:one-time#duration"}

// Monday
Switch LandroidScheduleMondayEnable "Monday: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:monday#enable"}
Number LandroidScheduleMondayStart "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:monday#time"}
Number LandroidScheduleMondayDuration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:monday#duration"}
Switch LandroidScheduleMondayEdgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:monday#edgecut"}
// Monday 2
Switch LandroidScheduleMonday2Enable "Monday Slot2: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:monday2#enable"}
Number LandroidScheduleMonday2Start "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:monday2#time"}
Number LandroidScheduleMonday2Duration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:monday2#duration"}
Switch LandroidScheduleMonday2Edgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:monday2#edgecut"}

// Tuesday
Switch LandroidScheduleTuesdayEnable "Tuesday: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday#enable"}
Number LandroidScheduleTuesdayStart "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday#time"}
Number LandroidScheduleTuesdayDuration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday#duration"}
Switch LandroidScheduleTuesdayEdgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday#edgecut"}
// Tuesday 2
Switch LandroidScheduleTuesday2Enable "Tuesday Slot2: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday2#enable"}
Number LandroidScheduleTuesday2Start "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday2#time"}
Number LandroidScheduleTuesday2Duration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday2#duration"}
Switch LandroidScheduleTuesday2Edgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:tuesday2#edgecut"}

// Wednesday
Switch LandroidScheduleWednesdayEnable "Wednesday: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday#enable"}
Number LandroidScheduleWednesdayStart "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday#time"}
Number LandroidScheduleWednesdayDuration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday#duration"}
Switch LandroidScheduleWednesdayEdgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday#edgecut"}
// Wednesday 2
Switch LandroidScheduleWednesday2Enable "Wednesday Slot2: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday2#enable"}
Number LandroidScheduleWednesday2Start "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday2#time"}
Number LandroidScheduleWednesday2Duration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday2#duration"}
Switch LandroidScheduleWednesday2Edgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:wednesday2#edgecut"}

// Thursday
Switch LandroidScheduleThursdayEnable "Thursday: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday#enable"}
Number LandroidScheduleThursdayStart "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday#time"}
Number LandroidScheduleThursdayDuration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday#duration"}
Switch LandroidScheduleThursdayEdgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday#edgecut"}
// Thursday 2
Switch LandroidScheduleThursday2Enable "Thursday Slot2: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday2#enable"}
Number LandroidScheduleThursday2Start "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday2#time"}
Number LandroidScheduleThursday2Duration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday2#duration"}
Switch LandroidScheduleThursday2Edgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:thursday2#edgecut"}

// Friday
Switch LandroidScheduleFridayEnable "Friday: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:friday#enable"}
Number LandroidScheduleFridayStart "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:friday#time"}
Number LandroidScheduleFridayDuration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:friday#duration"}
Switch LandroidScheduleFridayEdgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:friday#edgecut"}
// Friday 2
Switch LandroidScheduleFriday2Enable "Friday Slot2: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:friday2#enable"}
Number LandroidScheduleFriday2Start "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:friday2#time"}
Number LandroidScheduleFriday2Duration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:friday2#duration"}
Switch LandroidScheduleFriday2Edgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:friday2#edgecut"}

// Saturday
Switch LandroidScheduleSaturdayEnable "Saturday: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday#enable"}
Number LandroidScheduleSaturdayStart "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday#time"}
Number LandroidScheduleSaturdayDuration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday#duration"}
Switch LandroidScheduleSaturdayEdgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday#edgecut"}
// Saturday 2
Switch LandroidScheduleSaturday2Enable "Saturday Slot2: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday2#enable"}
Number LandroidScheduleSaturday2Start "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday2#time"}
Number LandroidScheduleSaturday2Duration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday2#duration"}
Switch LandroidScheduleSaturday2Edgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:saturday2#edgecut"}

// Sunday
Switch LandroidScheduleSundayEnable "Sunday: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday#enable"}
Number LandroidScheduleSundayStart "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday#time"}
Number LandroidScheduleSundayDuration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday#duration"}
Switch LandroidScheduleSundayEdgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday#edgecut"}
// Sunday 2
Switch LandroidScheduleSunday2Enable "Sunday Slot2: [MAP(landroid_schedule_enable.map):%s]" {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday2#enable"}
Number LandroidScheduleSunday2Start "Start [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday2#time"}
Number LandroidScheduleSunday2Duration "Duration [%d]" {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday2#duration"}
Switch LandroidScheduleSunday2Edgecut "Edgecut" oh:worxlandroid:lawnmower {channel="worxlandroid:mower:MyWorxBridge:mymower:sunday2#edgecut"}
``

@rense-k
Copy link

rense-k commented Jul 26, 2023

With org.openhab.binding.worxlandroid-4.1.0-SNAPSHOT.jar from Jul 25, 2023, 12:45 PM GMT+2 I unfortunately still get a deserializing error. Maybe it's because I have a "Find My Landroid" installed.

Unexpected error deserializing '[ <<see anonymized json below>> ]' : java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 273 path $[0].sim

The json appears to be valid json:

[{
	"id": 521194,
	"uuid": "96c52fe2-b305-4002-a016-cfe629b82643",
	"product_id": 49,
	"user_id": 0,
	"serial_number": "00000000000000000000",
	"mac_address": "XXXXXXXXXXXX",
	"name": "M",
	"locked": true,
	"firmware_version": 3.28,
	"firmware_auto_upgrade": true,
	"push_notifications": true,
	"sim": {
		"id": 12345,
		"iccid": "0000000000000000000",
		"sim_status": "provisioned",
		"pending_activation": false,
		"contract_starts_at": "2023-04-10 00:00:00",
		"contract_ends_at": "2026-04-10 00:00:00",
		"created_at": "2023-04-10 08:09:21",
		"updated_at": "2023-07-26 08:31:33"
	},
	"push_notifications_level": "warning",
	"test": false,
	"iot_registered": true,
	"mqtt_registered": true,
	"pin_code": "1803",
	"registered_at": "2021-08-19 00:00:00",
	"online": false,
	"app_settings": {
		"cellular_setup_completed": true
	},
	"protocol": 0,
	"pending_radio_link_validation": null,
	"capabilities": ["auto_lock", "bluetooth_pairing", "border_cut", "digital_fence_settings", "follow_border", "lock", "mqtt", "multi_zone", "multi_zone_percentage", "one_time_scheduler", "ota_upgrade", "pairing_smartconfig", "pause_over_wire", "rain_delay", "rain_delay_start", "safe_go_home", "scheduler_two_slots", "unrestricted_mowing_time"],
	"capabilities_available": ["zone_keeper"],
	"features": {
		"auto_lock": 3.25,
		"bluetooth_pairing": true,
		"chassis": "m_2019",
		"digital_fence_settings": 3.25,
		"display_type": "tube",
		"input_type": "keyboard_tube",
		"lock": true,
		"mqtt": true,
		"multi_zone": true,
		"multi_zone_percentage": true,
		"multi_zone_zones": 4,
		"one_time_scheduler": 3.15,
		"pause_over_wire": 3.26,
		"rain_delay": true,
		"rain_delay_start": 3.08,
		"safe_go_home": 3.25,
		"scheduler_two_slots": 3.15,
		"unrestricted_mowing_time": true,
		"wifi_pairing": "smartconfig"
	},
	"accessories": {
		"cellular": true
	},
	"mqtt_endpoint": "iot.eu-west-1.worxlandroid.com",
	"mqtt_topics": {
		"command_in": "PRM100\/F4CFA2A090C8\/commandIn",
		"command_out": "PRM100\/F4CFA2A090C8\/commandOut"
	},
	"warranty_registered": true,
	"purchased_at": "2021-08-08 00:00:00",
	"warranty_expires_at": "2024-08-08 00:00:00",
	"setup_location": {
		"latitude": 0.00000000,
		"longitude": 0.00000000
	},
	"city": {
		"id": 0,
		"country_id": 0,
		"name": "XXXXXXXXXXXX",
		"latitude": 0.000000,
		"longitude": 0.00000,
		"created_at": "2018-02-15 22:35:20",
		"updated_at": "2018-02-15 22:35:20"
	},
	"time_zone": "Europe\/Amsterdam",
	"lawn_size": 36,
	"lawn_perimeter": null,
	"auto_schedule_settings": {
		"boost": 0,
		"exclusion_scheduler": {
			"days": [{
				"slots": [],
				"exclude_day": false
			}, {
				"slots": [],
				"exclude_day": false
			}, {
				"slots": [],
				"exclude_day": false
			}, {
				"slots": [],
				"exclude_day": false
			}, {
				"slots": [],
				"exclude_day": false
			}, {
				"slots": [],
				"exclude_day": false
			}, {
				"slots": [],
				"exclude_day": false
			}],
			"exclude_nights": true
		},
		"grass_type": "lolium_perenne",
		"irrigation": false,
		"nutrition": null,
		"soil_type": null
	},
	"auto_schedule": false,
	"improvement": true,
	"diagnostic": true,
	"distance_covered": 46682,
	"mower_work_time": 4378,
	"blade_work_time": 4153,
	"blade_work_time_reset": 0,
	"blade_work_time_reset_at": null,
	"battery_charge_cycles": 58,
	"battery_charge_cycles_reset": 0,
	"battery_charge_cycles_reset_at": null,
	"created_at": "2020-11-22 05:19:53",
	"updated_at": "2023-04-10 09:24:43",
	"last_status": {
		"timestamp": "2023-07-23 16:25:25",
		"payload": {
			"cfg": {
				"id": 0,
				"sn": "00000000000000000000",
				"dt": "23\/07\/2023",
				"tm": "18:25:25",
				"lg": "en",
				"cmd": 0,
				"sc": {
					"m": 1,
					"d": [
						["09:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["09:00", 0, 0]
					],
					"dd": [
						["09:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["00:00", 0, 0],
						["09:00", 0, 0]
					],
					"distm": 0,
					"p": 0,
					"ots": {
						"wtm": 0,
						"bc": 0
					}
				},
				"mz": [0, 0, 0, 0],
				"mzv": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
				"rd": 180,
				"al": {
					"lvl": 1,
					"t": 30
				},
				"tq": 0,
				"modules": {
					"4G": {
						"enabled": 1,
						"geo": {
							"coo": [0.00000, 0.00000],
							"rad": 21
						}
					}
				}
			},
			"dat": {
				"mac": "XXXXXXXXXXXX",
				"fw": 3.28,
				"fwb": 1,
				"ls": 1,
				"le": 0,
				"conn": "wifi",
				"bt": {
					"t": 21.6,
					"v": 19.36,
					"p": 100,
					"nr": 58,
					"c": 0,
					"m": 0
				},
				"dmp": [1.3, 0.5, 0],
				"st": {
					"b": 4153,
					"d": 46682,
					"wt": 4378,
					"bl": 0
				},
				"act": 1,
				"rsi": 0,
				"lk": 1,
				"tr": 0,
				"lz": 0,
				"rain": {
					"s": 0,
					"cnt": 0
				},
				"modules": {
					"4G": {
						"stat": "ok",
						"vers": 2.51,
						"batt": {
							"t": 23,
							"v": 4.11,
							"l": 96
						},
						"mode": 0,
						"geo": {
							"stat": "unk"
						},
						"network": {
							"status": "disconnected",
							"ICCID": "0000000000000000000",
							"IMSI": "000000000000000",
							"rssi": -125
						}
					}
				}
			}
		}
	}
}]

@sihui62 sihui62 mentioned this pull request Aug 15, 2023
@Krata4
Copy link

Krata4 commented Aug 16, 2023

Hello,

may I help with implementation for OH4 please?

Thanks

Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
@clinique
Copy link
Author

clinique commented Aug 19, 2023

Updated jar.
This only address some missing status codes (issue #91) and missing Sim data when you've got "Find My Landroid" option.

Signed-off-by: clinique <gael@lhopital.org>
Code cleansing

Signed-off-by: clinique <gael@lhopital.org>
Signed-off-by: clinique <gael@lhopital.org>
…y opened connection

Added reset of blade time and charge cycle logic
Added retry loop when oAuth token refresh fails

Signed-off-by: clinique <gael@lhopital.org>
@clinique
Copy link
Author

clinique commented Oct 3, 2023

use the mqtt transport provided by openhab core

If I'm right, openhab uses HiveMQ version 1.2.2, but this version doesn't support custom headers for MQTT. The newer version 1.3.1 does.

This is now apparently done : openhab/openhab-core#3824
I will investigate this.

Signed-off-by: clinique <gael@lhopital.org>
@clinique
Copy link
Author

clinique commented Nov 6, 2023

@nibi79 : when do you plan to push it to OH repo ?

@clinique
Copy link
Author

clinique commented Nov 7, 2023

@nibi79 : sorry to push you on this but coping with a binding outside of the repo is a burden. Should I make the PR ?

@nibi79
Copy link
Owner

nibi79 commented Nov 9, 2023

hi @clinique, to be honest, I didn't really want to push into the OH repo, but let's talk about it again next week

@mitch-geht-ab
Copy link

hey guys,
thanks @clinique for all the refactoring.
@nibi79 why is there no interest to migrate to official oh repo?
if not, I think best solution to be independet from oh repo would be, to redesign it as a seperate peace of daemon and working as a worx2mqtt bridge. that there is no dependency.
otherwise every oh update/upgrade could lead to a dysfunction of the binding.

BR
mitch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants