Skip to main content

Modbus TCP Server / Galaxy panel gateway

This tutorial will guide you in setting up HSYCO as a gateway to enable communication between Modbus TCP and one of the security panels integrated into HSYCO. HSYCO will act as a Modbus TCP server.

To access HSYCO Manager open a browser and type the URL:

https://192.168.1.50/hsycoserver/manager

note

The IP address and the URLKey written above are the default ones

Add a security control panel I/O Server

Follow these steps of this tutorial:

Add a Galaxy I/O Server

Remember to set the Galaxy I/O Server attribute startupevents to true.

Add a Modbus Tcp server I/O Server

1. Go back to the Manager splash screen

2. Click on Settings.

3. Add a new I/O server.

4. Click the type input field.

5. Type "mod"

6. Select Modbus TCP Server.

7. Select the name input field.

8. Assign a unique name to the I/O server, for example "mserver"

9. Click the port input field.

10. Type "502", the default Modbus port.

11. Click "Confirm"

12. Click on the Options icon.

13. Add a new option.

14. Click the option field.

15. Select "eventslog".

16. Click the value input field.

17. Select "true".

18. Click "Confirm".

19. Close the Options popup.

20. Click "Save Apply & restart".

21. Confirm by clicking the Save button.

Check the connection status

1. Let’s now check the connection status of the I/O Servers we just added. Go back to the Manager splash screen and click on Status Browser.

2. Click the "Filter" field to search for the connection datapoint.

3. Type "galaxy.conn"

4. If the datapoint ‘galaxy.connection’ is equal to ‘online,’ this means that the Galaxy I/O server is successfully connected to HSYCO.

EVENTS scripting

1. From the Manager splash screen select Code Editor.

2. Click "New Events File"

3. Give a name to your script, for example: "gateway.txt"

4. Click "New File"

5. Now it's time to write some lines of code.

For further information about the logic of EVENTS programming, read EVENTS programming quickstart

Let's start with some simple functions:

#copy the status of a zone of the security panel to a Modbus register (Holding Register)
io galaxy.z1.alarm = 1 : io mserver.1.1.hr = "ushort:"1
io galaxy.z1.alarm = 0 : io mserver.1.1.hr = "ushort:"0

#copy the status of a zone of the security panel to a Modbus register (Coil)
io galaxy.z2.alarm = 1 : io mserver.1.10.co = "bit:"1
io galaxy.z2.alarm = 0 : io mserver.1.10.co = "bit:"0

#when a Modbus register is set to 1/0, arm/disarm a security panel program
io mserver.1.20.hr = 1 : io galaxy.g1.armed = tot
io mserver.1.20.hr = 0 : io galaxy.g1.armed = 0

Click ‘Save’ in the upper right corner to activate this script.

The complete list of all the datapoints generated by an I/O Server is available in the Integrations section.

You can use Javascript as well. For example, this code automatically keeps the status of a Galaxy panel aligned with a series of registers in a Modbus TCP Server.

First, a JS code to create and keep updated the Modbus register table:

#********************************************************
# ************** GATEWAY GALAXY MODBUS ******************
#********************************************************

# Initialization
init: {

// MODBUS GATEWAY ADDRESS
var unitid = "1";

//used for testing purposes
programTimerRepeat("galaxytest", 15);

}

