@@ -68,9 +68,8 @@ <h2><span class="step">1</span> Find Your Inverter</h2>
6868 < div class ="input-group mt-2 ">
6969 < label > Scan timeout</ label >
7070 < select x-model.number ="scanTimeoutMs " style ="max-width: 200px; ">
71- < option value ="500 "> 500ms (fast LAN only)</ option >
72- < option value ="2000 "> 2000ms (default)</ option >
73- < option value ="5000 "> 5000ms (Wi-Fi dongles)</ option >
71+ < option value ="2000 "> 2000ms (fast LAN)</ option >
72+ < option value ="5000 "> 5000ms (default)</ option >
7473 < option value ="10000 "> 10000ms (very slow devices)</ option >
7574 </ select >
7675 </ div >
@@ -181,27 +180,18 @@ <h2>
181180 </ h2 >
182181 < p class ="text-sm text-muted mb-2 "> Trying to identify your inverter by reading serial number registers...</ p >
183182
184- <!-- Detection progress log -->
185- < div x-show ="detectLog.length > 0 " class ="mt-4 ">
186- < div x-show ="detectSlaveID !== null " class ="text-sm text-muted mb-2 ">
187- Trying slave ID < strong x-text ="detectSlaveID "> </ strong >
188- </ div >
183+ <!-- Detection progress -->
184+ < div x-show ="detectLoading || detectLog.length > 0 " class ="mt-4 ">
189185 < div class ="scan-log ">
190- < template x-for ="entry in detectLog " :key ="entry.profile ">
191- < div class ="scan-log-entry " :class ="{ done: entry.status !== 'trying' } ">
192- < span >
193- < span x-text ="entry.displayName "> </ span >
194- < span class ="text-muted text-sm " x-text ="'(reg ' + entry.serialAddr + ')' "> </ span >
195- </ span >
196- < span x-show ="entry.status === 'trying' " class ="flex items-center gap-2 "> < span class ="spinner "> </ span > reading...</ span >
197- < span x-show ="entry.status === 'found' " class ="badge badge-ok " x-text ="'MATCH' + (entry.serial ? ' — ' + entry.serial : '') "> </ span >
198- < span x-show ="entry.status === 'no_match' " class ="flex items-center gap-2 ">
199- < span class ="badge badge-info "> no match</ span >
200- < span class ="text-muted text-sm " x-text ="entry.durationMs != null ? entry.durationMs + 'ms' : '' "> </ span >
201- </ span >
202- < span x-show ="entry.status === 'error' " class ="badge badge-fail "> error</ span >
203- </ div >
204- </ template >
186+ <!-- Slave ID being tried -->
187+ < div class ="scan-log-entry " x-show ="detectSlaveID !== null ">
188+ < span > Slave ID < strong x-text ="detectSlaveID "> </ strong > </ span >
189+ < span x-show ="detectLoading " class ="flex items-center gap-2 ">
190+ < span class ="spinner "> </ span >
191+ < span class ="text-muted text-sm " x-text ="detectProgress "> </ span >
192+ </ span >
193+ < span x-show ="!detectLoading && !detection?.detected " class ="badge badge-info "> no match</ span >
194+ </ div >
205195 </ div >
206196 </ div >
207197
@@ -492,7 +482,7 @@ <h2>History</h2>
492482 scanPorts : [ ] ,
493483 scanLog : [ ] ,
494484 customPortInput : '' ,
495- scanTimeoutMs : 2000 ,
485+ scanTimeoutMs : 5000 ,
496486
497487 // Target
498488 target : { host : '' , port : 502 , slaveID : 1 } ,
@@ -506,6 +496,7 @@ <h2>History</h2>
506496 detectLoading : false ,
507497 detectLog : [ ] ,
508498 detectSlaveID : null ,
499+ detectProgress : '' ,
509500 profiles : [ ] ,
510501 selectedProfile : '' ,
511502
@@ -584,11 +575,12 @@ <h2>History</h2>
584575 const ports = this . scanPorts . filter ( p => p . enabled ) ;
585576 if ( ports . length === 0 ) { this . scanning = false ; return ; }
586577
587- // Show all ports as "scanning" immediately
588- this . scanLog = ports . map ( p => ( { port : p . port , desc : p . description , status : 'scanning' , found : 0 } ) ) ;
578+ // Scan ports sequentially (parallel ports overwhelm slow devices like Wi-Fi dongles)
579+ // Hosts within each port are still scanned in parallel (256 concurrent)
580+ let allResults = [ ] ;
581+ for ( const portInfo of ports ) {
582+ this . scanLog = [ ...this . scanLog , { port : portInfo . port , desc : portInfo . description , status : 'scanning' , found : 0 } ] ;
589583
590- // Fire all port scans in parallel
591- const promises = ports . map ( async ( portInfo ) => {
592584 try {
593585 const res = await fetch ( '/api/network/scan' , {
594586 method : 'POST' ,
@@ -597,23 +589,18 @@ <h2>History</h2>
597589 } ) ;
598590 const hosts = await res . json ( ) ;
599591 const found = Array . isArray ( hosts ) ? hosts : [ ] ;
592+ allResults = [ ...allResults , ...found ] ;
600593
601- // Update this port's log entry to done
602594 this . scanLog = this . scanLog . map ( e =>
603595 e . port === portInfo . port ? { ...e , status : 'done' , found : found . length } : e
604596 ) ;
605-
606- return found ;
607597 } catch ( e ) {
608598 console . error ( 'Scan error port ' + portInfo . port + ':' , e ) ;
609599 this . scanLog = this . scanLog . map ( e =>
610600 e . port === portInfo . port ? { ...e , status : 'done' , found : 0 } : e
611601 ) ;
612- return [ ] ;
613602 }
614- } ) ;
615-
616- const allResults = ( await Promise . all ( promises ) ) . flat ( ) ;
603+ }
617604
618605 // Deduplicate by ip:port
619606 const seen = new Set ( ) ;
@@ -665,18 +652,15 @@ <h2>History</h2>
665652 else if ( tcpMs > 50 ) timeoutMs = 1000 ;
666653 }
667654
668- // Show all profiles as "trying"
669- this . detectLog = this . profiles . map ( p => ( {
670- profile : p . name ,
671- displayName : p . display_name ,
672- serialAddr : p . serial_address || '?' ,
673- status : 'trying'
674- } ) ) ;
655+ let found = false ;
675656
676- this . detectSlaveID = 'all (1, 0, 247)' ;
657+ // Try slave IDs sequentially (many devices only allow 1 TCP connection)
658+ for ( const slaveID of slaveIDs ) {
659+ if ( found ) break ;
660+ this . detectSlaveID = slaveID ;
661+ this . detectProgress = 'Testing ' + this . profiles . length + ' profiles...' ;
662+ this . detectLog = [ { slaveID } ] ;
677663
678- // Fire all slave IDs in parallel
679- const promises = slaveIDs . map ( async ( slaveID ) => {
680664 try {
681665 const res = await fetch ( '/api/diagnose/detect-batch' , {
682666 method : 'POST' ,
@@ -689,60 +673,33 @@ <h2>History</h2>
689673 } )
690674 } ) ;
691675 const results = await res . json ( ) ;
692- if ( ! Array . isArray ( results ) ) return null ;
693- const match = results . find ( r => r . detected ) ;
694- return { slaveID, results, match : match || null } ;
695- } catch ( e ) {
696- return null ;
697- }
698- } ) ;
699676
700- const allResults = await Promise . all ( promises ) ;
701-
702- // Find the first match (prefer slave ID order: 1, 0, 247)
703- let winner = null ;
704- let bestResults = null ;
705- for ( const r of allResults ) {
706- if ( r && r . match && ! winner ) {
707- winner = r ;
708- }
709- // Use results from slave ID 1 for the log display (or first non-null)
710- if ( r && r . results && ! bestResults ) {
711- bestResults = r ;
677+ if ( Array . isArray ( results ) ) {
678+ const match = results . find ( r => r . detected ) ;
679+ const totalMs = results . reduce ( ( sum , r ) => sum + ( r . duration_ms || 0 ) , 0 ) ;
680+
681+ if ( match ) {
682+ this . detectProgress = '' ;
683+ this . detection = {
684+ detected : true ,
685+ profile_name : match . profile ,
686+ display_name : match . display_name ,
687+ serial : match . serial ,
688+ slave_id : slaveID
689+ } ;
690+ this . selectedProfile = match . profile ;
691+ this . target . slaveID = slaveID ;
692+ found = true ;
693+ } else {
694+ this . detectProgress = results . length + ' profiles tested in ' + totalMs + 'ms — no match' ;
695+ }
696+ }
697+ } catch ( e ) {
698+ this . detectProgress = 'Connection error' ;
712699 }
713700 }
714701
715- if ( winner ) {
716- this . detectSlaveID = winner . slaveID ;
717- this . detectLog = winner . results . map ( r => ( {
718- profile : r . profile ,
719- displayName : r . display_name ,
720- serialAddr : ( this . profiles . find ( p => p . name === r . profile ) || { } ) . serial_address || '?' ,
721- status : r . detected ? 'found' : 'no_match' ,
722- durationMs : r . duration_ms ,
723- serial : r . serial || ''
724- } ) ) ;
725- this . detection = {
726- detected : true ,
727- profile_name : winner . match . profile ,
728- display_name : winner . match . display_name ,
729- serial : winner . match . serial ,
730- slave_id : winner . slaveID
731- } ;
732- this . selectedProfile = winner . match . profile ;
733- this . target . slaveID = winner . slaveID ;
734- } else {
735- // Show results from first slave ID attempt
736- if ( bestResults ) {
737- this . detectLog = bestResults . results . map ( r => ( {
738- profile : r . profile ,
739- displayName : r . display_name ,
740- serialAddr : ( this . profiles . find ( p => p . name === r . profile ) || { } ) . serial_address || '?' ,
741- status : 'no_match' ,
742- durationMs : r . duration_ms ,
743- serial : ''
744- } ) ) ;
745- }
702+ if ( ! found ) {
746703 this . detection = { detected : false } ;
747704 }
748705 this . detectLoading = false ;
0 commit comments