Skip to content

Client

feral3gp.feral.FCAPIClient

The FCAPIClient represents a client communicating with the gateway. The class does not use OO-paradigms (e.g. the "handle" of a primitive type is chosen) to ease development of an equivalent interface in C

Source code in feral3gp/feral/fcapi/client.py
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
class FCAPIClient:
    """
     The FCAPIClient represents a client communicating with the gateway.
     The class does not use OO-paradigms (e.g. the "handle" of a primitive type is chosen) to ease development of an
     equivalent interface in C
    """

    def __init__(self, protocol: feral.TransmissionBackend, name: str = "unnamed FCAPI Python client"):
        """
        :param name: The name of the client
        :param protocol: The transmission backend protocol to use for the connection
        """
        self.name = name
        java_transmission_backend = protocol
        self.java_instance = JClientControl(feral.console(), java_transmission_backend)

    def connect(self, server_address: str, server_port: int, client_address: str, port_name: str,
                mime_type: str = None):
        """
        Connect to a gateway.

        This blocks until the connection is established.

        :param server_address: The address that the fcapi can be reached at
        :param server_port: The port that the fcapi listens on
        :param client_address: The address that the client can be reached from the server
        :param port_name: The fcapi port name that shall be connected to
        :param mime_type: Identifies the decoder/encoder used to convert the messages to network specific packets
        :return: The connection ID that the fcapi provided
        """

        if mime_type is None:
            return self.java_instance.connect(server_address, server_port, client_address, port_name)
        else:
            return self.java_instance.connect(server_address, server_port, client_address, port_name, mime_type)

    def continue_(self, handle: int):
        """
        Indicate to the Gateway that a paused simulation can be continue

        :param handle: the connection handle (id)
        """
        self.java_instance.continue_(handle)

    def wait(self, handle: int):
        """
        If the simulation in the fcapi is running: wait until the simulation is paused again

        :param handle: the connection handle (id)
        :return: The simulation time that has been reached
        """
        return self.java_instance.wait_(handle)

    def disconnect(self, handle: int):
        """
        Gracefully disconnect the client from the fcapi

        :param handle: the connection handle (id)
        """
        self.java_instance.disconnect(handle)

    def disconnect_with_error(self, handle: int, error_message: str):
        """
        Forcefully disconnect from the fcapi, providing some feedback what went wrong.
        Upon this the fcapi will cease simulation and disconnect all other clients.

        :param handle: the connection handle (id)
        :param error_message: Give a justification for the error log
        """
        self.java_instance.disconnectWithError(handle, error_message)

    def disconnect_all(self):
        """
        Close all open connections
        """
        self.java_instance.disconnectAll()

    def tx(self, handle: int, data: JArray(JByte)):
        """
        Transmit data to the fcapi

        :param handle: the connection handle (id)
        :param data: raw data to be transmitted
        """
        self.java_instance.tx(handle, data)

    def rx(self, handle: int):
        """
        Fetch data from a port. Returns None if no data is available. If multiple data packets are available can be
        called multiple times, they are stored in the background. They are picked up chronologically, oldest first.

        :param handle: the connection handle (id)
        :return: if data is available: a pair with the timestamp of simulation time
        the data was produced at and the raw data or None if no data is available.
        """
        return self.java_instance.rx(handle)

    def rx_cb(self, handle: int, listener: RxCBListener):
        """
        Like 'rx()', but with a callback to be invoked when new data has been received

        :param handle: the connection handle (id)
        :param listener: The rx callback listener
        """
        self.java_instance.rxCB(handle, listener)

    def set_passive_mode(self):
        """
        Put the client into "passive" mode. This basically means that the client is only able to connect/disconnect
        and transmit data. It looses capability to alter simulation time (sync/wait/continue) and  it can not issue
        startSim anymore.
        This must be invoked before the client sets the first sync point. Can be invoked multiple times without error.
        """
        self.java_instance.setPassiveMode()

    def start_sim(self, handle: int):
        """
        Notify simulation from this client that it is ready to execute.

        :param handle: the connection handle (id)
        """
        self.java_instance.startSim(handle)

    def get_sim_time(self, handle: int):
        """
        Retrieve current simulation time from the client

        :param handle: the connection handle (id)
        :return: The current simulation time the fcapi's simulation is at
        """
        return self.java_instance.getSimTime(handle)

    def get_sim_duration(self, handle: int):
        """
        Retrieve the end time of the simulation from the fcapi.
        Blocks until the request is answered from the fcapi.

        :param handle: the connection handle (id)
        :return: The time that the simulation will run until
        """
        return self.java_instance.getSimDuration(handle)

    def get_network_properties(self, handle: int):
        """
        Retrieve names of all network related (i.e. specific for one handle) properties from fcapi.
        Unlike getSimulationProperties(int) this will yield different results for different handles.
        Blocking call, until fcapi has responded.

        :param handle: the connection handle (id)
        :return: List of all available simulation property names
        """
        return self.java_instance.getNetworkProperties(handle)

    def get_simulation_properties(self, handle: int):
        """
        Retrieve names of all simulation related (i.e. common for all clients/connections) properties from fcapi.
        Blocking call, until fcapi has responded.

        :param handle: the connection handle (id)
        :return: List of all available simulation property names
        """
        return self.java_instance.getSimulationProperties(handle)

    def get_property_value(self, handle: int, property_name: str):
        """
        Get the value assigned to a specific property. Property names should be queried with 'getNetworkProperties(int)'
        or 'getSimulationProperties(int)' before. Will reply with an exception if the property does not exist
        (for this handle).

        Blocking call, until fcapi has responded.

        :param handle: the connection handle (id)
        :param property_name: Name of the property to query
        :return: Value assigned to the property
        """
        return self.java_instance.getPropertyValue(handle, property_name)

    def set_property_value(self, handle: int, property_name: str, property_value: str):
        """
        Modify the value of a specific property. Property names should be queried with getNetworkProperties(int) or
        'getSimulationProperties(int)' before. Will reply with an exception if the property does not exist
        (for this handle).

        Blocking call, until fcapi has responded.

        :param handle: the connection handle (id)
        :param property_name: Name of the property to query
        :param property_value: Value to assign to the property
        """
        return self.java_instance.setPropertyValue(handle, property_name, property_value)

    def sync(self, handle: int, sim_time: int, interval: int = None):
        """
        Register a sync point where the simulation will pause and wait.

        :param handle: the connection handle (id)
        :param sim_time: The simulation time point when to stop
        :param interval: The delta which after the first point repetitively shall be stopped at
        """
        if interval is None:
            self.java_instance.sync(handle, sim_time)
        else:
            self.java_instance.sync(handle, sim_time, interval)

    def sync_cb(self, handle: int, sim_time: int, listener: SyncCBListener, interval: int = None):
        """
        Like 'sync()', but with a callback to be invoked on reaching the sync point.

        :param handle: the connection handle (id)
        :param sim_time: The simulation time point when to stop
        :param listener: The sync callback listener
        :param interval: The delta which after the first point repetitively shall be stopped at
        """
        if interval is None:
            self.java_instance.syncCB(handle, sim_time, listener)
        else:
            self.java_instance.syncCB(handle, sim_time, interval, listener)

    def close(self):
        """
        Forcefully bring down the client instance, free all resources.
        """
        self.java_instance.close()

