The SDK includes offline file parsers for reading and editing Fanuc controller files without a network connection. Download files from the robot via FTP, then parse them locally.

The offline parsers are available in .NET. The Python package does not wrap them yet: in Python, read these files from the controller with the FTP client (`robot.ftp.known_variable_files`, `robot.ftp.get_safety_status()`...), see [Diagnostics & variables](/fanuc/documentation/ftp-diagnostics).

## Variable files (.va)

Parse any variable file (.va) into a hierarchical list of typed variables:

**C# : OfflineFileParsingVariable**
```csharp
using UnderAutomation.Fanuc.Common.Files.Variables;
using UnderAutomation.Fanuc.Common.Files;
using UnderAutomation.Fanuc.Common;

public class OfflineFileParsingVariable
{
    static void Main()
    {
        /**/
        // Parse a variable file
        GenericVariableFile vaFile = FanucFileReaders.VariableReader.ReadFile("C:/backup/numreg.va", Languages.English);

        // Browse variables
        foreach (var variable in vaFile.Variables)
        {
            Console.WriteLine($"{variable.Name} = {variable.Value} [{variable.Type}]");
        }

        // Re-generate the .va file
        vaFile.GenerateVa("C:/backup/numreg_modified.va");
        /**/
    }
}
```

This works with all .va files: `numreg.va`, `posreg.va`, `strreg.va`, `sysvars.va`, `sysmotn.va`, etc.

## Error log (errall.ls)

**C# : OfflineFileParsingReaders**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Ftp;

public class OfflineFileParsingReaders
{
    static void Main()
    {
        /**/
        // Error log
        var errors = FanucFileReaders.ErrorListReader.ReadFile("C:/backup/errall.ls", Languages.English);
        foreach (var error in errors.Items)
        {
            Console.WriteLine($"{error.OccurringTime} [{error.ErrorCode}] {error.Message}");
        }

        // I/O state
        var ioState = FanucFileReaders.IOStateReader.ReadFile("C:/backup/iostate.dg", Languages.English);

        // Safety status
        var safety = FanucFileReaders.SafetyStatusReader.ReadFile("C:/backup/safety.dg", Languages.English);

        // Current position
        var currentPos = FanucFileReaders.CurrentPositionReader.ReadFile("C:/backup/curpos.dg", Languages.English);
        /**/
    }
}
```


## Workflow: FTP download + offline parse

A common pattern is to download files via FTP and parse them locally:

**C# : OfflineFileParsingWorkflow**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Ftp;

public class OfflineFileParsingWorkflow
{
    static void Main()
    {
        FanucRobot robot = new FanucRobot();
        robot.Connect("192.168.0.1");

        /**/
        // Download a file from the robot
        robot.Ftp.DirectFileHandling.DownloadFileFromController("numreg.va", "md:/numreg.va");

        // Parse offline
        var vaFile = FanucFileReaders.VariableReader.ReadFile("numreg.va", Languages.English);

        // Or use the built-in helpers
        var numRegs = robot.Ftp.KnownVariableFiles.GetNumregFile();
        var posRegs = robot.Ftp.KnownVariableFiles.GetPosregFile();
        /**/
    }
}
```

## Complete example

**C# : OfflineFileParsing**
```csharp
using UnderAutomation.Fanuc.Common;
using UnderAutomation.Fanuc.Common.Files;
using UnderAutomation.Fanuc.Common.Files.Variables;

public class OfflineFileParsing
{
  static void Main()
  {
    /**/
    // Parse a variable file and extract a hierarchical list of variables
    GenericVariableFile vaFile = FanucFileReaders.VariableReader.ReadFile("C:/path/to/variable.va", Languages.English);
    foreach (var variable in vaFile.Variables)
      Console.WriteLine($"{variable.Name} = {variable.Value} [{variable.Type}]");

    // Edit and regenerate the variable file
    vaFile.GenerateVa("C:/path/to/variable_modified.va\"");

    // Parse several types of files 
    FanucFileReaders.ErrorListReader.ReadFile("C:/path/to/errall.ls", Languages.English);
    FanucFileReaders.IOStateReader.ReadFile("C:/path/to/iostate.dg", Languages.English);
    FanucFileReaders.SafetyStatusReader.ReadFile("C:/path/to/safety.dg", Languages.English);
    FanucFileReaders.CurrentPositionReader.ReadFile("C:/path/to/curpos.dg", Languages.English);
    /**/
  }

}
```

## API reference

**Members of Common.Files.Variables.GenericVariableFile**
```csharp
public class GenericVariableFile : IGenericVariableType, IFanucContent {
    public GenericVariableFile()

    public override bool Equals(object obj)

    // Generates a .va file and writes it to the specified stream
    public void GenerateVa(Stream stream)

    // Generates a .va file and writes it to the specified path
    public void GenerateVa(string pathToVa)

    // Generates the content of a .va variable file as a string.
    public string GeneratedVa()

    // Gets a variable by name (case-insensitive)
    public GenericVariable GetField(string name)

    public override int GetHashCode()

    // File name
    public string Name { get; }

    // Parent container
    public IGenericVariableType Parent { get; set; }

    public override string ToString()

    // Variables declared in this file
    public GenericVariable[] Variables { get; }
}
```

**Members of Common.Files.FanucFileReaders**
```csharp
public static class FanucFileReaders {
    // Decode current position file curpos.dg
    public static readonly DiagnosisReader<CurrentPosition, CurrentPositionReader> CurrentPositionReader

    // Helper to read error files like errall.ls
    public static readonly ErrorListReader ErrorListReader

    // Decode IO Status file iostate.dg
    public static readonly DiagnosisReader<IOState, IOStateParser> IOStateReader

    // Decode task and program states prgstate.dg
    public static readonly DiagnosisReader<ProgramStates, ProgramStatesParser> ProgramStates

    // Read any file by path on disc, recognize it by name and decode it
    public static IFanucContent ReadFile(Stream fileStream, string fileName, Languages language)

    // Read any file by path on disc, recognize it by name and decode it
    public static IFanucContent ReadFile(string fileName, Languages language)

    // Get the collection of all parsers
    public static IFileReader<IFanucContent>[] Readers { get; }

    // Decode IO Status file iostate.dg
    public static readonly DiagnosisReader<SafetyStatus, SafetyStatusParser> SafetyStatusReader

    // Helper to read summary diagnosis file summary.dg
    public static readonly SummaryDiagnosisReader SummaryDiagnosticReader

    // Helper to read variable files *.va
    public static readonly VariableReader VariableReader
}
```