NAME App::Device::Chip::sensor - Base class to build Device::Chip::Sensor-based applications on SYNOPSIS #!/usr/bin/perl use v5.26; use Object::Pad; use Future::AsyncAwait; class App extends App::Device::Chip::sensor { method output_readings ( $now, $sensors, $values ) { print "At time $now, we have some sensor values...\n"; } } await App->new->parse_argv->run; DESCRIPTION This module provides a base class to assist in writing applications that process data periodically from one or more Device::Chip-based sensors, via the Device::Chip::Sensor interface. A typical program using this module would derive a subclass from it, provide the remaining methods as necessary, and eventually call the "run" method to start the application. COMMANDLINE OPTIONS The following commandline options are recognised by the base class and may be used in addition to any defined by the actual application logic. * --blib, -b Uses the blib module to add additional paths into @INC to search for more Perl modules. May be useful when testing chip drivers under development without needing to install them. * --interval, -i TIME Specifies the time, in seconds, between every round of collecting sensor readings and invoking the "output_readings" method. Defaults to 10 seconds. * --adapter, -A STR Adapter configuration string to pass to "new_from_description" in Device::Chip::Adapter to construct the chip adapter used for communication with the actual chip hardware. * --mid3, -m Enable "middle-of-3" filtering of gauge values, to reduce sensor noise from unreliable sensors. At each round of readings, the most recent three values from the sensor are sorted numerically and the middle one is reported. * --best-effort, -B Enables best-effort mode, which causes failures of sensor readings to be ignored, reporting undef instead. In this mode, the on_sensor_fail method may be invoked for failures; it can further refine what the behaviour should be. PROVIDED METHODS The following methods are provided on the base class, intended for subclasses or applications to invoke. parse_argv $app->parse_argv() $app->parse_argv( \@argv ) Provides a list of commandline arguments for parsing, either from a given array reference or defaulting to the process @ARGV if not supplied. This uses "OPTSPEC" to collect the defined arguments, whose references should handle the results. add_chip $app->add_chip( %config ); Since version 0.05. Adds a new chip to the stored configuration, as if it had been given as a commandline argument. Takes the following named arguments: type => STR Required string that gives the name of the chip class. adapter => Device::Chip::Adapter Required Device::Chip::Adapter instance. mountopts => HASH Optional hASH reference containing extra mount parameters. config => HASH Optional HASH reference containing extra chip configuration to set up using the configure method once mounted. chips @chips = await $app->chips; An asynchronous memoized lazy accessor for the list of Device::Chip instances, whose class names are taken from the remaining commandline arguments after the options are parsed. chips @sensors = await $app->sensors; An asynchronous memoized lazy accessor for the list of Device::Chip::Sensor instances of each of the configured chips (from the "chips" method). run await $app->run; An asynchronous method which performs the actual run loop of the sensor application. This implements the main application logic, of regular collection of values from all of the sensor instances and reporting them to the "output_readings" method. In normal circumstances the Future instance returned by this method would remain pending for the lifetime of the program, and not complete. For an application that has nothing else to perform concurrently it can simply await this future to run the logic. If it has other logic to perform as well it could combine this with other futures using a Future->needs_all or similar techniques. print_readings $app->print_readings( $sensors, $values ) Prints the sensor names and current readings in a human-readable format to the currently-selected output handle (usually STDOUT). REQUIRED METHODS This base class itself is incomplete, requiring the following methods to be provided by an implementing subclass to contain the actual application logic. output_readings $app->output_readings( $now, $sensors, $values ); This method is invoked regularly by the "run" method, to provide the application with the latest round of sensor readings. It is passed the current UNIX epoch timestamp as $now, an array reference containing the individual Device::Chip::Sensor instances as $sensors, and a congruent array reference containing the most recent readings taken from them, as plain numbers. The application should put the bulk of its processing logic in here, for example writing the values to some sort of file or database, displaying them in some form, or whatever else the application is supposed to do. OVERRIDABLE METHODS The base class provides the following methods, but it is expected that applications may wish to override them to customise the logic contained in them. If using Object::Pad to do so, don't forget to provide the :override method attribute. OPTSPEC %optspec = $app->OPTSPEC; This method is invoked by the "parse_argv" method to construct a definition of the commandline options understood by the program. These are returned in a key/value list to be processed by Getopt::Long. If the application wishes to parse additional arguments it should override this method, call the superclass version, and append any extra argument specifications it requires. As this is invoked as a regular instance method, a convenient way to store the parsed values is to pass references to instance slot variables created by the Object::Pad field keyword: field $_title; field $_bgcol = "#cccccc"; method OPTSPEC :override { return ( $self->SUPER::OPTSPEC, 'title=s' => \$_title, 'background-color=s' => \$_bgcol, ); } after_sensors await $app->after_sensors( @sensors ) This method is invoked once on startup by the "run" method, after it has configured the chip adapter and chips and obtained their individual sensor instances. The application may wish to perform one-time startup tasks in here, such as creating database files with knowledge of the specific sensor data types, or other such behaviours. on_sensor_ok $app->on_sensor_ok( $sensor ) This method is invoked in --best-effort mode after a successful reading from sensor; typically this is used to clear a failure state. The default implementation does nothing. on_sensor_fail $app->on_sensor_fail( $sensor, $failure ) This method is invoked in --best-effort mode after a failure of the given sensor. The caught exception is passed as $failure. The defaullt implementation prints this as a warning using the core warn() function. AUTHOR Paul Evans <leonerd@leonerd.org.uk>