Hello there,
Context:
I am currently working with a Programmable Logic controller (PLC) and using Modbus to read values from Analog Inputs.
With these values, I want to introduce them into graphics so that I can see the dynamics of my system.
I would also like to save these values to a CSV file using the open
and csv
objects from python.
This last part is where it gets tricky, I’ll show you my simplified code where I am not reading values but instead randomly generating them (x, y, z
).
Code:
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
from random import random
import csv
x, y, z = 0, 0, 0
save_list = [str(x), str(y), str(z)]
app = dash.Dash()
app.layout = html.Div([
html.Div([
html.Button('Save', id='button-save', n_clicks=0),
html.Button('Stop', id='button-stop', n_clicks=0),
dcc.Store(id='save-status', data=False),
html.Div(id='save-csv'),
dcc.Interval(
id='interval-component',
interval=2000, # 1000 miliseconds
n_intervals=0
)
])])
@app.callback([Output('save_status', 'data'),
Output('save_csv', 'children')],
[State('button-save', 'n_clicks'),
State('button-stop', 'n_clicks'),
State('save_status', 'data')])
def Save_stop(n_clicks3, n_clicks4, save):
global save_list, write_csv
changed_id_2 = [p['prop_id'] for p in dash.callback_context.triggered][0]
if 'button-save' in changed_id_2:
save = True
with open('Some/path/to/file.csv.csv', 'w') as writer:
write_csv = csv.writer(writer, delimiter='\n')
write_csv.writerow(save_list)
return save, html.Plaintext('{}'.format(save))
elif 'button-stop' in changed_id_2:
save = False
return save, html.Plaintext('{}'.format(save))
@app.callback(Output('save_status', 'data'),
[Input('interval-component', 'n_intervals')],
[State('save_status', 'data')])
def Build_csv(n, save):
global x, y, z, write_csv
if save:
x, y, z = random(), random(), random()
temp_line = [str(x), str(y), str(z)]
with open('Some/path/to/file.csv', 'w') as writer:
write_csv = csv.writer(writer, delimiter='\n')
write_csv.writerow(temp_line)
return save
if __name__ == '__main__':
app.run_server(debug=True)
Further thoughts:
What I am doing is using one callback to set “writting mode” to True
or False
, create the CSV file and write the index in case of True
, and the other callback to keep adding to the previously generated CSV file.
Basically nothing happens, the file isn’t generated anymore, but for attempts where it was created, nothing was written. And I can’t close it.
I am a bit cluesless as of what to try more. Is there anything wrong with the callbacks? Should I not use the with
statement in this case since I am trying to open it in both callbacks? Also, the path to file does not have blank spaces.
Thank you all in advance.