__init__(protocol, name='unnamed FCAPI Python client')

Parameters:

Name Type Description Default
name str

The name of the client

'unnamed FCAPI Python client'
protocol TransmissionBackend

The transmission backend protocol to use for the connection

required
Source code in feral3gp/feral/fcapi/client.py
16
17
18
19
20
21
22
23
def __init__(self, protocol: feral.TransmissionBackend, name: str = "unnamed FCAPI Python client"):
    """
    :param name: The name of the client
    :param protocol: The transmission backend protocol to use for the connection
    """
    self.name = name
    java_transmission_backend = protocol
    self.java_instance = JClientControl(feral.console(), java_transmission_backend)

close()

Forcefully bring down the client instance, free all resources.

Source code in feral3gp/feral/fcapi/client.py
227
228
229
230
231
def close(self):
    """
    Forcefully bring down the client instance, free all resources.
    """
    self.java_instance.close()

connect(server_address, server_port, client_address, port_name, mime_type=None)

Connect to a gateway.

This blocks until the connection is established.

Parameters:

Name Type Description Default
server_address str

The address that the fcapi can be reached at

required
server_port int

The port that the fcapi listens on

required
client_address str

The address that the client can be reached from the server

required
port_name str

The fcapi port name that shall be connected to

required
mime_type str

