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