viper_lasser Posted November 20, 2013 Report Posted November 20, 2013 How can I read logged alarms from sd card in .net ?
Saragani Posted November 20, 2013 Report Posted November 20, 2013 You can use SD Card Suite. It has a program called SD Card Manager, which let you import a data from a Micro SD, or from a directory from your local HD (Where the directory contains files that were created by the PLC and saved into SD)
viper_lasser Posted November 20, 2013 Author Report Posted November 20, 2013 I know about SD Card Suite but I would like to show logged alarms on sd directly on wins.form in visual studio Can someone share same sample ?
viper_lasser Posted November 21, 2013 Author Report Posted November 21, 2013 How to read some files from sd card ? I think that ual file where size of one logged alarm is 512 byte length. Its very simple to decode data, description etc. I don't know how can i transfer file ALARMS/alarm.ual to local computer by ethernet.
Saragani Posted November 21, 2013 Report Posted November 21, 2013 For reading files from the SD card, you will a PLC object. I believe you already know how to communicate with a PLC (using GetPLC etc). Now that you have a PLC object, called plc, you can write: plc.SD.ReadFile(SdFolder.DT_DT1, "Hello.utr", null); The SdFolder Enum is: public enum SdFolder { RootFolder = -1, ALARMS = 0, DT = 1, DT_DT1 = 100, DT_DT2 = 101, DT_DT3 = 102, DT_DT4 = 103, LOG = 3, SYSTEM = 4, USER_APP = 5, TRENDS = 6, TRENDS_TRENDS1 = 600, TRENDS_TRENDS2 = 601, TRENDS_TRENDS3 = 602, TRENDS_TRENDS4 = 603, SDBLOCKS = 9, EXCEL = 10, EXCEL_EXCEL1 = 1000, EXCEL_EXCEL2 = 1001, EXCEL_EXCEL3 = 1002, EXCEL_EXCEL4 = 1003, WEB = 11, } These are the folders that are used by unitroncis in the SD. There are other overloads to this function that also gets the folder as string (for example @"DT\DT1") You can also list the files on the SD, etc... just look at the set of APIs that the SD class exposes. Bte, the last parameter in the example I gave is a progress delegate, so if you want to have a progress car showing the download percentage, then use this delegate
viper_lasser Posted November 22, 2013 Author Report Posted November 22, 2013 Thanks Saragani for Your answer. Are there some methods for parsing read file ? What is maximum size for alarm.ual file ? How can I read file with alarms to show them from the newest to the oldest ? Do I have to read all file to memory and later invert all array with alarms ?
Saragani Posted November 25, 2013 Report Posted November 25, 2013 Hi, try the attached DLL. It should help you open Trend, UDT and UAL files. Usage: var trends = Trend.GetTrends(@"C:\Test\12345678.UTR"); var dt = Unitronics.SD.Files.DataTables.Table.GetTables(@"C:\Test\12345678.UDT"); var alarm = Unitronics.SD.Files.Alarms.Alarms.GetAlarms(@""C:\Test\Alarm.UAL"); In Trend, there is also another optional parameter which is Samples per page (else it will show all samples). In Trend you would get IEnumerable<IEnumerable<Trend>>, this is because when you append trends to file, you might have different trends (this is why there is the external IEnumerable), and the inner IEnumerable is for pages... Assuming you have 1 trend and you set 0 samples per page (which means no paging), then you can: trends.ElementAt(0).ElementAt(0).Curves And accessing the points: trends.ElementAt(0).ElementAt(0).Curves.ElementAt(0).Points As a notice, even though the trend has paging, it doesn't mean that it doesn't load all the data to the RAM (it is just for showing less data per page, for example 1000 samples per page). For large data sets, you might get an out of memory exception (but it would probably have to be a large file of a appended trends). The Alarms and Data Tables do have paging (as loading only a part of the file each time), so it is memory efficient. Both Data Tables and Alarms returns an IEnumerable<Table> (Because a file can contain appended data from different sources/strctures). Each table contains pages (Where each page contains up to 1000 samples). For accessing a data of a page, do: dt.ElementAt(0).Pages[0].DataTable; (or dt.ElementAt(i).Pages[j].DataTable; to be more generic) When requesting the property DataTable from a page, it will load the specific data from the file into a .Net DataTable. You can then use DataView in order to show the data in a Grid. The alarms code was not fully tested (It works, but please test it on several files to see that it works correctly) Unitronics.SD.Files.Zip
Saragani Posted November 26, 2013 Report Posted November 26, 2013 Hi, please try it and report (Did it help or not? Bugs, problems?) Thanks.
viper_lasser Posted November 28, 2013 Author Report Posted November 28, 2013 Thanks Saragani for help and samples. All it understandable. I was wondering if alarms also can have paging option like trends. What is the maximus file size for alarm.ual and trend.utr ?
Saragani Posted November 28, 2013 Report Posted November 28, 2013 Alarms and Data Tables have paging (Trends have paging, but it doesn't have data virtualization, which means that when reading a file, all data is loaded to RAM). Data Tables and Alarms have an automatic paging for each 1000 rows (this is why you have the property Pages on the DT and the Alarms) I don't know of any size limit, I have saw a 1.4 million rows Data Tables file which was 260MB size (the Data Tables Editor could not open it because of Out Of Memory error, because it loads everything to RAM, but the UDT viewer which its code is used in the Unitronics.SD.Files that you've got can open this kind of file)
Saragani Posted December 25, 2013 Report Posted December 25, 2013 Hi, I have updated the SD Files DLL with a new version (I've updated the file in the post #7: http://forum.unitronics.com/index.php?/topic/2630-alarms-from-sd-card/#entry9134 ) I have fixed some bugs with the UDT file opening.
Marco G Posted November 17, 2014 Report Posted November 17, 2014 Hi, I have updated the SD Files DLL with a new version (I've updated the file in the post #7: http://forum.unitronics.com/index.php?/topic/2630-alarms-from-sd-card/#entry9134 ) I have fixed some bugs with the UDT file opening. Thanks, i already looked into the driver documentation, but couldn't really find a answer there. This is my current code: Dim sSelectedIP As String = cbPLCnaam.SelectedValue Dim sDateTimePicker As String = DateTimePicker1.Text Dim sCompleteDirectory As String = sSelectedIP & "\Secure Digital-opslagapparaat\EXCELL" 'oud: Dim sCompleteDirectory As String = "C:\" & sSelectedIP & "\SDCard" slaat op in C:\"ipadres"\SDCard 'Het feitelijke opslaan als xml ds.Tables.Add(dtverzenden) ds.Tables(0).TableName = "verzenden" ds.WriteXml(sCompleteDirectory & "\" & sDateTimePicker & ".xml" As you can see, right now it writes to xml. according to our PLC programmer thats no problem, he has a method of reading it into the program. For the writefile i reckon i need this: plc.SD.Writefile(SdFolder.EXCEL_EXCEL1, sDateTimePicker &".xml", null); Where does the SdFolder and null come from and how can i make sure it writes the contents of the ds "verzenden" ? I tried some things like plc.SD.Writexml but that (ofcourse) doesn't work.
Saragani Posted November 17, 2014 Report Posted November 17, 2014 There is no SD.WriteXml, since the communication driver doesn't care which file you write. the SdFolder is an enum that tells the PLC to write to the specific folder EXCEL\EXCEL1. The null in this case is a delegate you give it in order to get progress updates. If the WriteFile doesn't throw any exception, then the file transfer was a success. You can read back the file (if you want) using ReadFile and validate its content. The ReadFile and WriteFile also have an overload that accepts a path instead of an enum for the folder //EDIT: Btw, the filenames must be 8.3 compliant (meaning no more than 8 characters to the filenamee and 3 characters for the extension)
Marco G Posted November 19, 2014 Report Posted November 19, 2014 There is no SD.WriteXml, since the communication driver doesn't care which file you write. the SdFolder is an enum that tells the PLC to write to the specific folder EXCEL\EXCEL1. The null in this case is a delegate you give it in order to get progress updates. If the WriteFile doesn't throw any exception, then the file transfer was a success. You can read back the file (if you want) using ReadFile and validate its content. The ReadFile and WriteFile also have an overload that accepts a path instead of an enum for the folder //EDIT: Btw, the filenames must be 8.3 compliant (meaning no more than 8 characters to the filenamee and 3 characters for the extension) Hello, Thanks. So with the null i need to declare what it should do? VB2010 sees the null as a byte and wants to change it to dbnull.value which doesn't work.
Saragani Posted November 19, 2014 Report Posted November 19, 2014 Hi, as I wrote in the other thread you are replying to, the function gets 4 parameters, not 3. public void WriteFile(SdFolder sdFolder, string fileName, byte[] fileContent, ProgressStatusChangedDelegate del) The first parameter is the folder the second one is the filename inside the plc (the target filename) the third parameter is the content of the file (byte array... You should read the content of the original file) The 4th parameter is the progress delegate. (which can be null) in VB.Net (and vb6) null is called Nothing. Here is an example of a demo code: Dim serial As Unitronics.ComDriver.Serial Dim plc As Unitronics.ComDriver.PLC Dim fileContent As Byte() fileContent = System.IO.File.ReadAllBytes("c:\Temp\Test.udt") serial = New Unitronics.ComDriver.Serial(Unitronics.ComDriver.SerialPortNames.COM1, Unitronics.ComDriver.BaudRate.BR115200) plc = PLCFactory.GetPLC(serial, 9) plc.SD.WriteFile(SD.SdFolder.EXCEL_EXCEL1, "test123.udt", fileContent, Nothing)
Marco G Posted December 15, 2014 Report Posted December 15, 2014 Thanks I've been busy lately and picking it up again today. I noticed that the savetoudt part doesn't work if you don't use a already created file as filepath(so if c:\Temp\Test.udt doesn't exist, it gives a file doesnt exist error). I'm going to work on fixing that right now, will let you know the results for further reference(and for others)
Marco G Posted December 15, 2014 Report Posted December 15, 2014 Dim path As String = "c:\voerkar\" & sDateTimePicker & ".udt" ' Create or overwrite the file. Dim fs As FileStream = File.Create(path) fs.Close() Using that code it does create the file, but it wont open in unitronics because it apparently is corrupted. Will work on that.
Saragani Posted December 16, 2014 Report Posted December 16, 2014 Hi, I'm using File.WriteAllBytes and as much as I remember, it creates the file. Please make sure that the directory exists. For example, you try to write c:\Temp\Test.udt, but c:\temp\ doesn't exist I think that it might throw an exceptino of path that doesn't exist.
Marco G Posted February 17, 2015 Report Posted February 17, 2015 Yeey, that part works. Just curious btw, is there a .net version of the SD card Explorer example?
Saragani Posted February 17, 2015 Report Posted February 17, 2015 Yes. The SD Card Explorer itself is written in .Net, and there is a lite version of it that doesn't use 3rd party controls (so the user can view the sources)
Marco G Posted February 18, 2015 Report Posted February 18, 2015 Thanks, just downloaded the Lite version, it can't be opened in vb 2010 express but wil try opening it with my version of Studio 2013. I found some code somewhere else, but that version of card explorer lite has been written in C. Also, i couldn't find the dll in there, which is included in the .net version(SdcardExplorer.lite.dll)
Saragani Posted February 18, 2015 Report Posted February 18, 2015 Hi, yes, it is written in C# The project opens fine with visual Studio 2010. The reason why it gets the exception is because the project was compiled as Any CPU while it requires x86 I've opened the project and made the needed adjustments so it will work. It should open fine. Please see the attached Zip file. Unitronics SD Card Explorer Lite.zip
Marco G Posted February 24, 2015 Report Posted February 24, 2015 Hey, I can't seem to get it copied to .net. I will keep working at it but the example is quite big, so converting it al to .net costs quite some time.. Is it also possible to save the alarms to a datatable? because i think it is possible to read a unitronics datatable in .net.
Saragani Posted February 26, 2015 Report Posted February 26, 2015 It is written in .Net C# and VB.Net are .Net They both compile to the same CLI.
Marco G Posted February 26, 2015 Report Posted February 26, 2015 It is written in .Net C# and VB.Net are .Net They both compile to the same CLI. I know that they are pretty much the same, but i want to implement a function to check for alarms in a existing vb.net project, and therefore i cant directly copy-paste
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now