Identifies the decoder/encoder used to convert the messages to network specific packets

None

Returns:

Type Description

The connection ID that the fcapi provided

Source code in feral3gp/feral/fcapi/client.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def connect(self, server_address: str, server_port: int, client_address: str, port_name: str,
            mime_type: str = None):
    """
    Connect to a gateway.

    This blocks until the connection is established.

    :param server_address: The address that the fcapi can be reached at
    :param server_port: The port that the fcapi listens on
    :param client_address: The address that the client can be reached from the server
    :param port_name: The fcapi port name that shall be connected to
    :param mime_type: Identifies the decoder/encoder used to convert the messages to network specific packets
    :return: The connection ID that the fcapi provided
    """

    if mime_type is None:
        return self.java_instance.connect(server_address, server_port, client_address, port_name)
    else:
        return self.java_instance.connect(server_address, server_port, client_address, port_name, mime_type)

continue_(handle)

Indicate to the Gateway that a paused simulation can be continue

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
Source code in feral3gp/feral/fcapi/client.py
45
46
47
48
49
50
51
def continue_(self, handle: int):
    """
    Indicate to the Gateway that a paused simulation can be continue

    :param handle: the connection handle (id)
    """
    self.java_instance.continue_(handle)

disconnect(handle)

Gracefully disconnect the client from the fcapi

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
Source code in feral3gp/feral/fcapi/client.py
62
63
64
65
66
67
68
def disconnect(self, handle: int):
    """
    Gracefully disconnect the client from the fcapi

    :param handle: the connection handle (id)
    """
    self.java_instance.disconnect(handle)

disconnect_all()

Close all open connections

Source code in feral3gp/feral/fcapi/client.py
80
81
82
83
84
def disconnect_all(self):
    """
    Close all open connections
    """
    self.java_instance.disconnectAll()

disconnect_with_error(handle, error_message)

Forcefully disconnect from the fcapi, providing some feedback what went wrong. Upon this the fcapi will cease simulation and disconnect all other clients.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
error_message str

Give a justification for the error log

required
Source code in feral3gp/feral/fcapi/client.py
70
71
72
73
74
75
76
77
78
def disconnect_with_error(self, handle: int, error_message: str):
    """
    Forcefully disconnect from the fcapi, providing some feedback what went wrong.
    Upon this the fcapi will cease simulation and disconnect all other clients.

    :param handle: the connection handle (id)
    :param error_message: Give a justification for the error log
    """
    self.java_instance.disconnectWithError(handle, error_message)

get_network_properties(handle)

Retrieve names of all network related (i.e. specific for one handle) properties from fcapi. Unlike getSimulationProperties(int) this will yield different results for different handles. Blocking call, until fcapi has responded.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required

Returns:

Type Description

List of all available simulation property names

Source code in feral3gp/feral/fcapi/client.py
151
152
153
154
155
156
157
158
159
160
def get_network_properties(self, handle: int):
    """
    Retrieve names of all network related (i.e. specific for one handle) properties from fcapi.
    Unlike getSimulationProperties(int) this will yield different results for different handles.
    Blocking call, until fcapi has responded.

    :param handle: the connection handle (id)
    :return: List of all available simulation property names
    """
    return self.java_instance.getNetworkProperties(handle)

get_property_value(handle, property_name)

Get the value assigned to a specific property. Property names should be queried with 'getNetworkProperties(int)' or 'getSimulationProperties(int)' before. Will reply with an exception if the property does not exist (for this handle).

Blocking call, until fcapi has responded.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
property_name str

Name of the property to query

required

Returns:

Type Description

Value assigned to the property

