Contribution - LG ThinQ Binding

Having an issue on my side.
The bridge is online :

UID: lgthinq:bridge:1
label: _ LG ThinQ
thingTypeUID: lgthinq:bridge
configuration:
  manualLanguage: fr-FR
  country: --
  password: xxxxxxxxx
  poolingIntervalSec: 300
  language: --
  manualCountry: FR
  username: xxxxx@xxxx.xx
location: internet

The washer is discovered and goes green, properties are present :
Capture d’écran du 2023-07-24 10-50-52

but after some second it goes offline and I observe this in the log :


2023-07-24 10:46:13.228 [ERROR] [al.handler.LGThinQWasherDryerHandler] - Error updating channels dynamic options descriptions based on capabilities of the device. Fallback to default values.
org.openhab.binding.lgthinq.internal.errors.LGThinqApiException: Error reading IO interface
	at org.openhab.binding.lgthinq.lgservices.LGThinQAbstractApiClientService.getCapability(LGThinQAbstractApiClientService.java:254) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQAbstractDeviceHandler.getCapabilities(LGThinQAbstractDeviceHandler.java:214) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQWasherDryerHandler.updateChannelDynStateDescription(LGThinQWasherDryerHandler.java:134) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQAbstractDeviceHandler.initializeThing(LGThinQAbstractDeviceHandler.java:229) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQWasherDryerHandler.initializeThing(LGThinQWasherDryerHandler.java:118) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQWasherDryerHandler.initialize(LGThinQWasherDryerHandler.java:129) ~[?:?]
	at jdk.internal.reflect.GeneratedMethodAccessor36.invoke(Unknown Source) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
	at org.openhab.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:147) ~[?:?]
	at org.openhab.core.internal.common.Invocation.call(Invocation.java:52) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 start byte 0xb0
 at [Source: (File); line: 293, column: 33]
	at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2418) ~[?:?]
	at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:749) ~[?:?]
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidInitial(UTF8StreamJsonParser.java:3706) ~[?:?]
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._reportInvalidChar(UTF8StreamJsonParser.java:3702) ~[?:?]
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishString2(UTF8StreamJsonParser.java:2628) ~[?:?]
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._finishAndReturnString(UTF8StreamJsonParser.java:2554) ~[?:?]
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.getText(UTF8StreamJsonParser.java:334) ~[?:?]
	at com.fasterxml.jackson.databind.deser.std.BaseNodeDeserializer._deserializeContainerNoRecursion(JsonNodeDeserializer.java:570) ~[?:?]
	at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:98) ~[?:?]
	at com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer.deserialize(JsonNodeDeserializer.java:23) ~[?:?]
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) ~[?:?]
	at com.fasterxml.jackson.databind.ObjectMapper._readTreeAndClose(ObjectMapper.java:4772) ~[?:?]
	at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:3157) ~[?:?]
	at org.openhab.binding.lgthinq.lgservices.LGThinQAbstractApiClientService.getCapability(LGThinQAbstractApiClientService.java:251) ~[?:?]
	... 14 more
2023-07-24 10:46:23.241 [ERROR] [al.handler.LGThinQWasherDryerHandler] - Error updating thing Lave-linge/0aa70645-554f-1b9f-9021-4cbad76ac66b from LG API. Thing goes OFFLINE until next retry.
org.openhab.binding.lgthinq.internal.errors.LGThinqApiException: Error reading IO interface
	at org.openhab.binding.lgthinq.lgservices.LGThinQAbstractApiClientService.getCapability(LGThinQAbstractApiClientService.java:254) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQAbstractDeviceHandler.getCapabilities(LGThinQAbstractDeviceHandler.java:214) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQAbstractDeviceHandler.updateThingStateFromLG(LGThinQAbstractDeviceHandler.java:296) ~[?:?]
	at org.openhab.binding.lgthinq.internal.handler.LGThinQAbstractDeviceHandler$UpdateThingStateFromLG.run(LGThinQAbstractDeviceHandler.java:289) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 start byte 0xb0
 at [Source: (File); line: 293, column: 33]

