HNZ south plugin
HNZ connexion initialization
When the HNZ south plugin establishes a new connection with a HNZ device, it will automatically send the following messages to the device:
- A set date and a set time: Those two messages will synchronize the date and time of the device with the one from the south plugin machine.
- A CG request: This message will request all TS to be sent by the device in CG format (equivalent of GI request of iec104).
HNZ Protocol stack configuration
The HNZ protocol stack configuration specifies communication parameters and is a collection of entries containing information about OSI Transport and OSI Application layers objects.
Each entry is comprised of attributes that describe the object. All the configuration data are structured using JSON.
Each entry shall be mapped with the corresponding configuration function in the chosen implementation protocol library.
The present specification corresponds to the HNZ B1/TR mode working on a TCP/IP connection.
Attributes definition
Attribute | Description | Expected values | Mandatory |
---|---|---|---|
name | this identifies the protocol stack | iec104client, iec104server, tase2client, tase2server, 61850client, 61850server, etc... | Yes |
version | version number of the configuration file | 2 digits x.y => x = major change, y = minor change | Yes |
connections | array of connections | Yes | |
connections.srv_ip | IP address to remote HNZ server | IP address | Yes |
connections.port | port number to remote HNZ server | default = 6001 | No |
remote_station_addr | remote server station address | 6 bits | Yes |
Inacc_timeout | timeout before declaring the remote server unreachable (DF.GLOB.TS) | default = 180 (seconds) | No |
max_sarm | max number of SARM messages before handing over to the passive path (A/B) | default = 30 | No |
repeat_path_A | max number of authorized repeats for path A | default = 3 | No |
repeat_path_B | max number of authorized repeats for path B | default = 3 | No |
repeat_timeout | time allowed for the receiver to acknowledge a frame, after this time, the sender repeats the frame. | default = 3000 | No |
anticipation_ratio | number of frames allowed to be received without acknowledgement | default = 3 | No |
test_msg_send | test message code in sending direction | default = 1304 | No |
test_msg_receive | test message code in receiving direction | default = 1304 | No |
gi_schedule | scheduled time for General Interrogation sending | default = 99:99 (disabled) | No |
gi_repeat_count | repeat GI for this number of times in case it is incomplete | default = 3 | No |
gi_time | time to wait for General Interrogation (GI) completion | default = 255 (seconds) | No |
c_ack_time | time to wait before receving a acknowledgement for a control command | default = 10 (seconds) | No |
cmd_recv_timeout | time to wait for bytes when receiving data from the HNZ device | default = 100000 (microseconds) | No |
bulle_time | time to wait before sending a BULLE message after the previous message sent | default = 10 (seconds) | No |
south_monitoring.asset | asset name used to send the connection and gi status information to the north | default = "CONNECTION-1" | No |
Configuration JSON structure
{ "protocol_stack":{ "name":"hnzclient", "version":"1.0", "transport_layer":{ "connections":[ { "srv_ip":"192.168.0.10", "port":6001 }, { "srv_ip":"192.168.0.11", "port":6002 } ] }, "application_layer":{ "remote_station_addr":12, "inacc_timeout":180, "max_sarm":30, "repeat_path_A":3, "repeat_path_B":3, "repeat_timeout":3000, "anticipation_ratio":3, "test_msg_send":"1304", "test_msg_receive":"1304", "gi_schedule":"99:99", "gi_repeat_count":3, "gi_time":255, "c_ack_time":10, "cmd_recv_timeout":100000, "bulle_time": 10 }, "south_monitoring":{ "asset":"CONNECTION-1" } } }
HNZ datapoint representation
This is the Datapoint representation of an HNZ message.
Attribute | Description | Expected values | Mandatory |
---|---|---|---|
do_type | message type | TS, TM, TC, TVC | YES |
do_station | station address | YES | |
do_address | message address | YES | |
do_value | value | TM (do_an = TMA): [-127..127] TM (do_an = TM8): [0..255] TM (do_an = TM16): [-32768..32767] TS: [0..1] TC: [1..2] (01b = on, 10b = off) TVC: [-255..255] | YES except in quality update readings |
do_valid | validity | valid = 0 or invalid = 1 | YES |
do_an | TM type (analogic / numeric) | "TMA", "TM8", "TM16" | TM only |
do_cg | TS source | CG = 1 or CE = 0 | TS only |
do_outdated | Outdated message (after connection loss) | up to date =0, outdated = 1 | TM and TS only |
do_ts | timestamp | epoch timestamp in milliseconds | TS CE only |
do_ts_iv | timestamp invalid | valid = 0 or invalid = 1 (from bit HNV) | TS CE only |
do_ts_c | loss of chronology | lost = 1 else = 0 (from bit CV) | TS CE only |
do_ts_s | ts not synchronized | synchronized = 0 else = 1 (from bit S) | TS CE only |
Example for a TS from CE:
{ "data_object":{ "do_type":"TS", "do_station":12, "do_addr":325, "do_value":1, "do_valid":0, "do_cg":0, "do_outdated":0, "do_ts":1685019425432, "do_ts_iv":0, "do_ts_c":0, "do_ts_s":0 } }
Example for a TS from CG:
{ "data_object":{ "do_type":"TS", "do_station":12, "do_addr":325, "do_value":1, "do_valid":0, "do_cg":1, "do_outdated":0 } }
Example for a TS quality update:
{ "data_object":{ "do_type":"TS", "do_station":12, "do_addr":325, "do_valid":0, "do_cg":0, "do_outdated":1, "do_ts":1685019425432, "do_ts_iv":0, "do_ts_c":0, "do_ts_s":0 } }
Example for a TMA:
{ "data_object":{ "do_type":"TM", "do_station":12, "do_addr":71, "do_value":-15, "do_valid":0, "do_an":"TMA", "do_outdated":0 } }
Example for a TMN 8 bits (TM8):
{ "data_object":{ "do_type":"TM", "do_station":12, "do_addr":71, "do_value":42, "do_valid":0, "do_an":"TM8", "do_outdated":0 } }
Example for a TMN 16 bits (TM16):
{ "data_object":{ "do_type":"TM", "do_station":12, "do_addr":71, "do_value":420, "do_valid":0, "do_an":"TM16", "do_outdated":0 } }
Example for a TM quality update:
{ "data_object":{ "do_type":"TM", "do_station":12, "do_addr":71, "do_valid":0, "do_an":"TMA", "do_outdated":1 } }
Example for a TC (after receiving ACK):
{ "data_object":{ "do_type":"TC", "do_station":12, "do_addr":71, "do_valid":0 } }
Example for a TVC (after receiving ACK):
{ "data_object":{ "do_type":"TVC", "do_station":12, "do_addr":31, "do_valid":0 } }
NB: if an attribute is not required, then it is not put in the output data object, which means that the output object structure always fits the protocol model object type.
HNZ command representation
This is the command representation of an HNZ message.
The current implementation does not use a json structure, so the order of parameters is mandatory.
Order | Attribute | Description | Expected values | Mandatory |
---|---|---|---|---|
0 | co_type | message type | TC, TVC | YES |
1 | co_addr | message address | [0..255][0..7] (ADO + ADB) for a TC, [0..31] for a TVC | YES |
2 | co_value | value | [1..2] (01b = on, 10b = off) | YES |
The processing of FLEDGE commands should evolve. Below is an example of JSON format :
Example for a TC:
{ "co_type":"TC", "co_addr":325, "co_value":1 }
Example for a TVC:
{ "co_type":"TVC", "co_addr":31, "co_value":42 }
NB: if an attribute is not required, then it is not put in the output data object, which means that the output object structure always fits the protocol model object type.
HNZ south event representation
South events are special messages used to communicate information about the state of the connection and GI requests between south and north plugins.
Their behivior and structure is defined here.
Path exploration
In redundant network configuration or generally in cases where several communication paths exist between one client and one server, the path checking exploration mechanism allows the client to try all the paths one by one without making any difference between them. The client uses the first available path. On disconnection this procedure starts again from the beginning.
Connection status audits
This plugin will send Fledge audits of type SRVFL containing different messages to notify about changes in the status of the connection.
The connection status will be tracked at two different levels:
- Path level: An HNZ connection has a maximum of two path defined (A and B), one of them is active, the other is passive.
- Global level: The same level as in south_events representing the global state of the connection.
Generated audit messages will have the following pattern based on their level:
- Path level:
<service_name>-<path_letter>-<status>
- Global level :
<service_name>-<status>
With:
<service_name>
: The name of the service running this plugin (eg: hnzsouth_s1)<path_letter>
: The letter of the path (A or B).<status>
: The connection status.
The connection status can take different values based on the level of connection, each value is sent with a given audit severity :
- Path level:
Status | Severity | Description |
---|---|---|
unused | INFORMATION | The configuration does not include this path |
disconnected | FAILURE | The path is not connected |
active | SUCCESS | The path is connected and is the active path |
passive | SUCCESS | The path is connected and is the passive path |
- Global level:
Status | Severity | Description |
---|---|---|
disconnected | FAILURE | None of the configured path is connected |
connected | SUCCESS | At least one of the configured path is connected |
These audits are sent :
- Whenever the plugin is reconfigured (including at plugin startup)
- Whenever the connection state they represent changes
Some audits may be repeated in the same state (in case of reconfiguration or plugin restart for example) but the implementation is designed to minimize the number of audits sent while ensuring that no state change can be missed.