# Modbus Slave/Server to Generate Read Only Tags

**URL:** <https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583>\
**Category:** 3rd Party Modules\
**Created:** [March 19, 2024, 6:45pm UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583 "2024-03-19T18:45:14Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 12, 2024, 5:20pm UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583/21 "2024-04-12T17:20:08Z")

</div>

> [@pturmel](#):
>
> However, if I were to do this ....

I've create a generic "Modbus Publish" script that eliminates the need for a second set of tags. I've publicly posted it here:

[https://www.automation-pros.com/ignition/modbusPublish.py](https://www.automation-pros.com/ignition/modbusPublish.py)

It requires the "Queue Utility" script posted here:

[https://www.automation-pros.com/ignition/queueUtil.py](https://www.automation-pros.com/ignition/queueUtil.py)

and described over here:

> [@Java concurrent queue for tag change scripts](https://forum.inductiveautomation.com/t/java-concurrent-queue-for-tag-change-scripts/82044):
>
> Continuing the discussion from [[SOLVED] Are tag Value Changed scripts running asynchronously?](https://forum.inductiveautomation.com/t/solved-are-tag-value-changed-scripts-running-asynchronously/68704/5): We've got code in our standard library that I need to log a value change on a tag and then associate various data points with that value change. The value is located in a UDT, and because this is part of our "standard" library we use for our customers, the number of tags is variable and quite possibly numerous so having a gateway tag event script isn't feasible for this solution. I was reading up on …

Both scripts rely on my Integration Toolkit's `globalVarMap()` script function, but you can rework that (not quite 1:1) to use `system.util.getGlobals()` if you must. ( **Not** recommended nor supported by me.)

Do read all of the comments in that topic and in both scripts. They need to be in the hierarchy for your global scripting project, as they are called from tag events.

A leaf project needs a gateway timer event that contains this one-liner:

```auto
modbusPublish.drainSlavePublish()

```

That timer event should use a fixed rate and a dedicated thread, in most cases. Select an interval that makes sense for your workload. Increase the size of the blocking queue (modbusPublish.py line 45) if you run this with very many tags. (It must be large enough for a flood of startup events.)

Once all of that is in place, for any tag or UDT member you wish to publish via my module, set the tag's valueChange event to this script:

```auto
def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
	modbusPublish.enqSlavePublish(tag, tagPath, previousValue, currentValue, initialChange, missedEvents)

```

Then create one of these string custom properties on the tag or UDT member:

- `publishOpcItem` : Containing the complete OPC Item Path to receive value changes. As written, must be in IA's local OPC Server, but doesn't necessarily have to use any of my drivers. The source tag can be anything.

- `publishOpcPrefix` : Containing an OPC Item Path prefix, of at least a bracketed device name, with optional unit address and memory area overrides. The source tag must have an OPC Item Path property containing a complete modbus address. The parts of the given prefix will be substituted to produce the complete target address.

Some examples for source OPC Item Path plus publish prefix:

`[device1]HRUI2345` & `[slave]2.` =\> `[slave]2.HRUI2345`

`[device1]HRUI2345` & `[slave]2.IR` =\> `[slave]2.IRUI2345`

`[device1]HRUI2345` & `[slave]IR` =\> `[slave]IRUI2345`

(Remember that IA Modbus driver defaults to unit #0 when omitted, while mine defaults to unit #1.)

The scripts above have been lightly tested in my lab.

---

<div class="post-metadata">

**Author:** ![Nick\_S](https://avatars.discourse-cdn.com/v4/letter/n/6a8cbe/32.png) [@Nick\_S](https://forum.inductiveautomation.com/u/Nick_S)\
**Post date:** [April 15, 2024, 2:51pm UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583/22 "2024-04-15T14:51:24Z")

</div>

Thanks Phil, I will look into this!

I was able to come up with a different successful method for pairing tags in folders.  
The script below is being held in the project library and called by a gateway event timer script. What are your thoughts on using this vs your method? Any Pros and cons?

```auto
# Define the source and destination tag paths
source_folder = "[default]_Gen 1_/UnitId 21/AllTags/Breaker Settings 2"
destination_folder = "[default]_Slave1_/UnitId 21/AllTags/Breaker Settings 2"

# Get all tags under the source folder
source_tags = system.tag.browseTags(parentPath=source_folder)

# Iterate through each tag and write its value to the corresponding tag in the destination folder
for tag in source_tags:
    source_tag_path = source_folder + "/" + tag.name
    destination_tag_path = destination_folder + "/" + tag.name
    source_tag_value = system.tag.read(source_tag_path).value
    system.tag.write(destination_tag_path, source_tag_value)

```

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [April 15, 2024, 2:59pm UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583/23 "2024-04-15T14:59:20Z")

</div>

Browsing every time the timer fires is brutally inefficient. Using individual tag reads and writes is even worse.

The concept is fine, but the tag lists desperately need caching, and there should only be one multi-tag read and one multi-tag write per timer event.

Some contrasts:

- Your method unconditionally reads every source tag and writes every destination tag on every timer event, while mine only writes values from tags that are starting/restarting and tags that actually change.

- My method never explicitly reads tags, because the values are handed to the script from the event.

- My method uses a single multi-value OPC write per timer event.

- My method doesn't use Ignition OPC tags pointing into the Modbus Server at all, so no excess gateway load from that.

---

<div class="post-metadata">

**Author:** ![Nick\_S](https://avatars.discourse-cdn.com/v4/letter/n/6a8cbe/32.png) [@Nick\_S](https://forum.inductiveautomation.com/u/Nick_S)\
**Post date:** [April 15, 2024, 3:00pm UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583/24 "2024-04-15T15:00:35Z")

</div>

Great info, Thanks for your response!!

---

<div class="post-metadata">

**Author:** ![Kamil\_Muza](https://avatars.discourse-cdn.com/v4/letter/k/cab0a1/32.png) [@Kamil\_Muza](https://forum.inductiveautomation.com/u/Kamil_Muza)\
**Post date:** [May 29, 2025, 1:46am UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583/25 "2025-05-29T01:46:33Z")

</div>

Not sure if this was asked some place else. Can this be done with a gateway event for a global tag change?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 29, 2025, 1:49am UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583/26 "2025-05-29T01:49:12Z")

</div>

Not sure what you mean. But my current recommendation is to use the Integration Toolkit's RePublish Tag Action. No scripting required at all.

---

<div class="post-metadata">

**Author:** ![Kamil\_Muza](https://avatars.discourse-cdn.com/v4/letter/k/cab0a1/32.png) [@Kamil\_Muza](https://forum.inductiveautomation.com/u/Kamil_Muza)\
**Post date:** [May 29, 2025, 1:10pm UTC](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583/27 "2025-05-29T13:10:19Z")

</div>

That's great. Let me give it a try. Thank you!

[Previous page](https://forum.inductiveautomation.com/t/modbus-slave-server-to-generate-read-only-tags/87583.md?page=1)