function ioEvent(name, value): {
# if and event comes from galaxy
if (name.startsWith("galaxy") == true ){
messageLog("GATEWAY GL - event from central: " + name + " / value: " + value );

var register = "";

if (name.startsWith("galaxy.g")){
var register = (name.split(".")[1]).replace("g","");
if (name.endsWith(".armed")){
//dp example: galaxy.g1.armed = 0,tot,part
//register 1-32
//0=disarmed, 1=tot, 2=part
messageLog("GATEWAY GL - group armed - T1.1 register: " + register + " | status: " + value);
if (value == "0"){
ioSet("mserver."+unitid+"."+register+".hr", "ushort:0");
} else if (value == "tot"){
ioSet("mserver."+unitid+"."+register+".hr", "ushort:1");
} else if (value == "part"){
ioSet("mserver."+unitid+"."+register+".hr", "ushort:2");
}
} else if (name.endsWith(".alarm")){
register = (register * 1) + 100;
//dp example: galaxy.g1.alarm = 0,1,reset
//register 101-132
//0=no alarm, 1=alarm, 2=reset
messageLog("GATEWAY GL - group alarm - T1.2 register: " + register + " | status: " + value);
if (value == "0"){
ioSet("mserver."+unitid+"."+register+".hr", "ushort:0");
} else if (value == "1"){
ioSet("mserver."+unitid+"."+register+".hr", "ushort:1");
} else if (value == "reset"){
ioSet("mserver."+unitid+"."+register+".hr", "ushort:2");
}
} else if (name.endsWith(".ready")){
register = (register * 1) + 200;
//dp example: galaxy.g1.ready = 0,1
//register 201-232
//0=not ready 1=ready
messageLog("GATEWAY GL - group ready - T1.3 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
}
} else if (name.startsWith("galaxy.o")){
var register = (name.split(".")[1]).replace("o","");
if (name.endsWith(".active")){
register = (register * 1) + 500;
//dp example: galaxy.o1.active = 0,1
//register 501-756
//0=not active, 1=active
messageLog("GATEWAY GL - output active - T2.1 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
}
} else if (name.startsWith("galaxy.z")){
var register = (name.split(".")[1]).replace("z","");
if (name.endsWith(".open")){
register = (register * 1) + 0;
//dp example: galaxy.z1.open = 0,1
//register 1001-5158
//0=not open, 1=open
messageLog("GATEWAY GL - zone open - T3.1 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
} else if (name.endsWith(".alarm")){
register = (register * 1) - + 9000;
//dp example: galaxy.z1.alarm = 0,1
//register 10001-14158
//0=no alarm, 1=alarm
messageLog("GATEWAY GL - zone alarm - T3.2 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
} else if (name.endsWith(".bypassed")){
register = (register * 1) + 19000;
//dp example: galaxy.z1.bypassed = 0,1
//register 20001-24158
//0=no bypassed, 1=bypassed
messageLog("GATEWAY GL - zone bypassed - T3.3 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
} else if (name.endsWith(".tamper")){
register = (register * 1) + 29000;
//dp example: galaxy.z1.tamper = 0,1
//register 30001-34158
//0=no tamper, 1=tamper
messageLog("GATEWAY GL - zone tamper - T3.4 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
} else if (name.endsWith(".fault")){
register = (register * 1) + 39000;
//dp example: galaxy.z1.fault = 0,1
//register 40001-44158
//0=no fault, 1=fault
messageLog("GATEWAY GL - zone fault - T3.5 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
} else if (name.endsWith(".masked")){
register = (register * 1) + 49000;
//dp example: galaxy.z1.masked = 0,1
//register 50001-54158
//0=no masked, 1=masked
messageLog("GATEWAY GL - zone masked - T3.6 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
} else if (name.endsWith(".resistance")){
register = (register * 1) + 59000;
//dp example: galaxy.z1.resistance = 0,1
//register 60001-64158
//0=no resistance problem, 1=resistance problem
messageLog("GATEWAY GL - zone resistance - T3.7 register: " + register + " | status: " + value);
ioSet("mserver."+unitid+"."+register+".hr", "ushort:" + value);
}
} else if (name.startsWith("galaxy.connection")){
//register 65200 = 1 online
if (value == "online"){
ioSet("mserver."+unitid+".65200.hr", "ushort:1");
} else {
ioSet("mserver."+unitid+".65200.hr", "ushort:2");
}
}
} else if (name.startsWith("mserver.")){
//commands
//messageLog("GATEWAY GL - T10.1 - mserver: " + name + "|" + value);
var splt = name.split(".");
var uid = splt[1];
var reg = splt[2] * 1;
// if the unit id is correct
if (uid == unitid){
// groups commands
if (reg >= 64 && reg <= 95){
var prog = (reg * 1) - 63;
//messageLog("GATEWAY GL - T10.1 - program arming: " + prog + " / new value: " + value);
if (value == "0"){
// then disarm
ioSet("galaxy.g" + prog + ".armed", "0");
messageLog("GATEWAY GL - T10.1 - program: " + prog + " disarm");
} else if (value == "1"){
// then arm tot
ioSet("galaxy.g" + prog + ".armed", "tot");
messageLog("GATEWAY GL - T10.1 - program arm tot: " + prog);
} else if (value == "2"){
// then arm part
ioSet("galaxy.g" + prog + ".armed", "part");
messageLog("GATEWAY GL - T10.1 - program arm part: " + prog);
} else if (value == "3"){
// then arm abort
ioSet("galaxy.g" + prog + ".armed", "abort");
messageLog("GATEWAY GL - T10.1 - program arm abort: " + prog);
} else if (value == "4"){
// then arm force
ioSet("galaxy.g" + prog + ".armed", "force");
messageLog("GATEWAY GL - T10.1 - program arm force: " + prog);
}
} else if (reg >= 164 && reg <= 195){
var prog = (reg * 1) - 163;
//messageLog("GATEWAY GL - T10.1 - program reset: " + prog + " / new value: " + value);
if (value == "1"){
// then reset
ioSet("galaxy.g" + prog + ".reset", "1");
messageLog("GATEWAY GL - T10.2 - program: " + prog + " reset");
}
} else if (reg >= 15001 && reg <= 19158){
var zone = (reg * 1) - 14000;
//messageLog("GATEWAY GL - T10.3 - zone bypass: " + zone + " / new value: " + value);
if (value == "1" || value == "0"){
ioSet("galaxy.z" + zone + ".bypassed", value);
messageLog("GATEWAY GL - T10.3 - zone: " + zone + " bypassed: " + value);
}
} else if (reg >= 601 && reg <= 856){
var out = (reg * 1) - 600;
//messageLog("GATEWAY GL - T10.6 - output control:" + out + " / new value: " + value);
if (value == "1" || value == "0"){
ioSet("galaxy.o" + out + ".active", value);
messageLog("GATEWAY GL - T10.3 - out: " + out + " active: " + value);
}
}
}
}
}



#subscribe to registers used to send commands to the galaxy panel
io mserver.connection = online or time : {
//groups arm/disarm
for (var i = 64; i <= 95; i++) {
ioSet("mserver."+unitid+"."+i+".hr", "subscribe:short");
}
//groups reset
for (var i = 164; i <= 195; i++) {
ioSet("mserver."+unitid+"."+i+".hr", "subscribe:short");
}
//zones enable disable
for (var i = 15001; i <= 19158; i++) {
sleep(2);
ioSet("mserver."+unitid+"."+i+".hr", "subscribe:short");
}
//outpus active
for (var i = 601; i <= 856; i++) {
sleep(2);
ioSet("mserver."+unitid+"."+i+".hr", "subscribe:short");
}
//connection status
ioSet("mserver."+unitid+".65200.hr", "subscribe:short");
}

MODBUS tables

Supported Modbus functions, Modbus TCP/IP

03: Read Holding Registers

06: Write Single Register

T1.1 Groups armed

Modbus addressInfo
1Group status 1
2Group status 2
3Group status 3
4Group status 4
......
32Group status 32

Values: 0=disarmed, 1=tot, 2=part

T1.2 Groups alarms

Modbus addressInfo
101Group alarm 1
102Group alarm 2
103Group alarm 3
104Group alarm 4
......
132Group alarm 32

Values: 0=no alarms, 1=alarms

T1.3 Groups ready

Modbus addressInfo
201Group ready 1
202Group ready 2
203Group ready 3
204Group ready 4
......
232Group ready 32

Values: 0=not ready, 1=ready

T2.1 Outputs active

Modbus addressInfo
501Output active 1
502Output active 2
503Output active 3
504Output active 4
......
756Output active 256

Values: 0=not active, 1=active

T3.1 Zones open

Modbus addressInfo
1001Zone open 1
1002Zone open 2
1003Zone open 3
1004Zone open 4
......
5158Zone open 4158

Values: 0=not open, 1=open

T3.2 Zones alarm

Modbus addressInfo
10001Zone open 1
10002Zone open 2
10003Zone open 3
10004Zone open 4
......
15158Zone open 4158

Values: 0=not in alarm, 1=alarm

T3.3 Zones bypassed

Modbus addressInfo
20001Zone bypassed 1
20002Zone bypassed 2
20003Zone bypassed 3
20004Zone bypassed 4
......
25158Zone bypassed 4158

Values: 0=not bypassed, 1=bypassed

T3.4 Zones tamper

Modbus addressInfo
30001Zone tamper 1
30002Zone tamper 2
30003Zone tamper 3
30004Zone tamper 4
......
35158Zone tamper 4158

Values: 0=not tampered, 1=tampered

T3.5 Zones fault

Modbus addressInfo
40001Zone fault 1
40002Zone fault 2
40003Zone fault 3
40004Zone fault 4
......
45158Zone fault 4158

Values: 0=not in fault, 1=fault

T3.6 Zones masked

Modbus addressInfo
50001Zone fault 1
50002Zone fault 2
50003Zone fault 3
50004Zone fault 4
......
55158Zone fault 4156

Values: 0=not masked, 1=masked

T3.7 Zones resistance

Modbus addressInfo
60001Zone resistance 1
60002Zone resistance 2
60003Zone resistance 3
60004Zone resistance 4
......
65158Zone resistance 4158

Connection status

Modbus addressInfo
65200Connection status

Values: 0=the Galaxy panel is not communicating with HSYCO, 1=the Galaxy panel in online

T10.1 Groups command arm table

Modbus addressInfo
64Group arm 1
65Group arm 2
66Group arm 3
67Group arm 4
......
95Group arm 32

Values: 0=disarm, 1=arm tot, 2=arm part, 3=abort, 4=force

T10.2 Groups command reset table

Modbus addressInfo
164Group reset 1
165Group reset 2
166Group reset 3
167Group reset 4
......
195Group reset 32

Values: 1=reset

T10.3 Zones command bypass table

Modbus addressInfo
15001Zone bypass 1
15002Zone bypass 2
15003Zone bypass 3
15004Zone bypass 4
......
19158Zone bypass 4158

Values: 0=remove bypass, 1=bypass

T10.6 Outputs command active table

Modbus addressInfo
601Output active 1
602Output active 2
603Output active 3
604Output active 4
......
856Output active 256

Values: 0=de-activate, 1=activate