Let's say you have 3 sensors name sensor1, sensor2, sensor3 in your system.
Assume it is a well-know configuration, you can build a list of expected sensors to check:
mySensors=['sensor1', 'sensor2', 'sensor3']
Then you have a dictionary data in which you store sensor data that you read, ie.
data={'sensor1':value1;'sensor2':value2;'sensor3':value3}
Sometimes you have missing value if, let's say sensor2 is OFF, then you'll end up with
data={'sensor1':value1;'sensor3':value3}
is that right ?
then with your current code, you miss the value and write sensor3's value in sensor2 column of the CSV.
To avoid this you may loop over your known configuration, ie. the list.
note that this is valid only if you have a well-known and fixed sensor configuration
with open(filename,'a') as outfile:
lineValue = ""
for component in mySensors:
# check that the sensor is in the data read
if component not in data:
# the sensor has not been read, set a neutral value
lineValue+= 'n/a' + ","
else:
v = data[component]
lineValue+= str(v) + "," # I cast value for my test, your value is probably already in correct format
#for k,v in data.items():
# if k[]=v[]: => Can you explain that comparison, please ?
# lineValue+= v + ","
lineValue = Time + "," + lineValue[:-1] + "\n"
outfile.write(lineValue)
This should handle value shifting. You can set any neutral value instead of 'n/a'
If data is in the second configuration (ie, missing sensor2), the line you'll write in your file will be:
'Time,5,n/a,20\n'
EDIT: upgrade from your comments
So I understand that you may have missing values from known sensors (already in CSV file), new values for known sensor and new values from new sensors.
First get your header line in CSV (which should look like 'duration, sensor1, sensor2, ... sensorx')
with open(filename,'r') as myFile:
readline = ""
# parse file until you hit the header line
for line in myFile:
readline = myFile.read()
if readline != "":
break
From this, get the list:
mySensors = readline.split(',')
# should give ['duration','sensor1','sensor2', etc.] => remove 'duration' column header
Then parse this sensorList. So if you hit a sensor from the list without value, it will write 'n/a'
To add new sensors that may have appear between two CSV file update, add a second 'for' loop after the first one:
# then check if there are new sensors that appeared and that are not in current set of sensors
header_update = False # to check if header has to be updated
for sensor, value in data.items():
if sensor not in mySensors:
# new sensor to add
lineValue+=str(value)
# add the new sensor id in the header list
mySensors.append(sensor)
if not header_update : header_update = True
# terminate the line to write
lineValue = Time + "," + lineValue[:-1] + "\n"
After that, the problem is to add the new sensor to your header line, so you have to build the new header line
# new header line to replace the previous header
if header_update:
new_header = "duration," # assuming that your first column header is 'duration'
new_header += ','_join.mySensors
# this will build a new header line like duration,sensor1,sensor2,..., sensorx, newsensor1, etc.
and to replace it in the file.
To do so you can have a look to this post
(I did test the answer of Kiran for my own purpose and it works pretty well, just make a backup of your CSV file until your script works properly to avoid unwanted file destruction)