function [FIG,FIG_ENG,datarif,contunit,IDscaduta] = report_CU(unitID,chainID,adesso,datainvio,numgiorni,...
    datasample,tipoarray,firstdata_num,siteID,datalogger,datalogger_ENG,FIG,FIG_ENG,rpt,rpt_ENG,...
    Font_caption,Font_section,activeEN,conn,FileName)

fileID = fopen(FileName,'a');
fmt = '%s \r';
text = 'report_CU function started';
fprintf(fileID,fmt,text);

import mlreportgen.dom.*
import mlreportgen.report.*

% Make sure DOM is compilable
makeDOMCompilable()

br = PageBreak();
[rC,~] = size(unitID);
[rAR,~] = size(chainID);
activeT = 1;
if numgiorni == 30 % report mensile
    day = '01';
    if adesso == 1 % gennaio
        month = '12-';
        year = datestr(today-31,'yyyy-'); % anno precedente
    else % altri mesi
        month = strcat(num2str(adesso-1),'-'); % Report del mese precedente a quello attuale
        year = datestr(today,'yyyy-');
        IDscaduta = zeros(rC,1);
    end
else % report con cadenza personalizzata
    day = datestr(datainvio,'dd');
    month = datestr(datainvio,'mm-');
    year = datestr(datainvio,'yyyy-');
