{"id":23469905,"url":"https://github.com/vapor-ware/synse-modbus-ip-plugin","last_synced_at":"2025-08-10T08:04:31.749Z","repository":{"id":32119272,"uuid":"131641318","full_name":"vapor-ware/synse-modbus-ip-plugin","owner":"vapor-ware","description":"Modbus over TCP/IP plugin for Synse","archived":false,"fork":false,"pushed_at":"2023-09-12T19:37:14.000Z","size":444,"stargazers_count":2,"open_issues_count":6,"forks_count":3,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-14T16:45:45.634Z","etag":null,"topics":["modbus-tcp","synse","synse-plugin"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vapor-ware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-30T20:07:29.000Z","updated_at":"2021-12-13T22:52:16.000Z","dependencies_parsed_at":"2024-06-19T19:01:41.827Z","dependency_job_id":"c5320fef-8658-4624-b39e-0d96e63f63fd","html_url":"https://github.com/vapor-ware/synse-modbus-ip-plugin","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/vapor-ware/synse-modbus-ip-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vapor-ware%2Fsynse-modbus-ip-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vapor-ware%2Fsynse-modbus-ip-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vapor-ware%2Fsynse-modbus-ip-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vapor-ware%2Fsynse-modbus-ip-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vapor-ware","download_url":"https://codeload.github.com/vapor-ware/synse-modbus-ip-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vapor-ware%2Fsynse-modbus-ip-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269693593,"owners_count":24460248,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["modbus-tcp","synse","synse-plugin"],"created_at":"2024-12-24T15:36:48.843Z","updated_at":"2025-08-10T08:04:31.727Z","avatar_url":"https://github.com/vapor-ware.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://build.vio.sh/buildStatus/icon?job=vapor-ware/synse-modbus-ip-plugin/master)](https://build.vio.sh/blue/organizations/jenkins/vapor-ware%2Fsynse-modbus-ip-plugin/activity)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fvapor-ware%2Fsynse-modbus-ip-plugin.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvapor-ware%2Fsynse-modbus-ip-plugin?ref=badge_shield)\n![GitHub release](https://img.shields.io/github/release/vapor-ware/synse-modbus-ip-plugin.svg)\n\n# Synse Modbus TCP/IP Plugin\n\nA plugin for Modbus over TCP/IP for [Synse Server][synse-server].\n\nThis plugin is a general-purpose plugin, meaning that there are no device-specific\nimplementations for this plugin. Instead, a set of default handlers are provided. Registering\ndevices with the plugin is then simply a matter of passing in the correct configuration.\n\n\u003e Note: By default, the plugin SDK will search for a device handler based on the name of the\n\u003e device type. Here, the device handlers for each device type should be manually overridden\n\u003e in order to get the functionality required for those devices/outputs. See the supported\n\u003e handlers and example config, below.\n\n## Getting Started\n\n### Getting\n\nYou can install the modbus plugin via a [release](https://github.com/vapor-ware/synse-modbus-ip-plugin/releases)\nbinary or via Docker image\n\n```\ndocker pull vaporio/modbus-ip-plugin\n```\n\nIf you wish to use a development build, fork and clone the repo and build the plugin\nfrom source.\n\n### Running\n\nThe modbus plugin comes with a set of sane [default plugin configurations](config.yml), so\nyou should be able to run the plugin without much additional configuration. You will, however\nneed to provide device configurations.\n\nThis repo includes a [compose file](docker-compose.yml) which provides a basic example of how\nto run the modbus plugin with Synse Server and how to configure devices with it. There is no\nemulated modbus backend, so all device reads/writes will fail with this compose file, but it\ncan serve as a good point of reference.\n\nTo run, simply:\n\n```bash\ndocker-compose up -d\n```\n\nYou can then use Synse's HTTP API or the [Synse CLI][synse-cli] to query Synse for plugin data.\n\n## Modbus Plugin Configuration\n\nPlugin and device configuration are described in detail in the [SDK Documentation][sdk-docs].\n\nThere is an additional config scheme specific to this plugin for the contents of a configured\ndevice's `data` field. Device `data` may be specified in two places (the prototype config and\nthe instance config sections). The data scheme describes the resulting unified config from\nboth sources.\n\nAn example:\n\n```yaml\ndevices:\n- type: temperature\n  handler: input_register\n  data:\n    host: 127.0.0.1\n    port: 502\n    slave_id: 3\n    timeout: 5s\n    failOnError: false\n  instances:\n  - info: Temperature Sensor 1\n    output: temperature\n    data:\n      address: 500\n      width: 2\n      type: f32\n  - info: Temperature Sensor 2\n    output: temperature\n    data:\n      address: 502\n      width: 2\n      type: f32\n```\n\nFor `Temperature Sensor 1`, the unified data config is:\n\n```yaml\nhost: 127.0.0.1\nport: 502\nslave_id: 3\ntimeout: 5s\nfailOnError: false\naddress: 500\nwidth: 2\ntype: f32\n```\n\n| Field         | Required            | Type   | Description                                         |\n| ------------- | ------------------- | ------ | --------------------------------------------------- |\n| `host`        | yes                 | string | The hostname/ip of the modbus server to connect to. |\n| `port`        | yes                 | int    | The port number for the modbus server to connect to. |\n| `slaveId`     | yes                 | int    | The modbus slave id for the device. |\n| `address`     | yes                 | int    | The register address which holds the output reading. |\n| `width`       | yes                 | int    | The number of registers to read, starting from the `address`. |\n| `type`        | yes                 | string | The type of the data held in the registers (see below). |\n| `timeout`     | no (default: 5s)    | string | The duration to wait for a modbus request to resolve. |\n| `failOnError` | no (default: false) | bool   | Fail the entire device read if a single output read fails. |\n\n\u003e By default, `failOnError` is false, so a failure to read a single register will cause that\n\u003e failure to be logged, but will *not* cause the entire bulk read to fail. If this is set to true,\n\u003e all registers must be successfully read in order for the read to complete.\n\nThe values that are supported in the `type` field are as follows:\n\n| Type             | Description             |\n| ---------------- | ----------------------- |\n| `u32`, `uint32`  | unsigned 32-bit integer |\n| `u64`, `uint64`  | unsigned 64-bit integer |\n| `s32`, `int32`   | signed 32-bit integer |\n| `s64`, `int64`   | signed 64-bit integer |\n| `f32`, `float32` | 32-bit floating point number |\n| `f64`, `float64` | 64-bit floating point number |\n\nNote that typically, an `*32` type will have width 2 while an `*64` type will have width 4.\n\n### Outputs\n\nOutputs are referenced by name. A single device may have more than one instance\nof an output type. A value of `-` in the table below indicates that there is no value\nset for that field. The *custom* section describes outputs which this plugin defines\nwhile the *built-in* section describes outputs this plugin uses which are [built-in to\nthe SDK](https://synse.readthedocs.io/en/latest/sdk/concepts/reading_outputs/#built-ins).\n\n**Custom**\n\n| Name              | Description                                               | Unit     | Type       | Precision |\n| ----------------- | --------------------------------------------------------- | :------: | ---------- | :-------: |\n| gallonsPerMin     | A measure of volumetric flow rate, in gallons per minute. | gpm      | `flow`     | 4         |\n| inchesWaterColumn | A measure of pressure, in inches of water column.         | inch wc  | `pressure` | 8         |\n\n**Built-in**\n\nSince this is a general-purpose plugin, any built-in unit may be specified via device\nconfiguration. See the link above for complete set of built-in outputs.\n\n### Device Handlers\n\nDevice Handlers are referenced by name.\n\n| Name             | Description                                  | Outputs | Read  | Write | Bulk Read | Listen |\n| ---------------- | -------------------------------------------- | ------- | :---: | :---: | :-------: | :----: |\n| coil             | A handler that reads from coils.             | any     | ✗     | ✓     | ✓         | ✗      |\n| holding_register | A handler that reads from holding registers. | any     | ✗     | ✓     | ✓         | ✗      |\n| input_register   | A handler that reads from input registers.   | any     | ✗     | ✗     | ✓         | ✗      |\n\n### Write Values\n\nThis plugin supports the following values when writing to a device via a handler.\n\n| Handler          | Write Action  | Write Data   | Description                                         |\n| ---------------- | :-----------: | :----------: | --------------------------------------------------- |\n| coil             | `-`           | `0`, `false` | Writing a zero (0x00) value to the register.        |\n|                  | `-`           | `1`, `true`  | Writing a one value (0xff00) value to the register. |\n| holding_register | `-`           | `uint16`     | The data (uint16) to write to the register.         |\n\n### Example Device Configuration\n\nThis section shows an example configuration for an eGauge 4115 Power Metering device. It exposes\nreadings for voltage and frequency via this config.\n\n```yaml\n# Sample Config\n# -------------\n\n# The config scheme version\nversion: 3\n\n# Define the device prototype(s) and their instance(s).\ndevices:\n  - type: power\n    context:\n      model: egauge 4115\n    handler: input_register\n    data:\n      host: 127.0.0.1\n      port: 502\n      slave_id: 3\n    instances:\n      # RMS Voltage\n      - info: Leg 1 to neutral RMS voltage\n        output: voltage\n        data:\n          address: 500\n          width: 2\n          type: f32\n      - info: Leg 2 to neutral RMS voltage\n        output: voltage\n        data:\n          address: 502\n          width: 2\n          type: f32\n\n      # Line Frequency\n      - info: L1 line frequency\n        output: frequency\n        data:\n          address: 600\n          width: 2\n          type: f32\n      - info: L2 line frequency\n        output: frequency\n        data:\n          address: 602\n          width: 2\n          type: f32\n```\n\n## Compatibility\n\nBelow is a table describing the compatibility of plugin versions with Synse platform versions.\n\n|             | Synse v2 | Synse v3 |\n| ----------- | -------- | -------- |\n| plugin v1.x | ✓        | ✗        |\n| plugin v2.x | ✗        | ✓        |\n\n## Troubleshooting\n\n### Debugging\n\nThe plugin can be run in debug mode for additional logging. This is done by:\n\n- Setting the `debug` option  to `true` in the plugin configuration YAML ([config.yml](config.yml))\n\n  ```yaml\n  debug: true\n  ```\n\n- Passing the `--debug` flag when running the binary/image\n\n  ```\n  docker run vaporio/modbus-ip-plugin --debug\n  ```\n\n- Running the image with the `PLUGIN_DEBUG` environment variable set to `true`\n\n  ```\n  docker run -e PLUGIN_DEBUG=true vaporio/modbus-ip-plugin\n  ```\n\n### Developing\n\nA [development/debug Dockerfile](Dockerfile.dev) is provided in the project repository to enable\nbuilding image which may be useful when developing or debugging a plugin. Unlike the slim `scratch`-based\nproduction image, the development image uses an ubuntu base, bringing with it all the standard command line\ntools one would expect. To build a development image:\n\n```\nmake docker-dev\n```\n\nThe built image will be tagged using the format `dev-{COMMIT}`, where `COMMIT` is the short commit for\nthe repository at the time. This image is not published as part of the CI pipeline, but those with access\nto the Docker Hub repo may publish manually.\n\n## Contributing / Reporting\n\nIf you experience a bug, would like to ask a question, or request a feature, open a\n[new issue](https://github.com/vapor-ware/synse-modbus-ip-plugin/issues) and provide as much\ncontext as possible. All contributions, questions, and feedback are welcomed and appreciated.\n\n## License\n\nThe Synse Modbus-IP Plugin is licensed under GPLv3. See [LICENSE](LICENSE) for more info.\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fvapor-ware%2Fsynse-modbus-ip-plugin.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvapor-ware%2Fsynse-modbus-ip-plugin?ref=badge_large)\n\n[synse-cli]: https://github.com/vapor-ware/synse-cli\n[synse-server]: https://github.com/vapor-ware/synse-server\n[plugin-dockerhub]: https://hub.docker.com/r/vaporio/modbus-ip-plugin\n[plugin-release]: https://github.com/vapor-ware/synse-modbus-ip-plugin/releases\n[sdk-docs]: https://synse.readthedocs.io/en/latest/sdk/intro/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvapor-ware%2Fsynse-modbus-ip-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvapor-ware%2Fsynse-modbus-ip-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvapor-ware%2Fsynse-modbus-ip-plugin/lists"}