13 changed files with 331 additions and 95 deletions
@ -0,0 +1,4 @@ |
|||||
|
[submodule "LibTeleinfo"] |
||||
|
path = main/libteleinfo |
||||
|
url = https://github.com/nmasse-itix/LibTeleinfo.git |
||||
|
branch = master |
||||
@ -1,2 +1,2 @@ |
|||||
idf_component_register(SRCS "main.c" "tic.c" |
idf_component_register(SRCS "main.c" "tic.c" "libteleinfo.cpp" "libteleinfo/src/LibTeleinfo.cpp" |
||||
INCLUDE_DIRS ".") |
INCLUDE_DIRS ".") |
||||
|
|||||
@ -0,0 +1,30 @@ |
|||||
|
#include "libteleinfo.h" |
||||
|
#include "libteleinfo/src/LibTeleinfo.h" |
||||
|
|
||||
|
static TInfo tinfo; |
||||
|
static libteleinfo_data_callback data_cb; |
||||
|
static libteleinfo_adps_callback adps_cb; |
||||
|
|
||||
|
void _libteleinfo_data_callback(ValueList * valueslist, uint8_t flags) { |
||||
|
data_cb(valueslist->ts, flags, valueslist->name, valueslist->value); |
||||
|
} |
||||
|
|
||||
|
void _libteleinfo_adps_callback(uint8_t phase) { |
||||
|
adps_cb(phase); |
||||
|
} |
||||
|
|
||||
|
EXTERNC void libteleinfo_init(libteleinfo_data_callback dcb, libteleinfo_adps_callback acb) { |
||||
|
data_cb = dcb; |
||||
|
adps_cb = acb; |
||||
|
|
||||
|
// Initialize the LibTeleinfo
|
||||
|
tinfo.init(); |
||||
|
tinfo.attachData(_libteleinfo_data_callback); |
||||
|
tinfo.attachADPS(_libteleinfo_adps_callback); |
||||
|
} |
||||
|
|
||||
|
EXTERNC void libteleinfo_process(uint8_t* buffer, int len) { |
||||
|
for (int i = 0; i < len; i++) { |
||||
|
tinfo.process(buffer[i]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// This is a C to C++ bridge. It is required to call the LibTeleinfo (C++) from FreeRTOS (C).
|
||||
|
|
||||
|
#ifndef __LIBTELEINFO_H__ |
||||
|
#define __LIBTELEINFO_H__ |
||||
|
|
||||
|
// The magic lays here...
|
||||
|
#ifdef __cplusplus |
||||
|
#define EXTERNC extern "C" |
||||
|
#else |
||||
|
#define EXTERNC |
||||
|
#endif |
||||
|
|
||||
|
// Needed for uint8_t
|
||||
|
#include <stdint.h> |
||||
|
// Needed for time_t
|
||||
|
#include <time.h> |
||||
|
|
||||
|
#define LIBTELEINFO_FLAGS_NONE 0x00 |
||||
|
#define LIBTELEINFO_FLAGS_NOTHING 0x01 |
||||
|
#define LIBTELEINFO_FLAGS_ADDED 0x02 |
||||
|
#define LIBTELEINFO_FLAGS_EXIST 0x04 |
||||
|
#define LIBTELEINFO_FLAGS_UPDATED 0x08 |
||||
|
#define LIBTELEINFO_FLAGS_ALERT 0x80 |
||||
|
|
||||
|
typedef void(*libteleinfo_data_callback)(time_t,uint8_t,char*,char*); |
||||
|
typedef void(*libteleinfo_adps_callback)(uint8_t); |
||||
|
|
||||
|
EXTERNC void libteleinfo_init(libteleinfo_data_callback, libteleinfo_adps_callback); |
||||
|
EXTERNC void libteleinfo_process(uint8_t* buffer, int len); |
||||
|
|
||||
|
#endif |
||||
@ -1,11 +1,6 @@ |
|||||
#ifndef __TIC_H__ |
#ifndef __TIC_H__ |
||||
#define __TIC_H__ |
#define __TIC_H__ |
||||
|
|
||||
#define TIC_BUFFER_SIZE (2048) |
|
||||
#define TIC_READ_BUFFER_SIZE (TIC_BUFFER_SIZE / 2) |
|
||||
#define TIC_CHECKSUM_THRESHOLD (10) |
|
||||
#define TIC_UART_NUM UART_NUM_2 |
|
||||
|
|
||||
void tic_uart_init(); |
void tic_uart_init(); |
||||
|
|
||||
#endif |
#endif |
||||
|
|||||
@ -0,0 +1 @@ |
|||||
|
e2e |
||||
@ -0,0 +1,92 @@ |
|||||
|
package main |
||||
|
|
||||
|
type TicMode int64 |
||||
|
|
||||
|
const ( |
||||
|
TIC_MODE_HISTORIQUE TicMode = iota |
||||
|
TIC_MODE_STANDARD |
||||
|
) |
||||
|
|
||||
|
type MQTTResult struct { |
||||
|
// TODO
|
||||
|
} |
||||
|
|
||||
|
type TestStep struct { |
||||
|
Sent []string |
||||
|
Expected []MQTTResult |
||||
|
} |
||||
|
|
||||
|
type TestCase struct { |
||||
|
Name string |
||||
|
Mode TicMode |
||||
|
Steps []TestStep |
||||
|
} |
||||
|
|
||||
|
var testCases []TestCase = []TestCase{ |
||||
|
{ |
||||
|
Name: "historique_simple", |
||||
|
Mode: TIC_MODE_HISTORIQUE, |
||||
|
Steps: []TestStep{ |
||||
|
{ |
||||
|
Sent: []string{ |
||||
|
"MOTDETAT 000000 B", |
||||
|
"PPOT 00 #", |
||||
|
"OPTARIF HC.. <", |
||||
|
"ISOUSC 25 =", |
||||
|
"HCHC 015558379 1", |
||||
|
"HCHP 011651340 (", |
||||
|
"PTEC HP.. ", |
||||
|
"IINST1 001 I", |
||||
|
"IINST2 001 J", |
||||
|
"IINST3 000 J", |
||||
|
"IMAX1 060 6", |
||||
|
"IMAX2 060 7", |
||||
|
"IMAX3 060 8", |
||||
|
"PMAX 08611 6", |
||||
|
"PAPP 00540 *", |
||||
|
"HHPHC A ,", |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
Sent: []string{ |
||||
|
"MOTDETAT 000000 B", |
||||
|
"PPOT 00 #", |
||||
|
"OPTARIF HC.. <", |
||||
|
"ISOUSC 25 =", |
||||
|
"HCHC 015558379 1", |
||||
|
"HCHP 011651341 )", |
||||
|
"PTEC HP.. ", |
||||
|
"IINST1 001 I", |
||||
|
"IINST2 009 R", |
||||
|
"IINST3 000 J", |
||||
|
"IMAX1 060 6", |
||||
|
"IMAX2 060 7", |
||||
|
"IMAX3 060 8", |
||||
|
"PMAX 08611 6", |
||||
|
"PAPP 02420 )", |
||||
|
"HHPHC A ,", |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
Sent: []string{ |
||||
|
"MOTDETAT 000000 B", |
||||
|
"PPOT 00 #", |
||||
|
"OPTARIF HC.. <", |
||||
|
"ISOUSC 25 =", |
||||
|
"HCHC 015558379 1", |
||||
|
"HCHP 011651343 +", |
||||
|
"PTEC HP.. ", |
||||
|
"IINST1 001 I", |
||||
|
"IINST2 006 O", |
||||
|
"IINST3 000 J", |
||||
|
"IMAX1 060 6", |
||||
|
"IMAX2 060 7", |
||||
|
"IMAX3 060 8", |
||||
|
"PMAX 08611 6", |
||||
|
"PAPP 01690 1", |
||||
|
"HHPHC A ,", |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
module github.com/nmasse-itix/tic-to-mqtt/test/e2e |
||||
|
|
||||
|
go 1.16 |
||||
|
|
||||
|
require go.bug.st/serial v1.3.4 // indirect |
||||
@ -0,0 +1,12 @@ |
|||||
|
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= |
||||
|
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= |
||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= |
||||
|
go.bug.st/serial v1.3.4 h1:fMpfNEOsPQjYGZ3VHcs/xxsxoaPgbcjrm4YnMkcir3Y= |
||||
|
go.bug.st/serial v1.3.4/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304= |
||||
|
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf h1:2ucpDCmfkl8Bd/FsLtiD653Wf96cW37s+iGx93zsu4k= |
||||
|
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
||||
@ -0,0 +1,91 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"bytes" |
||||
|
"flag" |
||||
|
"fmt" |
||||
|
"os" |
||||
|
"sort" |
||||
|
"time" |
||||
|
|
||||
|
"go.bug.st/serial" |
||||
|
) |
||||
|
|
||||
|
func main() { |
||||
|
var portName string |
||||
|
|
||||
|
flag.StringVar(&portName, "p", "/dev/ttyUSB1", "Serial port to use") |
||||
|
flag.Parse() |
||||
|
|
||||
|
wanted := flag.Args() |
||||
|
if len(wanted) == 0 { |
||||
|
fmt.Println("Usage: e2e [-t /dev/ttyUSBX ] test_case1 test_case2 ...") |
||||
|
fmt.Println() |
||||
|
fmt.Println("Available test cases:") |
||||
|
for _, testCase := range testCases { |
||||
|
fmt.Printf("- %s\n", testCase.Name) |
||||
|
} |
||||
|
os.Exit(1) |
||||
|
} |
||||
|
sort.Strings(wanted) |
||||
|
for _, testCase := range testCases { |
||||
|
i := sort.SearchStrings(wanted, testCase.Name) |
||||
|
if i >= len(wanted) || wanted[i] != testCase.Name { |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
fmt.Printf("Running test case %s...\n", testCase.Name) |
||||
|
|
||||
|
var mode serial.Mode |
||||
|
var modeName string |
||||
|
if testCase.Mode == TIC_MODE_HISTORIQUE { |
||||
|
mode = serial.Mode{ |
||||
|
BaudRate: 1200, |
||||
|
DataBits: 7, |
||||
|
Parity: serial.EvenParity, |
||||
|
StopBits: serial.OneStopBit, |
||||
|
} |
||||
|
modeName = "historique" |
||||
|
} else if testCase.Mode == TIC_MODE_STANDARD { |
||||
|
mode = serial.Mode{ |
||||
|
BaudRate: 9600, |
||||
|
DataBits: 7, |
||||
|
Parity: serial.EvenParity, |
||||
|
StopBits: serial.OneStopBit, |
||||
|
} |
||||
|
modeName = "standard" |
||||
|
} else { |
||||
|
panic("Unknown mode") |
||||
|
} |
||||
|
|
||||
|
fmt.Printf("Opening port %s with mode %s...\n", portName, modeName) |
||||
|
|
||||
|
port, err := serial.Open(portName, &mode) |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
defer port.Close() |
||||
|
|
||||
|
for i, step := range testCase.Steps { |
||||
|
fmt.Printf("Sending trame %d...\n", i) |
||||
|
var b bytes.Buffer |
||||
|
b.WriteByte(0x02) |
||||
|
for _, info := range step.Sent { |
||||
|
b.WriteString(fmt.Sprintf("\n%s\r", info)) |
||||
|
} |
||||
|
b.WriteByte(0x03) |
||||
|
buffer := b.Bytes() |
||||
|
n, err := port.Write(buffer) |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
if n != len(buffer) { |
||||
|
panic("Cannot send bytes to serial port!") |
||||
|
} |
||||
|
// Can be any value between 16.7 and 33.4 ms
|
||||
|
time.Sleep(33 * time.Millisecond) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
fmt.Println("Done.") |
||||
|
} |
||||
Loading…
Reference in new issue