Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/tiagocoutinho/modbus-proxy-rs

Rust version of python https://github.com/tiagocoutinho/modbus-proxy server
https://github.com/tiagocoutinho/modbus-proxy-rs

modbus modbus-tcp rust server

Last synced: 11 days ago
JSON representation

Rust version of python https://github.com/tiagocoutinho/modbus-proxy server

Awesome Lists containing this project

README

        

# Modbus TCP proxy

Many modbus devices support only one or very few clients. This proxy acts as a
bridge between the client and the modbus device. It can be seen as a layer 7
reverse proxy.
This allows multiple clients to communicate with the same modbus device.

When multiple clients are connected, cross messages are avoided by serializing
communication on a first come first served REQ/REP basis.

This project is the [Rust][rust] version of the [Python][python] based
[modbus-proxy][modbus-proxy-py] project.

I did it because it fitted my personal goal of exercising with the [Rust][rust]
programming language and it's async based [tokio] library.

The goal was to produce a robust, highly concurrent server with a low
memory footprint.

## Installation

```bash
$ cargo install modbus-proxy-rs
```

## Running the server

First, you will need write a configuration file where you specify for each
modbus device you which to control:

* modbus connection (the modbus device url)
* listen interface (to which url your clients should connect)

Configuration files can be written in YAML (*.yml* or *.yaml*) or
TOML (*.toml*).

Suppose you have a PLC modbus device listening on *plc1.acme.org:502* and
you want your clients to connect to your machine on port 9000. A YAML
configuration would look like this:

```yaml
devices:
- modbus:
url: plc1.acme.org:502 # device url (mandatory)
listen:
bind: 0:9000 # listening address (mandatory)
```

Assuming you saved this file as `modbus-config.yml`, start the server with:

```bash
$ modbus-proxy-rs -c ./modbus-config.yml
```

Now, instead of connecting your client(s) to `plc1.acme.org:502` you just need to
tell them to connect to `*machine*:9000` (where *machine* is the host where
modbus-proxy is running).

Note that the server is capable of handling multiple modbus devices. Here is a
configuration example for 2 devices:

```yaml
devices:
- modbus:
url: plc1.acme.org:502
listen:
bind: 0:9000
- modbus:
url: plc2.acme.org:502
listen:
bind: 0:9001
```

## Logging

Log levels can be adjusted by setting the `RUST_LOG` environment variable (default is `warn`):

```bash
$ RUST_LOG=debug modbus-proxy-rs -c ./modbus-config.yml
```

## Docker

This project ships with a [Dockerfile](./Dockerfile) which you can use as a
base to launch modbus-proxy inside a docker container.

First, build the docker image with:

```bash
$ docker build -t modbus-proxy .
```

Assuming you have prepared a `config.yml` in the current directory:

```yaml
devices:
- modbus:
url: plc1.acme.org:502
listen:
bind: 0:502
```

The supplied docker image by default runs the command `/modbus-proxy-rs -c /etc/modbus-proxy.yml`.
Therefore, running launching a container is as simple as:

```bash
docker run --init --rm -p 5020:502 -v $PWD/config.yml:/etc/modbus-proxy.yml modbus-proxy
```

You can supply a different configuration path (ex: `/config.yml`):

```bash
docker run --init --rm -p 5020:502 -v $PWD/config.yml:/config.yml modbus-proxy -c /config.yml
```

Now you should be able to access your modbus device through the modbus-proxy by
connecting your client(s) to `:5020`.

Note that for each modbus device you add in the configuration file you need
to publish the corresponding bind port on the host
(`-p :` argument).

## Credits

### Development Lead

* Tiago Coutinho

### Contributors

None yet. Why not be the first?

[rust]: https://www.rust-lang.org/
[python]: https://python.org/
[modbus-proxy-py]: https://github.com/tiagocoutinho/modbus-proxy
[tokio]: https://tokio.rs/