/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * Copyright 2009 Raritan Inc. All rights reserved.
 */

#include <Sensor.idl>
#include <PeripheralDeviceSlot.idl>
#include <UserEvent.idl>

/** Sensors Model */
module sensors {

    /**
     * Sensor logger interface.
     *
     * The sensor log stores a fixed number of log records for each
     * enabled sensor. Log records hold the minimum, maximum and average
     * reading of all samples within the period as well as the most
     * critical state.
     *
     * Record IDs start at 1 and grow continuously without wrap-around. To
     * avoid race conditions it is allowed to request records that are no
     * longer available, i.e. have rotated out of the log. Unavailable
     * records come back empty (available = false, timestamp = 0). It is
     * not OK to read past newestRecId.
     *
     * Log record periods are synchronized with the system time, so all
     * devices with the same log settings and proper time configuration
     * move to a new record simultaneously.
     */
    interface Logger_3_1_4 {

        /** Sensor logger info */
        structure Info {
            int samplePeriod;                   ///< Sample interval in milliseconds
            int maxTotalRecords;                ///< Maximum supported number of log records (number of
                                                ///< logged sensors multiplied by log capacity)
            int effectiveCapacity;              ///< Effective log capacity; may be lower than the
                                                ///< setting to meet the maxTotalRecords limit.
            int oldestRecId;                    ///< ID of oldest record in buffer (0 if empty)
            int newestRecId;                    ///< ID of newest record in buffer (0 if empty)
        };

        /** Sensor logger settings */
        structure Settings {
            boolean isEnabled;                  ///< \c true if sensor logging is enabled
            int samplesPerRecord;               ///< Number of samples per log record
            int logCapacity;                    ///< Maximum number of log records in buffer
            boolean backupEnabled;              ///< \c true if backup to external storage is enabled
        };

        /** Set of logged sensors */
        structure SensorSet {
            /** List of numeric or state sensors */
            vector<sensors.Sensor_4_0_7> sensors;
            /** List of peripheral device slots */
            vector<peripheral.DeviceSlot_5_0_2> slots;
        };

        /** Event: Sensor logger info has changed */
        valueobject InfoChangedEvent extends idl.Event {
            Info oldInfo;                       ///< Info before change
            Info newInfo;                       ///< Info after change
        };

        /** Event: Sensor logger settings have been changed */
        valueobject SettingsChangedEvent extends event.UserEvent {
            Settings oldSettings;               ///< Settings before change
            Settings newSettings;               ///< Settings after change
        };

        /** Event: Set of logged sensors has been changed */
        valueobject LoggedSensorsChangedEvent extends event.UserEvent {
            SensorSet oldSensors;               ///< Sensor set before change
            SensorSet newSensors;               ///< Sensor set after change
        };

        /**
         * Retrieve the sensor logger info.
         *
         * @return Sensor logger info
         */
        Info getInfo();

        /**
         * Retrieve the sensor logger settings.
         *
         * @return Sensor logger settings
         */
        Settings getSettings();

        /**
         * Change the sensor logger settings.
         *
         * @param settings  New settings
         *
         * @return 0 if OK
         * @return 1 if any parameters are invalid
         */
        int setSettings(in Settings settings);