Source code in feral3gp/feral/fcapi/client.py
172
173
174
175
176
177
178
179
180
181
182
183
184
def get_property_value(self, handle: int, property_name: str):
    """
    Get the value assigned to a specific property. Property names should be queried with 'getNetworkProperties(int)'
    or 'getSimulationProperties(int)' before. Will reply with an exception if the property does not exist
    (for this handle).

    Blocking call, until fcapi has responded.

    :param handle: the connection handle (id)
    :param property_name: Name of the property to query
    :return: Value assigned to the property
    """
    return self.java_instance.getPropertyValue(handle, property_name)

get_sim_duration(handle)

Retrieve the end time of the simulation from the fcapi. Blocks until the request is answered from the fcapi.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required

Returns:

Type Description

The time that the simulation will run until

Source code in feral3gp/feral/fcapi/client.py
141
142
143
144
145
146
147
148
149
def get_sim_duration(self, handle: int):
    """
    Retrieve the end time of the simulation from the fcapi.
    Blocks until the request is answered from the fcapi.

    :param handle: the connection handle (id)
    :return: The time that the simulation will run until
    """
    return self.java_instance.getSimDuration(handle)

get_sim_time(handle)

Retrieve current simulation time from the client

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required

Returns:

Type Description

The current simulation time the fcapi's simulation is at

Source code in feral3gp/feral/fcapi/client.py
132
133
134
135
136
137
138
139
def get_sim_time(self, handle: int):
    """
    Retrieve current simulation time from the client

    :param handle: the connection handle (id)
    :return: The current simulation time the fcapi's simulation is at
    """
    return self.java_instance.getSimTime(handle)

get_simulation_properties(handle)

Retrieve names of all simulation related (i.e. common for all clients/connections) properties from fcapi. Blocking call, until fcapi has responded.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required

Returns:

Type Description

List of all available simulation property names

Source code in feral3gp/feral/fcapi/client.py
162
163
164
165
166
167
168
169
170
def get_simulation_properties(self, handle: int):
    """
    Retrieve names of all simulation related (i.e. common for all clients/connections) properties from fcapi.
    Blocking call, until fcapi has responded.

    :param handle: the connection handle (id)
    :return: List of all available simulation property names
    """
    return self.java_instance.getSimulationProperties(handle)

rx(handle)

Fetch data from a port. Returns None if no data is available. If multiple data packets are available can be called multiple times, they are stored in the background. They are picked up chronologically, oldest first.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required

Returns:

Type Description

if data is available: a pair with the timestamp of simulation time the data was produced at and the raw data or None if no data is available.

Source code in feral3gp/feral/fcapi/client.py
 95
 96
 97
 98
 99
100
101
102
103
104
def rx(self, handle: int):
    """
    Fetch data from a port. Returns None if no data is available. If multiple data packets are available can be
    called multiple times, they are stored in the background. They are picked up chronologically, oldest first.

    :param handle: the connection handle (id)
    :return: if data is available: a pair with the timestamp of simulation time
    the data was produced at and the raw data or None if no data is available.
    """
    return self.java_instance.rx(handle)

rx_cb(handle, listener)

Like 'rx()', but with a callback to be invoked when new data has been received

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
listener RxCBListener

The rx callback listener

required
Source code in feral3gp/feral/fcapi/client.py
106
107
108
109
110
111
112
113
def rx_cb(self, handle: int, listener: RxCBListener):
    """
    Like 'rx()', but with a callback to be invoked when new data has been received

    :param handle: the connection handle (id)
    :param listener: The rx callback listener
    """
    self.java_instance.rxCB(handle, listener)

set_passive_mode()

Put the client into "passive" mode. This basically means that the client is only able to connect/disconnect and transmit data. It looses capability to alter simulation time (sync/wait/continue) and it can not issue startSim anymore. This must be invoked before the client sets the first sync point. Can be invoked multiple times without error.

Source code in feral3gp/feral/fcapi/client.py
115
116
117
118
119
120
121
122
def set_passive_mode(self):
    """
    Put the client into "passive" mode. This basically means that the client is only able to connect/disconnect
    and transmit data. It looses capability to alter simulation time (sync/wait/continue) and  it can not issue
    startSim anymore.
    This must be invoked before the client sets the first sync point. Can be invoked multiple times without error.
    """
    self.java_instance.setPassiveMode()