This is an I/O exception reading the cap json file and is not related to de binding.
You can try to visualize your Washer capability file to see if it’s readable and accessible though the SO. If you believe it’s not a corrupted file or hardware problem, you can attach the file here than I can take a look.

Hello @nemer , thanks for your quick answer.
The file is ok, owned by openhab:openhab. Opening it, I can read it and from a json syntax point of view it is correct.
Here’s a link to the file

Hi, @Nirtsep1. I found a bug in the Auto Dry mode for you device version. Can you try to download the latest version and try it out ?

Regards

Hi @nemer , I just tried it. It works Great. Thank you indeed!

Regards

1 Like

Thanks for the file. Look, at line 293:

the comment part contains a lot of invalid characters (not UTF-8). Json data should be in UTF-8, UTF-16, or UTF-32 and UTF-8 it the default.
You can try to edit the file by yourself and remove the invalid content or convert it to UTF-8 using some text editor. It must fix the problem. However, I must now why you have a JSON LG descriptor file with invalid encoding. If the source file come from LG API as you mention, then I need to handle it in some way. So… can you get the model’s URL info for me ?
To do so, you must go to:

administration > settings > things > [your thing]

Then you can see Thing Properties in Information session (normally is collapsed, then you can expand it), like this:

modl_url_info is the information I need, but it’s a big text and you can see only the beginning. To get the complete url (and it’s the boring part), you have to use Chrome’s DevTools to inspect this item and see the complete value of it (if you are using Chorme, I hope). To do so, simple press CTRL+SHIFT+C and use the mouse to click to the model_url_info value (https://objectcontent…). Then you gonna have something like this:


Expand the span element (normally it’s collapsed) and copy the fully URL.

Regards.

You’re correct, the json file comes directly from LG website.
Here’s the modl_url_info : https://objectcontent.lgthinq.com/39dd1e90-5aea-4ace-8bd1-e10bed926779?hdnts=exp=1741053656~hmac=5a31b83a0bd3875944bd85f4e3c3dc2d4aac0cdf2578185aa6381610468267de

If I open it directly with the browser, there is the same encoding error.

hi to all, I’m a OH4.0.2 user, and I have a new LG fridge, but I’m not a developer…
some questions :
how I have to handle .json file? do I have to copy in adding folder?
(I usually use .jar file for community bindings)
all my OH configuration is made by text files, do you have some example for .thing file?
thanks

Sorry for late response,
It’s possible to configure LG Thinq by this binding textually, but you first need to registry the bridge and discovery it from the UI. It’s necessary because the binding needs some informations that is available by the LG API, after the registry process. In other words, you can’t get this information manually.

So, the steps I recommend to configure textually your thing are:

  1. Add the LG Thinq Bridge configuring your LG Account. It will automaticatty discovery LG Thinqs associated toi your account
  2. Add the LG Thinq things you want to control
  3. Go to the thing, and copy the configurations the binding filled automatically.
  4. Remove the thing, and create the associated .thing file.

how I have to handle .json file? do I have to copy in adding folder?

No. No. Json files created by the binding is only to save the metadata from the device. You don´t need to handle it.

Here is an example of things file, based on my things.

Bridge lgthinq:bridge:LGAccount "LG ThinQ Account"
    [ username="email@domain.com", password="*******", language="pt-BR", country="BR", pollingIntervalSec=0 ] {

    401    ACEscritorio    "Ar Codicionado Escritório"    [ 
        device_id="qwe123qwe-qwe12-123e-1233-123qwe123qwe12",
        model_url_info="https://objectcontent.lgthinq.com/qwe123qwe-qwe12-123e-1233-123qwe123qwe12?hdnts=exp=172345285~hmac=asdfqwe12qwaed216234sdf435345sdfsdf24234sdfsdf23324fsdfsdf234234sdfsdf7f253867df5ba",
        platform_type="thinq2",
        polling-period-poweron-seconds=60,
        polling-period-poweroff-seconds=60,
        polling-extra-info-period-poweron-seconds=60,
        polling-extra-info-period-poweroff-seconds=0
    ]

    401    ACCozinha    "Ar Codicionado Cozinha"    [ 
        device_id="qw3453qwe-qwe345-123e-3453-123qwe1345qwe12",
        model_url_info="https://objectcontent.lgthinq.com/qwe234qwe-qwe12-123e-1233-123qwe123qwe12?hdnts=exp=1722345281~hmac=asdfqwe12qw2342344sdf4353234234234sdfsdf23324fsdfsdf234234sdfsdf7f253867df5ba",
        platform_type="thinq2",
        polling-period-poweron-seconds=60,
        polling-period-poweroff-seconds=60,
        polling-extra-info-period-poweron-seconds=60,
        polling-extra-info-period-poweroff-seconds=0
    ]
}
2 Likes

Ok many many thanks !!
I’m not sure I’ve understood step 3
Could you give me an example ?
Thanks

Simone

You get the @jgesser example and override the values based on what you have configured in the UI. To do so, as I told you, you need first create the Bridge and the Thing and both must be online. So… go to the bridge and get the values you filled to username, password, language, country, etc. and update the Bridge lgthinq:bridge:LGAccount session.
After, go to the Thing you created and get the properties:

Then override the properties based on this information. In my example, It should be:

Bridge lgthinq:bridge:LGAccount "LG ThinQ Account"
    [ username="xxxxxxx@domain.com", password="12345678", language="pt-BR", country="BR", pollingIntervalSec=0 ] {

    401    ACEscritorio    "Adega"    [ 
        device_id="c8419489-1fdc-1736-8145-60ab14f3da26",
        model_url_info="https://objectcontent.lgthinq.com/457b046b-b6a6-4fb8-b2bc-e479a03873ed?hdnts=exp=1748483609~hmac=ec76d76d05e7ec6aa8cb4a593897e0b930496bbe111cfe80b4f8486848941a54",
        platform_type="thinq2",
        polling-period-poweron-seconds=60,
        polling-period-poweroff-seconds=60,
        polling-extra-info-period-poweron-seconds=60,
        polling-extra-info-period-poweroff-seconds=0
    ]
}

There is a tip to you get model_url_info value from UI, since the value is big, the UI truncate it. You need to use the Developer Tool from Chrome to access this fully value. You can find it in some reply in this topic.

hi, thanks, now its’ work. but is correct there only 3 items available ?
what is the difference betwen ACEscritorio 401 and 101?
what is the correct configuration for a fridge?
thanks !!

401 is the type ID for LG Thinq Air Conditioner. 101 is for the Refrigerator
The correct type ID is what you get after the discovery process. Ex:

“401HP” is the type ID for Heat Pump

but is correct there only 3 items available

I don’t know what you mean.

sorry i means channel, I get only setpoint for fridge, refriferatore, open door and unit temperature,
from the LG app there are also “express cool” and “express frezze” switch, water filter information etc…
thanks

It’s planned… but not implemented yet.

sorry … why values are not updates? my freezer item always 3°C
but in the freezer it is at -18°C, this is my items :
Contact FrigoSomeDoorOpen “Porta APERTA” (GR_LgThinQ_FRIGO) {channel=“lgthinq:101:LGAccount:ACEscritorio:some-door-open”}
Number:Temperature FrigoFreezerTemperature “Setpoint Temperatura FRIGO” (GR_LgThinQ_FRIGO) {channel=“lgthinq:101:LGAccount:ACEscritorio:freezer-temperature”}
Number:Temperature FrigoFridgeTemperature “Setpoint Temperatura CONGELATORE” (GR_LgThinQ_FRIGO) {channel=“lgthinq:101:LGAccount:ACEscritorio:fridge-temperature”}
// String FrigoTempUnit “Temp. unit” (GR_LgThinQ_FRIGO) {channel=“lgthinq:101:LGAccount:ACEscritorio:temp-unit”}

what I’m worng?
thanks

Hi @nemer. I’m waiting to receice a new LG dishwasher that supports Thinq. Do you think you can add the dishwasher to your binding?

Yes. I can. It’d be great

How do I get the latest version of this binding installed?