This binding has now been updated to support local connections to /measures/current (Json) and /metrics (OpenMetrics). Tested on the 3.0.6 beta firmware.
I thought I would share how the AirGradient integration with OpenHAB now works with the latest Beta firmwares.
The adapter is currently on the (free) add-on store. When the beta firmware stabilizes, I will try to get it integrated into the official addons distribution to be bundled with every installation when the beta firmware work start stabilizing.
To install it from the add-on store, you search for âairgradientâ and press install.
After you have added the add-on, autodiscovery will kick on. If your devices are on your local network, they will be found and placed in the OpenHAB Inbox.
From here you can add it as a thing and give it a name.
Now you have a connection, but we havenât defined the sensor in OpenHAB. To do that you need to go to Things â Plus â AirGradient Binding â Scan. The sensor will pop up, and you add it and give it a name.
For the sensor you have all the properties, and you can add items in OpenHAB for them, to show them in dashboards (pages in OpenHAB terminology) or use them in automations.
You need a token from AirGradient Connectivity Settings
Copy the token from the AirGradient portal, and paste it into the token field when you create the thing on OpenHAB. If you Show Advanced, you can also change the refresh interval to suite you (default 10 minutes).
To discover devices in the cloud, you trigger the same scan as for local devices. To to Things â press the round blue plus - select the AirGradient Binding â Scan
Sensors in the cloud support a couple more features than the local sensors. There is a Calibration channel for triggering Co2 calibration, and there is a LEDs Mode channel for seeing the current LEDs mode and for changing the LEDs mode.
Here is how you can change it from the user interface, but it is also simple to make it prettier on a page with buttons or other controls:
I love the new beta firmwares and the possibilities they give. The only things I can see missing for feature parity between local and cloud, is the possibility to read and set LED mode locally and to trigger co2 calibrations locally. In addition, for the examples above, I am running my own mDNS setup built on top of the 3.0.7 firmware for autodetection to work. Without them we might need some fixes in some other software.
Hi, I am testing against a O-1PST running the old firmware and a I-9PSL with latest beta firmware in addition to the variety of devices on the cloud API for a wide coverage. When the beta becomes official Iâll update both of them to that.
Some functionality isnât supported on the old firmware (local detection and reading values), and some functionality isnât on the outdoor unit (LEDs), but everything that is supported on the firmware/hardware should work, and if it doesnât Iâll fix it.
In addition to what is officially supported in the firmware, it does also support prometheus and json locally against third party firmware, in case someone runs on older versions with those enabled.
I believe that I run the latest firmware 3.0.9, however, I am not sure as I canât seem to find the firmware version information in the dasshboard anymore.
But assuming I run 3.0.9 on the O-1PST, should I be able to access the outdoor monitor locally? Because scanning in OpenHAB does not discover the outdoor monitor.
Hi, if it isnât able to autodetect the monitor locally, the reason could be too old firmware, or there could be a bug. (I have tested here with O-1PST and 3.0.8.)
Another way, If you are able to show openhab logs and use the console, you could try setting âlog:set DEBUG org.openhab.binding.airgradientâ and look for version numbers strings like in the log line below:
Got measurements with status 200: {âwifiâ:-62,âserialnoâ:âxxxxxxxxâ,ârco2â:447,âtvocIndexâ:57,âtvoc_rawâ:31852,ânoxIndexâ:
2,ânox_rawâ:0,âatmpâ:21.99,ârhumâ:33,âbootâ:20437,âledModeâ:âoffâ,âfirmwareVersionâ:â3.0.6â}(application/json)
Sometimes I donât get the firmware version:
âmodelâ:âI-9PSLâ,âfirmwareVersionâ:null
âŠso if that is what you see, then the plugin isnât able to help.
Iâve verified that the outdoor monitor runs 3.0.9.
Where? The binding lets me select
AirGradient API
AirGradient Location
when pressing the â+â button. And It appears âAirGradient Locationâ requires a prior âAirGradient APIâ creating a âBridgeâ.
That said, yesterday, when I power cycled the montior, OpenHAB suddenly discovered the device. I was even able to add it. However, the AirGradient thing did not show up any channels. So I removed it again.
Believing that the, I assume zeroconf based, discovery only works a brief period after the monitor is powered on, I power cycled it this morning. However, OpenHAB does neither automatically or manually discover the device.
Not sure if this is related, but I see the following NullPointerException in OpenHABâs logs:
2024-04-08 00:43:59.414 [ERROR] [y.mdns.internal.MDNSDiscoveryService] - Participant 'org.openhab.binding.airgradient.internal.discovery.AirGradientMDNSDiscoveryParticipant' threw an exception
java.lang.NullPointerException: Cannot invoke "String.matches(String)" because "segment" is null
at org.openhab.core.common.AbstractUID.validateSegment(AbstractUID.java:99) ~[bundleFile:?]
at org.openhab.core.common.AbstractUID.<init>(AbstractUID.java:75) ~[bundleFile:?]
at org.openhab.core.common.AbstractUID.<init>(AbstractUID.java:58) ~[bundleFile:?]
at org.openhab.core.thing.UID.<init>(UID.java:57) ~[bundleFile:?]
at org.openhab.core.thing.ThingUID.<init>(ThingUID.java:47) ~[bundleFile:?]
at org.openhab.binding.airgradient.internal.discovery.AirGradientMDNSDiscoveryParticipant.getThingUID(AirGradientMDNSDiscoveryParticipant.java:126) ~[?:?]
at org.openhab.core.config.discovery.mdns.internal.MDNSDiscoveryService.removeDiscoveryResult(MDNSDiscoveryService.java:236) [bundleFile:?]
at org.openhab.core.config.discovery.mdns.internal.MDNSDiscoveryService.serviceRemoved(MDNSDiscoveryService.java:200) [bundleFile:?]
at javax.jmdns.impl.ListenerStatus$ServiceListenerStatus.serviceRemoved(ListenerStatus.java:81) [bundleFile:3.5.8]
at javax.jmdns.impl.JmDNSImpl$5.run(JmDNSImpl.java:1343) [bundleFile:3.5.8]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
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) [?:?]
There are two levels of autodetect kicking in. One MDNS/zeroconf (which is the one with the exception) which detects sensors in the local network, and another one which detects them if you are connected to the cloud API. The exception you get is from the MDNS discovery, where it fails because it is not able to find a serial number of a thing. Did you see any debug log line (just?) before that for âGetting thing ID for: Appâ? (This could also be related to the removal of the service)
I have sometimes seen that the MDNS autodiscovery has been slow. I do not know if it is AirGradient announcing the service slowly, or if it is OpenHAB detecting it slowly, but using Linux tools I have seen services being advertised by AirGradient before they are picked up by OpenHAB, so I fear that is a generic OpenHAB problem.
The namings of the thing types in OpenHAB makes more sense for when people connect to the CloudAPI than locally (local connections wasnât possible when I started). For the cloud API there is one connection to the API and it can have several sensors. For direct connection there is a one-to-one connection. Maybe it would be easier to understand if I added a âLocalSensorâ thing - which was either autodetected with MDNS or added manually with a URL?
Add new thing - Add an AirGradient Location which uses the API you just created as a Bridge
The AirGradient Location will have the channels you are looking for
Actually, you should be able to - instead of step 2 - Add new Thing - AirGradient Binding - Scan - and Sensor_serialnumber should appear in your inbox.
No, but that could very well be beaucse debug logs are disable. How about creating a non-debug log-level message in case an unexpected or incomplete ServiceInfo is encountered?
I can confirm that using avahi-discover, the _airgradient._tcp MDNS service is responsive and seems to contain all relevant information (model, serialno, fw_ver). Assuming there is no caching or similar involved, we could probably rule out the monitor being slow or sluggish with regard to MDNS announcements.
That said, in my experience MDNS-based discovery works reliable in OpenHAB, which makes we doubt that it is a generic MDNS implementation issue in OpenHAB. But that is just my experience and could very well be wrong.
That sounds like a sensible idea. In fact, I was expecting to see such an entry presented by the binding.
Furthermore, some settings could (and probably should) be different when querying the local API instead of the Airgradient API. For example, the refresh interval could very be less than 10 minutes (600 seconds).
This requires me to specify a token, which I do not have. Iâve tried a dummy string.
This requires me to specify a âLocation IDâ. Iâve tried a dummy string.
Nope, that did not work.
However, setting up the connection manually using dummy string values allowed me to add the thing.
That said, I only see NULL as value. Here is the debug log:
2024-04-09 09:16:18.474 [DEBUG] [t.internal.AirGradientHandlerFactory] - We support: [airgradient:location, airgradient:airgradientapi]
2024-04-09 09:16:18.485 [DEBUG] [t.internal.AirGradientHandlerFactory] - We support: [airgradient:location, airgradient:airgradientapi]
2024-04-09 09:16:18.488 [DEBUG] [t.internal.AirGradientHandlerFactory] - Creating Bridge Handler for airgradient:airgradientapi
2024-04-09 09:16:18.489 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Getting supported services
2024-04-09 09:16:18.491 [DEBUG] [.AirGradientLocationDiscoveryService] - Constructing discovery service
2024-04-09 09:16:26.420 [DEBUG] [.AirGradientLocationDiscoveryService] - Starting Location discovery for bridge airgradient:airgradientapi:AirGradientLocalOutdoor
2024-04-09 09:17:30.268 [DEBUG] [t.internal.AirGradientHandlerFactory] - We support: [airgradient:location, airgradient:airgradientapi]
2024-04-09 09:17:30.280 [DEBUG] [t.internal.AirGradientHandlerFactory] - We support: [airgradient:location, airgradient:airgradientapi]
2024-04-09 09:17:30.284 [DEBUG] [t.internal.AirGradientHandlerFactory] - Creating Location Handler for airgradient:location
2024-04-09 09:17:59.859 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:18:42.075 [WARN ] [.io.rest.auth.internal.TokenResource] - Not refreshing token for session 21103f99-d4bf-45ed-8456-f62b89e5792d of user flo, missing or invalid session cookie
2024-04-09 09:18:42.077 [WARN ] [.io.rest.auth.internal.TokenResource] - Token issuing failed: invalid_grant
2024-04-09 09:19:49.365 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":470,"pm01":14,"pm02":21,"pm10":21,"pm003Count":2601,"atmp":16.26,"rhum":73,"tvocIndex":99,"tvoc_raw":32355,"noxIndex":5,"nox_raw":19980,"boot":13,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:19:49.368 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.731 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:pm01: REFRESH
2024-04-09 09:21:49.820 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.823 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.838 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:atmp: REFRESH
2024-04-09 09:21:49.845 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:rhum: REFRESH
2024-04-09 09:21:49.848 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:wifi: REFRESH
2024-04-09 09:21:49.849 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:rco2: REFRESH
2024-04-09 09:21:49.860 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:leds: REFRESH
2024-04-09 09:21:49.862 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.861 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:tvoc: REFRESH
2024-04-09 09:21:49.865 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.877 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.879 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.894 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.895 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.902 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:calibration: REFRESH
2024-04-09 09:21:49.910 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:pm02: REFRESH
2024-04-09 09:21:49.914 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.916 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.922 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:pm10: REFRESH
2024-04-09 09:21:49.927 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.929 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.936 [DEBUG] [l.handler.AirGradientLocationHandler] - Channel airgradient:location:AirGradientLocalOutdoor:b94da66c81:pm003Count: REFRESH
2024-04-09 09:21:49.958 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.960 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.976 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-77,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.978 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:49.996 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-78,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:49.998 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:50.014 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-78,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:50.016 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
2024-04-09 09:21:50.026 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Got measurements with status 200: {"wifi":-78,"serialno":"012345678","rco2":467,"pm01":12,"pm02":19,"pm10":19,"pm003Count":2457,"atmp":16.15,"rhum":73,"tvocIndex":99,"tvoc_raw":32350,"noxIndex":4,"nox_raw":19958,"boot":15,"ledMode":"co2","firmwareVersion":"3.0.9","fwMode":"O-1PST"} (application/json)
2024-04-09 09:21:50.029 [DEBUG] [ternal.handler.AirGradientAPIHandler] - Could not find measures for location test
I also noticed that it appears that the binding performs one HTTP request per value. It would be great if there where only one request that updates all values.
This looks great. The operating system has (at least a cached) version of the information
I disconnect and reconnect the sensor. Nothing in the inbox.
The first line in createResult(ServiceInfo) is a log line which I have enabled.
I get this:
20:16:05.741 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Discovered airgradient_12345._airgradient._tcp.local. at []: \00 -
20:16:05.741 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Not able to find URLs for airgradient_12345._airgradient._tcp.local., not autodetecting
So I get autodiscovery information without hostname, which is useless for the purpose.
I press SCAN button on AirGradient binding, it finds a v3.0.8 device, but not the v3.0.9 device. It could be that the v3.0.8 device has been connected for a longer while so disconnect it and connect it some minutes later. Now it fails to find the v3.0.8 device, which is still visible in avahi-browse.
From wireshark, I see MDNS traffic with the information (vendor, fw_ver, serialno and model) included when the device boot up.
When I restart OpenHAB I see a proper detection:
21:12:46.830 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Discovered airgradient_12345._airgradient._tcp.local. at [http://192.168.x.x:80]: \022vendor=AirGradient\014fw_ver=3.0.9\025serialno=12345\014model=O-1PST
21:12:46.831 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Getting thing ID for: App: airgradient Host: [192.168.x.x] Name: airgradient_ecda3b1a2a50 Port: 80 Serial: 12345
21:12:46.831 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Autodiscovered API airgradient_ecda3b1a2a50 with id airgradient:airgradientapi:12345 with host name http://192.168.x.x:80/measures/current. It is a O-1PST
connecting the other device and it is also discovered now, but without the hostname initially:
21:15:41.343 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Discovered airgradient_54321._airgradient._tcp.local. at []: 1airgradient_84fce612e644._airgradient._tcp.local.
21:15:41.344 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Not able to find URLs for airgradient_54321._airgradient._tcp.local., not autodetecting
But then it sends everything, and it is detected:
21:15:41.345 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Discovered airgradient_54321._airgradient._tcp.local. at [http://192.168.x.y:80]: \022vendor=AirGradient\014fw_ver=3.0.6\025serialno=54321\014model=I-9PSL
21:15:41.346 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Getting thing ID for: App: airgradient Host: [192.168.x.y] Name: airgradient_54321 Port: 80 Serial: 54321
21:15:41.347 [DEBUG] [y.AirGradientMDNSDiscoveryParticipant] - Autodiscovered API airgradient_54321 with id airgradient:airgradientapi:54321 with host name http://192.168.x.y:80/measures/current. It is a I-9PSL
Maybe OpenHAB caches things it has tried to autodiscover and since the thing was deleted it doesnât show it again?
It at least looks like the sensor sends sufficient mDNS information, and it looks like the binding can discover it if it receives such information.
I add an API with token 123 (should not be required, have fixed but not created a new release of the plugin)
I set the hostname.
I set it to poll every 10 seconds.
I add a location with LocationID 123
I link temp and humidity.
I get null values for linked channels/items, like you have.
I change the location ID to the serialno from the response.
I get data for both channels.
I see 1 call every 10 seconds, which updates both temperature and humidity.
In your logs I see Channel ⊠REFRESH. That means that it is the UI which requests an updated value now. I think that explains the extra calls.
Try to change the locationid of the location thing to the serialno of the device.
Iâll be away for a couple of weeks, so donât expect a quick fix for the âLocalSensorâ, but Iâll try to add that when I return.
Thank you @Jorgen_Austvik to look into this. In case you think there is anything we can improve on the firmware please let me know.
Maybe one thing people need to be aware. To pull the data from the local network directly, the serial number is the identifier of the monitor. If you use our cloud api, the identifier is the location id which is different from the serial number.
I think the firmware is fine here. I think it is OpenHAB that remembered that you have had an item and deleted it, and then dont let you autodetect the same item again.
And I think my «reuse cloud for local» approach isnt user friendly, so I will make local more distinct
To answer my own question: Looking at the source code shows that the sensors are updated every 1-5 seconds, so polling every 10 seconds seems sensible.
Another suggestion, please change rhum from Double to Integer. Iâve added the âGoogleAssistantâ Metadata to the Airgradient Openhab Thing, and reporting humidity requires the item to be Integer. I actually believe that humidity being reported as integer is becoming the de-facto standard.
That said, looking at the JSON return value of the Airgradient:
I think there are more values that could (and therefore maybe should) be change from Double to Integer:
wifi
rco2
pm1
pm2
pm10
pm003Count
tvocIndex
noxIndex
Looking at the Airgradient source, it appears that most values are integers there too:
And please consider adding boot to the OpenHAB thing. Unlike its name may suggests, it is actually the number of times the Airgradient has submitted data to the Airgradient API. Ultimately, it is useful to determine when the Airgradient rebooted.