@@ -5,63 +5,90 @@ import (
55 "fmt"
66 "time"
77
8+ "github.com/warthog618/go-gpiocdev"
89 "go.opentelemetry.io/otel/codes"
910 "go.opentelemetry.io/otel/trace"
10- "periph.io/x/conn/v3/gpio"
1111)
1212
13+ const gpioChip = "gpiochip0"
14+
1315type PinsExecutor struct {
14- relays map [string ]gpio. PinIO
16+ relays map [string ]int
1517 tracer trace.Tracer
1618}
1719
18- func NewPinsExecutor (tracer trace.Tracer ) * PinsExecutor {
19- return & PinsExecutor {relays : relays , tracer : tracer }
20- }
21-
2220func (p * PinsExecutor ) Execute (ctx context.Context , seconds uint , pins []string ) error {
21+ if err := ctx .Err (); err != nil {
22+ return err
23+ }
24+
25+ ctx , span := p .tracer .Start (ctx , "PinsExecutor.Execute" )
26+ defer span .End ()
27+
28+ activatedPins := make ([]* gpiocdev.Line , 0 , len (pins ))
29+
30+ defer func () {
31+ for _ , line := range activatedPins {
32+ _ = line .SetValue (1 )
33+ _ = line .Close ()
34+ }
35+ }()
36+
37+ for _ , pinNumber := range pins {
38+ line , err := p .activatePin (pinNumber )
39+ if err != nil {
40+ span .RecordError (err )
41+ span .SetStatus (codes .Error , err .Error ())
42+ return err
43+ }
44+
45+ activatedPins = append (activatedPins , line )
46+ }
47+
48+ timer := time .NewTimer (time .Duration (seconds ) * time .Second )
49+ defer timer .Stop ()
50+
2351 select {
2452 case <- ctx .Done ():
53+ span .RecordError (ctx .Err ())
54+ span .SetStatus (codes .Error , ctx .Err ().Error ())
2555 return ctx .Err ()
26- default :
27- _ , span := p .tracer .Start (ctx , "PinsExecutor.Execute" )
28- defer span .End ()
29- activatedPins := make ([]gpio.PinIO , len (pins ))
30- for i , piNumber := range pins {
31- activatePin , err := p .activatePin (piNumber )
32- if err != nil {
33- span .RecordError (err )
34- span .SetStatus (codes .Error , err .Error ())
35- return err
36- }
37- activatedPins [i ] = activatePin
38- }
39- time .Sleep (time .Duration (seconds ) * time .Second )
40- for _ , act := range activatedPins {
41- if err := p .deActivatePin (act ); err != nil {
42- span .RecordError (err )
43- span .SetStatus (codes .Error , err .Error ())
44- return err
45- }
46- }
47- span .SetStatus (codes .Ok , "pins executed" )
48- return nil
56+
57+ case <- timer .C :
4958 }
59+
60+ span .SetStatus (codes .Ok , "pins executed" )
61+ return nil
5062}
5163
52- func (p * PinsExecutor ) activatePin (piNumber string ) (gpio. PinIO , error ) {
53- pi , ok := p .relays [piNumber ]
64+ func (p * PinsExecutor ) activatePin (pinNumber string ) (* gpiocdev. Line , error ) {
65+ lineNumber , ok := p .relays [pinNumber ]
5466 if ! ok {
55- return nil , InvalidPinToExecuteError {pinNumber : piNumber }
67+ return nil , InvalidPinToExecuteError {pinNumber : pinNumber }
5668 }
57- if err := pi .Out (gpio .Low ); err != nil {
58- return nil , err
69+
70+ line , err := gpiocdev .RequestLine (
71+ gpioChip ,
72+ lineNumber ,
73+ gpiocdev .AsOutput (1 ),
74+ )
75+ if err != nil {
76+ return nil , fmt .Errorf ("failed to request GPIO %s: %w" , pinNumber , err )
77+ }
78+
79+ if err := line .SetValue (0 ); err != nil {
80+ _ = line .Close ()
81+ return nil , fmt .Errorf ("failed to activate GPIO %s: %w" , pinNumber , err )
5982 }
60- return pi , nil
83+
84+ return line , nil
6185}
6286
63- func (p * PinsExecutor ) deActivatePin (pi gpio.PinIO ) error {
64- return pi .Out (gpio .High )
87+ func NewPinsExecutor (tracer trace.Tracer ) * PinsExecutor {
88+ return & PinsExecutor {
89+ relays : relays ,
90+ tracer : tracer ,
91+ }
6592}
6693
6794type InvalidPinToExecuteError struct {
0 commit comments