-
-
Notifications
You must be signed in to change notification settings - Fork 150
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
Conversation
The tests should be skipped on the CI (no board connected)
… is required) 🤷♂️
I still have to produce some docs |
Co-authored-by: per1234 <accounts@perglass.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments.
This is the diff I'm taking about, the only difference is the location of the casting. Apart from it they are the same. Removing --- /home/umberto/Nextcloud/8tb/Lavoro/arduino-create-agent/bufferflow_timedraw.go
+++ /home/umberto/Nextcloud/8tb/Lavoro/arduino-create-agent/bufferflow_timedbinary.go
@@ -7,50 +7,50 @@
log "github.com/sirupsen/logrus"
)
-type BufferflowTimedRaw struct {
- port string
- output chan<- []byte
- input chan string
- done chan bool
- ticker *time.Ticker
- bufferedOutputRaw []byte
- sPortRaw string
+type BufferflowTimedBinary struct {
+ port string
+ output chan<- []byte
+ input chan []byte
+ done chan bool
+ ticker *time.Ticker
+ bufferedOutputBinary []byte
+ sPortBinary string
}
-func NewBufferflowTimedRaw(port string, output chan<- []byte) *BufferflowTimedRaw {
- return &BufferflowTimedRaw{
- port: port,
- output: output,
- input: make(chan string),
- done: make(chan bool),
- ticker: time.NewTicker(16 * time.Millisecond),
- bufferedOutputRaw: nil,
- sPortRaw: "",
+func NewBufferflowTimedBinary(port string, output chan<- []byte) *BufferflowTimedBinary {
+ return &BufferflowTimedBinary{
+ port: port,
+ output: output,
+ input: make(chan []byte),
+ done: make(chan bool),
+ ticker: time.NewTicker(16 * time.Millisecond),
+ bufferedOutputBinary: nil,
+ sPortBinary: "",
}
}
-func (b *BufferflowTimedRaw) Init() {
- log.Println("Initting timed buffer raw flow (output once every 16ms)")
+func (b *BufferflowTimedBinary) Init() {
+ log.Println("Initting timed buffer binary flow (output once every 16ms)")
go b.consumeInput()
}
-func (b *BufferflowTimedRaw) consumeInput() {
+func (b *BufferflowTimedBinary) consumeInput() {
Loop:
for {
select {
case data := <-b.input: // use the buffer and append data to it
- b.bufferedOutputRaw = append(b.bufferedOutputRaw, []byte(data)...)
- b.sPortRaw = b.port
+ b.bufferedOutputBinary = append(b.bufferedOutputBinary, data...)
+ b.sPortBinary = b.port
case <-b.ticker.C: // after 16ms send the buffered output message
- if b.bufferedOutputRaw != nil {
- m := SpPortMessageRaw{b.sPortRaw, b.bufferedOutputRaw}
+ if b.bufferedOutputBinary != nil {
+ m := SpPortMessageRaw{b.sPortBinary, b.bufferedOutputBinary}
buf, _ := json.Marshal(m)
// data is now encoded in base64 format
// need a decoder on the other side
b.output <- buf
// reset the buffer and the port
- b.bufferedOutputRaw = nil
- b.sPortRaw = ""
+ b.bufferedOutputBinary = nil
+ b.sPortBinary = ""
}
case <-b.done:
break Loop //this is required, a simple break statement would only exit the innermost switch statement
@@ -59,16 +59,16 @@
close(b.input)
}
-func (b *BufferflowTimedRaw) BlockUntilReady(cmd string, id string) (bool, bool) {
+func (b *BufferflowTimedBinary) BlockUntilReady(cmd string, id string) (bool, bool) {
//log.Printf("BlockUntilReady() start\n")
return true, false
}
-func (b *BufferflowTimedRaw) OnIncomingData(data string) {
- b.input <- data
+func (b *BufferflowTimedBinary) OnIncomingData(data string) {
+ b.input <- []byte(data)
}
-func (b *BufferflowTimedRaw) Close() {
+func (b *BufferflowTimedBinary) Close() {
b.ticker.Stop()
b.done <- true
close(b.done)
|
I prepared a Release Candidate to test the functionality out. |
…nd raw and for open/close port)
Documetation have been updated: https://github.com/arduino/arduino-create-agent/wiki/How-to-use-the-agent#receiving-and-sending-data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, if you have tested it, it's ok to merge IMHO.
buffered_ch.Reset() | ||
for i, w := 0, 0; i < n; i += w { | ||
runeValue, width := utf8.DecodeRune(bufferPart[i:n]) // try to decode the first i bytes in the buffer (UTF8 runes do not have a fixed length) | ||
if runeValue == utf8.RuneError { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As it is, this loop won't go over a malformed UTF8 sequence. If the UTF8 rune is incomplete it will be completed over multiple iterations, but if the UTF8 rune is corrupted the loop won't go past it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW I see that it's the same loop as before, so it may be fixed in another PR if needed.
* update bufferflow_timedraw as bufferflow_timed * remove old commands * remove utf8 decoding with timedraw buffer type * binary support (WIP) * use switch case * fixed test deps * socketio test connection is working 🎉 (with the correct python-socketio version) * add callback to capture returned message, add new test for serial * fix tests: "socketio.exceptions.ConnectionError: Connection refused by the server" * minor optimizations: data and buf are already an array of bytes * enhanced a bit how the logic of the serial works * enhance a lot test on serial communication (with different buffer types) The tests should be skipped on the CI (no board connected) * update and enhance commands output (the space in front of `<` and `>` is required) 🤷♂️ * increased sleeptime, remove harcoded message[i]: should work on different systems * generalize the tests * Apply suggestions from code review Co-authored-by: per1234 <accounts@perglass.com> * add sketch used for testing * Fix panic closing closed channel * apply suggestions * Partially revert #e80400b7ddbbc2e8f34f1e6701b55102c3a99289 * 🧹(cleanup) and 🛠️(refactoring) of bufferflow stuff * extract code in helper function and uniform the code reintroduce the closing of input channel (it's required) * optimize the handling of data coming from the serial port * uniform default bufferflow and 🧹 * forgot to fix this in #621 * apply suggestions from code review ✨ * remove timedbinary: it's the same as timedraw except for the casting * Escape html commands string * forgot to remove timed_binary * remove useless id field (was unused) * remove useless channel done & other stuff * make sendNoBuf more general: will be used later 😏 * add `sendraw` command to send base64 encoded bytes, add tests (for send raw and for open/close port) * forgot to skip test_sendraw_serial on CI * update comments * refactor tests * remove BlockUntilReady because it was unused Co-authored-by: per1234 <accounts@perglass.com> Co-authored-by: Silvano Cerza <silvanocerza@gmail.com>
Please check if the PR fulfills these requirements
before creating one)
feature
no serial binary communication
serial binary communication have been added back: now you can open a serial with this buffer type by using
open <port> <baud> timedraw
command, once the socketio connection has been established.To send binary data you have to base64 encode yourself and use
sendraw <port> base64_encoded_binary
Tests have been added:
test_ws_connection
andtest_list
should work even on the CIother tests aim to verify if the communication through the serial works correctly, so you have to run them locally (
poetry run pytest test/test_ws.py
) with a board connected and the sketch present intest/testdata/SerialEcho/SerialEcho.ino
already flashedDoes this PR introduce a breaking change?
it should not