function priceFrame = PriceFrameGenerator(cfg)
%PriceFrameGenerator Generate frames for the Price ZigBee cluster
%   PRICEFRAME = PriceFrameGenerator(CFG) generates the Smart Energy frame
%   PRICEFRAME corresponding to the Price-cluster configuration object CFG.
%
%   See also zigbee.PriceFrameConfig, zigbee.PriceFrameDecoder.

%   Copyright 2017-2023 The MathWorks, Inc.

switch cfg.CommandType
  case 'Get Current Price'
    % 1. Command options
    priceFrame = zeros(8, 1);
    
    % 1.1 Rx on when idle    
    priceFrame (1) = double(cfg.IdleReceiving);
    
  case 'Price Acknowledgment'
    % 1. Provider identifier
    providerID = int2bit(cfg.ProviderID, 4*8, false)';
    
    % 2. Issuer event identifier
    EventID = int2bit(cfg.EventID, 4*8, false)';
    
    % 3. Generated time
    GenerationTime = int2bit(cfg.GenerationTime, 4*8, false)';
    
    % 4. Control
    control = zeros(1, 8);
    
    % 4.1 Price acknowledgment
    control(1) = double(cfg.PriceAcknowledgment);        
    
    % 5. Putting all together
    priceFrame = [providerID EventID GenerationTime control]';
    
  case 'Publish Price'
    % 1. Provider Id
    providerID = int2bit(cfg.ProviderID, 4*8, false)';
    
    % 2. Rate label
    lengthOfTheLabel = length(cfg.RateLabel);
    rateLabel = zeros(1, lengthOfTheLabel*8+8);
    rateLabel(1:8) = int2bit(lengthOfTheLabel, 8, false)'; % First octet contains the length of the message
    rateLabel(9:end) = zigbee.internal.encodeLabel(cfg.RateLabel);
      
    % 3. Issuer event ID
    EventID = int2bit(cfg.EventID, 4*8, false)';
    
    % 4. Generated Time
    GenerationTime = int2bit(cfg.GenerationTime, 4*8, false)';
    
    % 5. Unit of measure
    index = find(strcmp(cfg.Unit, zigbee.PriceFrameConfig.UnitValues));
    if strcmp(cfg.UnitFormat, 'Binary')
      ID = index - 1;
    else
      ID = index - 1 + hex2dec('80');
    end
    Unit = int2bit(ID, 8, false)';
    
    % 6. Currency
    currency = int2bit(cfg.Currency, 2*8, false)';        
    
    % 7. Price tier
    priceTier = int2bit(min(15, cfg.PriceTier), 4, false)';
    
    % 8. Price trailing digit - Indicates the number of digits after the decimal point of the price
    stringFormatOfPrice = num2str(cfg.Price);
    if cfg.Price ~= round(cfg.Price)
      splitPrice = split(stringFormatOfPrice, '.');
      priceTrailing = int2bit(length(splitPrice{2}), 4, false)';  
    else
      priceTrailing = int2bit(0, 4, false)';
    end
        
    % 9. Register tier
    registerTier = int2bit(min(15, cfg.RegisterTier), 4, false)';
    
    % 10. Number of price tiers
    NumPriceTiers = int2bit(min(15, cfg.NumPriceTiers), 4, false)';
            
    % 11. Start time
    startTime = int2bit(cfg.StartTime, 4*8, false)';
    
    % 12. Duration in minutes
    Duration = int2bit(cfg.Duration, 2*8, false)';
    
    % 13. Price
    price = int2bit(str2double(strrep(stringFormatOfPrice, '.', '')), 4*8, false)';
    
    % 14. Optional fields
    priceControl = zeros(1, 8);
    otherOptional = ones(1, 13*8); % values indicating no usage
    
    % 27. Putting all together
    priceFrame = [providerID rateLabel EventID GenerationTime Unit currency ...
      priceTier priceTrailing registerTier NumPriceTiers startTime Duration ...
      price priceControl otherOptional]';      
end

% Convert bits to bytes:
priceFrame = zigbee.internal.bits2bytes(priceFrame);

end
