Is there a solution for viewing files and saving (exporting) to a PC files that are on a flash drive?
I have a flash drive and it periodically writes files, I want through web visualization to see what are the files on the flash drive and selecting a certain save yourself.
Previously, I did it via FTP (fileZilla).
The VisuDialogs library has a āFileOpenSaveā dialog that may be useful here, and also the Visu_fbFileListProvider function block that works with it.
A few years ago, I created my own function similar to what you describe by using the WagoAppFileDir library and WagoAppFtp library, utilizing a made-from-scratch Visualization that employs tables to display the directory contents.
I have two questions at once:
- This can work on cockpit ?
- āFileOpenSaveā I found this elite in cockpit, I didnāt find the bibilio with Visu_fbFileListProvider.
Yes, I found it in my e!Cockpit installation. Be sure to click āAdvancedā at the bottom of the Add Library dialog before you do your search for VisuDialogs.
Thanks, Iāve almost figured out how to do it. Iāll write later about the result.
I ran into the problem that I canāt unload the file.
Using File Transfer, nothing happens when pressing.
File (s) are stored on the SD card.
spathtofile: = ā/Media/sd/csv_files/2024-07-01-01-13_07_23_save_dp.csvā
Tell me the right path? Why doesnāt it save the file?
Iāve never tried that File Transfer function. I suggest having your visu button trigger a function block from the WagoAppFtp library instead.
Hello,
You are missing so much things to have it work.
Please check this export part of a project I made:
VisuFileTransfert.export.txt (555.1 KB)
Ps remove the .txt and do an import in e!Cockpit.
I am using Cockpit to check the solution, will it be possible to do this? Or is this solution only for Codesys?
So you will need the SysFile lib. and the other missing function are just function which convert a REAL to a String with ānā number after the ā.ā
Sorry Iāve exported the function from my e!Cockpit project without looking is some function where used.
You are right, sorry I totally forgot about it:
FUNCTION TO_NSTRING : STRING
(* This function convert a LREAL into a STRING.*)
VAR_INPUT
lrValue : LREAL;
usiPres : USINT := 3;
END_VAR
VAR
_lrValue : LREAL;
_uliHelp : ULINT;
_sHelp : STRING;
END_VAR
(* LIMIT usiPres between 0 and 7 *)
usiPres := LIMIT(0, usiPres, 7);
_lrValue := lrValue;
IF (_lrValue = 0) THEN
_sHelp := '0';
IF (usiPres > 0) THEN
// _sHelp := Standard.CONCAT(_sHelp, '.');
WagoAppString.StrAppend(sBuffer := _sHelp, udiSize := SIZEOF(_sHelp), sAppendee := '.');
FOR _uliHelp := 1 TO usiPres BY 1 DO
// _sHelp := Standard.CONCAT(_sHelp, '0');
WagoAppString.StrAppend(sBuffer := _sHelp, udiSize := SIZEOF(_sHelp), sAppendee := '0');
END_FOR;
END_IF;
ELSE
(* round the rVar to bPres digits *)
_uliHelp := TO_ULINT(ABS(_lrValue) * EXP(usiPres * LN(10)));
(* convert _uliHelp to string *)
_sHelp := TO_STRING(_uliHelp);
(* add missing "0"s *)
WHILE (Standard.LEN(_sHelp) < usiPres) DO
// _sHelp := Standard.CONCAT('0', _sHelp);
WagoAppString.StrAppend(sBuffer := _sHelp, udiSize := SIZEOF(_sHelp), sAppendee := '0');
END_WHILE
(* add the separator *)
IF (usiPres > 0) THEN
//_sHelp := Standard.INSERT(_sHelp, '.', Standard.LEN(_sHelp) - bPres);
WagoAppString.StrInsert(sBuffer := _sHelp, udiSize := SIZEOF(_sHelp), udiPos := TO_UDINT(Standard.LEN(_sHelp) - usiPres) + 1, sInsert := '.');
END_IF;
(* add leading 0 if needed *)
IF (-1 < _lrValue) AND (_lrValue < 1) THEN
// _sHelp := Standard.CONCAT('0', _sHelp);
WagoAppString.StrAppend(sBuffer := _sHelp, udiSize := SIZEOF(_sHelp), sAppendee := '0');
END_IF;
(* add a minus sign if rVar is negative *)
IF (_lrValue < 0) THEN
// _sHelp := Standard.CONCAT('-', _sHelp);
WagoAppString.StrAppend(sBuffer := _sHelp, udiSize := SIZEOF(_sHelp), sAppendee := '-');
END_IF;
END_IF;
(* we copy the _sHelp in the output *)
TO_NSTRING := _sHelp;
FUNCTION FuFileRename : STRING
(*
Extract a string which start after a '=' and end with a & or a 'CR' or 'LF' from a buffer;
*)
VAR_INPUT
sFile : STRING;
dtLastModification : DT; // Time of last modification (in GMT, i.e. no timezone).
END_VAR
VAR
_sFile : STRING;
_sLastModification : STRING;
_iHelp : INT;
_sHelp : STRING;
_iExtention : INT;
_sExtention : STRING;
END_VAR
// Init the String
_sFile := sFile;
// Remove the Path from the filename
_iHelp := Standard.FIND(_sFile, '/');
WHILE (_iHelp > 0) DO
_sFile := Standard.RIGHT(_sFile, Standard.LEN(_sFile) - _iHelp);
_iHelp := Standard.FIND(_sFile, '/');
END_WHILE;
// Find the file extention
_sExtention := _sFile;
_iHelp := Standard.FIND(_sExtention, '.');
WHILE (_iHelp > 0) DO
_iExtention := _iHelp - 1;
_sExtention := Standard.RIGHT(_sExtention, Standard.LEN(_sExtention) - _iHelp);
_iHelp := Standard.FIND(_sExtention, '.');
END_WHILE;
IF (_iExtention > 0) THEN
_sExtention := Standard.CONCAT('.', _sExtention);
_iExtention := Standard.LEN(_sExtention);
ELSE
_sExtention := '';
END_IF;
// Add '-'
_sFile := Standard.CONCAT(_sFile, '-');
// 'DATE_AND_TIME#1970-01-01-00:00:01' OR 'DT#1970-01-01-00:00:01'
_sLastModification := TO_STRING(dtLastModification);
// Remove the unused header '1970-01-01-00:00:01'
_sLastModification := Standard.RIGHT(_sLastModification, Standard.LEN(_sLastModification) - Standard.FIND(_sLastModification, '#'));
// Year
_sHelp := Standard.LEFT(_sLastModification, Standard.FIND(_sLastModification, '-'));
_iHelp := TO_INT(_sHelp);
IF (_iHelp < 10) THEN
_sFile := Standard.CONCAT(_sFile, '000');
ELSIF (_iHelp < 100) THEN
_sFile := Standard.CONCAT(_sFile, '00');
ELSIF (_iHelp < 1000) THEN
_sFile := Standard.CONCAT(_sFile, '0');
END_IF;
_sFile := Standard.CONCAT(_sFile, TO_STRING(_iHelp));
// Remove the Year and the corresponding separator
_sLastModification := Standard.RIGHT(_sLastModification, Standard.LEN(_sLastModification) - Standard.FIND(_sLastModification, '-'));
// Month
_sHelp := Standard.LEFT(_sLastModification, Standard.FIND(_sLastModification, '-'));
_iHelp := TO_INT(_sHelp);
IF (_iHelp < 10) THEN
_sFile := Standard.CONCAT(_sFile, '0');
END_IF;
_sFile := Standard.CONCAT(_sFile, TO_STRING(_iHelp));
// Remove the Month and the corresponding separator
_sLastModification := Standard.RIGHT(_sLastModification, Standard.LEN(_sLastModification) - Standard.FIND(_sLastModification, '-'));
// Day
_sHelp := Standard.LEFT(_sLastModification, Standard.FIND(_sLastModification, '-'));
_iHelp := TO_INT(_sHelp);
IF (_iHelp < 10) THEN
_sFile := Standard.CONCAT(_sFile, '0');
END_IF;
_sFile := Standard.CONCAT(_sFile, TO_STRING(_iHelp));
// Remove the Day and the corresponding separator
_sLastModification := Standard.RIGHT(_sLastModification, Standard.LEN(_sLastModification) - Standard.FIND(_sLastModification, '-'));
// Add separator '-'
_sFile := Standard.CONCAT(_sFile, '-');
// Hour
_sHelp := Standard.LEFT(_sLastModification, Standard.FIND(_sLastModification, ':'));
_iHelp := TO_INT(_sHelp);
IF (_iHelp < 10) THEN
_sFile := Standard.CONCAT(_sFile, '0');
END_IF;
_sFile := Standard.CONCAT(_sFile, TO_STRING(_iHelp));
// Remove the Hour and the corresponding separator
_sLastModification := Standard.RIGHT(_sLastModification, Standard.LEN(_sLastModification) - Standard.FIND(_sLastModification, ':'));
// Minute
_sHelp := Standard.LEFT(_sLastModification, Standard.FIND(_sLastModification, ':'));
_iHelp := TO_INT(_sHelp);
IF (_iHelp < 10) THEN
_sFile := Standard.CONCAT(_sFile, '0');
END_IF;
_sFile := Standard.CONCAT(_sFile, TO_STRING(_iHelp));
// Remove the Minute and the corresponding separator
_sLastModification := Standard.RIGHT(_sLastModification, Standard.LEN(_sLastModification) - Standard.FIND(_sLastModification, ':'));
// Second
_sHelp := _sLastModification;
_iHelp := TO_INT(_sHelp);
IF (_iHelp < 10) THEN
_sFile := Standard.CONCAT(_sFile, '0');
END_IF;
_sFile := Standard.CONCAT(_sFile, TO_STRING(_iHelp));
IF (_iExtention > 0) THEN
// Add the file extention
_sFile := Standard.CONCAT(_sFile, _sExtention);
END_IF;
// Output
FuFileRename := _sFile;
Thank you now the code compiles!
Thereās some kind of mistake. I donāt know where it came from.
prgTransfer._iFileReadError = FILE_TRANSFER_SERVICES_NOT_SUPPORTED
The problem turns out to be more global.
I made a project on codesys 3.5 SP19 P7. It turned out to have the same error (FILE_TRANSFER_SERVICES_NOT_SUPPORTED). So I need to somehow enable the transmission for the PLC? I have a 750-8212 FW28. Maybe I need to write some settings in the configuration file?
Did you enable the FTP protocol from the Web-Based Management? It is disabled by default.
Of course it is enabled I log in via filezilla to view files.
Right now my configuration is like this:
Hello, The problem is not FTP or other but you have to modify a file in the PFC:
In one of those files (depending on where the [CmpWebServerHandlerV3] is already declared: \etc\codesys3.d\CmpWSServer.cfg
\etc\codesys3.d\CODESYSControl.cfg
\etc\codesys3.d\RtsCore.cfg
(If not available, use CODESYSControl.cfg as shown here: Example: File Transfer )
You need to add:
[CmpWebServerHandlerV3]
AllowFileTransferServices=1
Sorry I totally forgot about this one ā¦
I added the line you advised me to all four files and it worked!
Thank you!
In the future I hope this will be taken into account in new PLC firmware so that this feature is immediately available.
I donāt think it should be enabled by default.
But having an easier option to enable it would be a nice touch indeed.