Skip to content

Commit 3c920dd

Browse files
mxmxchereMalte Muench
and
Malte Muench
authored
New loglib (#55)
* Some typofixing and doc improvements Signed-off-by: Malte Muench <mamu@stablerock.de> * Write help to stderr Signed-off-by: Malte Muench <mamu@stablerock.de> * Improve logging, and improve error handling in reading the csv Signed-off-by: Malte Muench <mamu@stablerock.de> * Remove unused methods Signed-off-by: Malte Muench <mamu@stablerock.de> * Adds logging for receivehandling.go Signed-off-by: Malte Muench <mamu@stablerock.de> * Various smaller IDE proposed improvements Signed-off-by: Malte Muench <mamu@stablerock.de> * renamings, prefer short names Signed-off-by: Malte Muench <mamu@stablerock.de> --------- Signed-off-by: Malte Muench <mamu@stablerock.de> Co-authored-by: Malte Muench <mamu@stablerock.de>
1 parent b963565 commit 3c920dd

File tree

11 files changed

+118
-191
lines changed

11 files changed

+118
-191
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Example:
4141
123,uint322ascii,huette/all/000/airmonitor/sensors/pm10
4242
```
4343

44-
Explanation for the 1st Line: For example our Doorstatus is published on the CAN-Bus every second with the CAN-ID 112 (decimal). can2mqtt will take everything thats published there and will push it through to mqtt-topic huette/all/a03/door/sensors/opened.
44+
Explanation for the 1st Line: For example our Doorstatus is published on the CAN-Bus every second with the CAN-ID 112 (decimal). can2mqtt will take everything that is published there and will push it through to mqtt-topic huette/all/a03/door/sensors/opened.
4545

4646
## convert-modes
4747
Here they are:

src/can2mqtt.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ func main() {
3939

4040
// help function (obvious...)
4141
func printHelp() {
42-
fmt.Printf("welcome to the CAN2MQTT bridge!\n\n")
43-
fmt.Printf("Usage: can2mqtt [-f <file>] [-c <CAN-Interface>] [-m <MQTT-Connect>] [-v] [-h] [-d <dirMode>]\n")
44-
fmt.Printf("<file>: a can2mqtt.csv file\n")
45-
fmt.Printf("<CAN-Interface>: a CAN-Interface e.g. can0\n")
46-
fmt.Printf("<MQTT-Connect>: connectstring for MQTT. e.g.: tcp://[user:pass@]localhost:1883\n")
47-
fmt.Printf("<dirMode>: directional Mode 0 = bidirectional, 1 = can2mqtt only, 2 = mqtt2can only\n")
42+
_, _ = fmt.Fprintf(os.Stderr, "welcome to the CAN2MQTT bridge!\n\n")
43+
_, _ = fmt.Fprintf(os.Stderr, "Usage: can2mqtt [-f <file>] [-c <CAN-Interface>] [-m <MQTT-Connect>] [-v] [-h] [-d <dirMode>]\n")
44+
_, _ = fmt.Fprintf(os.Stderr, "<file>: a can2mqtt.csv file\n")
45+
_, _ = fmt.Fprintf(os.Stderr, "<CAN-Interface>: a CAN-Interface e.g. can0\n")
46+
_, _ = fmt.Fprintf(os.Stderr, "<MQTT-Connect>: connectstring for MQTT. e.g.: tcp://[user:pass@]localhost:1883\n")
47+
_, _ = fmt.Fprintf(os.Stderr, "<dirMode>: directional Mode 0 = bidirectional, 1 = can2mqtt only, 2 = mqtt2can only\n")
4848
}
Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
// Package can2mqtt contains some tools for bridging a CAN-Interface
1+
// Package internal of c3re/can2mqtt contains some tools for bridging a CAN-Interface
22
// and a mqtt-network
33
package internal
44

55
import (
6-
"fmt"
76
"github.com/brutella/can"
8-
"log"
7+
"log/slog"
8+
"os"
99
"sync"
1010
)
1111

@@ -18,23 +18,21 @@ var bus *can.Bus // CAN-Bus pointer
1818
func canStart(canInterface string) {
1919

2020
var err error
21-
if dbg {
22-
fmt.Printf("canbushandler: initializing CAN-Bus interface %s\n", canInterface)
23-
}
21+
slog.Debug("canbus: initializing CAN-Bus", "interface", canInterface)
2422
bus, err = can.NewBusForInterfaceWithName(canInterface)
2523
if err != nil {
26-
if dbg {
27-
fmt.Printf("canbushandler: error while activating CAN-Bus interface: %s\n", canInterface)
28-
}
29-
log.Fatal(err)
24+
slog.Error("canbus: error while initializing CAN-Bus", "error", err)
25+
os.Exit(1)
3026
}
27+
slog.Info("canbus: connected to CAN")
28+
slog.Debug("canbus: registering handler")
3129
bus.SubscribeFunc(handleCANFrame)
30+
slog.Debug("canbus: starting receive loop")
31+
// will not return if everything is fine
3232
err = bus.ConnectAndPublish()
3333
if err != nil {
34-
if dbg {
35-
fmt.Printf("canbushandler: error while activating CAN-Bus interface: %s\n", canInterface)
36-
}
37-
log.Fatal(err)
34+
slog.Error("canbus: error while processing CAN-Bus", "error", err)
35+
os.Exit(1)
3836
}
3937
}
4038

@@ -43,18 +41,14 @@ func handleCANFrame(frame can.Frame) {
4341
var idSub = false // indicates, whether the id was subscribed or not
4442
for _, i := range csi {
4543
if i == frame.ID {
46-
if dbg {
47-
fmt.Printf("canbushandler: ID %d is in subscribed list, calling receivehadler.\n", frame.ID)
48-
}
44+
slog.Debug("canbus: received subscribed frame", "id", frame.ID)
4945
go handleCAN(frame)
5046
idSub = true
5147
break
5248
}
5349
}
5450
if !idSub {
55-
if dbg {
56-
fmt.Printf("canbushandler: ID:%d was not subscribed. /dev/nulled that frame...\n", frame.ID)
57-
}
51+
slog.Debug("canbus: ignored unsubscribed frame", "id", frame.ID)
5852
}
5953
}
6054

@@ -63,26 +57,19 @@ func canSubscribe(id uint32) {
6357
csiLock.Lock()
6458
csi = append(csi, id)
6559
csiLock.Unlock()
66-
if dbg {
67-
fmt.Printf("canbushandler: mutex lock+unlock successful. subscribed to ID:%d\n", id)
68-
}
60+
slog.Debug("canbus: successfully subscribed CAN-ID", "id", id)
6961
}
7062

7163
// expects a CANFrame and sends it
7264
func canPublish(frame can.Frame) {
73-
if dbg {
74-
fmt.Println("canbushandler: sending CAN-Frame: ", frame)
75-
}
65+
slog.Debug("canbus: sending CAN-Frame", "frame", frame)
7666
// Check if ID is using more than 11-Bits:
7767
if frame.ID >= 0x800 {
7868
// if so, enable extended frame format
7969
frame.ID |= 0x80000000
8070
}
8171
err := bus.Publish(frame)
8272
if err != nil {
83-
if dbg {
84-
fmt.Printf("canbushandler: error while transmitting the CAN-Frame.\n")
85-
}
86-
log.Fatal(err)
73+
slog.Error("canbus: error while publishing CAN-Frame", "error", err)
8774
}
8875
}

src/internal/convertfunctions/bytecolor2colorcode.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func ByteColor2ColorCodeToCan(input []byte) (can.Frame, error) {
1717
if err != nil {
1818
return can.Frame{}, errors.New(fmt.Sprintf("Error while converting: %s", err.Error()))
1919
}
20-
var returner can.Frame = can.Frame{Length: 3}
20+
var returner = can.Frame{Length: 3}
2121
copy(res, returner.Data[0:3])
2222
return returner, nil
2323
}

src/internal/convertfunctions/int2ascii.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func FourInt162AsciiToMqtt(input can.Frame) ([]byte, error) {
7979
// numberAmount*numberWidth shall not be larger than 64
8080
// input has to contain the data that shall be converted. The input is split at whitespaces, the amount of fields has
8181
// to match numberAmount.
82-
// If the amount of fields matches, each field is converted to a uint of size numberWidth. The results are then added to the CAN-frame.
82+
// If the amount of fields matches, each field is converted to an uint of size numberWidth. The results are then added to the CAN-frame.
8383
func NIntM2AsciiToCan(numberAmount, numberWidth uint, input []byte) (can.Frame, error) {
8484
if !(numberWidth == 8 || numberWidth == 16 || numberWidth == 32 || numberWidth == 64) {
8585

src/internal/convertfunctions/pixelbin2ascii.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func PixelBin2AsciiToCan(input []byte) (can.Frame, error) {
2626
if err != nil {
2727
return can.Frame{}, errors.New(fmt.Sprintf("Error while converting: %s", err.Error()))
2828
}
29-
var returner can.Frame = can.Frame{Length: 4}
29+
var returner = can.Frame{Length: 4}
3030
returner.Data[0] = uint8(number)
3131
copy(res, returner.Data[1:4])
3232
return returner, nil

src/internal/convertfunctions/uint2ascii.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func FourUint162AsciiToMqtt(input can.Frame) ([]byte, error) {
7979
// numberAmount*numberWidth shall not be larger than 64
8080
// input has to contain the data that shall be converted. The input is split at whitespaces, the amount of fields has
8181
// to match numberAmount.
82-
// If the amount of fields matches, each field is converted to a uint of size numberWidth. The results are then added to the CAN-frame.
82+
// If the amount of fields matches, each field is converted to an uint of size numberWidth. The results are then added to the CAN-frame.
8383
func NUintM2AsciiToCan(numberAmount, numberWidth uint, input []byte) (can.Frame, error) {
8484
if !(numberWidth == 8 || numberWidth == 16 || numberWidth == 32 || numberWidth == 64) {
8585

@@ -139,7 +139,7 @@ func NUintM2AsciiToMqtt(numberAmount, numberWidth uint, input can.Frame) ([]byte
139139
for i := uint(0); i < numberAmount; i++ {
140140
switch numberWidth {
141141
case 64:
142-
returnStrings = append(returnStrings, strconv.FormatUint(uint64(binary.LittleEndian.Uint64(input.Data[i*bytePerNumber:(i+1)*bytePerNumber])), 10))
142+
returnStrings = append(returnStrings, strconv.FormatUint(binary.LittleEndian.Uint64(input.Data[i*bytePerNumber:(i+1)*bytePerNumber]), 10))
143143
case 32:
144144
returnStrings = append(returnStrings, strconv.FormatUint(uint64(binary.LittleEndian.Uint32(input.Data[i*bytePerNumber:(i+1)*bytePerNumber])), 10))
145145
case 16:

src/internal/main.go

Lines changed: 29 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import (
66
"fmt" // print :)
77
"github.com/brutella/can"
88
"github.com/c3re/can2mqtt/internal/convertfunctions"
9-
"io" // EOF const
10-
"log" // error management
9+
"io" // EOF const
10+
"log" // error management
11+
"log/slog"
1112
"os" // open files
1213
"strconv" // parse strings
1314
"sync"
@@ -46,6 +47,7 @@ var wg sync.WaitGroup
4647
// just standard information output. Default is false.
4748
func SetDbg(v bool) {
4849
dbg = v
50+
slog.SetLogLoggerLevel(slog.LevelDebug)
4951
}
5052

5153
// SetCi sets the CAN-Interface to use for the CAN side
@@ -86,28 +88,8 @@ func SetConfDirMode(s string) {
8688
// parses the can2mqtt.csv file and from there everything takes
8789
// its course...
8890
func Start() {
89-
fmt.Println("Starting can2mqtt")
90-
fmt.Println()
91-
fmt.Println("MQTT-Config: ", cs)
92-
fmt.Println("CAN-Config: ", ci)
93-
fmt.Println("can2mqtt.csv: ", c2mf)
94-
fmt.Print("dirMode: ", dirMode, " (")
95-
if dirMode == 0 {
96-
fmt.Println("bidirectional)")
97-
}
98-
if dirMode == 1 {
99-
fmt.Println("can2mqtt only)")
100-
}
101-
if dirMode == 2 {
102-
fmt.Println("mqtt2can only)")
103-
}
104-
fmt.Print("Debug-Mode: ")
105-
if dbg {
106-
fmt.Println("yes")
107-
} else {
108-
fmt.Println("no")
109-
}
110-
fmt.Println()
91+
log.SetFlags(0)
92+
slog.Info("Starting can2mqtt", "mqtt-config", cs, "can-interface", ci, "can2mqtt.csv", c2mf, "dir-mode", dirMode, "debug", dbg)
11193
wg.Add(1)
11294
go canStart(ci) // epic parallel shit ;-)
11395
mqttStart(cs)
@@ -121,10 +103,12 @@ func readC2MPFromFile(filename string) {
121103

122104
file, err := os.Open(filename)
123105
if err != nil {
124-
log.Fatal(err)
106+
slog.Error("can2mqtt.csv could not be opened", "filename", filename, "error", err)
107+
os.Exit(1)
125108
}
126109

127110
r := csv.NewReader(bufio.NewReader(file))
111+
r.FieldsPerRecord = 3
128112
pairFromID = make(map[uint32]*can2mqtt)
129113
pairFromTopic = make(map[string]*can2mqtt)
130114
for {
@@ -133,16 +117,26 @@ func readC2MPFromFile(filename string) {
133117
if err == io.EOF {
134118
break
135119
}
120+
if err != nil {
121+
slog.Warn("skipping line", "filename", filename, "error", err)
122+
continue
123+
}
124+
line, _ := r.FieldPos(0)
136125
tmp, err := strconv.ParseUint(record[0], 10, 32)
137126
if err != nil {
138-
fmt.Printf("Error while converting can-ID: %s :%s\n", record[0], err.Error())
127+
slog.Warn("skipping line, malformed can-ID", "error", err, "line", line)
139128
continue
140129
}
141130
canID := uint32(tmp)
142131
convMode := record[1]
143132
topic := record[2]
144-
if isInSlice(canID, topic) {
145-
panic("main: each ID and each topic is only allowed once!")
133+
if isIDInSlice(canID) {
134+
slog.Warn("skipping line, duplicate ID", "id", canID, "line", line)
135+
continue
136+
}
137+
if isTopicInSlice(topic) {
138+
slog.Warn("skipping line duplicate topic", "topic", topic, "line", line)
139+
continue
146140
}
147141
switch convMode {
148142
case "16bool2ascii":
@@ -217,7 +211,7 @@ func readC2MPFromFile(filename string) {
217211
toCan: convertfunctions.EightUint82AsciiToCan,
218212
toMqtt: convertfunctions.EightUint82AsciiToMqtt,
219213
}
220-
// Int methodes come here now
214+
// Int methods come here now
221215
case "int82ascii":
222216
pairFromID[canID] = &can2mqtt{
223217
canId: canID,
@@ -311,45 +305,18 @@ func readC2MPFromFile(filename string) {
311305
mqttSubscribe(topic) // TODO move to append function
312306
canSubscribe(canID) // TODO move to append function
313307
}
314-
if dbg {
315-
fmt.Printf("main: the following CAN-MQTT pairs have been extracted:\n")
316-
fmt.Printf("main: CAN-ID\t\t conversion mode\t\tMQTT-topic\n")
317-
for _, c2mp := range pairFromID {
318-
fmt.Printf("main: %d\t\t%s\t\t%s\n", c2mp.canId, c2mp.convMethod, c2mp.mqttTopic)
319-
}
320-
}
321-
}
322308

323-
// check function to check if a topic or an ID is in the slice
324-
func isInSlice(canId uint32, mqttTopic string) bool {
325-
if pairFromID[canId] != nil {
326-
if dbg {
327-
fmt.Printf("main: The ID %d or the Topic %s is already in the list!\n", canId, mqttTopic)
328-
}
329-
return true
309+
for _, c2mp := range pairFromID {
310+
slog.Debug("extracted pair", "id", c2mp.canId, "convertmode", c2mp.convMethod, "topic", c2mp.mqttTopic)
330311
}
331-
if pairFromTopic[mqttTopic] != nil {
332-
if dbg {
333-
fmt.Printf("main: The ID %d or the Topic %s is already in the list!\n", canId, mqttTopic)
334-
}
335-
return true
336-
}
337-
return false
338-
}
339-
340-
// get the corresponding ID for a given topic
341-
func getIdFromTopic(topic string) uint32 {
342-
return pairFromTopic[topic].canId
343312
}
344313

345-
// get the conversion mode for a given topic
346-
func getConvModeFromTopic(topic string) string {
347-
return pairFromTopic[topic].convMethod
314+
func isIDInSlice(canId uint32) bool {
315+
return pairFromID[canId] != nil
348316
}
349317

350-
// get the convertMode for a given ID
351-
func getConvModeFromId(canId uint32) string {
352-
return pairFromID[canId].convMethod
318+
func isTopicInSlice(mqttTopic string) bool {
319+
return pairFromTopic[mqttTopic] != nil
353320
}
354321

355322
// get the corresponding topic for an ID

0 commit comments

Comments
 (0)