I had the same problem and was able to fix it. However, I had to look through a lot of documentation to find bits and pieces of information I needed. So, in order to help others, here’s a summary.
What’s the problem?
There was some change in how certain type of fields are presisted in InfluxDB. Due to that change, the definition of the field in InfluxDB, made by a previous version of OH, doesn’t match the data type that the newer version of OH is trying to put into the database. That results in the data getting lost and an error in the log file. This error typically looks like this:
2021-01-01 13:00:00.660 [ERROR] [org.influxdb.impl.BatchProcessor ] - Batch could not be sent. Data will be lost
org.influxdb.InfluxDBException$FieldTypeConflictException: partial write: field type conflict: input field "value" on measurement "GF_Convectorput_Battery" is type integer, already exists as type float dropped=2
at org.influxdb.InfluxDBException.buildExceptionFromErrorMessage(InfluxDBException.java:144) ~[bundleFile:?]
at org.influxdb.InfluxDBException.buildExceptionForErrorState(InfluxDBException.java:173) ~[bundleFile:?]
at org.influxdb.impl.InfluxDBImpl.execute(InfluxDBImpl.java:827) ~[bundleFile:?]
at org.influxdb.impl.InfluxDBImpl.write(InfluxDBImpl.java:460) ~[bundleFile:?]
at org.influxdb.impl.OneShotBatchWriter.write(OneShotBatchWriter.java:22) ~[bundleFile:?]
at org.influxdb.impl.BatchProcessor.write(BatchProcessor.java:340) [bundleFile:?]
at org.influxdb.impl.BatchProcessor$1.run(BatchProcessor.java:287) [bundleFile:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:834) [?:?]
Note that chances are that you have this problem for several measurements. Also note that this error message is written to the log everytime OH tries to persist a value into that measurement. So, even if you have the problem only for one value, you still might have multiple errors in your log files.
How to fix it?
Step 1: find all errors in the log
You can use the grep
command to search to log files. To do so, log into the machine where OH is running via SSH, and perform the following command:
grep "field type conflict:" /var/log/openhab/openhab.log*
This will give you all lines in the log files with “field type conflict:” in it. Note that log files are rotated if they get too long. You might have more than one log file, they will have names with numbers appended, like openhab.log.1
. That’s why there is a *
at the end of the file name; this way, also files names openhab.log.1
, etc, will be searched.
Step 2: get a copy-pastable list of measurement names
To get a list of only the measurement names, we need some more bash magic. @OMR assembled a nice oneliner. I present a slightly improved version here:
grep "field type conflict:" /var/log/openhab/openhab.log* | cut -d ' ' -f 12 | cut -d '"' -f 2 | sort | uniq
The pipes |
are used to pipe the output of one command to the other. In this case the log lines from the grep
command are piped to two cut
commands, that cut the start and end of the log line, keeping onlye the measurement name. Than the list is sorted by sort
and double values are filtered out by uniq
.
Note, as @Masssssy pointed out in a comment below, different operating systems come with different versions of grep
. It might be that your output is different, in that case, you might have to fiddle with the parameters of the cut
commands to get it right. The commands given here are tested on the latest openHABian.
Step 3: create a script
Now you have to create a script that issues an InfluxDB query for every measurement, that fixes the problem. Wouter Born posted a bash script in this Github issue. I copy-pasted it here, for easy reference:
#!/bin/bash
MEASUREMENTS=$(cat << EOF
****insert list of measurements here****
EOF
)
command="SELECT value::integer INTO temp FROM measurement; DROP MEASUREMENT measurement; SELECT value::integer INTO measurement FROM temp; DROP MEASUREMENT temp;"
for m in $MEASUREMENTS; do
echo "Updating $m..."
influx -database 'openhab' -execute "$(sed "s#measurement#$m#g" <<< $command)"
done
Replace ****insert list of measurements here****
with the outcome of step 2.
Step 4: Make sure you can connect to InfluxDB
The script from step 3 uses the influx
command to connect to the InfluxDB database. This should work directly if you run the bash script on the machine where InfluxDB is running. This might be the same machine where OH is running, but it might also be another machine. To try if it works, execute the following command:
influx -database 'openhab' -execute "show measurements"
This should give you a list of all measurements in the InfluxDB. If you don’t get a list, refer to the documentation of InfluxDB to see if you can get it to work.
In case you run InfluxDB on another machine, you can also install InfluxDB on your local machine and make a remote connection, in that case, the previous command should look like this:
influx -host <host> -port <port> -username <user> -password <pass> -database 'openhab' -execute "show measurements"
(Replace <host>
with the hostname or IP-address of the machine, and also replace <port>
, <user>
and <pass>
with the appropriate values.)
If you figured out the right way to connect to InfluxDB, you might need to adapt the script from step 3 accordingly.
Step 5: Run the script
Save the script in a file and give it a name, e.g. fix-influx.sh
. Most of the time you need to give yourself execute rights on this script before you can run it:
chmod ug+x fix-influx.sh
Then, in the same directory, run the script:
./fix-influx.sh
Depending on the number of measurements you have to fix, the script might need some time to run. For each measurement it fixes, it will show something like this on the output:
Updating measurement_xyz...
name: result
time written
---- -------
0 17244
0 17244
That’s it!