end
ar_tot = 1;
UNIT = zeros(rC,1); % Metto uno zero se la centralina ha solo ANALOG ARRAY, 1 se ha almeno un MUMS
for G = 1:rC % creo una sottosezione per ciascuna centralina
    lastsample = 0; % inizializzo con data "nulla" (ultima lettura)
    firstsample = 9*10^10; %inizializzo con data "lontanissima" (prima lettura)
    contunit = unitID(G,2);
    IDcentralina = char(contunit);
    
    % Cerco la data di scadenza della centralina
    comando = ['select duedate from units where name = ''' IDcentralina ''' '];
    curs = exec(conn,comando);
    curs = fetch(curs);
    Date = curs.Data;
    Check = cell2mat(Date);
    if strcmp(Check,'null') || strcmp(Check,'No Data')
        analisi = 1; % La data di scadenza centralina non č impostata
    else
        if datenum(Date) < now % Centralina scaduta
            analisi = 0;
        else
            analisi = 1;
        end
    end
    
    ID = Section();
    app = Heading2(['Centralina ', IDcentralina]);
    app.Style = {OuterMargin('0in','0in','0.2in','0.2in'),FontSize(Font_section),HAlign('justify')}; % Sx-Dx-Alto-Basso
    ID.Title = app;
    if activeEN == 1
        ID_ENG = Section();
        app_ENG = Heading2(['Control Unit ', IDcentralina]);
        app_ENG.Style = {OuterMargin('0in','0in','0.2in','0.2in'),FontSize(Font_section),HAlign('justify')}; % Sx-Dx-Alto-Basso
        ID_ENG.Title = app_ENG;
    end
    num_array = zeros(rC,1);
    if analisi == 0
        testo = Paragraph(['I dati della centralina ' IDcentralina ' non '...
            'sono disponibili in quanto ' char(232) ' scaduto l''abbonamento ai dati della stessa. '...
            'I dati torneranno ad essere disponibili non appena sar' char(224) ...
            ' rinnovato il canone annuo.']);
        testo.HAlign = 'justify';
        add(ID,testo);
        add(datalogger,ID)
        IDscaduta(G,1) = 1;
        datarif = strcat(year, month, day);
        UNIT(G,1) = 99999;
        if activeEN == 1
            testo = Paragraph(['Data recorded by control unit' IDcentralina ' are not '...
                'available due to the expiration of the data management subscription for this data logger. '...
                'Access to monitoring data will be resumed following the payment of the annual fee. ']);
            testo.HAlign = 'justify';
            add(ID_ENG,testo);
            add(datalogger_ENG,ID_ENG)
        end
    else
        contunitID = num2str(cell2mat(unitID(G,1)));
        IDscaduta(G,1) = 0;
        datarif = strcat(year, month, day);
        cen = 1;
        for kk = 1:rAR
            comando = ['select prod_date from tools where unit_ID like ''' contunitID  ''' and name like ''' char(chainID(kk,4)) ''' '];
            curs = exec(conn,comando);
            curs = fetch(curs);
            data_ini = curs.Data;
            stringa = cell2mat(data_ini);
            [~,cst] = size(stringa);
            if cst > 10
                date = stringa(1,1:10);
                time = stringa(1,11:21);
                dataora_sito(1,1) = cellstr(date);
                dataora_sito(1,2) = cellstr(time);
                datasito{cen,1} = datestr(data_ini, 'yyyy-mm-dd HH:MM'); % Data definita sul sito
                cen = cen+1;
            end
        end
        datasito801 = min(datenum(datasito));
        if datenum(datasito801) > datenum(datarif)
            datarif = datestr(datenum(datasito801),'yyyy-mm-dd');
        end
        
        Indici = [];
        for rr = 1:rAR
            if strcmp(char(chainID(rr,2)),char(unitID(G,2))) == 1
                Indici = [Indici; rr];
            end
        end
        IN = size(Indici);
        num_array(G) = IN(1);
        ARRAY = tipoarray(Indici,1);
        for NUM = 1:num_array(G)
            if strcmp(ARRAY(NUM,1),'Analog Array') == 1
                UNIT(G,1) = 0;
            elseif strcmp(ARRAY(NUM,1),'MUSA') == 1 || strcmp(ARRAY(NUM,1),'RSN') == 1 || strcmp(ARRAY(NUM,1),'Klino Array D2W') == 1
                UNIT(G,1) = 0.5;
            else
                UNIT(G,1) = 1;
                break
            end
        end
    end
        
    if UNIT(G,1) == 1
        for arr = 1:num_array(G)
            datasample_num = cell2mat(datasample(ar_tot+arr,1));
            if datasample_num ~= 9999
                if datasample_num >= lastsample && cell2mat(firstdata_num(arr+1)) <= firstsample || ...
                        datasample_num >= lastsample && firstsample == 0 % ultima lettura pių recente, prima lettura pių vecchia
                    Indici = [];
                    for rr = 1:rAR
                        if strcmp(char(chainID(rr,2)),char(unitID(G,2))) == 1
                            Indici = [Indici; rr];
                        end
                    end
                    catenarif = char(chainID(Indici(arr),4));
                    lastsample = datasample_num;
                    firstsample = cell2mat(firstdata_num(arr+1));
                end
            end
        end
        
        if exist('catenarif','var')
            % Scarico dati batteria
            comando = ['select Date, Time, UnitName, ToolNameID, BatLevel, Temperature from RawDataView where Date >= ''' ...
                datarif ''' and UnitName = ''' char(contunit) ''' and ToolNameID = '''...
                catenarif ''' and NodeNum = 1 '];
            curs = exec(conn,comando);
            curs = fetch(curs);
            BatTemp = curs.Data;
            [~,cc] = size(BatTemp);
        else
            cc = 1;
        end
        if cc ~= 1 % ci sono dati riferiti all'ultimo mese/periodo di interesse
            DataPlot = [BatTemp(:,1) BatTemp(:,2)];
            % sistemo date, batteria e temperatura
            [rD,~] = size(DataPlot);
            T = [cell2mat(DataPlot(:,1)) repmat(' ', [rD,1]) cell2mat(DataPlot(:,2))];
            Date = datenum(T);
            Batteria = cell2mat(BatTemp(:,5));
            Temperatura = cell2mat(BatTemp(:,6));
            
            % testo introduttivo
            testo = Paragraph(['Di seguito sono riportati i valori di tensione '...
                    'di alimentazione registrati durante il periodo di riferimento. '...
                    'L''ultimo dato disponibile ' char(232) ' pari '...
                    'a ' num2str(Batteria(end,1)) ' V.']);
            if activeT == 1
                testo = Paragraph(['Di seguito sono riportati i valori di tensione '...
                    'di alimentazione registrati durante il periodo di riferimento. '...
                    'Il corretto funzionamento del sistema '...
                    char(232) ' assicurato per una carica superiore a 12 V. '...
                    'L''ultimo dato disponibile ' char(232) ' pari '...
                    'a ' num2str(Batteria(end,1)) ' V.']);
                testo2 = Paragraph(['La medesima centralina dispone al proprio interno '...
                    'di un termometro per monitorare la temperatura di esercizio ed identificare '...
                    'eventuali anomalie. I dati di temperatura registrati sono riportati di seguito.']);
                testo2.HAlign = 'justify';
            end
            testo.HAlign = 'justify';
            % grafico batteria
            figure(1)
            plot(Date,Batteria);
            hold on
            title('Livello di carica e temperatura');
            xlabel('Data [gg/mm/aaaa]');
            ylabel('Livello della Batteria [V]');
            xlim([Date(1)-1 Date(end)+1]);
            ylim([floor(min(Batteria(:,1))) ceil(max(Batteria(:,1)))]);
            h = gca;
            h.XAxis.MinorTick = 'on';
            datetick('x','dd/mm/yyyy','keepticks','keeplimits');
            xtickangle(20);
            yyaxis right
            CEN = plot(Date,Temperatura,':','LineWidth',1.1);
            ylim([floor(min(Temperatura(:,1))) ceil(max(Temperatura(:,1)))]);
            ylabel(['Temperatura [' char(176) 'C]']);
            set(gca,'YColor','k');
            str(1,1) = cellstr('Batteria');
            str(2,1) = cellstr('Temperatura');
            legend(str,'Location','northwest');
            h = gca;
            h.XAxis.MinorTick = 'on';
            datetick('x','dd/mm/yyyy','keepticks','keeplimits');
            xtickangle(20);
            grid on
            grid minor
            xlim([Date(1)-1 Date(end)+1]);
            TempName = char(strcat('Report',siteID,'-', contunit,'.png'));
            saveas(CEN,TempName);
            Chart = Image(TempName);
            Chart.Style = {Height('7.5cm'),HAlign('center')};
            
            if Batteria(end,1) >= 12.5
                TempName = char(strcat('B_13.jpg'));
            elseif Batteria(end,1) >= 12
                TempName = char(strcat('B_12.jpg'));
            elseif Batteria(end,1) >= 11.3
                TempName = char(strcat('B_115.jpg'));
            elseif Batteria(end,1) >= 10.5
                TempName = char(strcat('B_11.jpg'));
            else
                TempName = char(strcat('B_10.jpg'));
            end
            Batt = Image(TempName);
            Batt2 = Image(TempName);
            Batt.Style = {Height('4cm'),HAlign('center')};
            Batt2.Style = {Height('4cm'),HAlign('center')};
           
            lot = Table({Chart, Batt});
            lot.TableEntriesStyle = {HAlign('center'),VAlign('middle')};
            lot.Style = {ResizeToFitContents(false),Width("100%")};
            grps(1) = TableColSpecGroup;
            grps(1).Span = 2;
            specs(1) = TableColSpec;
            specs(1).Span = 1;
            specs(1).Style = {Width("80%")};
            specs(2) = TableColSpec;
            specs(2).Span = 1;
            specs(2).Style = {Width("20%")};
            grps(1).ColSpecs = specs;
            lot.ColSpecGroups = grps;
            
            lot_cap = Paragraph(['Fig. ' num2str(FIG) ' - Livello di carica della batteria e temperatura della '...
                'centralina registrati durante il periodo di riferimento']);
            FIG = FIG+1;
            lot_cap.Style = {HAlign('center'),FontSize(Font_caption),Italic(1),Color('midnightblue')};
            close(figure(1));
            
            add(ID,testo);
            if cc ~= 1
                if activeT == 1
                    add(ID,testo2);
                end
                add(ID,lot);
                add(ID,lot_cap);
                if G == rC || activeT == 1
                    add(ID,br);
                    activeT = 0;
                end
                add(datalogger,ID)
            end
        else
            testo = Paragraph('Non sono presenti dati relativi al periodo temporale considerato.');
            add(ID,testo);
            if G == rC
                add(ID,br);
            end
            add(datalogger,ID)
        end

        if activeEN == 1 % --- INGLESE ---
            if cc ~= 1
                % testo introduttivo
                testo = Paragraph(['The following chart reports the battery level trend recorded '...
                    'during the reference time period. The last available data is equal to ' num2str(Batteria(end,1)) ' V.']);
                if activeT == 1
                    testo = Paragraph(['The following chart reports the battery level trend recorded '...
                        'during the reference time period. '...
                        'The correct functioning of the data acquisition system is guaranteed for a '...
                        'minimum level of 12 V. The last available data is equal to ' num2str(Batteria(end,1)) ' V.']);
                    testo2 = Paragraph(['The control unit equips also a thermometer that allows the monitoring '...
                        'of the working temperature and the identification of eventual malfunctioning. The same '...
                        'chart displays also temperature data recorded by the control unit.']);
                    testo2.HAlign = 'justify';
                end
                testo.HAlign = 'justify';
                % grafico batteria
                figure(1)
                plot(Date,Batteria);
                hold on
                title('Battery level and temperature');
                xlabel('Date [dd/mm/yyyy]');
                ylabel('Level [V]');
                xlim([Date(1)-1 Date(end)+1]);
                ylim([floor(min(Batteria(:,1))) ceil(max(Batteria(:,1)))]);
                h = gca;
                h.XAxis.MinorTick = 'on';
                datetick('x','dd/mm/yyyy','keepticks','keeplimits');
                xtickangle(20);
                yyaxis right
                CEN = plot(Date,Temperatura,':','LineWidth',1.1);
                ylim([floor(min(Temperatura(:,1))) ceil(max(Temperatura(:,1)))]);
                ylabel(['Temperature [' char(176) 'C]']);
                set(gca,'YColor','k');
                str(1,1) = cellstr('Battery');
                str(2,1) = cellstr('Temperature');
                legend(str,'Location','northwest');
                h = gca;
                h.XAxis.MinorTick = 'on';
                datetick('x','dd/mm/yyyy','keepticks','keeplimits');
                xtickangle(20);
                grid on
                grid minor
                xlim([Date(1)-1 Date(end)+1]);
                TempName = char(strcat('Report',siteID,'-', contunit,'_ENG.png'));
                saveas(CEN,TempName);
                Chart = Image(TempName);
                Chart.Style = {Height('7.5cm'),HAlign('center')};
                
                lot = Table({Chart, Batt2});
                lot.TableEntriesStyle = {HAlign('center'),VAlign('middle')};
                lot.Style = {ResizeToFitContents(false),Width("100%")};
                grps(1) = TableColSpecGroup;
                grps(1).Span = 2;
                specs(1) = TableColSpec;
                specs(1).Span = 1;
                specs(1).Style = {Width("80%")};
                specs(2) = TableColSpec;
                specs(2).Span = 1;
                specs(2).Style = {Width("20%")};
                grps(1).ColSpecs = specs;
                lot.ColSpecGroups = grps;
                
                lot_cap = Paragraph(['Fig. ' num2str(FIG_ENG) ' - Battery level and control unit temperature recorded '...
                    'during the reference time period']);
                FIG_ENG = FIG_ENG+1;
                lot_cap.Style = {HAlign('center'),FontSize(Font_caption),Italic(1),Color('midnightblue')};
                close(figure(1));
                
                add(ID_ENG,testo);
                if cc ~= 1
                    if activeT == 1
                        add(ID_ENG,testo2);
                    end
                    add(ID_ENG,lot);
                    add(ID_ENG,lot_cap);
                    if G == rC || activeT == 1
                        add(ID_ENG,br);
                        activeT = 0;
                    end
                    add(datalogger_ENG,ID_ENG)
                end
            else
                testo = Paragraph('No data available for the reference time period.');
                add(ID_ENG,testo);
                if G == rC
                    add(ID_ENG,br);
                end
                add(datalogger_ENG,ID_ENG)
            end
        end
    elseif UNIT(G,1) == 0 % SOLO Analog Array
        testo = Paragraph(['Questa centralina legge solo sensori analogici (Analog Array): i dati di batteria e temperatura '...
            'faranno quindi riferimento ai valori registrati dai singoli moduli GMUX e verranno pertanto '...
            'riportati nelle apposite sezioni.']);
        testo.Style = {HAlign('justify')};
        add(ID,testo);
        if G == rC
            add(ID,br);
        end
        add(datalogger,ID)
        if activeEN == 1 % SOLO Analog Array
            testo = Paragraph(['This control unit read Analog Arrays only: for this reason, '...
                'battery level and temperature data should be referred to each single GMUX '...
                'module, and they will be presented in the appropriate section of the report.']);
            testo.Style = {HAlign('justify')};
            add(ID_ENG,testo);
            if G == rC
                add(ID_ENG,br);
            end
            add(datalogger_ENG,ID_ENG)
        end
    elseif UNIT(G,1) == 0.5 % SOLO MUSA o RSN
        testo = Paragraph(['Questa centralina legge solo sensori MUSA, RSN o D2W: i dati di batteria e temperatura '...
            'presentati in questo report faranno riferimento ai singoli moduli e verranno '...
            'riportati nelle apposite sezioni.']);
        testo.Style = {HAlign('justify')};
        add(ID,testo);
        if G == rC
            add(ID,br);
        end
        add(datalogger,ID)
        if activeEN == 1
            testo = Paragraph(['This control unit read MUSA, RSN or D2W sensors: for this reason, '...
                'battery level and temperature data should be referred to each single module, '...
                'and they will be presented in the appropriate section of the report.']);
            testo.Style = {HAlign('justify')};
            add(ID_ENG,testo);
            if G == rC
                add(ID_ENG,br);
            end
            add(datalogger_ENG,ID_ENG)
        end
    end
    ar_tot = ar_tot+num_array(G);
end
add(rpt,datalogger);
template(rpt);
add(rpt_ENG,datalogger_ENG);
template(rpt_ENG);

text = 'report_CU function executed correctly';
fprintf(fileID,fmt,text);
fclose(fileID);

end