4 "code.octet-stream.net/broadcaster/protocol"
6 "golang.org/x/net/websocket"
10 type BeginDelayStatus
struct {
16 type BeginWaitForChannelStatus
struct {
21 type BeginPlaybackStatus
struct {
26 type StatusCollector
struct {
27 Websocket
chan *websocket
.Conn
28 PlaylistBeginIdle
chan bool
29 PlaylistBeginDelay
chan BeginDelayStatus
30 PlaylistBeginWaitForChannel
chan BeginWaitForChannelStatus
31 PlaylistBeginPlayback
chan BeginPlaybackStatus
34 Config
chan RadioConfig
38 var statusCollector
= NewStatusCollector()
40 func NewStatusCollector() StatusCollector
{
41 sc
:= StatusCollector
{
42 Websocket
: make(chan *websocket
.Conn
),
43 PlaylistBeginIdle
: make(chan bool),
44 PlaylistBeginDelay
: make(chan BeginDelayStatus
),
45 PlaylistBeginWaitForChannel
: make(chan BeginWaitForChannelStatus
),
46 PlaylistBeginPlayback
: make(chan BeginPlaybackStatus
),
49 Config
: make(chan RadioConfig
),
50 FilesInSync
: make(chan bool),
52 go runStatusCollector(sc
)
56 func runStatusCollector(sc StatusCollector
) {
58 var msg protocol
.StatusMessage
59 var lastSent protocol
.StatusMessage
60 msg
.T
= protocol
.StatusType
61 msg
.TimeZone
= config
.TimeZone
62 msg
.Status
= protocol
.StatusIdle
63 var ws
*websocket
.Conn
64 // Go 1.23: no need to stop tickers when finished
65 var ticker
= time
.NewTicker(time
.Second
* time
.Duration(30))
69 case newWebsocket
:= <-sc
.Websocket
:
72 // should always be ticking at 1 second for these
73 if msg
.Status
== protocol
.StatusDelay
{
74 if msg
.DelaySecondsRemaining
> 0 {
75 msg
.DelaySecondsRemaining
-= 1
78 if msg
.Status
== protocol
.StatusChannelInUse
{
79 msg
.WaitingForChannelSeconds
+= 1
81 if msg
.Status
== protocol
.StatusPlaying
{
82 msg
.PlaybackSecondsElapsed
+= 1
84 case <-sc
.PlaylistBeginIdle
:
85 msg
.Status
= protocol
.StatusIdle
86 msg
.DelaySecondsRemaining
= 0
87 msg
.WaitingForChannelSeconds
= 0
88 msg
.PlaybackSecondsElapsed
= 0
91 // Update things more slowly when nothing's playing
92 ticker
= time
.NewTicker(time
.Second
* time
.Duration(30))
93 case delay
:= <-sc
.PlaylistBeginDelay
:
94 msg
.Status
= protocol
.StatusDelay
95 msg
.DelaySecondsRemaining
= delay
.Seconds
96 msg
.WaitingForChannelSeconds
= 0
97 msg
.PlaybackSecondsElapsed
= 0
98 msg
.Playlist
= delay
.Playlist
99 msg
.Filename
= delay
.Filename
100 // Align ticker with start of state change, make sure it's faster
101 ticker
= time
.NewTicker(time
.Second
* time
.Duration(1))
102 case wait
:= <-sc
.PlaylistBeginWaitForChannel
:
103 msg
.Status
= protocol
.StatusChannelInUse
104 msg
.DelaySecondsRemaining
= 0
105 msg
.WaitingForChannelSeconds
= 0
106 msg
.PlaybackSecondsElapsed
= 0
107 msg
.Playlist
= wait
.Playlist
108 msg
.Filename
= wait
.Filename
109 ticker
= time
.NewTicker(time
.Second
* time
.Duration(1))
110 case playback
:= <-sc
.PlaylistBeginPlayback
:
111 msg
.Status
= protocol
.StatusPlaying
112 msg
.DelaySecondsRemaining
= 0
113 msg
.WaitingForChannelSeconds
= 0
114 msg
.PlaybackSecondsElapsed
= 0
115 msg
.Playlist
= playback
.Playlist
116 msg
.Filename
= playback
.Filename
117 ticker
= time
.NewTicker(time
.Second
* time
.Duration(1))
118 case ptt
:= <-sc
.PTT
:
120 case cos
:= <-sc
.COS
:
122 case inSync
:= <-sc
.FilesInSync
:
123 msg
.FilesInSync
= inSync
125 msg
.LocalTime
= time
.Now().Format(protocol
.LocalTimeFormat
)
126 msg
.COS
= cos
.COSValue()
132 msgJson
, _
:= json
.Marshal(msg
)
133 if _
, err
:= ws
.Write(msgJson
); err
!= nil {
134 // If websocket has failed, wait 'til we get a new one