[PARTIALLY-SOLVED] AirVisual Node Binding can't initialize thing

Hello,
This is my first post on the forums because so far I have always been able to find a post and solution for any problem I had :smiley: albeit not this one.

I’m running openhabian (1.4) on a Raspberry pi 3.

I installed the AirVisual Node Binding and configured a thing according to the instructions in the binding documentation.
https://www.openhab.org/addons/bindings/airvisualnode/

airvisual.things

airvisualnode:avnode:1a2b3c4 [ address="192.168.3.112", username="airvisual", password="twmmmx23#ALf", share="airvisual", refresh=60 ]

The thing shows up in paper UI as INITIALIZING and there it stays.
The events log shows the following.

events.log

2019-01-04 14:20:41.911 [hingStatusInfoChangedEvent] - 'airvisualnode:avnode:1a2b3c4' changed from UNINITIALIZED to INITIALIZING

then about 4 seconds later the openhab log show the following.

openhab.log

2019-01-04 14:20:46.091 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: 

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 7 column 22 path $.measurements

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224) ~[?:?]

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129) ~[?:?]

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:887) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:852) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:801) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:773) ~[?:?]

	at org.openhab.binding.airvisualnode.internal.handler.AirVisualNodeHandler.pollNode(AirVisualNodeHandler.java:162) ~[?:?]

	at org.openhab.binding.airvisualnode.internal.handler.AirVisualNodeHandler.poll(AirVisualNodeHandler.java:152) ~[?:?]

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

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

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

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

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

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

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

Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 7 column 22 path $.measurements

	at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) ~[?:?]

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213) ~[?:?]

	... 15 more

Does anyone have any ideas or suggestions how I might rectify this problem?
I have tested reinstalling the binding and restarting the raspberry pi.

EDIT:
Forgot to say I’m in mainland China so anything google is blocked for my openhab installation.
EDIT2:
I tested adding the discovered thing from the inbox in papper UI, but the result and error remain exactly the same.

Looking at the error, the json sent by your device is not recognised by the binding
Put the binding on debug mode and post the result

Cool, thank you :slight_smile:
Now I know how to set debug mode for bindings :smiley:
I just bought this unit and also updated the firmware when I got it, can the json have changed to a new format?

2019-01-07 11:34:19.585 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'airvisual.things'

2019-01-07 11:34:19.658 [DEBUG] [nternal.handler.AirVisualNodeHandler] - Initializing AirVisual Node handler

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

2019-01-07 11:34:19.659 [hingStatusInfoChangedEvent] - 'airvisualnode:avnode:1a2b3c4' changed from UNINITIALIZED to INITIALIZING

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

2019-01-07 11:34:19.662 [DEBUG] [nternal.handler.AirVisualNodeHandler] - Scheduling poll for 500ms out, then every 60000 ms

2019-01-07 11:34:20.164 [DEBUG] [nternal.handler.AirVisualNodeHandler] - Polling for state

2019-01-07 11:34:20.678 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'airvisual.things'

2019-01-07 11:34:23.860 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: 

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 7 column 22 path $.measurements

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224) ~[?:?]

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129) ~[?:?]

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:887) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:852) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:801) ~[?:?]

	at com.google.gson.Gson.fromJson(Gson.java:773) ~[?:?]

	at org.openhab.binding.airvisualnode.internal.handler.AirVisualNodeHandler.pollNode(AirVisualNodeHandler.java:162) ~[?:?]

	at org.openhab.binding.airvisualnode.internal.handler.AirVisualNodeHandler.poll(AirVisualNodeHandler.java:152) ~[?:?]

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

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

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

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

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

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

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

Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 7 column 22 path $.measurements

	at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) ~[?:?]

	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213) ~[?:?]

	... 15 more

I’m sorry that everything is double, I’m not home at the moment and for some reason I can’t remove the thing added through paper UI. I’m triggering the error by removing the binding and reinstalling it.

EDIT:
Updated to a proper debug log.
Triggering by removing things file and adding again.

I don’t know if the log helped but I managed to find a json in the samba share.
Last time I opened the samba share I had no idea what a json was but now I know, learning things here :slight_smile:

Now looking at it, it seems different (too me) from what the binding would expect looking at the github repo.
Looking at github, co2 it seems like the binding expects the co2 reading to be named co2Ppm while in my retreived json it’s named co2_ppm.

