#include #include #include #include #include #include #include #include "libcpd2.h" #include "util.h" #include "sfmt.h" #include "display.h" #include "dispgen.h" #include "wins.h" #include "mainmenu.h" #include "status.h" #include "net_ds/dispaggregator.h" #include "net_ds/filter.h" #include "net_ds/cutpoints.h" #include "net_ds/io.h" #include "net_ds/log.h" typedef struct { WINS_window *win; SFMT_buffer sbfr; char name[CPD_NAME_LENGTH]; NET_DISPAGGREGATOR_All all; char tag_filter[CPD_NAME_LENGTH]; NET_FILTER_Status filter; BOOL filter_defined; char name_dP_pitot[CPD_NAME_LENGTH]; double dP_pitot; NET_CUTPOINTS_Status cutpoints; NET_LOG_AVG_Bypass bypass; BOOL cutpoints_defined; } AGGREGATE_prv_data; BOOL g_aggregate_active = FALSE; static void AGGREGATE_time( SFMT_buffer *sbfr, FTIME t ) { FTIME ftfloor; time_t unix_time; struct tm tv; if (t == MVC_FTIME || t == MVC) { SFMT_copystr( sbfr, "" ); return; } ftfloor = floor(t); unix_time = (time_t)ftfloor; gmtime_r( &unix_time, &tv ); SFMT_printf( sbfr, "%02d:%02d:%02d", tv.tm_hour, tv.tm_min, tv.tm_sec); } static void AGGREGATE_print_line( AGGREGATE_prv_data *pd, int *cy, NET_DISPAGGREGATOR_One *line, char *title, char *fmt, double scale ) { int cols[8] = {1, 21,29, 37,45,53, 62,71}; // Ignore blank lines if (line->in == MVC && line->ra == MVC && line->full_avg == MVC && line->min == MVC && line->max == MVC) return; mvwaddstr( pd->win->win, *cy,cols[0], title); SFMT_altprintf(&pd->sbfr, fmt, SCALE_MVC(line->in, scale)); mvwaddstr( pd->win->win, *cy,cols[1], SFMT_get_buffer(&pd->sbfr)); SFMT_altprintf(&pd->sbfr, fmt, SCALE_MVC(line->ra, scale)); mvwaddstr( pd->win->win, *cy,cols[2], SFMT_get_buffer(&pd->sbfr)); SFMT_altprintf(&pd->sbfr, fmt, SCALE_MVC(line->full_avg, scale)); mvwaddstr( pd->win->win, *cy,cols[3], SFMT_get_buffer(&pd->sbfr)); SFMT_altprintf(&pd->sbfr, fmt, SCALE_MVC(line->min, scale)); mvwaddstr( pd->win->win, *cy,cols[4], SFMT_get_buffer(&pd->sbfr)); SFMT_altprintf(&pd->sbfr, fmt, SCALE_MVC(line->max, scale)); mvwaddstr( pd->win->win, *cy,cols[5], SFMT_get_buffer(&pd->sbfr)); AGGREGATE_time(&pd->sbfr, line->t_min); mvwaddstr( pd->win->win, *cy,cols[6], SFMT_get_buffer(&pd->sbfr)); AGGREGATE_time(&pd->sbfr, line->t_max); mvwaddstr( pd->win->win, *cy,cols[7], SFMT_get_buffer(&pd->sbfr)); (*cy)++; } void AGGREGATE_update( void *private_data, DISPLAY_common_params *cparams, void *display_param ) { AGGREGATE_prv_data *pd = (AGGREGATE_prv_data *)private_data; int cy; WINS_set_size( pd->win, COLS, LINES-1 ); WINS_absolute_move( pd->win, 0,0 ); // Draw the standard window wattrset( pd->win->win, WINS_DEF_BOARDER_ATTR(pd->win) ); WINS_blank_window( pd->win ); WINS_window_border( pd->win, WINS_DEF_BOARDER_ATTR(pd->win) ); if (pd->all.station[0]) { SFMT_printf( &pd->sbfr, "CATCOS aerosol monitoring station - %s", // edited nb May 1, 2012 pd->all.station ); WINS_center_string( pd->win, SFMT_get_buffer(&pd->sbfr), 0 ); } else { WINS_center_string( pd->win, "CATCOS aerosol monitoring station", 0 );// edited nb May 1, 2012 } wattrset( pd->win->win, WA_NORMAL|COLOR_PAIR(CP_WHITE_BLUE) ); cy=1; SFMT_printf( &pd->sbfr, " Latest ---Latest %2u Averages--- -------Time------", pd->all.n_avgs); mvwaddstr( pd->win->win, cy++,1, SFMT_get_buffer(&pd->sbfr)); mvwaddstr( pd->win->win, cy++,1, " Current Average Mean Min Max Min Max"); //AGGREGATE_print_line( pd, &cy, &pd->all.cncc, "N cncc (1/cc)", // "*~5.1f", 1.0 ); //AGGREGATE_print_line( pd, &cy, &pd->all.cnca, "N cnca (1/cc)", // "*~5.1f", 1.0 ); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); mvwaddstr( pd->win->win, cy++,1, "Digital readings Aethalometer"); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); AGGREGATE_print_line( pd, &cy, &pd->all.aeth_conc, "BC 880nm (ng/m3)",// edited nb May 1, 2012 "*~5.1f", 1 );// edited nb May 1, 2012 AGGREGATE_print_line( pd, &cy, &pd->all.aeth_attn, "Attn 880 nm (%)",// edited nb May 1, 2012 "*~5.1f", 1 );// edited nb May 1, 2012 AGGREGATE_print_line( pd, &cy, &pd->all.aeth_flow, "Flow (vlpm)",// edited nb May 1, 2012 "*~5.1f", 1 );// edited nb May 1, 2012 mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); mvwaddstr( pd->win->win, cy++,1, "Digital readings Nephelometer"); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); AGGREGATE_print_line( pd, &cy, &pd->all.bsp[0], "Bsp blue (1/Mm)", "*~5.1f", 1.0E6 ); AGGREGATE_print_line( pd, &cy, &pd->all.bsp[1], "Bsp green (1/Mm)", "*~5.1f", 1.0E6 ); AGGREGATE_print_line( pd, &cy, &pd->all.bsp[2], "Bsp red (1/Mm)", "*~5.1f", 1.0E6 ); AGGREGATE_print_line( pd, &cy, &pd->all.bbsp[0], "Bbsp blue (1/Mm)", "*~5.1f", 1.0E6 ); AGGREGATE_print_line( pd, &cy, &pd->all.bbsp[1], "Bbsp green (1/Mm)", "*~5.1f", 1.0E6 ); AGGREGATE_print_line( pd, &cy, &pd->all.bbsp[2], "Bbsp red (1/Mm)", "*~5.1f", 1.0E6 ); AGGREGATE_print_line( pd, &cy, &pd->all.alphaGR, "Alpha GR", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.alphabGR, "AlphaB GR", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.neph_P, "Neph P (hPa)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.neph_T, "Neph T (C)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.neph_RH,"Neph RH (%)", "*~5.1f", 1.0 ); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); mvwaddstr( pd->win->win, cy++,1, "Analog readings Mass Flow Controller"); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); AGGREGATE_print_line( pd, &cy, &pd->all.MFC_Aeth,"Flow Aeth (vlpm)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.MFC_Neph,"Flow Neph (vlpm)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.MFC_Dil_Air,"Flow DilAir (vlpm)", "*~5.1f", 1.0 ); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); mvwaddstr( pd->win->win, cy++,1, "Analog readings Sensors"); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); AGGREGATE_print_line( pd, &cy, &pd->all.P_Inl_Air,"P Mixed Air (mbar)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.P_Pmp_Air,"P Pump Air (mbar)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.T_Ind,"T Indoor (C)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.T_Inl_Air,"T Mixed Air (C)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.RH_Inl_Air,"RH Mixed Air (%)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.T_Amb_Air,"T Ambient (C)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.RH_Amb_Air,"RH Ambient (%)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.T_Dil_Air,"T Dil Air (C)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.RH_Dil_Air,"RH Dil Air (%)", "*~5.1f", 1.0 ); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); mvwaddstr( pd->win->win, cy++,1, "Analog readings Aethalometer and Nephelometer"); mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); AGGREGATE_print_line( pd, &cy, &pd->all.Ana_BC_Aeth,"BC 880nm (ng/m3)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.Ana_Sc_Blue,"Bsp Blue (1/Mm)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.Ana_Sc_Green,"Bsp Green (1/Mm)", "*~5.1f", 1.0 ); AGGREGATE_print_line( pd, &cy, &pd->all.Ana_Sc_Red,"Bsp Red (1/Mm)", "*~5.1f", 1.0 ); //AGGREGATE_print_line( pd, &cy, &pd->all.wind_s, "Wind Speed (m/s)", // "*~5.1f", 1.0 ); //if (pd->all.wind_d.in != MVC || pd->all.wind_d.ra != MVC || pd->all.wind_d.full_avg != MVC) { // SFMT_altprintf(&pd->sbfr, "Wind Dir. (deg) *~5.1f *~5.1f *~5.1f", // pd->all.wind_d.in, // pd->all.wind_d.ra, // pd->all.wind_d.full_avg); // mvwaddstr( pd->win->win, cy++,1, SFMT_get_buffer(&pd->sbfr)); //} //if (pd->dP_pitot != MVC && pd->dP_pitot > 0.0) { // SFMT_altprintf(&pd->sbfr, "Q stack (slpm) *~5.1f", // 2011.0 * sqrt( 273.15 * pd->dP_pitot / 1013.25 )); // mvwaddstr( pd->win->win, cy++,1, SFMT_get_buffer(&pd->sbfr)); //} if (pd->bypass.bypassed) { SFMT_copystr(&pd->sbfr, "Bypassed"); wattrset( pd->win->win, WA_NORMAL|COLOR_PAIR(CP_RED_BLUE) ); mvwaddstr( pd->win->win, cy++,1, SFMT_get_buffer(&pd->sbfr)); wattrset( pd->win->win, WA_NORMAL|COLOR_PAIR(CP_WHITE_BLUE) ); } else if (pd->cutpoints_defined) { SFMT_printf(&pd->sbfr, "Cut size %14s", pd->cutpoints.cp_cur.val?" Fine (1 um)":"Coarse (10 um)"); if (pd->cutpoints.time_next != MVC_FTIME) { FTIME ftfloor; time_t unix_time; struct tm tv; ftfloor = floor(pd->cutpoints.time_next); unix_time = (time_t)ftfloor; gmtime_r( &unix_time, &tv ); SFMT_printfcat( &pd->sbfr, " NEXT %02d:%02d:%02d", tv.tm_hour, tv.tm_min, tv.tm_sec); } mvwaddstr( pd->win->win, cy++,1, SFMT_get_buffer(&pd->sbfr)); } if (pd->filter_defined) { SFMT_printf(&pd->sbfr, "Active Filter %7d %10s", pd->filter.current_filter, pd->filter.bypassed?"(BYPASSED)":""); mvwaddstr( pd->win->win, cy++,1, SFMT_get_buffer(&pd->sbfr)); } mvwaddstr( pd->win->win, cy++,1, "----------------------------------------------------------------------------"); } void AGGREGATE_msg_proc( void *private_data, DISPLAY_common_params *cparams, DISPLAY_msg_params *mp, void *display_param ) { AGGREGATE_prv_data *pd = (AGGREGATE_prv_data *)private_data; NET_IO_MultiReal *mr; int i; switch(mp->pm->msg->msg) { case MSG_DISPAGGREGATOR_ALL: if (!mp->pm->src_name || strcmp(mp->pm->src_name, pd->name)) break; if (!mp->pm->pds) break; memcpy( &pd->all, mp->pm->pds, sizeof(NET_DISPAGGREGATOR_All) ); break; case MSG_FILTER_STATUS: if (pd->tag_filter[0] && !CPDMSG_filter_name_and_tag( INST_msglink(&g_lnk), mp->pm->src_name, pd->tag_filter )) break; if (!mp->pm->pds) break; memcpy(&pd->filter, mp->pm->pds, sizeof(NET_FILTER_Status)); pd->filter_defined = TRUE; break; case MSG_CUTPOINTS_STATUS: if (!mp->pm->pds) break; memcpy(&pd->cutpoints, mp->pm->pds, sizeof(NET_CUTPOINTS_Status)); pd->cutpoints_defined = TRUE; break; case MSG_LOG_AVG_BYPASS: if (!mp->pm->pds) break; memcpy( &pd->bypass, mp->pm->pds, sizeof(NET_LOG_AVG_Bypass) ); break; case MSG_IO_INSTANT: if (!mp->pm->pds) break; mr = (NET_IO_MultiReal *)mp->pm->pds; for (i=0; in; i++) { if (!mr->chans[i].name[0]) continue; if (!UTIL_strcasecmp(mr->chans[i].name, pd->name_dP_pitot)) { pd->dP_pitot = mr->chans[i].val; } } break; default: break; } } static void AGGREGATE_init_netone( NET_DISPAGGREGATOR_One *no ) { no->in = MVC; no->ra = MVC; no->full_avg = MVC; no->min = MVC; no->max = MVC; no->t_min = MVC; no->t_max = MVC; } static AGGREGATE_prv_data *AGGREGATE_init_pd( char *src_name ) { AGGREGATE_prv_data *pd; int i; char *ret; CPD_RETURN_ASSERT_PERROR( (pd=(AGGREGATE_prv_data *)malloc(sizeof(AGGREGATE_prv_data))) != NULL, NULL ); pd->win = NULL; AGGREGATE_init_netone( &pd->all.cncc ); AGGREGATE_init_netone( &pd->all.cnca ); AGGREGATE_init_netone( &pd->all.aeth_conc );// edited nb May 1, 2012 AGGREGATE_init_netone( &pd->all.aeth_attn ); AGGREGATE_init_netone( &pd->all.aeth_flow ); for (i=0; i<3; i++) { //AGGREGATE_init_netone( &pd->all.bap[i] );// edited nb May 1, 2012 AGGREGATE_init_netone( &pd->all.bsp[i] ); AGGREGATE_init_netone( &pd->all.bbsp[i] ); } AGGREGATE_init_netone( &pd->all.alphaGR ); AGGREGATE_init_netone( &pd->all.alphabGR ); AGGREGATE_init_netone( &pd->all.neph_T ); AGGREGATE_init_netone( &pd->all.neph_RH ); AGGREGATE_init_netone( &pd->all.Ana_Sc_Blue );// edited nb May 1, 2012 AGGREGATE_init_netone( &pd->all.Ana_Sc_Green ); AGGREGATE_init_netone( &pd->all.Ana_Sc_Red ); AGGREGATE_init_netone( &pd->all.Ana_BC_Aeth ); AGGREGATE_init_netone( &pd->all.P_Inl_Air ); AGGREGATE_init_netone( &pd->all.P_Pmp_Air ); AGGREGATE_init_netone( &pd->all.T_Amb_Air ); AGGREGATE_init_netone( &pd->all.RH_Amb_Air ); AGGREGATE_init_netone( &pd->all.T_Ind ); AGGREGATE_init_netone( &pd->all.T_Dil_Air ); AGGREGATE_init_netone( &pd->all.RH_Dil_Air ); AGGREGATE_init_netone( &pd->all.T_Inl_Air ); AGGREGATE_init_netone( &pd->all.RH_Inl_Air ); AGGREGATE_init_netone( &pd->all.MFC_Neph ); AGGREGATE_init_netone( &pd->all.MFC_Aeth ); AGGREGATE_init_netone( &pd->all.MFC_Dil_Air ); AGGREGATE_init_netone( &pd->all.wind_s ); AGGREGATE_init_netone( &pd->all.wind_d ); pd->all.n_avgs = 0; pd->filter.bypassed = FALSE; pd->filter.done = FALSE; pd->filter.changing = FALSE; pd->filter.current_filter = 0; pd->filter.time_started = MVC_FTIME; pd->filter.time_next = MVC_FTIME; for (i=0; ifilter.volumes[i] = MVC; pd->filter.V_bypass = MVC; pd->filter_defined = FALSE; if ((ret=CONF_lookup(g_conf,"Aggregate;Tag;Filter")) != NULL) { UTIL_strncpynt(pd->tag_filter, ret,CPD_NAME_LENGTH); } else { pd->tag_filter[0] = '\0'; } pd->dP_pitot = MVC; if ((ret=CONF_lookup(g_conf,"Aggregate;Stack;Pitot")) != NULL) { UTIL_strncpynt(pd->name_dP_pitot, ret, CPD_NAME_LENGTH); } else { strcpy(pd->name_dP_pitot, "Pd_P01"); } pd->cutpoints.cp_cur.val = -1; pd->cutpoints.time_cur = MVC_FTIME; pd->cutpoints.cp_next.val = -1; pd->cutpoints.time_next = MVC_FTIME; pd->cutpoints_defined = FALSE; pd->bypass.bypassed = FALSE; pd->bypass.flush_until = MVC_FTIME; SFMT_init_buffer( &pd->sbfr ); if (src_name) UTIL_strncpynt( pd->name, src_name, CPD_NAME_LENGTH ); else pd->name[0] = '\0'; // Check for overrides if ((ret=CONF_lookup_va(g_conf,"Aggregate", src_name, "Tag;Filter", NULL)) != NULL) { UTIL_strncpynt(pd->tag_filter, ret,CPD_NAME_LENGTH); } if ((ret=CONF_lookup_va(g_conf,"Aggregate", src_name, "Stack;Pitot", NULL)) != NULL) { UTIL_strncpynt(pd->name_dP_pitot, ret, CPD_NAME_LENGTH); } if ((pd->win=WINS_create( NULL, COLS, LINES-1 )) == NULL) { SFMT_destroy_buffer( &pd->sbfr ); free(pd); return NULL; } pd->win->flags |= WINS_FLAG_ALWAYS_BOTTOM; WINS_show_window( pd->win ); return pd; } void *AGGREGATE_match( void *private_data, DISPLAY_common_params *cps, DISPLAY_msg_params *msg, void *display_param ) { AGGREGATE_prv_data *pd = (AGGREGATE_prv_data *)private_data; if (!pd) { /* Check to see if this one already exists */ if (!g_aggregate_active) { if (msg->pm->msg->msg == MSG_DISPAGGREGATOR_ALL) { pd = AGGREGATE_init_pd(msg->pm->src_name); if (pd) { g_aggregate_active = TRUE; } } } } else { if (g_aggregate_active) { if (msg->pm->msg->msg == MSG_NOTIFY_CLIENT_TERMINATE && msg->pm->src_name && !strcmp(msg->pm->src_name, pd->name)) { pd = NULL; g_aggregate_active = FALSE; } } } return pd; } void AGGREGATE_cleanup( void *private_data ) { AGGREGATE_prv_data *pd = (AGGREGATE_prv_data *)private_data; SFMT_destroy_buffer( &pd->sbfr ); if (pd->win) WINS_delete( pd->win ); pd->win = NULL; } DECLARE_DISPLAY( AGGREGATE, sizeof(AGGREGATE_prv_data), NULL, AGGREGATE_cleanup, AGGREGATE_update, AGGREGATE_msg_proc, NULL, AGGREGATE_match )