Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add serial binary communication #653

Merged
merged 37 commits into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
895cc03
update bufferflow_timedraw as bufferflow_timed
umbynos Jul 15, 2021
05ee6f5
remove old commands
umbynos Jul 15, 2021
6a50f87
remove utf8 decoding with timedraw buffer type
umbynos Jul 19, 2021
e80400b
binary support (WIP)
umbynos Jul 19, 2021
eb2b3f3
use switch case
umbynos Jul 20, 2021
1cd174a
fixed test deps
umbynos Mar 1, 2021
48cc695
socketio test connection is working 🎉 (with the correct python-socket…
umbynos Mar 4, 2021
fc1222e
add callback to capture returned message, add new test for serial
umbynos Jul 21, 2021
9c7d3f8
fix tests: "socketio.exceptions.ConnectionError: Connection refused b…
umbynos Jul 21, 2021
dfcc14e
minor optimizations: data and buf are already an array of bytes
umbynos Jul 23, 2021
b7f70f1
enhanced a bit how the logic of the serial works
umbynos Jul 23, 2021
c86bb4f
enhance a lot test on serial communication (with different buffer types)
umbynos Jul 23, 2021
099a575
update and enhance commands output (the space in front of `<` and `>`…
umbynos Jul 23, 2021
b41d0cc
increased sleeptime, remove harcoded message[i]: should work on diffe…
umbynos Jul 29, 2021
fcaa53c
generalize the tests
umbynos Jul 29, 2021
43451a3
Apply suggestions from code review
umbynos Aug 2, 2021
15af2e4
add sketch used for testing
umbynos Aug 2, 2021
575efa1
Fix panic closing closed channel
silvanocerza Aug 3, 2021
2d78733
apply suggestions
umbynos Aug 3, 2021
8f9ff20
Partially revert #e80400b7ddbbc2e8f34f1e6701b55102c3a99289
umbynos Aug 3, 2021
0bbb45b
🧹(cleanup) and 🛠️(refactoring) of bufferflow stuff
umbynos Aug 4, 2021
5e2ad37
extract code in helper function and uniform the code
umbynos Aug 4, 2021
5d0bd27
optimize the handling of data coming from the serial port
umbynos Aug 4, 2021
f3d5dca
uniform default bufferflow and 🧹
umbynos Aug 4, 2021
5db1975
forgot to fix this in #621
umbynos Aug 4, 2021
37cf997
apply suggestions from code review ✨
umbynos Aug 5, 2021
724de59
remove timedbinary: it's the same as timedraw except for the casting
umbynos Aug 5, 2021
402a848
Escape html commands string
silvanocerza Aug 6, 2021
d5228ec
forgot to remove timed_binary
umbynos Aug 6, 2021
bcf0023
remove useless id field (was unused)
umbynos Aug 9, 2021
d077ded
remove useless channel done & other stuff
umbynos Aug 9, 2021
d704dd2
make sendNoBuf more general: will be used later 😏
umbynos Aug 10, 2021
791b03e
add `sendraw` command to send base64 encoded bytes, add tests (for se…
umbynos Aug 11, 2021
8dadd0c
forgot to skip test_sendraw_serial on CI
umbynos Aug 11, 2021
500a1ee
update comments
umbynos Aug 12, 2021
a86a61a
refactor tests
umbynos Aug 12, 2021
a21ae9e
remove BlockUntilReady because it was unused
umbynos Aug 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 2 additions & 44 deletions bufferflow.go
Original file line number Diff line number Diff line change
@@ -1,49 +1,7 @@
package main

import (
//"log"
//"time"
)

var availableBufferAlgorithms = []string{"default", "timed", "timedraw"}

type BufferMsg struct {
Cmd string
Port string
TriggeringResponse string
//Desc string
//Desc string
}

type Bufferflow interface {
Init()
BlockUntilReady(cmd string, id string) (bool, bool) // implement this method
//JustQueue(cmd string, id string) bool // implement this method
OnIncomingData(data string) // implement this method
ClearOutSemaphore() // implement this method
BreakApartCommands(cmd string) []string // implement this method
Pause() // implement this method
Unpause() // implement this method
SeeIfSpecificCommandsShouldSkipBuffer(cmd string) bool // implement this method
SeeIfSpecificCommandsShouldPauseBuffer(cmd string) bool // implement this method
SeeIfSpecificCommandsShouldUnpauseBuffer(cmd string) bool // implement this method
SeeIfSpecificCommandsShouldWipeBuffer(cmd string) bool // implement this method
SeeIfSpecificCommandsReturnNoResponse(cmd string) bool // implement this method
ReleaseLock() // implement this method
IsBufferGloballySendingBackIncomingData() bool // implement this method
Close() // implement this method
}

/*data packets returned to client*/
type DataCmdComplete struct {
Cmd string
Id string
P string
BufSize int `json:"-"`
D string `json:"-"`
}

type DataPerLine struct {
P string
D string
OnIncomingData(data string) // implement this method
Close() // implement this method
}
81 changes: 31 additions & 50 deletions bufferflow_default.go
Original file line number Diff line number Diff line change
@@ -1,71 +1,52 @@
package main

import (
"encoding/json"

log "github.com/sirupsen/logrus"
)

type BufferflowDefault struct {
Name string
Port string
port string
output chan<- []byte
input chan string
done chan bool
}

var ()
func NewBufferflowDefault(port string, output chan<- []byte) *BufferflowDefault {
return &BufferflowDefault{
port: port,
output: output,
input: make(chan string),
done: make(chan bool),
}
}

func (b *BufferflowDefault) Init() {
log.Println("Initting default buffer flow (which means no buffering)")
go b.consumeInput()
}

func (b *BufferflowDefault) BlockUntilReady(cmd string, id string) (bool, bool) {
//log.Printf("BlockUntilReady() start\n")
return true, false
func (b *BufferflowDefault) consumeInput() {
Loop:
for {
select {
case data := <-b.input:
m := SpPortMessage{b.port, data}
message, _ := json.Marshal(m)
b.output <- message
case <-b.done:
break Loop //this is required, a simple break statement would only exit the innermost switch statement
}
}
close(b.input) // close the input channel at the end of the computation
}

func (b *BufferflowDefault) OnIncomingData(data string) {
//log.Printf("OnIncomingData() start. data:%v\n", data)
}

// Clean out b.sem so it can truly block
func (b *BufferflowDefault) ClearOutSemaphore() {
}

func (b *BufferflowDefault) BreakApartCommands(cmd string) []string {
return []string{cmd}
}

func (b *BufferflowDefault) Pause() {
return
}

func (b *BufferflowDefault) Unpause() {
return
}

func (b *BufferflowDefault) SeeIfSpecificCommandsShouldSkipBuffer(cmd string) bool {
return false
}

func (b *BufferflowDefault) SeeIfSpecificCommandsShouldPauseBuffer(cmd string) bool {
return false
}

func (b *BufferflowDefault) SeeIfSpecificCommandsShouldUnpauseBuffer(cmd string) bool {
return false
}

func (b *BufferflowDefault) SeeIfSpecificCommandsShouldWipeBuffer(cmd string) bool {
return false
}

func (b *BufferflowDefault) SeeIfSpecificCommandsReturnNoResponse(cmd string) bool {
return false
}

func (b *BufferflowDefault) ReleaseLock() {
}

func (b *BufferflowDefault) IsBufferGloballySendingBackIncomingData() bool {
return false
b.input <- data
}

func (b *BufferflowDefault) Close() {
b.done <- true
close(b.done)
}
129 changes: 41 additions & 88 deletions bufferflow_timed.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,104 +8,57 @@ import (
)

type BufferflowTimed struct {
Name string
Port string
Output chan []byte
Input chan string
done chan bool
ticker *time.Ticker
port string
output chan<- []byte
input chan string
done chan bool
ticker *time.Ticker
sPort string
bufferedOutput string
}

var (
bufferedOutput string
sPort string
)
func NewBufferflowTimed(port string, output chan<- []byte) *BufferflowTimed {
return &BufferflowTimed{
port: port,
output: output,
input: make(chan string),
done: make(chan bool),
ticker: time.NewTicker(16 * time.Millisecond),
sPort: "",
bufferedOutput: "",
}
}

func (b *BufferflowTimed) Init() {
log.Println("Initting timed buffer flow (output once every 16ms)")
bufferedOutput = ""
sPort = ""

go func() {
b.ticker = time.NewTicker(16 * time.Millisecond)
b.done = make(chan bool)
Loop:
for {
select {
case data := <-b.Input:
bufferedOutput = bufferedOutput + data
sPort = b.Port
case <-b.ticker.C:
if bufferedOutput != "" {
m := SpPortMessage{sPort, bufferedOutput}
buf, _ := json.Marshal(m)
// data is now encoded in base64 format
// need a decoder on the other side
b.Output <- []byte(buf)
bufferedOutput = ""
sPort = ""
}
case <-b.done:
break Loop
go b.consumeInput()
}

func (b *BufferflowTimed) consumeInput() {
Loop:
for {
select {
case data := <-b.input: // use the buffer and append data to it
b.bufferedOutput = b.bufferedOutput + data
b.sPort = b.port
case <-b.ticker.C: // after 16ms send the buffered output message
if b.bufferedOutput != "" {
m := SpPortMessage{b.sPort, b.bufferedOutput}
buf, _ := json.Marshal(m)
b.output <- buf
// reset the buffer and the port
b.bufferedOutput = ""
b.sPort = ""
}
case <-b.done:
break Loop //this is required, a simple break statement would only exit the innermost switch statement
}

close(b.Input)

}()

}

func (b *BufferflowTimed) BlockUntilReady(cmd string, id string) (bool, bool) {
//log.Printf("BlockUntilReady() start\n")
return true, false
}
close(b.input)
}

func (b *BufferflowTimed) OnIncomingData(data string) {
b.Input <- data
}

// Clean out b.sem so it can truly block
func (b *BufferflowTimed) ClearOutSemaphore() {
}

func (b *BufferflowTimed) BreakApartCommands(cmd string) []string {
return []string{cmd}
}

func (b *BufferflowTimed) Pause() {
return
}

func (b *BufferflowTimed) Unpause() {
return
}

func (b *BufferflowTimed) SeeIfSpecificCommandsShouldSkipBuffer(cmd string) bool {
return false
}

func (b *BufferflowTimed) SeeIfSpecificCommandsShouldPauseBuffer(cmd string) bool {
return false
}

func (b *BufferflowTimed) SeeIfSpecificCommandsShouldUnpauseBuffer(cmd string) bool {
return false
}

func (b *BufferflowTimed) SeeIfSpecificCommandsShouldWipeBuffer(cmd string) bool {
return false
}

func (b *BufferflowTimed) SeeIfSpecificCommandsReturnNoResponse(cmd string) bool {
return false
}

func (b *BufferflowTimed) ReleaseLock() {
}

func (b *BufferflowTimed) IsBufferGloballySendingBackIncomingData() bool {
return true
b.input <- data
}

func (b *BufferflowTimed) Close() {
Expand Down
Loading