If this is true then Airvisual/IQAir have quite significantly changed the json return format of the node/pro.
Again if this is true, can I help somehow to modify the binding to accept new devices?
Maybe using the model number in status?
I’m adding the json below.

EDIT: Looking at this now the JSON now the error message makes sense, there is definately an array in that position in the json. Which at least means the binding finds the json and can read the date-time part :slight_smile:

latest_config_measurements.json

{
    "date_and_time": {
        "date": "2019/01/14",
        "time": "10:21:03",
        "timestamp": "1547461263"
    },
    "measurements": [
        {
            "co2_ppm": "1521",
            "humidity_RH": "61",
            "pm01_ugm3": "6",
            "pm10_ugm3": "8",
            "pm25_AQICN": "11",
            "pm25_AQIUS": "33",
            "pm25_ugm3": "8.0",
            "temperature_C": "20.6",
            "temperature_F": "69.1",
            "voc_ppb": "-1"
        }
    ],
    "serial_number": "XXXXXXX",
    "settings": {
        "follow_mode": "station",
        "followed_station": "1641",
        "is_aqi_usa": true,
        "is_concentration_showed": false,
        "is_indoor": true,
        "is_lcd_on": true,
        "is_network_time": true,
        "is_temperature_celsius": true,
        "language": "en-GB",
        "lcd_brightness": 49,
        "node_name": "Home",
        "power_saving": {
            "2slots": [
                {
                    "hour_off": 9,
                    "hour_on": 7
                },
                {
                    "hour_off": 22,
                    "hour_on": 18
                }
            ],
            "mode": "no",
            "running_time": 99,
            "yes": [
                {
                    "hour": 8,
                    "minute": 0
                },
                {
                    "hour": 21,
                    "minute": 0
                }
            ]
        },
        "sensor_mode": {
            "custom_mode_interval": 3,
            "mode": 1
        },
        "speed_unit": "m/s",
        "timezone": "Asia/Shanghai"
    },
    "status": {
        "app_version": "1.1651",
        "battery": 100,
        "datetime": 1547461263,
        "device_name": "AIRVISUAL-XXXXXXX",
        "ip_address": "192.168.3.112",
        "mac_address": "xxxxxxxxxxxx",
        "model": "20",
        "sensor_life": {
            "pm25": 1514366422897
        },
        "sensor_pm25_serial": "XXXXXXXXXXXXXXXXXXXX",
        "sync_time": 60000,
        "system_version": "KBG60F82",
        "used_memory": 2,
        "wifi_strength": 5
    }
}

Good going.
The json format must have changed
Please post an issue on gitHub, here:
https://github.com/issues

The title of the issue should be something like:
[AirVisual Node Binding] Json error

1 Like

Done!
I hope it’s ok, it’s my first time to open an issue so I’m not sure what is expected.
https://github.com/openhab/openhab2-addons/issues/4593

This affects me as well.

Exact same problem.

AirVisualPro purchased recently.

Hi Everyone,

I have created a fix for the JSON binding for the current version of the hardware and firmware. See the GitHub issue linked above (in the comments and the linked Pull Request).

However, currently it is unclear if all older devices receive the new firmware and the new JSON format or old devices remain on the old firmware and use the old JSON.

If anybody has an older device which worked with the OpenHAB binding previously, please let us know if your device still works with the old JSON or you got a firmware update and the binding stopped working because the new firmware started to output the new JSON format.

Maybe only the newer devices called “Pro” have the new firmware?

Maybe all of the older devices are called “Node” still have the old firmware and will not be updated to the new firmware.

I have submitted a query to Airvisual but who knows when they will answer so please chime in if you have any info on the above !

I would say it makes sense to create a new one named airvisualpro using the new JSON format.
The node was the original crowdfunded project, the new pro is the current one and the only one in production.
The airvisualnode binding could remain as a legacy binding for legacy products.
Perhaps the nodes can be updated to the new JSON format, but either way there should be a binding using the new JSON format.

Hello, the author of original AirVisual Node binding is here. :slight_smile: I apologize for such a late response, but I didn’t know AirVisual changed the JSON data format. My Node which I bought in early 2017 is not updating for quite a long time, so its data is still in old JSON format and hence my binding works with it without any major problems. It seems that API changes introduced in latest Pro updates are rather breaking to implement them in the current binding, so maybe it’s a good idea to create a new binding for newer Pro devices.

So if I understand you correctly, you have a Node and it can not be updated to the Pro firmware and API. Is that correct? :thinking:

Yes, exactly.