        /** Sensor state in log record */
        constant int STATE_UNAVAILABLE = 0;             ///< Unavailable
        constant int STATE_OPEN = 1;                    ///< Circuit breaker open
        constant int STATE_CLOSE = 2;                   ///< Circuit breaker closed
        constant int STATE_BELOW_LOWER_CRITICAL = 3;    ///< Numeric sensor below lower critical threshold
        constant int STATE_BELOW_LOWER_WARNING = 4;     ///< Numeric sensor below lower warning threshold
        constant int STATE_NORMAL = 5;                  ///< Numeric sensor in normal range; normal operation
        constant int STATE_ABOVE_UPPER_WARNING = 6;     ///< Numeric sensor above upper warning threshold
        constant int STATE_ABOVE_UPPER_CRITICAL = 7;    ///< Numeric sensor above upper critical threshold
        constant int STATE_ON = 8;                      ///< Power state on
        constant int STATE_OFF = 9;                     ///< Power state off
        constant int STATE_ALARMED = 10;                ///< Alarmed
        constant int STATE_OK = 11;                     ///< OK
        constant int STATE_MARGINAL = 12;               ///< Marginal
        constant int STATE_FAIL = 13;                   ///< Fail
        constant int STATE_YES = 14;                    ///< Yes
        constant int STATE_NO = 15;                     ///< No
        constant int STATE_STANDBY = 16;                ///< Standby operation
        constant int STATE_ONE = 17;                    ///< First source active
        constant int STATE_TWO = 18;                    ///< Second source active
        constant int STATE_IN_SYNC = 19;                ///< Phases are in sync
        constant int STATE_OUT_OF_SYNC = 20;            ///< Phases are out of sync
        constant int STATE_FAULT = 21;                  ///< Fault
        constant int STATE_SELF_TEST = 22;              ///< Sensor is currently testing itself
        constant int STATE_I1_OPEN_FAULT = 23;          ///< Inlet 1 switch open fault
        constant int STATE_I1_SHORT_FAULT = 24;         ///< Inlet 1 switch short fault
        constant int STATE_I2_OPEN_FAULT = 25;          ///< Inlet 2 switch open fault
        constant int STATE_I2_SHORT_FAULT = 26;         ///< Inlet 2 switch short fault
        constant int STATE_WARNING = 27;                ///< Warning
        constant int STATE_CRITICAL = 28;               ///< Critical
        constant int STATE_NON_REDUNDANT = 29;          ///< Non-redundant operation
        constant int STATE_INACTIVE = 30;               ///< Bypass inactive
        constant int STATE_BYPASS_SELECTED_BUT_INACTIVE = 31; ///< Bypass selected but inactive
        constant int STATE_I1_ACTIVE = 32;              ///< Inlet 1 active
        constant int STATE_I2_ACTIVE = 33;              ///< Inlet 2 active
        constant int STATE_BYPASS_ACTIVE = 34;          ///< Operational state: bypass active

        /**
         * Retrieve a set of log record timestamps.
         *
         * @param timestamps  Result: Log record timestamps
         * @param recid       First record id
         * @param count       Number of records
         *
         * @return 0 if OK
         * @return 1 if any record id is invalid
         */
        int getTimeStamps(out vector<time> timestamps,
                          in int recid, in int count);

        /** Sensor log record */
        structure Record {
            boolean available;                  ///< Sensor was available for at least one sample
            int takenValidSamples;              ///< Number of samples with a valid reading/state
            int state;                          ///< Sensor state
            double minValue;                    ///< Minimum sensor reading
            double avgValue;                    ///< Average sensor reading
            double maxValue;                    ///< Maximum sensor reading
        };

        /**
         * Retrieve log records for a given sensor.
         *
         * @param recs    Result: Sensor log records
         * @param sensor  Sensor reference
         * @param recid   First record id
         * @param count   Number of records
         *
         * @return 0 if OK
         * @return 1 if any record id is invalid
         */
        int getSensorRecords(out vector<Record> recs, in sensors.Sensor_4_0_7 sensor,
                             in int recid, in int count);

        /**
         * Retrieve log records for an peripheral device slot.
         *
         * @param recs       Result: Sensor log records
         * @param slot       Peripheral device slot reference
         * @param recid      First record id
         * @param count      Number of records
         *
         * @return 0 if OK
         * @return 1 if any record id is invalid
         */
        int getPeripheralDeviceRecords(out vector<Record> recs,
                                       in peripheral.DeviceSlot_5_0_2 slot,
                                       in int recid, in int count);

