1- using HidSharp ;
21using System . Diagnostics ;
3- using System . Text ;
42using ICommand = InverterMon . Server . InverterService . Commands . ICommand ;
53
64namespace InverterMon . Server . InverterService ;
75
86internal class CommandExecutor : BackgroundService
97{
108 private readonly CommandQueue queue ;
11- private DeviceStream ? dev ;
129 private readonly ILogger < CommandExecutor > log ;
1310 private readonly IConfiguration confing ;
1411
@@ -36,36 +33,30 @@ private bool Connect()
3633 {
3734 var devPath = confing [ "LaunchSettings:DeviceAddress" ] ?? "/dev/hidraw0" ;
3835
39- dev = DeviceList . Local
40- . GetDevices (
41- types : DeviceTypes . Hid | DeviceTypes . Serial ,
42- filter : d => DeviceFilterHelper . MatchHidDevices ( d , 0x0665 , 0x5161 ) || DeviceFilterHelper . MatchSerialDevices ( d , devPath ) )
43- . FirstOrDefault ( ) ? . Open ( ) ;
44-
45- if ( dev is null )
36+ if ( ! Inverter . Connect ( devPath , log ) )
4637 {
4738 return false ;
4839 }
4940 else
5041 {
51- log . LogInformation ( "connected to inverter at: [{adr}]" , dev . Device . DevicePath ) ;
42+ log . LogInformation ( "connected to inverter at: [{adr}]" , devPath ) ;
5243 return true ;
5344 }
5445 }
5546
56- protected override async Task ExecuteAsync ( CancellationToken c )
47+ protected override async Task ExecuteAsync ( CancellationToken ct )
5748 {
5849 var delay = 0 ;
5950 var timeout = TimeSpan . FromMinutes ( 5 ) ;
6051
61- while ( ! c . IsCancellationRequested && delay <= timeout . TotalMilliseconds )
52+ while ( ! ct . IsCancellationRequested && delay <= timeout . TotalMilliseconds )
6253 {
6354 var cmd = queue . GetCommand ( ) ;
6455 if ( cmd is not null )
6556 {
6657 try
6758 {
68- await ExecuteCommand ( cmd , dev ! , c ) ;
59+ await ExecuteCommand ( cmd , ct ) ;
6960 queue . IsAcceptingCommands = true ;
7061 delay = 0 ;
7162 queue . RemoveCommand ( ) ;
@@ -79,54 +70,17 @@ protected override async Task ExecuteAsync(CancellationToken c)
7970 }
8071 else
8172 {
82- await Task . Delay ( 500 , c ) ;
73+ await Task . Delay ( 500 , ct ) ;
8374 }
8475 }
85-
8676 log . LogError ( "command execution halted due to excessive failures!" ) ;
8777 }
8878
89- private static async Task ExecuteCommand ( ICommand command , Stream port , CancellationToken c )
79+ private static async Task ExecuteCommand ( ICommand command , CancellationToken ct )
9080 {
9181 command . Start ( ) ;
92- byte [ ] ? cmdBytes = Encoding . ASCII . GetBytes ( command . CommandString ) ;
93- ushort crc = CalculateXmodemCrc16 ( command . CommandString ) ;
94-
95- byte [ ] ? buf = new byte [ cmdBytes . Length + 3 ] ;
96- Array . Copy ( cmdBytes , buf , cmdBytes . Length ) ;
97- buf [ cmdBytes . Length ] = ( byte ) ( crc >> 8 ) ;
98- buf [ cmdBytes . Length + 1 ] = ( byte ) ( crc & 0xff ) ;
99- buf [ cmdBytes . Length + 2 ] = 0x0d ;
100-
101- await port . WriteAsync ( buf , c ) ;
102- byte [ ] ? buffer = new byte [ 1024 ] ;
103- int pos = 0 ;
104- do
105- {
106- int readCount = await port . ReadAsync ( buffer . AsMemory ( pos , buffer . Length - pos ) , c ) ;
107- if ( readCount > 0 )
108- pos += readCount ;
109- }
110- while ( ! buffer . Any ( b => b == 0x0d ) ) ;
111-
112- command . Parse ( Encoding . ASCII . GetString ( buffer , 0 , pos - 3 ) . Sanitize ( ) ) ;
82+ await Inverter . Write ( command . CommandString , ct ) ;
83+ command . Parse ( await Inverter . Read ( ct ) ) ;
11384 command . End ( ) ;
11485 }
115-
116- private static ushort CalculateXmodemCrc16 ( string data )
117- {
118- ushort crc = 0 ;
119- for ( int i = 0 ; i < data . Length ; i ++ )
120- {
121- crc ^= ( ushort ) ( data [ i ] << 8 ) ;
122- for ( int j = 0 ; j < 8 ; j ++ )
123- {
124- if ( ( crc & 0x8000 ) != 0 )
125- crc = ( ushort ) ( ( crc << 1 ) ^ 0x1021 ) ;
126- else
127- crc <<= 1 ;
128- }
129- }
130- return crc ;
131- }
13286}
0 commit comments