Add custom how-to guides to documentation, additional notebook around how to use dev cli
This commit is contained in:
78
docs/source/how_to_guides/custom_software.rst
Normal file
78
docs/source/how_to_guides/custom_software.rst
Normal file
@@ -0,0 +1,78 @@
|
||||
.. 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`.
|
||||
Reference in New Issue
Block a user