        /** Sensor log record with timestamp */
        structure TimedRecord {
            time timestamp;                     ///< UNIX timestamp (UTC)
            Record record;                      ///< Log record
        };

        /**
         * Retrieve log records with timestamps for a given sensor.
         *
         * @param recs    Result: Sensor log records
         * @param sensor  Sensor reference
         * @param recid   First record id
         * @param count   Number of records
         *
         * @return 0 if OK
         * @return 1 if any record id is invalid
         */
        int getSensorTimedRecords(out vector<TimedRecord> recs, in sensors.Sensor_4_0_7 sensor,
                            in int recid, in int count);

        /**
         * Retrieve log records with timestamps for an peripheral device slot.
         *
         * @param recs       Result: Sensor log records
         * @param slot       Peripheral device slot reference
         * @param recid      First record id
         * @param count      Number of records
         *
         * @return 0 if OK
         * @return 1 if any record id is invalid
         */
        int getPeripheralDeviceTimedRecords(out vector<TimedRecord> recs,
                                            in peripheral.DeviceSlot_5_0_2 slot,
                                            in int recid, in int count);

        /**
         * Retrieve the set of logged sensors.
         *
         * @return Set of logged sensors
         */
        SensorSet getLoggedSensors();

        /**
         * Change the set of logged sensors.
         *
         * @param sensors  New set of sensors
         *
         * @return 0 if OK
         * @return 1 if any sensor in the list is unknown
         */
        int setLoggedSensors(in SensorSet sensors);

        /**
         * Enable logging for one or more sensors or peripheral device slots.
         *
         * Sensors in the list that are already logged are ignored. Logged
         * sensors not in the list remain enabled.
         *
         * @param sensors  Sensors and slots to be logged
         *
         * @return 0 if OK
         * @return 1 if any sensor in the list is unknown
         */
        int enableSensors(in SensorSet sensors);

        /**
         * Disable logging for one or more sensors or peripheral device slots.
         *
         * Sensors in the list that are not logged are ignored. Logged sensors
         * not in the list remain enabled.
         *
         * @param sensors  Sensors and slots to be disabled
         *
         * @return 0 if OK
         * @return 1 if any sensor in the list is unknown
         */
        int disableSensors(in SensorSet sensors);

        /**
         * Check if logging is enabled for a given sensor.
         *
         * @param sensor  Sensor to be checked
         *
         * @return \c true if sensor is logged, \c false otherwise
         */
        boolean isSensorEnabled(in sensors.Sensor_4_0_7 sensor);

        /**
         * Check if logging is enabled for a given peripheral device slot.
         *
         * @param sensor  Peripheral device slot to be checked
         *
         * @return \c true if slot is logged, \c false otherwise
         */
        boolean isSlotEnabled(in peripheral.DeviceSlot_5_0_2 slot);

        /**
         * Enable logging for all PDU sensors.
         */
        void enableAllSensors();

        /**
         * Disable logging for all PDU sensors.
         */
        void disableAllSensors();

        /**
         * Get the time of the last sensor set modification.
         *
         * This can be used by clients which keep a cached copy of the sensor
         * set to determine whether that copy is still up-to-date.
         *
         * @return Sensor set time stamp (UNIX timestamp, UTC)
         */
        time getSensorSetTimestamp();

        /** One full log row */
        structure LogRow {
            /** Time of last sensor set modification (UNIX timestamp, UTC) */
            time sensorSetTimestamp;
            /** Log row time stamp (UNIX timestamp, UTC) */
            time timestamp;
            /** Sensor records; same order as in SensorSet::sensors */
            vector<Record> sensorRecords;
            /** Peripheral device records; same order as in SensorSet::slots */
            vector<Record> peripheralDeviceRecords;
        };

        /**
         * Get one full log row.
         *
         * @param row    Result: Log row
         * @param recid  Record id
         *
         * @return 0 if OK
         * @return 1 if the record id is invalid
         */
        int getLogRow(out LogRow row, in int recid);

    };

}
