**!This release contains interface changes for the callback/event handling and the handler constructors!**
Stream/function callback handling
The _register_callback_ and _unregister_callback_ methods in the handler classes have been renamed to _register_stream_function_ and _unregister_stream_function_.
Only one callback can be registered for a stream/function. Therefore the results of the callback can be used in the calling function.
A callback can also be registered with the callback property. Please note the syntax and the leading zeros:
python
secsHandler.callbacks.s01f01 = handle_s01f01
The callbacks for the streams/functions don't need to be registered with _register_stream_function_ for HsmsHandler derived classes any more. They can be registered using a special method naming scheme: `_on_s<SS>f<FF>`. For example:
python
def _on_s01f01(self, handler, packet):
Note the leading zeros! The _register_stream_function_ method can be used anyway. It will override any object method for the stream/function.
The callbacks don't send the response any more, the just return the stream/function class. If None is returned nothing will be sent.
The existing callback sends be found and replaced with a regex like:
> handler.send_response((.*), packet.header.system)
and replaced with:
> return $1
where $1 is the match group 1 of the search regex.
If no callback is registered a `S09F05` is sent, if an exception occurs in the callback a `S<SS>F00` (Abort) is sent.
Callback handling
The property callbacks of the handler can be used to register and deregister a callback. You can also override the `_on_<callback>` method in derived classes to handle the callback.
python
gemHandler.callbacks.alarm_received = alarm_received_callback_function
Only one function can be registered for a callback now. A callback function has a specific number of arguments and a specific return value. This value may be required by the calling function in order to continue processing. Callback function are called synchronous, they should be as effective as possible else they could slow down the processing.
The following callbacks are available:
| Class | Callback | Parameters | Return |
| --- | --- | --- | --- |
| GemHostHandler | alarm_received | handler, ALID, ALCD, ALTX | ACKC5 |
| GemHostHandler | terminal_received | handler, TID, TEXT | ACKC10 |
Event handling
The property events of the handler can be used to register and deregister a callback. You can also override the `_on_event_<event>` method in derived classes to handle the event.
python
secsHandler.events.hsms_selected += event_hsms_selected
secsHandler.events.hsms_selected += on_hsms_selected
Multiple events can be registered for one event. To unregister use the subtract assignment operator
python
secsHandler.events.hsms_selected -= on_hsms_selected
The event_handler parameter of the handler constructor isn't used any more and was removed,
Support for alarms in GEM equipment handler (18)
`GemEquipmentHandler` now has a member `alarms`. This dictionary can be used to define available alarms. To set or clear an alarm use the methods _set_alarm_ or _clear_alarm_
See the [documentation](https://secsgem.readthedocs.io/en/latest/gem/equipment.html#adding-alarms) for details.
The GEM host handler got some functions for alarm handling too.
More tests and code optimization
The coverage was raised to almost 100% with more than 2700 tests. Currently there are a few functions excluded as well as the fysom state machine, which will be replaced in the future. Connection related classes that can't be tested without a socket are also excluded. I am still searching for a way to test these (mock socket, ...). Also the runtime of the tests was reduced by about 70%.
The landscape.io code quality was raised to almost 100% leaving only style errors.
Added support for JIS8 data
I added a python de-/encoder for JIS8 strings. This code is unverified, as I don't have any JIS8 encoded data available.
Streams/functions can print their structure
Calling the class itself returns a textual representation of the data structure. This is also used for testing the actual structure against what is expected.
python
>>> secsgem.SecsS01F03
[
SVID: U1/U2/U4/U8/I1/I2/I4/I8/A
...
]
Use Unicode internally
Unicode strings are used internally instead of ASCII representation, to raise compatibility with python 3
Minor changes/fixes
- python3 changes
- split up the common module in different submodules
- updated documentation