Skip to content

Commit

Permalink
interface refactor (#64)
Browse files Browse the repository at this point in the history
* Introduce new interface ConvertMode

Signed-off-by: Malte Muench <[email protected]>

* Refine ConvertMode interface doc

* Implements first convertmode (none) as interface

* Adds convertmode interface to the can2mqtt struct

* bytecolor2colorcode change to interfaced version

* mymode changed to interfaced version

* pixelbin2ascii changed to interfaced version

* 16bool2ascii into interfaced version

* int2ascii into interfaced version

* uint2ascii into interfaced version

* Use new interface for creation of convertmodes

* Remove old unused types

* Bundle all int and uint convertmodes in one row

Signed-off-by: Malte Muench <[email protected]>

* Renamings, shorter, hopefully better understandable

* Use String() of convertmodes to register convertmode

* Update README

---------

Signed-off-by: Malte Muench <[email protected]>
Co-authored-by: Malte Muench <[email protected]>
  • Loading branch information
mxmxchere and Malte Muench authored Jul 29, 2024
1 parent 11f05c9 commit ff7248f
Show file tree
Hide file tree
Showing 16 changed files with 360 additions and 558 deletions.
52 changes: 21 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,30 +54,14 @@ 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 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 |
| 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 |
| `{i}[u]int{b}2ascii` | `i` is the amount of instances of numbers in the CAN-Frame/the MQTT-message. Valid instance amounts are currently 1,2,4 and 8. Although other combinations are possible. Might be added in the future, if the need arises. `b` is the size of each number in bits. Supported values are 8,16,32 and 64. You can use either one unsigned or signed integers. This are all possible combinations: `int82ascii`, `2int82ascii`, `4int82ascii`, `8int82ascii`, `int162ascii`, `2int162ascii`, `4int162ascii`, `int322ascii`, `2int322ascii`, `int642ascii`, `uint82ascii`, `2uint82ascii`, `4uint82ascii`, `8uint82ascii`, `uint162ascii`, `2uint162ascii`, `4uint162ascii`, `uint322ascii`, `2uint322ascii`, `uint642ascii` |
|


## Unidirectional Mode
Expand All @@ -101,14 +85,20 @@ sudo ip link set vcan0 up
Now you can use your new interface `vcan0` as socket-can interface with can2mqtt.

## Debugging
To debug can2mqtts behaviour you need to be able to send and receive CAN frames and MQTT messages. For MQTT I recommend [mosquitto](https://mosquitto.org/) with its `mosquitto_pub` and `mosquitto_sub` commands. For CAN i recommend [can-utils]() with its tools `cansend` and `candump`.
## Add a convert-Mode
To debug the behaviour of can2mqtt you need to be able to send and receive CAN frames and MQTT messages. For MQTT I recommend [mosquitto](https://mosquitto.org/) with its `mosquitto_pub` and `mosquitto_sub` commands. For CAN i recommend [can-utils]() with its tools `cansend` and `candump`.

## Add a convert-Mode
If you want to add a convert-Mode think about a name. This is the name that you can later refer to when you want to
use your convert-Mode in the `can2mqtt.csv` config-file. In this example the name of the new convert-Mode is `"mymode"`.
Next, add the new convert-Mode in the [switch-case block in `src/main.go`](./src/main.go#L247). In the new case
statement you refer to two functions. One is called when a MQTT-message is received and the other one when a CAN-frame is
received. Change the contents of those functions to the behaviour that you seek for. Mockup code for `MyModeToCan` and
`MyModeToMqtt` can be found in [mymode.go](./src/mymode.go).
use your convert-Mode in the `can2mqtt.csv` config-file. Now, use the file `src/convertmode/mymode.go` as a template for your own convertmode. Copy that file to `src/convertmode/<yournewmode>.go`. Now change all occurrences of "MyMode" with your preferred Name (Lets say `YourNewMode` in this example). Note that it has to start with an upper-case letter, so that it is usable outside of this package. Next you have to write three functions (implement the `ConvertMode` interface):
1. A conversion method from CAN -> MQTT: `ToMqtt(input can.Frame) ([]byte, error)`
2. A conversion method from MQTT -> CAN: `ToCan(input []byte) (can.Frame, error)`
3. A `String() string` method that reports the name of that convertmode. This method is used in some log-messages

Your almost done, the last step is to "register" your new convertmode. To do so add the following line to [`src/main.go#L72`](./src/main.go#L72)
```go
convertModeFromString[convertmode.<YourNewMode>{}.String()] = convertmode.<YourNewMode>{}
```

Now you can use your new convertmode in your `can2mqtt.csv` config File. Use the string that your return in the `String()` function as the name of the convertmode. In the `mymode.go` code this is `"mymode"`.

Good luck & happy hacking ✌
File renamed without changes.
Loading

0 comments on commit ff7248f

Please sign in to comment.