fix: cache relay-board drivers so Denkovi/USB-serial boards stay connected
The station-control code rebuilt a fresh driver on every status poll and every relay set. Stateful boards (Denkovi FTDI D2XX, USB-serial) hold an OS handle only one opener can own, so the first poll opened the board and leaked the handle, and every poll after failed with 'device in use' — the relays greyed out a second after Save and auto-control never switched. Drivers are now cached per device and reused, closed on config change. Adds a Test-connection button + detect feedback in the device editor (reported by VK4MA).
This commit is contained in:
@@ -27,6 +27,11 @@ type Device interface {
|
||||
Count() int // number of user-controllable relays
|
||||
Status(ctx context.Context) ([]bool, error) // state of each relay (index 0 = relay 1)
|
||||
Set(ctx context.Context, relay int, on bool) error // relay is 1-based
|
||||
// Close releases any OS handle the driver holds (serial port, FTDI handle).
|
||||
// Network boards hold nothing and no-op. MUST be called when a cached driver is
|
||||
// discarded so the port/handle is freed for the next open — stateful boards
|
||||
// (Denkovi, USB-serial) can only be opened by one handle at a time.
|
||||
Close() error
|
||||
}
|
||||
|
||||
func httpClient() *http.Client { return &http.Client{Timeout: 5 * time.Second} }
|
||||
@@ -62,7 +67,8 @@ type webswitch struct {
|
||||
// NewWebswitch builds a WebSwitch 1216H client (5 relays).
|
||||
func NewWebswitch(host string) Device { return &webswitch{host: host, count: 5} }
|
||||
|
||||
func (w *webswitch) Count() int { return w.count }
|
||||
func (w *webswitch) Count() int { return w.count }
|
||||
func (w *webswitch) Close() error { return nil } // stateless HTTP, nothing to release
|
||||
|
||||
func (w *webswitch) Set(ctx context.Context, relay int, on bool) error {
|
||||
if relay < 1 || relay > w.count {
|
||||
@@ -118,7 +124,8 @@ func NewKMTronic(host, user, pass string) Device {
|
||||
return &kmtronic{host: host, user: user, pass: pass, count: 8}
|
||||
}
|
||||
|
||||
func (k *kmtronic) Count() int { return k.count }
|
||||
func (k *kmtronic) Count() int { return k.count }
|
||||
func (k *kmtronic) Close() error { return nil } // stateless HTTP, nothing to release
|
||||
|
||||
func (k *kmtronic) Set(ctx context.Context, relay int, on bool) error {
|
||||
if relay < 1 || relay > k.count {
|
||||
|
||||
Reference in New Issue
Block a user