set_property_value(handle, property_name, property_value)

Modify the value of a specific property. Property names should be queried with getNetworkProperties(int) or 'getSimulationProperties(int)' before. Will reply with an exception if the property does not exist (for this handle).

Blocking call, until fcapi has responded.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
property_name str

Name of the property to query

required
property_value str

Value to assign to the property

required
Source code in feral3gp/feral/fcapi/client.py
186
187
188
189
190
191
192
193
194
195
196
197
198
def set_property_value(self, handle: int, property_name: str, property_value: str):
    """
    Modify the value of a specific property. Property names should be queried with getNetworkProperties(int) or
    'getSimulationProperties(int)' before. Will reply with an exception if the property does not exist
    (for this handle).

    Blocking call, until fcapi has responded.

    :param handle: the connection handle (id)
    :param property_name: Name of the property to query
    :param property_value: Value to assign to the property
    """
    return self.java_instance.setPropertyValue(handle, property_name, property_value)

start_sim(handle)

Notify simulation from this client that it is ready to execute.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
Source code in feral3gp/feral/fcapi/client.py
124
125
126
127
128
129
130
def start_sim(self, handle: int):
    """
    Notify simulation from this client that it is ready to execute.

    :param handle: the connection handle (id)
    """
    self.java_instance.startSim(handle)

sync(handle, sim_time, interval=None)

Register a sync point where the simulation will pause and wait.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
sim_time int

The simulation time point when to stop

required
interval int

The delta which after the first point repetitively shall be stopped at

None
Source code in feral3gp/feral/fcapi/client.py
200
201
202
203
204
205
206
207
208
209
210
211
def sync(self, handle: int, sim_time: int, interval: int = None):
    """
    Register a sync point where the simulation will pause and wait.

    :param handle: the connection handle (id)
    :param sim_time: The simulation time point when to stop
    :param interval: The delta which after the first point repetitively shall be stopped at
    """
    if interval is None:
        self.java_instance.sync(handle, sim_time)
    else:
        self.java_instance.sync(handle, sim_time, interval)

sync_cb(handle, sim_time, listener, interval=None)

Like 'sync()', but with a callback to be invoked on reaching the sync point.

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
sim_time int

The simulation time point when to stop

required
listener SyncCBListener

The sync callback listener

required
interval int

The delta which after the first point repetitively shall be stopped at

None
Source code in feral3gp/feral/fcapi/client.py
213
214
215
216
217
218
219
220
221
222
223
224
225
def sync_cb(self, handle: int, sim_time: int, listener: SyncCBListener, interval: int = None):
    """
    Like 'sync()', but with a callback to be invoked on reaching the sync point.

    :param handle: the connection handle (id)
    :param sim_time: The simulation time point when to stop
    :param listener: The sync callback listener
    :param interval: The delta which after the first point repetitively shall be stopped at
    """
    if interval is None:
        self.java_instance.syncCB(handle, sim_time, listener)
    else:
        self.java_instance.syncCB(handle, sim_time, interval, listener)

tx(handle, data)

Transmit data to the fcapi

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required
data JArray(JByte)

raw data to be transmitted

required
Source code in feral3gp/feral/fcapi/client.py
86
87
88
89
90
91
92
93
def tx(self, handle: int, data: JArray(JByte)):
    """
    Transmit data to the fcapi

    :param handle: the connection handle (id)
    :param data: raw data to be transmitted
    """
    self.java_instance.tx(handle, data)

wait(handle)

If the simulation in the fcapi is running: wait until the simulation is paused again

Parameters:

Name Type Description Default
handle int

the connection handle (id)

required

Returns:

Type Description

The simulation time that has been reached

Source code in feral3gp/feral/fcapi/client.py
53
54
55
56
57
58
59
60
def wait(self, handle: int):
    """
    If the simulation in the fcapi is running: wait until the simulation is paused again

    :param handle: the connection handle (id)
    :return: The simulation time that has been reached
    """
    return self.java_instance.wait_(handle)