classdef DRLCFrameConfig  < matlab.mixin.CustomDisplay
  %DRLCFRAMECONFIG Configuration for ZigBee Smart Energy frames of the DRLC cluster
  % FRAMECONFIG = DRLCFRAMECONFIG creates a configuration object for
  % DRLC frames of the ZigBee Smart Energy cluster.
  %
  % FRAMECONFIG = DRLCFRAMECONFIG(Name, Value) creates a configuration
  % object for ZigBee Smart Energy frames of the DRLC clusters with the
  % specified property Name set to the specified Value. You can specify
  % additional name-value pair arguments in any order as (Name1, Value1,
  % ..., NameN, ValueN).
  %
  % DRLCFrameConfig properties:
  %
  % CommandType       - Command type
  % EventID           - ID of Load Control Event
  % DeviceClass       - Device Class
  % DeviceGroup       - Subset of a device class
  % Time              - Start time, Effective time, or Event Status time
  % Duration          - Duration of event in minutes
  % CriticalityLevel  - Criticality level
  % CoolingOffset     - Change to the cooling set point
  % HeatingOffset     - Change to the heating set point
  % CoolingSetPoint   - Cooling set point
  % HeatingSetPoint   - Heating set point
  % RandomStart       - Option to randomize start time of event
  % RandomEnd         - Option to randomize end time of event
  % EventStatus       - Status of Event
  %
  % See also zigbee.DRLCFrameGenerator, zigbee.DRLCFrameDecoder.

  %   Copyright 2017-2023 The MathWorks, Inc.

  properties
    %CommandType Command type
    % Specify CommandType as one of 'Load Control Event' | 'Cancel Load
    % Control Event' | 'Cancel All Load Control Events' | 'Report Event
    % Status'. The default is 'Load Control Event'.
    CommandType = 'Load Control Event'  

    %EventID ID of Load Control Event
    % Specify EventID as an 8-character hexadecimal vector denoting a
    % unique event identifier generated by the energy provider. The special
    % value 'FFFFFFFF' indicates the current event. The default is
    % '00000000'.
    EventID = '00000000'
    
    %EventStatus Status of Event
    % Specify EventStatus as one of 'Command received' | 'Event started' |
    % 'Event completed' | 'User opt-out' | 'User opt-in' | 'Event
    % cancelled' | 'Event superseded' | 'Partial completion (opt-out)' |
    % 'Partial completion (opt-in)' | 'Event completed (opt-out)' |
    % 'Invalid Cancel Command' | 'Invalid Effective Time' | 'Event Received
    % after Expiry' | 'Undefined Event' | 'Load Control Event command
    % rejected'. The default is 'Command received'
    EventStatus = 'Command received'

    %DeviceClass Device Class
    % Specify DeviceClass as one of 'HVAC Compressor or Furnace' | 'Strip
    % Heaters/Baseboard Heaters' | 'Water Heater' | 'Pool Pump/Spa/Jacuzzi'
    % | 'Smart Appliances' | 'Irrigation Pump' | 'Managed Commercial &
    % Industrial (C&I) loads' | 'Simple misc. (Residential On/Off) loads' |
    % 'Exterior lighting' | 'Interior lighting' | 'Electric Vehicle' |
    % 'Generation Systems'. The default is 'HVAC Compressor or Furnace'.
    DeviceClass = 'HVAC Compressor or Furnace'

    %DeviceGroup Subset of a device class
    % Specify DeviceGroup as a two-character hexadecimal vector. This
    % property allows grouping of same-class devices in distinct groups.
    % The special value '00' denotes a group containing all devices of a
    % class. The default is '00'.
    DeviceGroup = '00'

    %Time Start time, Effective time, or Event Status time
    % Specify Time as a scalar non-negative real integer expressing the
    % number of seconds since midnight of 1-1-2000. This property
    % represents the Start time for Load Control Event commands, the
    % Effective time for Cancel Load Control Event commands and the Event
    % Status time for Report Event Status commands. The default is 0, which
    % is a special value denoting 'now'.
    Time = 0

    %Duration Duration of event in minutes
    % Specify Duration as a scalar non-negative real integer describing the
    % duration of the event in minutes (Since Start time). The default is 0.
    Duration = 0;

    %CriticalityLevel Criticality level
    % Specify CriticalityLevel as one of 'Green' | 'Load Reduction Level 1'
    % | 'Load Reduction Level 2' | 'Load Reduction Level 3' | 'Load
    % Reduction Level 4' | 'Load Reduction Level 5' | 'Emergency' |
    % 'Planned Outage' | 'Service Disconnect' | 'Utility Defined'. The
    % default is 'Green'.
    CriticalityLevel = 'Green'

    %CoolingOffset Change to the cooling set point
    % Specify CoolingOffset as a scalar non-negative real integer between 0
    % and 25.4 C. Changes can be applied at 0.1 C increments. The default
    % is 25.5, which indicates that this property is not used.
    CoolingOffset = 25.5

    %HeatingOffset Change to the heating set point
    % Specify HeatingOffset as a scalar non-negative real integer between 0
    % and 25.4 C. Changes can be applied at 0.1 C increments. The default
    % is 25.5, which indicates that this property is not used.
    HeatingOffset = 25.5
    
    %CoolingSetPoint Cooling set point
    % Specify CoolingSetPoint as a signed scalar integer between -273.15 
    % and 327.67 C. The setting must also be an integer multiple of 0.01 C.
    % The default is -327.68, which indicates that this property is not used.
    CoolingSetPoint = -327.68

    %HeatingSetPoint Heating set point
    % Specify HeatingSetPoint as a signed scalar integer between -273.15 
    % and 327.67 C. The setting must also be an integer multiple of 0.01 C.
    % The default is -327.68, which indicates that this property is not used.
    HeatingSetPoint = -327.68

    %RandomStart Option to randomize start time of event
    % Specify RandomStart as a scalar logical. If true, the event start
    % time is randomized. The default is true.
    RandomStart = true

    %RandomEnd Option to randomize end time of event
    % Specify RandomEnd as a scalar logical. If true, the event end
    % time is randomized. The default is true.
    RandomEnd = true
    
    %SignatureType Algorithm used for signature
    % The Report Event Status commands do not use signatures.
    SignatureType = 'No Signature' 
  end

  properties(Constant, Hidden)
    CommandTypeValues      = {'Report Event Status', 'Load Control Event', ...
        'Cancel Load Control Event', 'Cancel All Load Control Events'};
    DeviceClassValues      = {'HVAC Compressor or Furnace', 'Strip Heaters/Baseboard Heaters', ...
      'Water Heater', 'Pool Pump/Spa/Jacuzzi', 'Smart Appliances', 'Irrigation Pump', ...
      'Managed Commercial & Industrial (C&I) loads', 'Simple misc. (Residential On/Off) loads', ...
      'Exterior lighting', 'Interior lighting', 'Electric Vehicle', 'Generation Systems'}
    CriticalityLevelValues = {'Green', ...
      'Load Reduction Level 1', 'Load Reduction Level 2', 'Load Reduction Level 3', ...
      'Load Reduction Level 4', 'Load Reduction Level 5', 'Emergency', 'Planned Outage', 'Service Disconnect', 'Utility Defined'};
    EventStatusValues      = {'Command received', 'Event started', 'Event completed', ...
      'User opt-out', 'User opt-in', 'Event cancelled', 'Event superseded', ...
      'Partial completion (opt-out)', 'Partial completion (opt-in)', 'Event completed (opt-out)', ...
      'Invalid Cancel Command', 'Invalid Effective Time', 'Event Received after Expiry', ...
      'Undefined Event', 'Command rejected'};
    SignatureTypeValues    = {'No Signature'}
  end

  methods
    function obj = DRLCFrameConfig(varargin)
      % Apply constructor name value pairs:
      for i = 1:2:nargin
        obj.(varargin{i}) = varargin{i+1};
      end
    end
    
    function v = set(obj, prop)
      v = obj.([prop, 'Values']);
    end
    
    function obj = set.CommandType(obj, value)
      obj.CommandType = validatestring(value, obj.CommandTypeValues, '', 'CommandType');
    end
    
    function obj = set.EventID(obj, value)
      value = convertStringsToChars(value);
      validateattributes(value, {'char'}, {'row', 'numel', 8}, 'EventID');
      obj.EventID = value;
    end
     
    function obj = set.DeviceGroup(obj, value)
      value = convertStringsToChars(value);
      validateattributes(value, {'char'}, {'row', 'numel', 2}, '', 'DeviceGroup');
      obj.DeviceGroup = value;
    end
    
    function obj = set.Time(obj, value)
      validateattributes(value, {'numeric'}, {'scalar', 'integer', 'nonnegative', 'real', '<', 4294967296}, '', 'Time');
      obj.Time = value;
    end
    
    function obj = set.Duration(obj, value)
      validateattributes(value, {'numeric'}, {'scalar', 'integer', 'nonnegative', 'real', '<', 1440}, '', 'Duration');
      obj.Duration = value;
    end
    
    function obj = set.CriticalityLevel(obj, value)
      value = convertStringsToChars(value);
      validateattributes(value, {'char'}, {'row'}, '', 'CriticalityLevel');
      validatestring(value, obj.CriticalityLevelValues);
      obj.CriticalityLevel = value;
    end
    
    function obj = set.CoolingOffset(obj, value)
      validateattributes(value, {'numeric'}, {'scalar', 'nonnegative', 'real', '<=', 25.5}, '', 'CoolingOffset');
      obj.CoolingOffset = value;
    end
    
    function obj = set.HeatingOffset(obj, value)
      validateattributes(value, {'numeric'}, {'scalar', 'nonnegative', 'real', '<=', 25.5}, '', 'HeatingOffset');
      obj.HeatingOffset = value;
    end
    
    function obj = set.CoolingSetPoint(obj, value)
      validateattributes(value, {'numeric'}, {'scalar', 'real', '>=', -273.15, '<=', 327.68}, '', 'CoolingSetPoint');
      obj.CoolingSetPoint = value;
    end
    
    function obj = set.HeatingSetPoint(obj, value)
      validateattributes(value, {'numeric'}, {'scalar', 'real', '>=', -273.15, '<=', 327.68}, '', 'HeatingSetPoint');
      obj.HeatingSetPoint = value;
    end
    
    function obj = set.RandomStart(obj, value)
      validateattributes(value, {'logical'}, {'scalar'}, '', 'RandomStart');
      obj.RandomStart = value;
    end
    
    function obj = set.RandomEnd(obj, value)
      validateattributes(value, {'logical'}, {'scalar'}, '', 'RandomEnd');
      obj.RandomEnd = value;
    end
    
    function obj = set.EventStatus(obj, value)
      value = convertStringsToChars(value);
      obj.EventStatus = validatestring(value, obj.EventStatusValues, '', 'EventStatus');
    end
    
    function obj = set.SignatureType(obj, value)
      value = convertStringsToChars(value);
      obj.SignatureType = validatestring(value, obj.SignatureTypeValues, '', 'SignatureType');
    end
  end

  methods (Access = protected)
    function groups = getPropertyGroups(obj)
      propList = properties(obj);
      activeIdx1 = true(size(propList));
      
      for n = 1:numel(propList)
        if isInactiveProperty(obj, propList{n})
          activeIdx1(n) = false;
        end
      end
      groups = matlab.mixin.util.PropertyGroup(propList(activeIdx1));
    end
    
    function flag = isInactiveProperty(obj, prop)
      flag = false;
      
      if strcmp(obj.CommandType, 'Load Control Event')
        flag = any(strcmp(prop, {'EventStatus', 'SignatureType'}));
        
      elseif strcmp(obj.CommandType, 'Cancel Load Control Event')
        flag = ~any(strcmp(prop, {'CommandType', 'EventID', 'DeviceClass', 'DeviceGroup', 'RandomEnd', 'Time'}));
        
      elseif strcmp(obj.CommandType, 'Cancel All Load Control Events')
        flag = ~any(strcmp(prop, {'CommandType', 'RandomEnd'}));
        
      elseif strcmp(obj.CommandType, 'Report Event Status')
        flag = any(strcmp(prop, {'DeviceClass', 'DeviceGroup', 'Duration', 'CoolingOffset', 'HeatingOffset'}));
      end
      
      if any(strcmp(prop, {'CoolingOffset', 'HeatingOffset'})) && (obj.(prop) - 25.5 < eps)
        flag = true;
      end
      
      if any(strcmp(prop, {'CoolingSetPoint', 'HeatingSetPoint'})) && (obj.(prop) - -327.68 < eps)
        flag = true;
      end
    end
  end
  
end
