Skip to content

Commit

Permalink
Add instructions and mockup code how to create a custom convert-mode
Browse files Browse the repository at this point in the history
Signed-off-by: Malte Muench <[email protected]>
  • Loading branch information
Malte Muench committed Jun 18, 2024
1 parent 4b99e4d commit 07071a6
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 31 deletions.
66 changes: 35 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Here you can see can2mqtt in action:
can2mqtt is written in Go and static linked binaries are available [here](https://github.com/c3re/can2mqtt/releases/latest).
can2mqtt has no further dependencies. On a Raspberry for example it should be enough to run:
```
wget https://github.com/c3re/can2mqtt/releases/download/v2.0.0/can2mqtt-v2.0.0-linux-arm -O can2mqtt
wget https://github.com/c3re/can2mqtt/releases/download/v2.2.0/can2mqtt-v2.2.0-linux-arm -O can2mqtt
chmod +x can2mqtt
./can2mqtt
```
Expand All @@ -19,7 +19,7 @@ The commandline parameters are the following:
./can2mqtt -f <can2mqtt.csv> -c <can-interface> -m <mqtt-connectstring> [-v]
```

Where can2mqtt.csv is the file for the configuration of can and mqtt pairs, can-interface is a socketcan interface and mqtt-connectstring is string that is accepted by the eclipse paho mqtt client. An additional -v flag can be passed to get verbose debug output. Example:
Where can2mqtt.csv is the file for the configuration of can and mqtt pairs, can-interface is a socket-can interface and mqtt-connectstring is string that is accepted by the eclipse paho mqtt client. An additional -v flag can be passed to get verbose debug output. Example:
```
./can2mqtt -f /etc/can2mqtt.csv -c can0 -m tcp://127.0.0.1:1883
```
Expand All @@ -46,37 +46,41 @@ Explanation for the 1st Line: For example our Doorstatus is published on the CAN
## convert-modes
Here they are:

| convertmode | description |
|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `none` | does not convert anything. It just takes a bunch of bytes and hands it over to the other side. If you want to send strings, this will be your choice. If you have a mqtt payload that is longer than eight bytes, only the first eight bytes will be send via CAN. |
| `bytecolor2colorcode` | Converts an bytearray of 3 bytes to hexadecimal colorcode |
| `pixelbin2ascii` | This mode was designed to adress colorized pixels. MQTT-wise you can insert a string like "<0-255> #RRGGBB" wich will be converted to 4 byte on the CAN-BUS the first byte will be the number of the LED 0-255 and bytes 1, 2, 3 are the color of red, green and blue. |
| `16bool2ascii` | Interprets two bytes can-wise and publishes them as 16 boolean values to mqtt |
| *uint* | |
| `uint82ascii` | one uint8 in the CAN-Frame to one uint8 as string in the mqtt payload |
| `4uint82ascii` | four uint8 in the CAN-Frame to four uint8 as string seperated by spaces in the mqtt payload. |
| `8uint82ascii` | eight uint8 in the CAN-Frame to eight uint8 as string seperated by spaces in the mqtt payload. |
| `uint162ascii` | one uint16 in the CAN-Frame to one uint16 as string in the mqtt payload |
| `4uint162ascii` | four uint16 in the CAN-Frame to four uint16 as string seperated by spaces in the mqtt payload. |
| `uint322ascii` | one uint32 in the CAN-Frame to one uint32 as string in the mqtt payload |
| `2uint322ascii` | two uint32 in the CAN-Frame to two uint32 as string seperated by spaces in the mqtt payload. |
| `uint642ascii` | one uint64 in the CAN-Frame to one uint64 as string in the mqtt payload |
| *int* | |
| `int82ascii` | one int8 in the CAN-Frame to one int8 as string in the mqtt payload |
| `4int82ascii` | four int8 in the CAN-Frame to four int8 as string seperated by spaces in the mqtt payload. |
| `8int82ascii` | eight int8 in the CAN-Frame to eight int8 as string seperated by spaces in the mqtt payload. |
| `int162ascii` | one int16 in the CAN-Frame to one int16 as string in the mqtt payload |
| `4int162ascii` | four int16 in the CAN-Frame to four int16 as string seperated by spaces in the mqtt payload. |
| `int322ascii` | one int32 in the CAN-Frame to one int32 as string in the mqtt payload |
| `2int322ascii` | two int32 in the CAN-Frame to two int32 as string seperated by spaces in the mqtt payload. |
| `int642ascii` | one int64 in the CAN-Frame to one int64 as string in the mqtt payload |
| convertmode | description |
|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `none` | does not convert anything. It just takes a bunch of bytes and hands it over to the other side. If you want to send strings, this will be your choice. If you have a mqtt payload that is longer than eight bytes, only the first eight bytes will be send via CAN. |
| `bytecolor2colorcode` | Converts an bytearray of 3 bytes to hexadecimal colorcode |
| `pixelbin2ascii` | This mode was designed to address colorized pixels. MQTT-wise you can insert a string like "<0-255> #RRGGBB" which will be converted to 4 byte on the CAN-BUS the first byte will be the number of the LED 0-255 and bytes 1, 2, 3 are the color of red, green and blue. |
| `16bool2ascii` | Interprets two bytes can-wise and publishes them as 16 boolean values to mqtt |
| *uint* | |
| `uint82ascii` | one uint8 in the CAN-Frame to one uint8 as string in the mqtt payload |
| `4uint82ascii` | four uint8 in the CAN-Frame to four uint8 as string seperated by spaces in the mqtt payload. |
| `8uint82ascii` | eight uint8 in the CAN-Frame to eight uint8 as string seperated by spaces in the mqtt payload. |
| `uint162ascii` | one uint16 in the CAN-Frame to one uint16 as string in the mqtt payload |
| `4uint162ascii` | four uint16 in the CAN-Frame to four uint16 as string seperated by spaces in the mqtt payload. |
| `uint322ascii` | one uint32 in the CAN-Frame to one uint32 as string in the mqtt payload |
| `2uint322ascii` | two uint32 in the CAN-Frame to two uint32 as string seperated by spaces in the mqtt payload. |
| `uint642ascii` | one uint64 in the CAN-Frame to one uint64 as string in the mqtt payload |
| *int* | |
| `int82ascii` | one int8 in the CAN-Frame to one int8 as string in the mqtt payload |
| `4int82ascii` | four int8 in the CAN-Frame to four int8 as string seperated by spaces in the mqtt payload. |
| `8int82ascii` | eight int8 in the CAN-Frame to eight int8 as string seperated by spaces in the mqtt payload. |
| `int162ascii` | one int16 in the CAN-Frame to one int16 as string in the mqtt payload |
| `4int162ascii` | four int16 in the CAN-Frame to four int16 as string seperated by spaces in the mqtt payload. |
| `int322ascii` | one int32 in the CAN-Frame to one int32 as string in the mqtt payload |
| `2int322ascii` | two int32 in the CAN-Frame to two int32 as string seperated by spaces in the mqtt payload. |
| `int642ascii` | one int64 in the CAN-Frame to one int64 as string in the mqtt payload |


## Unidirectional Mode
Normally can2mqtt works in bidirectional mode, that means all messages von can are send to mqtt and vice versa. If you wish you can run can2mqtt in a unidirectional mode to only send messages from can to mqtt or only mqtt to can. To do so you have to use the flag `-d` with one fo the following settings:

|dirMode|effect|
|--|--|
|0|bidirectional mode, messages will be send from can to mqtt and vice versa |
|1|unidirectional mode, messages will only be send from CAN-Bus to mqtt broker|
|2|unidirectional mode, messages will only be send from mqtt broker to the CAN-Bus|
| dirMode | effect |
|---------|---------------------------------------------------------------------------------|
| 0 | bidirectional mode, messages will be send from can to mqtt and vice versa |
| 1 | unidirectional mode, messages will only be send from CAN-Bus to mqtt broker |
| 2 | unidirectional mode, messages will only be send from mqtt broker to the CAN-Bus |

## Add your own convert-Mode
I noticed people forking this repo and adding their own convert-Modes (which is great by the way). I wanted to make life
for you a bit easier and added some code-stubs in the repo to quickly write your own convert-Mode.
40 changes: 40 additions & 0 deletions src/convertfunctions/yourmode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package convertfunctions

import (
"errors"
"github.com/brutella/can"
)

const mockErr string = "I am just mockup-code and not supposed to be actually used, implement something useful here"

func YourModeToCan(input []byte) (can.Frame, error) {
/*
This is your area to create your convertMode (Receive MQTT, convert to CAN).
You can find the payload of the received MQTT-Message
in the []byte input. You can craft your returning can-Frame here. It does not make sense to set the ID,
it will be overwritten. You can also return an error, the Frame is not sent in that case.
As an example you could use the following code to implement the "none" convert-Mode.
var returner [8]byte
var i uint8 = 0
for ; int(i) < len(input) && i < 8; i++ {
returner[i] = input[i]
}
return can.Frame{Length: i, Data: returner}, nil
*/
return can.Frame{}, errors.New(mockErr)
}

func YourModeToMqtt(input can.Frame) ([]byte, error) {
/*
This is your area to create your convertMode (Receive CAN, convert to MQTT).
You can find the received CAN-Frame in the can.Frame input. You can craft your returning MQTT-Payload here.
You can also return an error, the MQTT-Message is not sent in that case.
As an example you could use the following code to implement the "none" convert-Mode.
return input.Data[:input.Length], nil
*/
return []byte{}, errors.New(mockErr)
}
8 changes: 8 additions & 0 deletions src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ func readC2MPFromFile(filename string) {
toCan: convertfunctions.PixelBin2AsciiToCan,
toMqtt: convertfunctions.PixelBin2AsciiToMqtt,
}
case "yourmode":
pairFromID[canID] = &can2mqtt{
canId: canID,
convMethod: convMode,
mqttTopic: topic,
toCan: convertfunctions.YourModeToCan,
toMqtt: convertfunctions.YourModeToMqtt,
}
default:
pairFromID[canID] = &can2mqtt{
canId: canID,
Expand Down

0 comments on commit 07071a6

Please sign in to comment.