{"id":19610464,"url":"https://github.com/valiot/snapex7","last_synced_at":"2025-04-27T21:31:41.733Z","repository":{"id":57549886,"uuid":"143184715","full_name":"valiot/snapex7","owner":"valiot","description":"Elixir wrapper for Snap7","archived":false,"fork":false,"pushed_at":"2025-03-15T05:13:04.000Z","size":356,"stargazers_count":14,"open_issues_count":0,"forks_count":5,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-24T11:49:54.669Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/valiot.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}},"created_at":"2018-08-01T17:00:10.000Z","updated_at":"2025-03-15T05:13:15.000Z","dependencies_parsed_at":"2022-09-10T04:26:02.946Z","dependency_job_id":null,"html_url":"https://github.com/valiot/snapex7","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fsnapex7","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fsnapex7/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fsnapex7/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valiot%2Fsnapex7/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/valiot","download_url":"https://codeload.github.com/valiot/snapex7/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251212027,"owners_count":21553394,"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","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":[],"created_at":"2024-11-11T10:29:28.182Z","updated_at":"2025-04-27T21:31:41.353Z","avatar_url":"https://github.com/valiot.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/valiot/snapex7/master/assets/images/snapex7-logo.png\" alt=\"Snapex7 Logo\" width=\"512\" height=\"201\" /\u003e\n\u003c/div\u003e\n\n***\n\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/valiot/snapex7/master/assets/images/valiot-logo-blue.png\" alt=\"Valiot Logo\" width=\"384\" height=\"80\" /\u003e\n\u003c/div\u003e\n\u003cbr\u003e\nSnapex7 is an Elixir wrapper for the Snap7 library. Snap7 i san open source, 32/64 bit, multi-platform Ethernet communication suite for interfacing natively with Siemens S7 PLCs.\n\n * Snapex7 is developer for snap7 1.4.2 and Elixir 1.8.1. It is tested on:\n    * Ubuntu\n    * MacOS\n    * Nerves\n\n  * **Note** Currently only the **Client implementation as synchronous** of Snap7 is available. Future implementations can be found in our [TODO](#todo) section.\n\n## Content\n\n  * [Installation](#installation)\n  * [Target Compatibility](#target-compatibility)\n  * [Using Snapex7](#using-snapex7)\n    * [Connection functions](#connection-functions)\n    * [Data IO functions](#data-io-functions)\n    * [Error format](#error-format)\n    * [Types](#types)\n  * [Further Documentation and Examples](#further-documentation-and-examples)\n  * [Contributing to this Repo](#contributing-to-this-repo)\n  * [TODO](#todo)\n\n## Installation\n\nThe package can be installed by adding `snapex7` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:snapex7, \"~\u003e 0.1.2\"}\n  ]\nend\n```\nFetch the dependency by running `mix deps.get` in your terminal.\n\n## Target Compatibility\nMany hardware components equipped with an Ethernet port can communicate via the S7 protocol. \nCheck compatibility with the component that you are using:\n *  **Snap7** full compatibility documentation can be found at pg.33 [Snap7-refman.pdf](https://github.com/valiot/snap7/blob/a1845454f5f16f3b127b987807f1cbc59205db70/doc/Snap7-refman.pdf)\n\nHere is a summary compatibility table from the documentation above:\n\n\u003cimg src=\"https://raw.githubusercontent.com/valiot/snapex7/master/assets/images/compatibility.png\" alt=\"Compatibility\" /\u003e\n\n## Using Snapex7\n\nStart a `Snapex7.Client` and connect it to the PLC's IP, where:\n  *  **port**: C port process\n  *  **controlling_process**: where events get sent\n  *  **queued_messages**: queued messages when in passive mode **(WIP)**.\n  *  **ip**: the address of the server\n  *  **rack**: the rack of the server.\n  *  **slot**: the slot of the server.\n  *  **is_active**: active or passive mode **(WIP)**.\n\n```elixir\niex\u003e {:ok, pid} = Snapex7.Client.start_link()\niex\u003e Snapex7.Client.connect_to(pid, ip: \"192.168.0.1\", rack: 0, slot: 1)\n```  \n### Connection functions\n  * **Connect to a S7 server**.\n  The following options are available:\n    * `:active` - (`true` or `false`) specifies whether data is received as\n       messages or by calling \"Data I/O functions\".\n    * `:ip` - (string) PLC/Equipment IPV4 Address (e.g., \"192.168.0.1\")\n    * `:rack` - (int) PLC Rack number (0..7).\n    * `:slot` - (int) PLC Slot number (1..31).\n\n```elixir\niex\u003e :ok = Snapex7.Client.connect_to(pid, ip: \"192.168.0.1\", rack: 0, slot: 1)\n```\n\n  * **Disconnects** gracefully the Client from the PLC.\n```elixir\niex\u003e :ok = Snapex7.Client.disconnect(pid)\n``` \n\n  * **Get connected** returns the connection status.\n```elixir\niex\u003e {:ok, boolean} = Snapex7.Client.get_connected(pid)\n``` \n\n### Data IO functions\n\n  * **Reads a data area** from a PLC.\nThe following options are available:\n    * `:area` - (atom) Area Identifier. See [@area_types](#types).\n    * `:db_number` - (int) DataBase number, if `area: :DB` otherwise is ignored.\n    * `:start` - (int) An offset to start.\n    * `:amount` - (int) Amount of words to read/write.\n    * `:word_len` - (atom) Word size See [@word_types](#types).\n\n```elixir\n  iex\u003e {:ok, resp_binary} =\n          Snapex7.Client.read_area(pid,\n            area: :DB,\n            word_len: :byte,\n            start: 2,\n            amount: 4,\n            db_number: 1\n          )\n```\n\n  * **Write a data area** from a PLC..\nThe same options of `Snapex.Client.read_area` are available here plus:\n    * `:data` - (atom) buffer to write.\n\n```elixir\n  iex\u003e :ok =\n          Snapex7.Client.write_area(pid,\n            area: :DB,\n            word_len: :byte,\n            start: 2,\n            amount: 4,\n            db_number: 1,\n            data: \u003c\u003c0x42, 0xCB, 0x00, 0x00\u003e\u003e\n          )\n```\n  * Lean functions of `Snapex.Client.read_area` and `Snapex.Client.write_area` for different types of ... are implemented:\n    * `db_read` \u0026 `db_write`: for PLC Database.\n    * `ab_read` \u0026 `ab_write`: for PLC process outputs.\n    * `eb_read` \u0026 `eb_write`: for PLC process inputs.\n    * `mb_read` \u0026 `mb_write`: for PLC merkers.\n    * `tm_read` \u0026 `tm_write`: for PLC timers.\n    * `ct_read` \u0026 `ct_write`: for PLC counters.\n\n  * **Write and Read different kinds of variables** from a PLC in a single call. It can do so with it can read DB, inputs, outputs, Merkers, Timers and Counters.\n```elixir\n  iex\u003e data1 = %{\n      area: :DB,\n      word_len: :byte,\n      db_number: 1,\n      start: 2,\n      amount: 4,\n      data: \u003c\u003c0x42, 0xCB, 0x20, 0x10\u003e\u003e\n    }\n\n  iex\u003e data2 = %{\n      area: :PA,\n      word_len: :byte,\n      db_number: 1,\n      start: 0,\n      amount: 1,\n      data: \u003c\u003c0x0F\u003e\u003e\n    }\n  iex\u003e r_data1 = %{\n      area: :DB,\n      word_len: :byte,\n      db_number: 1,\n      start: 2,\n      amount: 4\n    }\n\n  iex\u003e r_data2 = %{\n      area: :PA,\n      word_len: :byte,\n      db_number: 1,\n      start: 0,\n      amount: 1\n    }\n\n  iex\u003e :ok = Snapex7.Client.write_multi_vars(pid, data: [data1, data2])\n  iex\u003e {:ok, [binary]} = Snapex7.Client.read_multi_vars(pid, data: [r_data1, r_data2])\n```\n\n### Error format\nWhen a response returns an error, it will have the following format:\n```elixir\niex\u003e {:error, %{eiso: nil, es7: nil, etcp: 113}}\n```\n  * **eiso**: returns an atom with the ISO TCP error.\n  * **es7**: returns an atom with the S7 protocol error.\n  * **etcp**: returns an int TCP error or nil (Depends on your OS). Example: see [TCP_error_info](https://gist.github.com/gabrielfalcao/4216897) for Ubuntu OS.\n\nSee [Snap7-refman.pdf](https://github.com/valiot/snap7/blob/a1845454f5f16f3b127b987807f1cbc59205db70/doc/Snap7-refman.pdf) pg.252 for further error info.\n\n### Types\nArguments definition for each particular memory block:\n\n```elixir\n  @block_types [\n    OB: 0x38,  # Organization block\n    DB: 0x41,  # Data block\n    SDB: 0x42, # System data block\n    FC: 0x43,  # Function\n    SFC: 0x44, # System function\n    FB: 0x45,  # Functional block\n    SFB: 0x46  # System functional block\n  ]\n\n  @connection_types [\n    PG: 0x01,      # Programming console\n    OP: 0x02,      # Siemens HMI panel\n    S7_basic: 0x03 # Generic data transfer connection\n  ]\n\n  @area_types [\n    PE: 0x81, # Process Inputs\n    PA: 0x82, # Process Outputs\n    MK: 0x83, # Merkers\n    DB: 0x84, # DB\n    CT: 0x1C, # Counters\n    TM: 0x1D  # Timers\n  ]\n\n  @word_types [\n    bit: 0x01,\n    byte: 0x02,\n    word: 0x04,\n    d_word: 0x06,\n    real: 0x08,\n    counter: 0x1C,\n    timer: 0x1D\n  ]\n```\n\n## Further documentation and examples\nSnapex7 has further client functions implementation which can be found at [Snapex7 Hexdocs](https://hexdocs.pm/snapex7).\n  * Client function types in [Hexdocs](https://hexdocs.pm/snapex7):\n    * Administrative\n    * Data IO\n    * Directory\n    * Block oriented\n    * Date/Time\n    * System Info\n    * PLC Control\n    * Security\n    * Low level\n    * Miscellaneous\n\n  * **Additional examples of usage** can be found in the testing section of the project \n[/test/s7_client_text/](https://github.com/valiot/snapex7/tree/master/test/s7_client_test)\n    * **Note**: Tests where writen with a local preconfigured PLC.\n\n  * **Snap7** source code and documentation can be found at [Snap7-refman.pdf](https://github.com/valiot/snap7/blob/a1845454f5f16f3b127b987807f1cbc59205db70/doc/Snap7-refman.pdf)\n\n## Contributing to this Repo\n  * Fork our repository on github.\n  * Fix or add what is needed.\n  * Commit to your repository\n  * Issue a github pullrequest.\n\nIf you wish to clone this Repo use:\n```\ngit clone --recursive git@github.com:valiot/snap7.git\n```\n\n## License\n\n  See [LICENSE](./LICENSE).\n  \n## TODO\n  * **Better handling c code**\n  * **Server implementation**\n  * **Partner implementation**\n  * **Asynchronous Client implementation**\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaliot%2Fsnapex7","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvaliot%2Fsnapex7","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvaliot%2Fsnapex7/lists"}