Synology

Waffle.io

Ready Progress
Stories in Ready Stories in Progress

AppVeyor

Status Master Dev
Build status Build status Build status

NuGet

Synology
NuGet version

This is an implementation of Synology Built-In APIs for .NET projects. You can use it for access your Synology information, upload/download files from disk, use the built-in torrent client and all other services available.

Pull request will be accepted only if targeting dev branch.

API Progress:

API Status
SYNO.API
Auth
login OK
logout OK
Info
query OK
SYNO.DownloadStation
Info
getinfo OK
getconfig OK
setserverconfig OK
Schedule
getconfig OK
setserverconfig OK
Task
list OK
getinfo OK
create OK
delete OK
pause OK
resume OK
edit OK
SYNO.DownloadStation2
Task
create OK
SYNO.FileStation
CheckPermission
write OK
CopyMove
start OK
status OK
stop OK
DirSize
start OK
status OK
stop OK
Favorite
list OK
add OK
delete OK
clear_broken OK
edit OK
FileShare
list_share OK
list OK
getinfo OK
Info
getinfo OK
List
list_share OK
list OK
getinfo OK
MD5
start OK
status OK
stop OK
Rename
rename OK
Search
start OK
list OK
stop OK
clear OK
Thumb
get OK
Upload
upload OK
VirtualFolder
list OK
SYNO.SurveillanceStation
Info
getinfo OK

Trello Board

Kanban Board

The following code is my test project, you can use it as a guide for now. I will write the documentation, I promise.

class MainClass
{
    public static void Main(string[] args)
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

        Log.Logger = new LoggerConfiguration().WriteTo.Console().MinimumLevel.Verbose().CreateLogger();

        var serviceCollection = new ServiceCollection();

        serviceCollection.AddLogging(b => b.AddSerilog());
        serviceCollection.AddSynology(b =>
        {
            b.AddApi();
            b.AddAudioStation();
            b.AddDownloadStation();
            b.AddDownloadStation2();
            b.AddFileStation();
            b.AddSurveillanceStation();
            b.AddVideoStation();
        });
        
        var serviceProvider = serviceCollection.BuildServiceProvider();

        try
        {
            var settings = serviceProvider.GetService<ISynologyConnectionSettings>();

            settings.BaseHost = LoginData.Url;
            settings.Password = LoginData.Password;
            settings.Port = LoginData.Port;
            settings.Ssl = LoginData.Ssl;
            settings.SslPort = LoginData.SslPort;
            settings.Username = LoginData.Username;

            using (var syno = serviceProvider.GetService<ISynologyConnection>())
            {
                DoConnection(syno);
            }
        }
        catch (Exception ex)
        {
            var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<MainClass>();

            logger.LogError(ex, "Error during execution");
        }
    }

    private static void DownloadStationTests(ISynologyConnection syno)
    {
        Console.WriteLine("DS Info");
        var dsResInfo = syno.DownloadStation().Info().GetInfo();
        Console.WriteLine(JsonConvert.SerializeObject(dsResInfo));

        Console.WriteLine("DS Config");
        var dsResConfig = syno.DownloadStation().Info().Config();
        Console.WriteLine(JsonConvert.SerializeObject(dsResConfig));

        Console.WriteLine("DS Schedule Config");
        var dsResSchedule = syno.DownloadStation().Schedule().Config();
        Console.WriteLine(JsonConvert.SerializeObject(dsResSchedule));

        Console.WriteLine("DS Task List");
        var dsResTasks = syno.DownloadStation().Task().List(new TaskListParameters
        {
            Additional = TaskDetailsType.Detail | TaskDetailsType.Transfer | TaskDetailsType.File | TaskDetailsType.Tracker | TaskDetailsType.Peer
        });
        Console.WriteLine(JsonConvert.SerializeObject(dsResTasks));
    }

    private static void FileStationTests(ISynologyConnection syno)
    {
        Console.WriteLine("FS GetInfo");
        var fsResInfo = syno.FileStation().Info().Get();
        Console.WriteLine(JsonConvert.SerializeObject(fsResInfo));

        Console.WriteLine("FS File Share List Share");
        var fsResShares = syno.FileStation().FileShare().ListShare(
            FileShareDetailsType.RealPath | FileShareDetailsType.Size | FileShareDetailsType.Owner |
            FileShareDetailsType.Time | FileShareDetailsType.Perm | FileShareDetailsType.VolumeStatus |
            FileShareDetailsType.MountPointType);
        Console.WriteLine(JsonConvert.SerializeObject(fsResShares));

        Console.WriteLine("FS File Share List");
        var fsResList = syno.FileStation().FileShare().List("/downloads", null, FileType.All, null,
            FileDetailsType.RealPath | FileDetailsType.Size | FileDetailsType.Owner | FileDetailsType.Time |
            FileDetailsType.Perm | FileDetailsType.Type | FileDetailsType.MountPointType);
        Console.WriteLine(JsonConvert.SerializeObject(fsResList));

        Console.WriteLine("FS File Share Info");
        var fsResFileInfo = syno.FileStation().FileShare().Info("/downloads/.apdisk",
            FileDetailsType.RealPath | FileDetailsType.Size | FileDetailsType.Owner | FileDetailsType.Time |
            FileDetailsType.Perm | FileDetailsType.Type | FileDetailsType.MountPointType);
        Console.WriteLine(JsonConvert.SerializeObject(fsResFileInfo));

        Console.WriteLine("FS Virtual Folder List");
        var fsVfResList = syno.FileStation().VirtualFolder().List(
            VirtualFolderDetailsType.RealPath | VirtualFolderDetailsType.Owner | VirtualFolderDetailsType.Time |
            VirtualFolderDetailsType.Perm | VirtualFolderDetailsType.MountPointType |
            VirtualFolderDetailsType.VolumeStatus);
        Console.WriteLine(JsonConvert.SerializeObject(fsVfResList));
    }

    private static void GetOtp(ISynologyConnection syno, ref ResultData<AuthResult> resLogin)
    {
        do
        {
            Console.Write("Otp Code: ");

            var otp = Console.ReadLine();

            if (string.IsNullOrWhiteSpace(otp))
            {
                resLogin.Error = new ResultError {Code = 404};
                continue;
            }

            resLogin = syno.Api().Auth().Login(new LoginParameters
            {
                Username = LoginData.Username,
                Password = LoginData.Password,
                OtpCode = otp
            });

            Console.WriteLine(JsonConvert.SerializeObject(resLogin));
        } while (resLogin.Error != null && resLogin.Error.Code == 404);
    }

    private static void DoConnection(ISynologyConnection syno)
    {
        Console.WriteLine("Info");
        var resInfo = syno.Api().Info().Query();

        Console.WriteLine(JsonConvert.SerializeObject(resInfo));

        Console.WriteLine("Auth Login");
        var resLogin = syno.Api().Auth().Login(new LoginParameters
        {
            Username = LoginData.Username,
            Password = LoginData.Password
        });

        Console.WriteLine(JsonConvert.SerializeObject(resLogin));

        if (resLogin.Error == null || (resLogin.Error != null && resLogin.Error.Code == 403))
        {
            if (resLogin.Error != null && resLogin.Error.Code == 403)
            {
                GetOtp(syno, ref resLogin);
            }

            if (resLogin.Error == null)
            {
                DownloadStationTests(syno);

                FileStationTests(syno);

                Console.WriteLine("Auth Logout");
                var resLogout = syno.Api().Auth().Logout();
                Console.WriteLine(JsonConvert.SerializeObject(resLogout));
            }
        }

        Console.ReadLine();
    }
}