List of sequential blocks 1/2¶
List of sequential blocks offered by the edzed library - first part.
Conventions used in this chapter:
Only block specific parameters are listed in the signatures. In detail:
the mandatory positional argument name is documented in the base class
Blockcommon optional keyword arguments on_output, debug, comment and x_NAME are shown only as
**block_kwargs, they are documented in the base classBlockif persistent state is supported, only the persistent parameter is listed, but sync_state and expiration are always supported together with persistent, refer to
SBlockinitdef, init_timeout and stop_timeout are listed in the class signature only if supported by the particular block type. Their descriptions are not repeated here, refer to
SBlock
all time duration values (timeouts, intervals, etc.) can be given as a number of seconds or as a string with time units The corresponding type is
int|float|strand if optional, it could be alsoNone.all on_something parameters expect zero, one or more events. The corresponding type is
None|edzed.Event|Iterator[edzed.Event]|Sequence[edzed.Event]and we omit this long annotation for brevity.
Inputs¶
Pushing external data into the circuit¶
Important
Data are transported by events. To push new data use ExtEvent.send(),
refer to external events.
Depending on your application’s needs, any sequential block
may serve as a part of the circuit’s input interface.
The most common data entry block is the Input.
- class edzed.Input(name, *, check=None, allowed=None, schema=None, persistent=False, initdef=edzed.UNDEF, **block_kwargs)¶
An input block with optional value validation.
- Parameters:
check (Callable[[Any], Any] or None) – A value test function or
Noneif unused. If the function’s return value evaluates to true, new value is accepted, otherwise it is rejected.allowed (Collection or None) – A collection of allowed values or
Noneif unused. Equivalent to:check=lambda value: value in ALLOWEDschema (Callable[[Any], Any] or None) – A function possibly modifying (preprocessing) the value or
Noneif unused. If the function raises, value is rejected, otherwise the input is set to the returned value. Schema is the only validator capable of changing the value. It is called last to ensure all validators test the original input value.persistent (bool) – If true, initialize from the last known value
initdef (Any) – Default value; must pass the validators.
The
Inputaccepts only'put'events. It stores and outputs the'value'data item sent with the event provided that it validates successfully. The event returnsTrueif the new value is accepted,Falseotherwise.You should always validate inputs. It is recommended to use only one validator, but any combination of schema, check and allowed is allowed.
- class edzed.InputExp(name, *, duration, expired=None, check=None, allowed=None, schema=None, persistent=False, initdef=edzed.UNDEF, **block_kwargs)¶
Like
Input, but after certain time after the'put'event replace the current value with the expired value.An
InputExptakes the same arguments asInputplus two additional ones:- Parameters:
duration (int or float or str or None) – The default duration in seconds before a value expires. May be overridden on a per-event basis. The argument may be
Nonefor no default duration. Without a default, every event must explicitly specify the duration.expired (Any) – A value to be applied after expiration; must pass the validators.
If a
'duration'item (with the same format as the duration parameter) is present in the event data, it overrides the default duration.
Polling data sources¶
A specialized block is provided for this task:
- class edzed.ValuePoll(name, *, func, interval, init_timeout=None, initdef=edzed.UNDEF, **block_kwargs)¶
A source of measured or computed values. This block outputs the result of an acquisition function func every interval seconds.
- Parameters:
func (Callable) – The data acquisition function func. It could be a regular function (defined with
def) or a coroutine function (defined withasync def).interval (int or float or str) – The interval between function calls. The duration of the call itself represents an additional delay.
A data acquisition error (i.e. any unhandled exception in func) terminates the simulation. If a real value could become unavailable, the function should handle such condition. It has these basic options:
return some default value
return some sentinel value understood by connected circuit blocks as missing value
return
UNDEF. If it returnsUNDEF, it will be ignored and no output change will happen
Initialization rules: If the very first value is not obtained within the init_timeout limit, the initdef value will be used as a default. If initdef is not defined, the initialization fails.
Outputs¶
The output blocks invoke a function in response to a 'put' event.
See also
the Repeat block. Repeated output actions
may increase the robustness of applications.
Error handling¶
Both output blocks described in this section require the error handling to be set explicitly. The options are:
on_error=Noneto ignore errorson_error=edzed.Event.abort()to make every error fatal; see theEvent.abort()customized error handling: specify events which will notify circuit blocks created for this purpose
In each case the error will be logged.
Output blocks¶
Output blocks invoke a supplied function to perform an output operation. The appropriate block type depends on the output function’s type:
OutputFunc- for regular non-blocking functionsOutputAsyncwithInExecutor- for regular blocking functions:edzed.OutputAsync(..., coro=edzed.InExecutor(blocking_function), ...)
OutputAsync- for coroutine functions
In this context, a blocking function is a function that does not always return in a short time, because it could do a CPU intensive computation or slow I/O. Local file access is considered not blocking, but any network communication is a typical example of blocking I/O.
- class edzed.OutputFunc(name, *, func, f_args=['value'], f_kwargs=(), on_success=None, on_error, stop_data=None, **block_kwargs)¶
Call a function when a
'put'event arrives.- Parameters:
func (Callable) – function to be invoked on each
'put'eventf_args (Sequence[str]) – specifies which event data values will be passed to func as positional arguments (args)
f_kwargs (Sequence[str]) – specifies which event data values will be passed to func as keyword arguments (kwargs)
on_error – event(s) to be sent on a function call error, this is a mandatory parameter
on_success – event(s) to be sent after a successful function call
stop_data (Mapping[str, Any] or None) – event data (a
{'name': value}dictionary) orNoneif not used. See the “Final state” paragraph below..
Output function and its arguments: The function func is called with arguments extracted from the event data. The default f_args and f_kwargs values cause the func to be called with
data['value']as its sole argument. This covers most use-cases, but the argument passing can be easily configured differently by adjusting f_args and f_kwargs.The keys of values to be extracted as positional (keyword) arguments are specified with the f_args (f_kwargs) respectively. The event data of every received
'put'event must contain all keys listed in f_args and f_kwargs.(side note: due to a software limitation, the default f_args value is shown as a list, but it is a tuple.)
Generated events: After calling the output function func, any returned value is considered a success. An exception means an error.
- On success:
on_success events are triggered and the returned value is added to the event data as
'value'the
'put'event returns('result', <returned_value>)
- On error (see error handling):
on_error events are triggered and the the exception is added to the on_error event data as:
'error'.the
'put'event returns('error', <exception>)
Final state: If the stop_data is not
None, it is used as the event data of a synthetic event delivered to the block during the cleanup and processed as the last item before stopping. This allows to leave the controlled process in a well-defined state.Output: The output of an OutputFunc block is always
False.
- class edzed.OutputAsync(name, *, coro, mode: str, f_args=['value'], f_kwargs=(), guard_time=None, on_success=None, on_cancel=None, on_error, stop_data=None, stop_timeout=None, **block_kwargs)¶
Run an async function coro in an asyncio task when a
'put'event arrives. The async function is invoked with arguments extracted from the event data. The event returns immediately and does not return any result.Parameters f_args, f_kwargs, on_success, on_error, and stop_data have the same meaning as in
OutputFunc.Operation modes: There are three operation modes. The difference is in the behavior when a new
'put'event arrives before the processing of the previous one has finished:mode
event handling
cancel
the latest one only
wait
sequential (FIFO)
start
concurrent
In detail:
mode=’cancel’ or just ‘c’ (cancel before start)
In this mode the task processing the previous event will be cancelled and awaited. Unprocessed events except the last one are discarded. Discarded events are reported as cancelled, even if their task was never started.
mode=’wait’ or just ‘w’ (wait before start)
In this mode the task processing the previous event will be awaited before the next one is started. All events are enqueued and processed one by one in order of arrival. This may introduce delays. Make sure the coroutine can keep up with the rate of incoming events.
mode=’start’ or ‘s’ (start immediately)
In this mode a new task is immediately started for each new event regardless of the state of previously started tasks. Unlike other modes, multiple output tasks may be running concurrently. The order of their termination may differ from the order they were started.
Output: The output of an OutputAsync block is the number of active output tasks, a non-negative integer. It can be only 0 (idle) or 1 (active) in the
'cancel'and'wait'modes. In the'start'mode the active task count is not limited.Generated events: The block triggers on_success, on_cancel and on_error events depending on the result of the task. A normal termination is considered a success and the returned value is added to the on_success event data as
'value'. An exception other thanasyncio.CancelledErrormeans an error; the raised exception is added to the on_error event data as'error'. Cancelled tasks trigger on_cancel events. Note that tasks are cancelled only in the'cancel'mode. In all three cases (success, cancel, error) the original'put'event data is inserted into the output event data as item'put'. This makes it possible to match an event with its result.Note
Due to the asynchronous character of this block, some events may be generated during the simulation shutdown. It those events are sent to other asynchronous blocks, their effect is undefined, because those destination blocks are shutting down as well. Events sent to non-asynchronous blocks will be always processed normally.
Final state: If the stop_data is defined, it is processed as the last item before stopping. As this happen during the stop phase, make sure the stop_timeout gives enough time for finishing all work in progress and then a successful output task run with stop_data.
Guard time: The guard_time is the duration in seconds of a mandatory and uncancellable sleep after each run of the output task. No output activity can happen during the sleep. The purpose is to limit the frequency of actions, for instance when controlling a hardware switch. Default value is
Nonefor no guard_time, equivalent to 0.0 seconds. The guard_time must not be longer than the stop_timeout.Note
The guard_time should not be used in the
'start'mode which allows multiple output tasks running concurrently defeating the effect of a guard_time sleep.
- class edzed.InExecutor(func, executor=concurrent.futures.ThreadPoolExecutor)¶
Create a coroutine function - suitable as coro argument in
OutputAsync- that runs the provided regular function func in a thread pool or other executor, e.g. a process pool. This allows to run an otherwise blocking function without actually blocking the asyncio’s event loop.InExecutoris a thin wrapper around the asyncio’s run_in_executor. Starting with Python 3.9 asyncio provides to_thread with similar functionality, but different usage.
Initialization helper¶
- class edzed.InitAsync(name, *, init_coro: Sequence, **block_kwargs)¶
Run a coroutine once during the circuit initialization.
This block usually initializes other blocks lacking an async support by sending an output event. For example it can obtain a value from an external command and send it to an
Inputblock in a'put'event.- Parameters:
init_coro – a sequence (list, tuple, …) containing the coroutine function (i.e. defined with
async def) to be awaited followed by its arguments.
In order to fully utilize this block, you might need to specify additional parameters. Refer to the base class
SBlock.- Parameters:
init_timeout – the coroutine timeout
initdef – a default value for the case the coroutine fails
on_output – an output event addressed to the block to be initialized
If the coroutine finishes successfully, the block’s output is set to the returned value. That generates an output event.
If the coroutine fails (timeout, exception), the problem is logged and the output is set to the
initdefvalue if it is defined. That generates an output event too.If the coroutine fails and the
initdefvalue is not set, then no output events are generated. The output is set toNoneonly to prevent a circuit failure. The block listed as the event recipient must initialize by itself.See also
NotIfInitializedevent filter
Counter¶
- class edzed.Counter(name, *, modulo: int | float | None = None, initdef=0, persistent=False, **kwarg)¶
A counter.
If modulo is set to a number M, count modulo M. For a positive integer M it means to count only from 0 to M-1 and then wrap around. If modulo is not set, the output value is not bounded.
The counter can process floats, but be prepared for inevitable rounding errors of floating point arithmetic.
Initialization parameters:
- Parameters:
persistent (bool) – If true, initialize from the last known value
initdef – Initial value, 0 by default
Accepted events and relevant data items:
'inc'increment (count up) by 1 or by the value of
'amount'data item if such item is present in the event data
'dec'decrement (count down) the counter by 1 or by
'amount'
'put'set to
'value'data item (mod M)
'reset'reset to the initial value as defined by initdef
All events return the updated output value.
Repeat¶
- class edzed.Repeat(name, *, dest, etype='put', interval, count=None, **block_kwargs)¶
Periodically repeat the last received event.
- Parameters:
etype (str or EventType) – type of events to be repeated
dest (block.SBlock or str) – destination block, an instance or its name
interval (int or float or str) – time interval between repetitions
count (int or None) – optional limit for repetition count, the original event is not counted
Tip
The
Eventclass offers a convenient automatic creation of aRepeatblock for a given event. It is the preferred method for most cases. However, if there are multiple event sources for the given destination, an explicitly createdRepeatblock is necessary.The Repeat block is intended mainly to repeat output events and thus minimize the chance that some connected device will fail to act due to temporary communication problems. The key requirement is that repeating must not change the outcome, i.e. multiple invocations produce the same effect as a single invocation. Such actions are called idempotent.
For a predictable operation only one selected event type etype is repeated and all others are ignored. This implies a separate
Repeatblock for each event type. A warning is logged on the first encounter with an unexpected type.The event is sent to the destination block specified by dest. The received event is re-sent immediately and then duplicates are sent in time intervals specified by interval. The number of repetitions may be limited with count. If not
None, the repeating stops after count duplicates sent. The original event is always re-sent and not counted.A Repeat block saves the event data item
'source'to'orig_source', because the block itself will become the source. It also adds a'repeat'count value. The original event is sent withrepeat=0, subsequent repetitions are sent withrepeat=Nwhere N is 1, 2, 3, … This repeat value is also copied to the output, the initial output is 0.Important
It is not possible to repeat the conditional event
EventCond. The condition is evaluated and one of the two choices is selected before the event reaches theRepeatblock.Note
It is recommended to repeat only events identified by a string.
The type of every received event is compared with the etype argument. This is a well-defined operation for strings, but the comparison result for special events (derived from the
EventType) depends on how the equality is defined in the particular class. This concerns mainly user-defined special events, becauseedzedprovides only two special events from which theEventCondcannot be repeated and theGotoshould not be even sent from block to block.
Timer¶
- class edzed.Timer(name, *, restartable=True, persistent=False, **block_kwargs)¶
A timer (source).
This is an FSM block. The output is
Falsein state'off'for time duration t_off, thenTruein state'on'for duration t_on, and then the cycle repeats.By default both durations are infinite (timer disabled), i.e. the block is bistable. If one duration is set, the block is monostable. If both durations are set, the block is astable.
- Parameters:
restartable (bool) – If
True(default), a'start'event occurring while in the'on'state restarts the timer to measure the't_on'time from the beginning. If not restartable, the timer will continue to measure the time and ignore the event. The same holds for the'stop'event in the'off'state.
The
Timeraccepts all standard FSM parameters and a t_period added for convenience:- Parameters:
t_on –
'on'state timer durationt_off –
'off'state timer durationt_period –
t_period=Tis a shortcut for settingt_on = t_off = T/2, i.e. to create a clock signal generator with the periodT(plus some small overhead) and a duty cycle of 50%. Arguments t_period and t_on, t_off are mutually exclusive.initdef – Set the initial state. Default is
'off'. Useinitdef='on'to start in the'on'state.persistent – Enable persistent state.
Events:
'start'Go to the
'on'state. See also: restartable.
'stop'Go to the
'off'state. See also: restartable.
'toggle'Go from
'on'to'off'or vice versa.
Hint
A conditional event
EventCond('start', 'stop')is often used forTimercontrol.
Simulator control block¶
- class edzed.ControlBlock(name, **block_kwargs)¶
The simulator control block accepts two event types:
'shutdown'Shut down the circuit.'abort'Abort the simulation due to an error. An'error'item is expected to be included in the event data. Its value may be anExceptionobject or just an error message.
A ControlBlock named
'_ctrl'will be automatically created if there exists a reference to this name in the circuit. TheEventclass provides constructorsEvent.abort()andEvent.shutdown()creating the corresponding events in a convenient way.The output value is fixed to
None.