granola.command_readers module

Command Readers are the objects that handle the processing of individual serial commands. Each serial command that comes in is processed by each Command Reader and once a Command Reader returns a valid response, the next Command Readers will skip processing the command. This allows you to change the behavior of individual commands by defining new Command Readers.

class granola.command_readers.BaseCommandReaders(hooks=None, data_path_root=None, *args, **kwargs)

Bases: ABC

BaseCommandReaders Class that sets the interface for other CommandReaders. The basic form of a command reader is that Cereal will interact with it solely through its __init__ and granola.command_readers.BaseCommandReaders.get_reading(). The get_reading method is the method that will be called, handed in a serial command, processed in some way, and returned. If the Command Reader can not process the serial command, it instead returns None or a SENTINEL object (more on that below) to indicate that the supplied serial command isn’t defined for that Command Reader, allowing any other Command Readers to process it instead.

The get_reading commands are also decorated with @wrap_in_hooks, which will run _hooks_ attributes (of type hooks) that have a defined prehook method before get_reading and _hooks_ with a defined posthook method after after get_reading.

Because “” is a valid serial command response, we use None to signify an unsupported response. We also have a defined SENTINEL object for responses that are undefined in other ways. For example, Canned Queries (command and response defined from list) by default loop back when they get to the end of the list. However, if you exclude a command from that list, and then don’t handle it another way, we return a SENTINEL object instead of having undefined behavior. Cereal will treat this as an undefined response, but also emit a warning log message as well.

Parameters
  • hooks (list[BaseHook], optional) – List of Hooks to run on this Command Reader. Defaults to []

  • data_path_root (str | Path, optional) – Base path for all data file paths for this command reader (such as defining the serial commands). Not every Command Reader, or every way to initialize a certain Command Reader uses data files, so this doesn’t apply to every Command Reader. Defaults to current working directory.

See also

Cereal : Breakfast Cereal class used for mocking Custom Command Readers and Hooks Configuration : Configuration Overview Basic Overview of Mock Cereal and API : Intro Tutorial

assign_default_hook()

If self._hooks_ hooks is empty, add any default hooks for this Command Reader.

abstract get_reading(data)

Processes incoming serial command data and return a response if a matching one is found.

Parameters

data (str) – Incoming serial command

Returns

the response from either the matching getter or setter.

Returns None if serial command is not supported. Returns SENTINEL as a flag for some kind of none processing of the serial command by the hooks and CommandReader, dependent on the individual CommandReader.

Return type

str | None | SENTINEL

register_hook(hook)
class granola.command_readers.CannedQueries(data=None, data_path_root=None, **kwargs)

Bases: BaseCommandReaders

Helper class that processes canned queries (queries defined ahead of time from a list such as a csv or configuration dictionary).

It stores a dictionary of SerialCmds, which represents canned queries as pandas DataFrames of the serial commands. And then as a serial command comes in, it is directed to the correct SerialCmds and then creates a slice of your DataFrame to get only the matching serial commands to iterate over.

See also

Canned Queries Configuration for examples on configuration formatting.

Custom Command Readers and Hooks Configuration : Command Readers and Hook Overviews

assign_default_hook()

If self._hooks_ hooks is empty, add any default hooks for this Command Reader.

get_reading(data)

Process incoming canned queries by extracting just the serial commands that match the incoming serial command and then create a generator of those matching serial commands and response to iterate through.

Parameters

data (str) – Incoming serial command

Returns

the response from matching serial df. If no matching matching command is found, then it returns None. If The generator is exhausted, and no Hook is activate to reseed the generator or alter the behavior in some other way, return SENTINEL.

Return type

str | None | SENTINEL

See also

Hooks : Hook API information

Canned Queries Configuration for examples on configuration formatting.

Custom Command Readers and Hooks Configuration : Command Readers and Hook Overviews

class granola.command_readers.GettersAndSetters(default_values=None, getters=None, setters=None, variable_start_string='{{', variable_end_string='}}', **kwargs)

Bases: BaseCommandReaders

Command Reader to handle getters and setters. It initializes the default values and stores those values in the attribute self.instrument_attributes. These attributes can then be modified with setters defined in the setters in self.setters, and then grabbed from the getters stored in self.getters.

Inside the getters and setters, the formatting follows Jinja2 formatting syntax.

Parameters

BaseCommandReaders (arguments for) –

property attribute_vals
get_reading(data)

Processes incoming serial command data and sends it to self._process_getter to see if it is a getter and get its response, if not, sends it to self._process_setter, to see if it is a setter and then set the respective setter and get its response, if not, it returns None.

Parameters

data (str) – Incoming serial command

Returns

the response from either the matching getter or setter. If no matching

getter or setter, then it returns None.

Return type

str | None

render_template(string, attribute_vals=None)
class granola.command_readers.InstrumentAttribute(name, value, meta_data=None)

Bases: object

class granola.command_readers.SerialCmds(data=None, will_randomize_responses=RandomizeResponse.not_randomized)

Bases: object

Serial Command DataFrame container object. Required columns for DataFrame are cmd and response, Other columns are optional, and may or may not be used by certain Command Readers.

Parameters
  • data (list[pd.DataFrame]) – list of DataFrames containing serial command, response pairs, as well potentially other columns.

  • will_randomize_responses (RandomizeResponse) – Whether the responses of each command will be randomized or not.

See also

Class CannedQueries

Config guide Canned Queries Configuration

add_dataframe(df)

Add dataframe to data

add_df_from_dict(dic, **kwargs)

Add a df to data from a dictionary of serial commands. The format for this dictionary can take a few forms. It can either be expressed in a JSON configuration or passed as a python dictionary to Cereal. Here is the most basic form, where each command is mapped directly to a single response.

Parameters
  • dic (dict) – Dictionary of serial commands. See examples above for formatting.

  • extra_fields (dict) – Dictionary of extra fields to add to DataFrame of commands. Either key will be mapped to a new column in the DataFrame, and each value can either be a single value, in which case it will be broadcast to all rows. Or a list of values the same length as the number of rows in the data.

add_df_from_file(file, data_path_root=None, **kwargs)

Add a df to data from a csv file path

Parameters
  • file (str) – Path to csv file.

  • data_path_root (str, optional) – Path to configuration. Required if file path is not an absolute path

  • extra_fields (dict, optional) – Dictionary of extra fields to add to DataFrame of commands. Either key will be mapped to a new column in the DataFrame, and each value can either be a single value, in which case it will be broadcast to all rows. Or a list of values the same length as the number of rows in the data.