feat: Denkovi USB 8-relay board (FT245 D2XX bit-bang)

Third relay device alongside WebSwitch and KMTronic. Despite enumerating as a
COM port, this board is driven via FTDI D2XX synchronous bit-bang (one byte = 8
relays, bit 0 = relay 1), not serial ASCII — so we load ftd2xx.dll at runtime
(no CGO) and call FT_OpenEx/FT_SetBitMode/FT_Write, addressing the board by its
FTDI serial (e.g. DAE0006K), exactly like the vendor tool. Windows-only (stub
elsewhere); ListDenkoviDevices enumerates connected serials for the picker.

Wired into relaydev (Count/Status/Set), app.go (deviceDriver/relayCountFor/type
whitelist + ListDenkoviDevices binding), and the Station device editor (new type
+ FTDI-serial field with Detect). Untested on hardware; bit order / on-polarity
may need a flip after a live test.
This commit is contained in:
2026-07-20 16:50:04 +02:00
parent 3cef885934
commit c07a17dc47
8 changed files with 279 additions and 11 deletions
+29
View File
@@ -0,0 +1,29 @@
//go:build !windows
// The Denkovi USB board is driven through FTDI's D2XX bit-bang API (ftd2xx.dll),
// which OpsLog only wires up on Windows. This stub keeps the package building on
// other platforms; every call reports the board is unavailable.
package relaydev
import (
"context"
"fmt"
)
type denkoviStub struct{}
// NewDenkovi returns a stub on non-Windows builds.
func NewDenkovi(serial string) Device { return denkoviStub{} }
func (denkoviStub) Count() int { return 8 }
func (denkoviStub) Status(context.Context) ([]bool, error) {
return nil, fmt.Errorf("Denkovi USB relay board is only supported on Windows")
}
func (denkoviStub) Set(context.Context, int, bool) error {
return fmt.Errorf("Denkovi USB relay board is only supported on Windows")
}
// ListDenkovi has no devices to report off Windows.
func ListDenkovi() ([]string, error) {
return nil, fmt.Errorf("Denkovi USB relay board is only supported on Windows")
}