IOMapper
Under Construction
IOMapper is a generalization of external bind requests, hiding details that the main 'controller' application doesn't need to know, the gritty 'how to' mechanism of determining call structure and marshalling parameters.
Basic structures:
| values | VolatileDict ['indexable', 'Any'] | source of all values, very dynamic. Can be defined and owned externally to iomapper. |
| iomap | dict [str,Map] | key/value 'action key' / Map Definition. |
| read_keys | list [str] | action keys for read_cycle, to sync the values dict with state of external objects, can trigger a chain of actions. |
| local_values | dict [str, 'ObjectRef'] | key names / references to objects local to IOMapper. |
| transforms | dict [str, 'FunctionRef'] | transform values returned into values in the values dict. |
Working Structures:
| vkeys | list[str] | a list of dictionary keys in the values dict, like OrderedDict with extra functionality. Default dict is unordered in MicroPython. |
| keys_changed | list[str] | list of keys with changed values in the values dict since the last reset ( clear changed flags ). Generated from changed integer, bit encoded to vkeys. |
| agenda | list[Run, SetVal] | a list of actions to be performed in the next binding cycle, that is method read_into_values |
The Map Definition is a namedtuple structure for mapping requests to calls.
| wrap | item/attr getter or item/attr setter |
| target | function name or parameter for item/attr setter |
| params | list of key names for the values dict |
| vreturn | key name of value to update in the values dict |
| chain | list of action keys for function(s) in the iom dict, post-processing, mostly for sync of values in values dict. |
IOMapper being driven by a controller.

A more detailed view:
Note that there is an 'undefined' transitional state in the values dict, which can be in a mixed state reflecting both old and new values. Using action 'set_a' would require updating the value of a, which would be inconsistent until set_a is executed and the update chain synchronizes the dependent values.
Two ways to update IOMapper:
- Direct update using valuesdict['vkey'] = 'newvalue' and then write('action_key'), where 'action_key' uses parameter valuesdict['vkey']. This takes effect immediately and changes get lost in the next binding cycle. That is the meaning of phrase "no key change" in the diagram. The cycle reset zeros out all changes from the previous cycle.
- Add actions and value setting to the agenda for update at the start of the next cycle. This preserves key changed flags and is absolutely required by the IOEngine class driving an IOMapper instance.
IOMapper Example

In an async world, there may need to be a locked state for the VolatileDict, or a locking 'bitint' for sets of individual value keys.
Aside: How long does it take to read a digital thermometer ? 10 milliseconds, 20 ? 500 or more !!!
-
asyncio dir from MicroPython, implementing maybe one third of Python 3.9 methods:
>>> import asyncio as a >>> dir(a) [ '__class__', '__getattr__', '__name__', '__dict__', '__file__', '__path__', '__version__', '_attrs', 'CancelledError', 'Task', 'TaskQueue', 'Event', 'IOQueue', 'Lock', 'Loop', 'SingletonGenerator', 'StreamReader', 'StreamWriter', 'ThreadSafeFlag', 'TimeoutError', 'run', 'select', 'sleep', 'sleep_ms', 'sys', 'ticks_add', 'ticks_diff', 'core', 'create_task', 'current_task', 'event', 'gather', 'get_event_loop', 'new_event_loop', 'open_connection', 'run_until_complete', 'start_server', 'stream', 'ticks', 'wait_for', 'wait_for_ms']