How to set a Write-only Modbus IP Data point
-
Hi guys, I am wondering if you can help me with a little issue with a Write-only Data point inside a Modbus IP Datasource. I am trying to set the value of this data point through a scripting data source, but it doesn't work.
Through the legacy data sources page of my mango, I had tested successfully with the write data command, but when I create a data point with the type "Write-only" and try to set a value to it, it doesn't work, so I don't know how I can set Write-only data points to write on my device registers.
Let me know if I make myself clear and if you can help me with this or give me some ideas. Thanks!
-
Hi @jmartinez0 ,
Firstly are you getting any error events ( in the events table of Mango instance) which indicate whether the write command was not successful i.e 01, 02, 03, 04 exception codes. (illegal function, illegal data address, illegal data value, salve device failure) ?
Secondly, I am just wondering are you checking the write command through a read also to check if it actually went through or not?
If I remember correctly, if you set it as write-only then the datapoint will not be polling (reading) the register and the value should show the last written value in the point. The latest value will be in cache until the value saving event has been triggered by Mango to the database. i.e if you reset Mango instance before it has written it to the database then the value will not be saved to the database.
IAS staff can correct me if I am wrong here.
If you want the point to poll also the register then set it as settable and it will also be polling ( reading ) the datapoint also.
-
Hi @jmartinez0
As Thomas said we will need the error code to help debug the issue. There should be a log in the ma.log file every time it fails to write the point.
-
Hi jmartinez0, welcome to the forum!
Thomas and Craig's suggestions will likely be helpful if the issue is to do with the Modbus IP side of things, which it may be. Have you tried setting the write only point through the data point details page to extricate the question from scripting?
If the question is only about through scripts, it would be helpful to see the script and its permissions.
-
Hi guys, thanks for your replies. Let me provide you more details.
1.- I am trying to control this device:
This device is an ATS controller that helps with load sharing and a lot of stuff. This device talks Modbus TCP/IP and have a very large list of Modbus registers, like the one with the offset 4104, that is indicated as "System Control Key" and its complement in the offset 4015 indicated as "System Control Key Compliment", both defined as Write-only registers (Number 8 and 9 in the list).
.
2.- I have to set these two registers using the following table to trigger functions in the device.
3.- The instructions of the device says this about the control:
" ***Control is performed by sending System Control Keys to the module, and also sending the bitwise opposite (or one’s complement) of the control key to another register ‘in the same write operation’ for security.
To Modbus register 4104 (decimal) write the system control key as below
To Modbus register 4105 (decimal) write the compliment of the system control key as belowBoth of these registers MUST be written to the controller at the SAME TIME using the SAME MODBUS WRITE
COMMAND.A table of Control Keys and the one's complement of the keys is included overleaf.*** "
"4.- But I figured a solution to test it with the Modbus "Write data" feature in the legacy data sources page at my Mango. (I construct the decimal value that results from joining together the key and its compliment). And IT WORKS! Yesterday I was able to trigger functions using this:
5.- Then I proceeded to create a data point inside my Modbus IP data source that triggers this 4104 offset register and a Write-only type, as the following pic:
6.- My intention is to set this data point from a view that I designed by clicking the button in the SVG. But it doesn't work... I try to use something like:
<div ma-selector="#ats_x5F_btn_x5F_manual" ng-click="$ctrl.controllerClick($ctrl.data.atsSistemControlKey, 2339796105)"></div>
with the method
this.controllerClick = (variable, value) => { variable.value = value; };
I tried to use a virtual data point and this method set the value successfully. But it doesn't work with the Modbus Write-only data point.
7.- I did test the Phil suggestion, to set the data point from the data point details page, but it doesn't work either, so I think that there is a special way to set Write-only data points or something else.
8.- I also tried to use a virtual data point that set the Modbus data point with a scripting data source, but it says to me this error:
"Permissions failure setting point DP_238a7211-42a8-469c-8b53-444fdc6fd9c2", this XID is the Modbus IP system control key data point.
9.- When I try to set the data point as settable, it triggers an error saying "Unreliable data point" or something like this, forgive me, tomorrow I can test with the equipment and send you the exact error logs so you can help me.
Sorry for this very large message, but I think is necessary to set the context.
-
@jmartinez0 said in How to set a Write-only Modbus IP Data point:
5.- Then I proceeded to create a data point inside my Modbus IP data source that triggers this 4104 offset register and a Write-only type, as the following pic:
I suspect that due to you are running into a problem with number conversion. If you create a numeric data point (which your screenshot shows) then the value you set to the data point will be coerced into a 64-bit IEEE 754 number. When this is written out to the Modbus device the binary representation will be different to the integer you input, and almost certainly the value written to register 4015 will not be the compliment of register 4014 anymore.
If you check the checkbox "Multistate numeric" the value will instead be coerced into 32-bit signed integer, which you can get to work but will require a little manipulation with the value you set to the point.
@jmartinez0 said in How to set a Write-only Modbus IP Data point:
6.-
with the method
this.controllerClick = (variable, value) => {
variable.value = value;
};I tried to use a virtual data point and this method set the value successfully. But it doesn't work with the Modbus Write-only data point.
This will absolutely not work for any type of data point assuming
variable
is a data point. You have to usevariable.setValue(value);
@jmartinez0 said in How to set a Write-only Modbus IP Data point:
I also tried to use a virtual data point that set the Modbus data point with a scripting data source, but it says to me this error:
"Permissions failure setting point DP_238a7211-42a8-469c-8b53-444fdc6fd9c2", this XID is the Modbus IP system control key data point.Data points have settings that restrict which role is allowed to set them. You must give your script the appropriate role.
I will get back to you shortly with my proposed solution.
-
OK try changing your point to multistate and adding something like this to your controller -
writeWithCompliment(point, value) { const littleEndian = false; const buffer = new ArrayBuffer(4); // 4 bytes or 32 bits const view = new DataView(buffer); const valueCompliment = value ^ 0xFFFF; view.setUint16(0, value, littleEndian); view.setUint16(2, valueCompliment, littleEndian); return point.setValue(view.getInt32(0, littleEndian)); }
You should then just able able to call
$ctrl.writeWithCompliment(point, 35700)
etc from your markup. -
Hi guys, I forget to feedback on your support, the solution you give to me worked like a charm!
Thank you very much!