package gpio import ( "context" "io" "log" "time" gpio "github.com/stianeikeland/go-rpio/v4" ) const ( waitCtxTimeout = 100 * time.Microsecond ) type gpioPin struct { logger *log.Logger pin gpio.Pin } type Pin interface { Init() error PowerOn() PowerOnCtx(ctx context.Context) io.Closer } func New(logger *log.Logger, pin uint8) Pin { return gpioPin{ logger: logger, pin: gpio.Pin(pin), } } func (p gpioPin) Init() error { return gpio.Open() } func waitCtx(ctx context.Context, timeout time.Duration) { deadline := time.Now().Add(timeout) for { select { case <-ctx.Done(): return default: if time.Now().After(deadline) { return } } time.Sleep(waitCtxTimeout) } } func (p gpioPin) sendOnOffSignal(ctx context.Context) { p.pin.Output() p.logger.Println("Power on 0/3 + 100ms") p.pin.Low() p.pin.Toggle() waitCtx(ctx, 100*time.Millisecond) p.logger.Println("Power on 1/3 + 3s") p.pin.High() p.pin.Toggle() waitCtx(ctx, 3*time.Second) p.logger.Println("Power on 2/3 + 30s") p.pin.Low() p.pin.Toggle() waitCtx(ctx, 30*time.Second) p.logger.Println("Power on 3/3") } func (p gpioPin) PowerOn() { p.sendOnOffSignal(context.Background()) } func (p gpioPin) PowerOnCtx(ctx context.Context) { p.sendOnOffSignal(ctx) } func (p gpioPin) Close() error { return gpio.Close() }