WriteCSV.g — writes data to CSV files.
The code for this and other example scripts can be found in the DataHub distribution archive, typically at one of these locations: C:\Program Files\Cogent\OPC DataHub\scripts\ C:\Program Files\Cogent\Cascade DataHub\scripts\ Please refer to Section 3.1, “How to Run a Script” for more information on using scripts. |
/* * Write data to a number of different CSV files. Each data set is written at * a different interval, either per second, per minute or per hour. A new CSV * file is created every hour or every day. * * The points names in each data set are read from a file. The file consists of each * point name, one per line. The output file will contain a time stamp followed * by the value for each point in the order that the points are listed in the * point name file. * * To change the format of the file name, change the method "GenerateFileName". * * To change the extension of the file, change the member variable "filesuffix". * * To change the file names and timing, change the .NewDataSet calls in the * method WriteCSV.constructor. */ require ("Application"); require ("CSVSupport"); class WriteCSV Application { datasets; } class MyCSVWriter CSVWriter { pointfile; // The name of a file containing the point list. sample_rate; // one of #second, #minute, #hour or list(hour,minute,second) file_rotate_rate; // one of #minute, #hour, #day or list(hour,minute,second) filesuffix = ".csv"; // normally .csv. Override it to create .txt files. } /* This will produce a file name like: * base_20090423_PM3.csv */ /* method MyCSVWriter.GenerateFileName() { local tm = localtime(nanoclock()); format("%s_%d%02d%02d_%s%d%s", .filebase, tm.year+1900, tm.mon+1, tm.mday, tm.hour >= 12 ? "PM" : "AM", tm.hour > 12 ? tm.hour - 12 : (tm.hour == 0 ? 12 : tm.hour), .filesuffix); } */ /* This will produce a file name like: * base-20090423-1545.csv */ method MyCSVWriter.GenerateFileName() { local tm = localtime(nanoclock()); format("%s-%d%02d%02d-%02d%02d%s", .filebase, tm.year+1900, tm.mon+1, tm.mday, tm.hour, tm.min, .filesuffix); } /* * Create a new writer and start the timers to write new data and to * create a new log file. */ method WriteCSV.NewDataSet (output_file_base, pointfile, sample_rate, file_rotate_rate, separate_lines) { local writer = new MyCSVWriter(); if (writer.ReadPointsFromCSV(pointfile)) { writer.sample_rate = sample_rate; writer.file_rotate_rate = file_rotate_rate; writer.SetFileBase(output_file_base); writer.SetSeparateLines(separate_lines); switch(writer.sample_rate) { case (#second): .TimerAt(nil,nil,nil,nil,nil,nil,`(@self).WriteData(@writer)); case (#minute): .TimerAt(nil,nil,nil,nil,nil,0,`(@self).WriteData(@writer)); case (#hour): .TimerAt(nil,nil,nil,nil,0,0,`(@self).WriteData(@writer)); case (#day): .TimerAt(nil,nil,nil,0,0,0,`(@self).WriteData(@writer)); default: if (list_p(writer.sample_rate)) { // List of hour, minute, second specification local times = list_to_array(writer.sample_rate); .TimerAt(nil,nil,nil,times[0],times[1],times[2],`(@self).WriteData(@writer)); } else // Default is hourly { .TimerAt(nil,nil,nil,nil,0,0,`(@self).WriteData(@writer)); } } switch(writer.file_rotate_rate) { case (#minute): .TimerAt(nil,nil,nil,nil,nil,0,`(@self).RotateFile(@writer)); case (#hour): .TimerAt(nil,nil,nil,nil,0,0,`(@self).RotateFile(@writer)); case (#day): .TimerAt(nil,nil,nil,0,0,0,`(@self).RotateFile(@writer)); default: if (list_p(writer.file_rotate_rate)) { // List of hour, minute, second specification local times = list_to_array(writer.file_rotate_rate); .TimerAt(nil,nil,nil,times[0],times[1],times[2],`(@self).RotateFile(@writer)); } else // Default is hourly { .TimerAt(nil,nil,nil,nil,0,0,`(@self).RotateFile(@writer)); } } .datasets = cons(writer, .datasets); } } method WriteCSV.WriteData(writer) { writer.WriteLine(); } method WriteCSV.RotateFile(writer) { .TimerAfter(0.1, `(@writer).IncrementFileName()); } /* Write the 'main line' of the program here. */ method WriteCSV.constructor () { /* Specify the CSV files to write. Modify the .NewDataSet lines to specify how * to write each CSV file. * Arguments are: * output_file_base: The first part of the file, before the date string * pointfile: The name of a file containing the point names for this data set * sample_rate: One of #second, #minute, #hour or list(hour,minute,second) * telling how frequently to write a line to the CSV file * file_rotate_rate: One of #minute, #hour, #day or list(hour,minute,second) * telling how frequently to create a new CSV file. * separate_lines: If this is nil, write all point values on one line. If this * is t, write each point value on a separate line. * * This function will read the pointfile as a CSV file and treat the first field in each * row as the name of a point to be recorded into the output file. * * When specifying timing, the input is the list of (hour,minute,second) as accepted * by the "at" function (see documentation). A value of nil for hour, minute or second * stands for all values for that parameter. A list of values for hour, minute or second * specifies an event only when the hour, minute or second matches one of the values in * the list. * Examples: * list(nil,nil,nil) - every second * list(nil,list(0,15,30,45),0) - every 15 minutes * list(nil,list(0,15,30,45),30) - every 15 minutes, 30 seconds past the minute * list(list(0,8,16), 0, 0) - at midnight, 8AM and 4PM exactly * list(list(0,8,16), 5, 0) - at 12:05AM, 8:05AM and 4:05PM * * The symbols #second, #minute, #hour, #day are conveniences for: * second: list(nil,nil,nil) - any hour, any minute, every second * minute: list(nil,nil,0) - any hour, every minute at 0 seconds * hour: list(nil,0,0) - every hour, on the hour * day: list(0,0,0) - at midnight (0 hour, 0 minute, 0 second) */ .NewDataSet("c:/tmp/Group1", "c:/tmp/Group1_Points.txt", #second, #hour, nil); .NewDataSet("c:/tmp/Group2", "c:/tmp/Group2_Points.txt", #second, list(nil,list(0, 15,30,45),0), nil); .NewDataSet("c:/tmp/Group3", "c:/tmp/Group3_Points.txt", #second, list(nil,nil,0), nil); } /* Any code to be run when the program gets shut down. */ method WriteCSV.destructor () { with writer in .datasets do { destroy(writer); } } /* Start the program by instantiating the class. If your * constructor code does not create a persistent reference to * the instance (self), then it will be destroyed by the * garbage collector soon after creation. If you do not want * this to happen, assign the instance to a global variable, or * create a static data member in your class to which you assign * 'self' during the construction process. ApplicationSingleton() * does this for you automatically. */ ApplicationSingleton (WriteCSV);
Copyright © 1995-2010 by Cogent Real-Time Systems, Inc. All rights reserved.