79 lines
3.2 KiB
ReStructuredText
79 lines
3.2 KiB
ReStructuredText
.. only:: comment
|
|
|
|
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
|
|
|
Creating Custom Software for PrimAITE
|
|
*************************************
|
|
|
|
This page aims to provide a how-to guide on how to create your own custom software for use within PrimAITE.
|
|
|
|
PrimAITE has a base software class which should be inherited from when building custom software. Examples of this can be seen in the ``IOSoftware`` and ``Process`` classes.
|
|
It's important that any new software created within PrimAITE has the ``identifier`` attribute defined, for use when generating the environment.
|
|
|
|
Some default attributes may need to be adjusted to align with the intended application of the custom software.
|
|
|
|
|
|
.. code:: Python
|
|
|
|
from src.primaite.simulator.system.software import Software
|
|
|
|
class CustomSoftware(Software, identifier="CustomSoftware"):
|
|
"""
|
|
An example of Custom Software within PrimAITE.
|
|
"""
|
|
|
|
operating_state: OperatingState
|
|
"The current operating state of the Custom software"
|
|
|
|
def describe_state(self) -> Dict:
|
|
"""
|
|
Produce a dictionary describing the current state of this object.
|
|
|
|
:return: Current state of this object and child objects.
|
|
:rtype: Dict
|
|
"""
|
|
state = super().describe_state()
|
|
state.update({"operating_state": self.operating_state.value})
|
|
|
|
Default Install
|
|
###############
|
|
|
|
Software can be set to auto-install onto a Node by adding it to the ``SYSTEM_SOFTWARE`` dictionary for the node. An example can be seen in the ``HostNode`` class, which pre-installs some key software that is expected on Nodes, such as the ``NTPClient`` and ``UserManager``.
|
|
|
|
Requirements
|
|
############
|
|
|
|
Any custom software will need to provide an implementation of the ``describe_state`` method, and conform to the general Pydantic requirements.
|
|
It's a good idea, if possible, to also create a ``.show()`` method, as this can be used for visualising the software's status when developing within PrimAITE.
|
|
|
|
Interaction with the PrimAITE Request System
|
|
############################################
|
|
|
|
If the software is intended to be used by an agent via a :ref:`custom_action`, then it will likely need an implementation of the ``RequestManager``.
|
|
Detailed information about the PrimAITE request system can be seen in :ref:`request_system`. An example implementation, derived from the `Application` class is seen below:
|
|
|
|
.. code:: Python
|
|
|
|
def _init_request_manager(self) -> RequestManager:
|
|
"""
|
|
Initialise the request manager.
|
|
|
|
More information in user guide and docstring for SimComponent._init_request_manager.
|
|
"""
|
|
_is_application_running = Application._StateValidator(application=self, state=ApplicationOperatingState.RUNNING)
|
|
|
|
rm = super()._init_request_manager()
|
|
rm.add_request(
|
|
"scan",
|
|
RequestType(
|
|
func=lambda request, context: RequestResponse.from_bool(self.scan()), validator=_is_application_running
|
|
),
|
|
)
|
|
return rm
|
|
|
|
|
|
Further information
|
|
###################
|
|
|
|
For more detailed information about the implementation of software within PrimAITE, see :ref:`software`.
|