diff --git a/csharp/App/SaliMax/Doc/Zustandsdiagramm_IBN_Standard.graphml b/csharp/App/SaliMax/Doc/Zustandsdiagramm_IBN_Standard.graphml
new file mode 100644
index 000000000..1968f44f8
--- /dev/null
+++ b/csharp/App/SaliMax/Doc/Zustandsdiagramm_IBN_Standard.graphml
@@ -0,0 +1,503 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+Aus (mit Netz)
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
+
+
+
+
+
+
+ 5
+
+
+
+
+
+
+
+
+
+
+ 6
+
+
+
+
+
+
+
+
+
+
+ 7
+
+
+
+
+
+
+
+
+
+
+ 8
+
+
+
+
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+
+
+
+ 4
+
+
+
+
+
+
+
+
+
+
+ 11
+
+
+
+
+
+
+
+
+
+
+ 12
+
+
+
+
+
+
+
+
+
+
+ 13
+
+
+
+
+
+
+
+
+
+
+ 14
+
+
+
+
+
+
+
+
+
+
+ 15
+
+
+
+
+
+
+
+
+
+
+ 16
+Netzparallel
+
+
+
+
+
+
+
+
+
+
+ 17
+
+
+
+
+
+
+
+
+
+
+ 18
+
+
+
+
+
+
+
+
+
+
+ 19
+
+
+
+
+
+
+
+
+
+
+ 20
+
+
+
+
+
+
+
+
+
+
+ 21
+Inselbetrieb
+
+
+
+
+
+
+
+
+
+
+ 22
+
+
+
+
+
+
+
+
+
+
+ 23
+
+
+
+
+
+
+
+
+
+
+ 24
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+ 9
+
+
+
+
+
+
+
+
+
+
+ 13
+
+
+
+
+
+
+
+
+
+
+ 15
+
+
+
+
+
+
+
+
+
+
+ 17
+
+
+
+
+
+
+
+
+
+
+ 1
+Aus (ohne Netz)
+
+
+
+
+
+
+
+
+
+
+ K1 schliesst
+
+
+
+
+
+
+
+
+
+
+ Uebergang nach Off
+
+
+
+
+
+
+
+
+
+
+ Uebergang nach Netzparallel
+
+
+
+
+
+
+
+
+
+
+ K3 öffnet
+
+
+
+
+
+
+
+
+
+
+ K2 schliesst
+
+
+
+
+
+
+
+
+
+
+ K3 schliesst
+
+
+
+
+
+
+
+
+
+
+ K1 öffnet
+
+
+
+
+
+
+
+
+
+
+ K2 öffnet
+
+
+
+
+
+
+
+
+
+
+ K3 öffnet
+
+
+
+
+
+
+
+
+
+
+ K3 schliesst
+
+
+
+
+
+
+
+
+
+
+ Uebergang nach Off
+
+
+
+
+
+
+
+
+
+
+ Uebergan nach Inselbetrieb
+
+
+
+
+
+
+
+
+
+
+
+ K1 Schliesst
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Turnoff The inverter
+
+
+
+
+
+
+
+
+
diff --git a/csharp/App/SaliMax/Doc/Zustandsmatrix_Salimax.xlsx b/csharp/App/SaliMax/Doc/Zustandsmatrix_Salimax.xlsx
new file mode 100644
index 000000000..6cd1ceb13
Binary files /dev/null and b/csharp/App/SaliMax/Doc/Zustandsmatrix_Salimax.xlsx differ
diff --git a/csharp/App/SaliMax/run (Salimax 0001).sh b/csharp/App/SaliMax/run (Salimax 0001).sh
new file mode 100755
index 000000000..a138c3067
--- /dev/null
+++ b/csharp/App/SaliMax/run (Salimax 0001).sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+dotnet_version='net6.0'
+salimax_ip= '10.2.3.104'
+username='ie-entwicklung@'
+
+set -e
+
+echo -e "\n============================ Build ============================\n"
+
+dotnet publish \
+ ./SaliMax.csproj \
+ -c Release \
+ -r linux-x64
+
+echo -e "\n============================ Deploy ============================\n"
+
+rsync -v \
+ ./bin/Release/$dotnet_version/linux-x64/publish/* \
+ ie-entwicklung@10.2.3.104:~/salimax
+
+echo -e "\n============================ Restart Salimax sevice ============================\n"
+
+ssh -tt \
+ ie-entwicklung@10.2.3.104 \
+ sudo systemctl restart salimax.service
+
+
+echo -e "\n============================ Print service output ============================\n"
+
+ssh -tt \
+ ie-entwicklung@10.2.3.104 \
+ journalctl -f -u salimax.service
diff --git a/csharp/App/SaliMax/run (SalimnaxProto Meiringen).sh b/csharp/App/SaliMax/run (SalimnaxProto Meiringen).sh
new file mode 100755
index 000000000..7c2defe21
--- /dev/null
+++ b/csharp/App/SaliMax/run (SalimnaxProto Meiringen).sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+
+dotnet_version='net6.0'
+salimax_ip= '10.2.3.115'
+username='ie-entwicklung@'
+
+set -e
+
+echo -e "\n============================ Build ============================\n"
+
+dotnet publish \
+ ./SaliMax.csproj \
+ -c Release \
+ -r linux-x64
+
+echo -e "\n============================ Deploy ============================\n"
+
+rsync -v \
+ ./bin/Release/$dotnet_version/linux-x64/publish/* \
+ ie-entwicklung@10.2.3.115:~/salimax
+
+echo -e "\n============================ Restart Salimax sevice ============================\n"
+
+ssh -tt \
+ ie-entwicklung@10.2.3.115 \
+ sudo systemctl restart salimax.service
+
+
+echo -e "\n============================ Print service output ============================\n"
+
+ssh -tt \
+ ie-entwicklung@10.2.3.115 \
+ journalctl -f -u salimax.service
diff --git a/csharp/App/SaliMax/src/DeviceConfig.cs b/csharp/App/SaliMax/src/DeviceConfig.cs
new file mode 100644
index 000000000..ca7982760
--- /dev/null
+++ b/csharp/App/SaliMax/src/DeviceConfig.cs
@@ -0,0 +1,42 @@
+using Newtonsoft.Json;
+
+namespace InnovEnergy.App.SaliMax;
+
+public class DeviceConfig
+{
+ public String RelaysIp { get; set; }
+ public String TruConvertAcIp { get; set; }
+ public String TruConvertDcIp { get; set; }
+ public String GridMeterIp { get; set; }
+ public String InternalMeter { get; set; }
+ public String AmptIp { get; set; }
+ public byte[] BatteryNodes { get; set; }
+ public String BatteryTty { get; set; }
+
+ [JsonConstructor]
+ public DeviceConfig(string relaysIp, string truConvertAcIp, string truConvertDcIp, string gridMeterIp, string internalMeter, string amptIp, byte[] batteryNodes, string batteryTty)
+ {
+ RelaysIp = relaysIp;
+ TruConvertAcIp = truConvertAcIp;
+ TruConvertDcIp = truConvertDcIp;
+ GridMeterIp = gridMeterIp;
+ InternalMeter = internalMeter;
+ AmptIp = amptIp;
+ BatteryNodes = batteryNodes;
+ BatteryTty = batteryTty;
+ }
+
+ public static DeviceConfig? LoadDeviceConfig(String configFilePath)
+ {
+ try
+ {
+ var json = File.ReadAllText(configFilePath);
+ return JsonConvert.DeserializeObject(json);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+}
\ No newline at end of file
diff --git a/csharp/App/SaliMax/src/Logfile.cs b/csharp/App/SaliMax/src/Logfile.cs
new file mode 100644
index 000000000..295d7729b
--- /dev/null
+++ b/csharp/App/SaliMax/src/Logfile.cs
@@ -0,0 +1,67 @@
+using InnovEnergy.Lib.Time.Unix;
+using Microsoft.Extensions.Logging;
+
+namespace InnovEnergy.App.SaliMax;
+
+public class CustomLogger : ILogger
+{
+ private readonly String _logFilePath;
+ private readonly Int64 _maxFileSizeBytes;
+ private readonly Int32 _maxLogFileCount;
+ private Int64 _currentFileSizeBytes;
+
+ public CustomLogger(String logFilePath, Int64 maxFileSizeBytes, Int32 maxLogFileCount)
+ {
+ _logFilePath = logFilePath;
+ _maxFileSizeBytes = maxFileSizeBytes;
+ _maxLogFileCount = maxLogFileCount;
+ _currentFileSizeBytes = File.Exists(logFilePath) ? new FileInfo(logFilePath).Length : 0;
+ }
+
+ public IDisposable BeginScope(TState state)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Boolean IsEnabled(LogLevel logLevel)
+ {
+ return true; // Enable logging for all levels
+ }
+
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
+ {
+ var logMessage = formatter(state, exception!);
+
+ // Check the file size and rotate the log file if necessary
+ if (_currentFileSizeBytes + logMessage.Length >= _maxFileSizeBytes)
+ {
+ RotateLogFile();
+ _currentFileSizeBytes = 0;
+ }
+
+ // Write the log message to the file
+ File.AppendAllText(_logFilePath, logMessage + Environment.NewLine);
+ _currentFileSizeBytes += logMessage.Length;
+ }
+
+ private void RotateLogFile()
+ {
+ // Check the log file count and delete the oldest file if necessary
+ var logFileDir = Path.GetDirectoryName(_logFilePath)!;
+ var logFileExt = Path.GetExtension(_logFilePath);
+ var logFileBaseName = Path.GetFileNameWithoutExtension(_logFilePath);
+
+ var logFiles = Directory.GetFiles(logFileDir, $"{logFileBaseName}_*{logFileExt}")
+ .OrderBy(file => file)
+ .ToList();
+
+ if (logFiles.Count >= _maxLogFileCount)
+ {
+ File.Delete(logFiles.First());
+ }
+
+ // Rename the current log file with a timestamp
+ var logFileBackupPath = Path.Combine(logFileDir, $"{logFileBaseName}_{UnixTime.Now}{logFileExt}");
+ File.Move(_logFilePath, logFileBackupPath);
+ }
+}
diff --git a/csharp/App/SaliMax/tunnelsToProto.sh b/csharp/App/SaliMax/tunnelsToProto.sh
new file mode 100755
index 000000000..0a136e54b
--- /dev/null
+++ b/csharp/App/SaliMax/tunnelsToProto.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+host=ie-entwicklung@10.2.3.115
+
+tunnel() {
+ name=$1
+ ip=$2
+ rPort=$3
+ lPort=$4
+
+ echo -n "localhost:$lPort $name "
+ ssh -nNTL "$lPort:$ip:$rPort" "$host" 2> /dev/null &
+
+ until nc -vz 127.0.0.1 $lPort 2> /dev/null
+ do
+ echo -n .
+ sleep 0.3
+ done
+
+ echo "ok"
+}
+
+echo ""
+
+tunnel "Trumpf Inverter (http) " 10.0.2.1 80 8001
+tunnel "Trumpf DCDC (http) " 10.0.3.1 80 8002
+tunnel "Ext Emu Meter (http) " 10.0.4.1 80 8003
+tunnel "Int Emu Meter (http) " 10.0.4.2 80 8004
+tunnel "AMPT (http) " 10.0.5.1 8080 8005
+
+tunnel "Trumpf Inverter (modbus)" 10.0.2.1 502 5001
+tunnel "Trumpf DCDC (modbus) " 10.0.3.1 502 5002
+tunnel "Ext Emu Meter (modbus) " 10.0.4.1 502 5003
+tunnel "Int Emu Meter " 10.0.4.2 502 5004
+tunnel "AMPT (modbus) " 10.0.5.1 502 5005
+tunnel "Adam " 10.0.1.1 502 5006
+tunnel "Batteries " 127.0.0.1 6855 5007
+
+
+echo
+echo "press any key to close the tunnels ..."
+read -r -n 1 -s
+kill $(jobs -p)
+echo "done"
diff --git a/csharp/App/SaliMax/tunnelstoSalimax0001.sh b/csharp/App/SaliMax/tunnelstoSalimax0001.sh
new file mode 100755
index 000000000..2f5ed3520
--- /dev/null
+++ b/csharp/App/SaliMax/tunnelstoSalimax0001.sh
@@ -0,0 +1,45 @@
+j#!/bin/bash
+
+host=ie-entwicklung@10.2.3.104
+
+tunnel() {
+ name=$1
+ ip=$2
+ rPort=$3
+ lPort=$4
+
+ echo -n "localhost:$lPort $name "
+ ssh -nNTL "$lPort:$ip:$rPort" "$host" 2> /dev/null &
+
+ until nc -vz 127.0.0.1 $lPort 2> /dev/null
+ do
+ echo -n .
+ sleep 0.3
+ done
+
+ echo "ok"
+}
+
+echo ""
+
+tunnel "Trumpf Inverter (http) " 10.0.2.1 80 8001
+tunnel "Trumpf DCDC (http) " 10.0.3.1 80 8002
+tunnel "Ext Emu Meter (http) " 10.0.4.1 80 8003
+tunnel "Int Emu Meter (http) " 10.0.4.2 80 8004
+tunnel "AMPT (http) " 10.0.5.1 8080 8005
+
+
+tunnel "Trumpf Inverter (modbus)" 10.0.2.1 502 5001
+tunnel "Trumpf DCDC (modbus) " 10.0.3.1 502 5002
+tunnel "Ext Emu Meter (modbus) " 10.0.4.1 502 5003
+tunnel "Int Emu Meter " 10.0.4.2 502 5004
+tunnel "AMPT (modbus) " 10.0.5.1 502 5005
+tunnel "Adam " 10.0.1.1 502 5006
+
+
+
+echo
+echo "press any key to close the tunnels ..."
+read -r -n 1 -s
+kill $(jobs -p)
+echo "done"