void upsdrv_updateinfo(void) { if (ivt_status() < 7) { dstate_datastale(); return; } dstate_setinfo("battery.voltage", "%.2f", battery.voltage.act); dstate_setinfo("battery.voltage.minimum", "%.2f", battery.voltage.min); dstate_setinfo("battery.voltage.maximum", "%.2f", battery.voltage.max); dstate_setinfo("battery.current", "%.1f", battery.current.act); dstate_setinfo("battery.current.minimum", "%.1f", battery.current.min); dstate_setinfo("battery.current.maximum", "%.1f", battery.current.max); dstate_setinfo("battery.temperature", "%.0f", battery.temperature); status_init(); if (battery.current.act > 0) { status_set("OL"); /* charging */ } else { status_set("OB"); /* discharging */ } if (battery.voltage.act < battery.voltage.low) { status_set("LB"); } status_commit(); dstate_dataok(); }
void upsdrv_updateinfo(void) { char reply[REPLY_PACKETSIZE]; int ret, online, battery_normal; if (!udev) { ret = usb_device_open(&udev, &usbdevice, &device_matcher, &driver_callback); if (ret < 0) { return; } } ret = query_ups(reply); if (ret < 4) { usb_comm_fail("Query to UPS failed"); dstate_datastale(); usb_device_close(udev); udev = NULL; return; } usb_comm_good(); dstate_dataok(); /* * 3rd bit of 4th byte indicates whether the UPS is on line (1) * or on battery (0) */ online = (reply[3]&4)>>2; /* * 2nd bit of 4th byte indicates battery status; normal (1) * or low (0) */ battery_normal = (reply[3]&2)>>1; status_init(); if (online) { status_set("OL"); } else { status_set("OB"); } if (!battery_normal) { status_set("LB"); } status_commit(); }
void upsdrv_updateinfo(void) { alarm_init(); /* poll status values values */ sec_poll(FLAG_POLL); alarm_commit(); update_pseudovars(); dstate_dataok(); }
void upsdrv_updateinfo(void) { int r; int x,i=0,j,k,value; float value1; char ch; char data[10]; int data_position = 4; test_EOL(); x= ser_get_buf_len(upsfd,buf, 64, SER_WAIT_SEC,SER_WAIT_USEC); printf("reading status is %d\n",x); printf("the reading data is %s\n",buf); ser_comm_good(); r = test_CMD(); if(r != TRUE){ printf("command error\n"); return; } i = data_position; for(j =0;j< _countof(pacefield);j++) { for(k=0;k<pacefield[j].len;k++) { data[k] = buf[i+k]; } data[k] = '\0'; printf("the reading data is %s\n",data); value = atoi(data); value1 = (float)value/pacefield[j].divident; printf("value 1 = %f\n",value1); dstate_setinfo(pacefield[j].name, "%0.2f",value1); i = i+pacefield[j].len; } status_init(); update_err_status(); update_charge_source_status(); update_inverter_status(); update_battery_status(); update_load_status(); update_battery_charge_dchrg_status(); status_commit(); dstate_dataok(); }
void upsdrv_updateinfo(void) { upsdebugx(1, "upsdrv_updateinfo..."); sleep(1); switch (mode) { case MODE_DUMMY: /* Now get user's defined variables */ if (parse_data_file(upsfd) >= 0) dstate_dataok(); break; case MODE_META: case MODE_REPEATER: if (upsclient_update_vars() > 0) { dstate_dataok(); } else { /* try to reconnect */ upscli_disconnect(ups); if (upscli_connect(ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) { upsdebugx(1, "Error reconnecting: %s", upscli_strerror(ups)); } else { upsdebugx(1, "Reconnected"); } } break; case MODE_NONE: default: break; } }
void upsdrv_updateinfo(void) { static int retry = 0; if (blazer_status(command[proto].status)) { if (retry < MAXTRIES) { upsdebugx(1, "Communications with UPS lost: status read failed!"); retry++; } else if (retry == MAXTRIES) { upslogx(LOG_WARNING, "Communications with UPS lost: status read failed!"); retry++; } else { dstate_datastale(); } return; } if (getval("runtimecal")) { time_t now; time(&now); if (online) { /* OL */ batt.runt.est += batt.runt.nom * difftime(now, lastpoll) / batt.chrg.time; if (batt.runt.est > batt.runt.nom) { batt.runt.est = batt.runt.nom; } } else { /* OB */ batt.runt.est -= load.eff * difftime(now, lastpoll); if (batt.runt.est < 0) { batt.runt.est = 0; } } dstate_setinfo("battery.charge", "%.0f", 100 * batt.runt.est / batt.runt.nom); dstate_setinfo("battery.runtime", "%.0f", batt.runt.est / load.eff); lastpoll = now; } if (retry > MAXTRIES) { upslogx(LOG_NOTICE, "Communications with UPS re-established"); } retry = 0; dstate_dataok(); }
void upsdrv_updateinfo(void) { upsdebugx(1, "upsdrv_updateinfo..."); /* FIXME: implement sensors monitoring */ if (nut_ipmi_get_sensors_status(&ipmi_dev) != 0) { upsdebugx(1, "Error while updating sensors values"); dstate_datastale(); } else { dstate_dataok(); } /* * poll_interval = 2; */ }
void upsdrv_updateinfo(void) { static int retry = 0; if (subdriver[mode]->updateinfo() < 0) { ser_comm_fail("Status read failed!"); if (retry < 3) { retry++; } else { dstate_datastale(); } return; } retry = 0; ser_comm_good(); dstate_dataok(); }
void upsdrv_updateinfo(void) { getupdateinfo(); /* new package for updates */ dstate_setinfo("output.voltage", "%03.1f", OutVoltage); dstate_setinfo("input.voltage", "%03.1f", InVoltage); dstate_setinfo("battery.voltage", "%02.1f", BattVoltage); /* output and bypass tests */ if( OutputOn ) dstate_setinfo("outlet.switchable", "%s", "yes"); else dstate_setinfo("outlet.switchable", "%s", "no"); if( BypassOn ) dstate_setinfo("outlet.1.switchable", "%s", "yes"); else dstate_setinfo("outlet.1.switchable", "%s", "no"); status_init(); if (!SourceFail ) status_set("OL"); /* on line */ else status_set("OB"); /* on battery */ if (Autonomy < 5 ) status_set("LB"); /* low battery */ status_commit(); dstate_setinfo("ups.temperature", "%2.2f", Temperature); dstate_setinfo("input.frequency", "%2.1f", InFreq); dstate_dataok(); }
static int parse_args(int numargs, char **arg) { if (numargs < 1) { return 0; } if (!strcasecmp(arg[0], "PONG")) { upsdebugx(3, "Got PONG from UPS"); return 1; } if (!strcasecmp(arg[0], "DUMPDONE")) { upsdebugx(3, "UPS: dump is done"); dumpdone = 1; return 1; } if (!strcasecmp(arg[0], "DATASTALE")) { dstate_datastale(); return 1; } if (!strcasecmp(arg[0], "DATAOK")) { dstate_dataok(); return 1; } if (numargs < 2) { return 0; } /* DELINFO <var> */ if (!strcasecmp(arg[0], "DELINFO")) { dstate_delinfo(arg[1]); return 1; } if (numargs < 3) { return 0; } /* SETINFO <varname> <value> */ if (!strcasecmp(arg[0], "SETINFO")) { if (!strncasecmp(arg[1], "driver.", 7) || !strcasecmp(arg[1], "battery.charge.low") || !strcasecmp(arg[1], "battery.runtime.low") || !strncasecmp(arg[1], "ups.delay.", 10) || !strncasecmp(arg[1], "ups.timer.", 10)) { /* don't pass on upstream driver settings */ return 1; } if (!strcasecmp(arg[1], "ups.status")) { snprintf(ups.status, sizeof(ups.status), "%s", arg[2]); online = strstr(ups.status, "OL") ? 1 : 0; if (ups.timer.shutdown > 0) { dstate_setinfo("ups.status", "FSD %s", ups.status); return 1; } } if (!strcasecmp(arg[1], "battery.charge")) { battery.charge.act = strtod(arg[2], NULL); dstate_setinfo("battery.charge.low", "%g", battery.charge.low); dstate_setflags("battery.charge.low", ST_FLAG_RW | ST_FLAG_STRING); dstate_setaux("battery.charge.low", 3); } if (!strcasecmp(arg[1], "battery.runtime")) { battery.runtime.act = strtod(arg[2], NULL); dstate_setinfo("battery.runtime.low", "%g", battery.runtime.low); dstate_setflags("battery.runtime.low", ST_FLAG_RW | ST_FLAG_STRING); dstate_setaux("battery.runtime.low", 4); } dstate_setinfo(arg[1], "%s", arg[2]); return 1; } return 0; }
void upsdrv_updateinfo(void) { int res, int_num; #ifdef EXTRADATA int day, hour, minute; #endif float float_num; long int long_num; unsigned char my_answer[255]; /* GET Output data */ res = command_read_sequence(UPS_OUTPUT_DATA, my_answer); if (res < 0) { printf("Could not communicate with the ups"); dstate_datastale(); } else { /* Active power */ int_num = get_word(&my_answer[1]); if (nominal_power != 0) { float_num = (float)((int_num * 100)/nominal_power); dstate_setinfo("ups.load", "%2.1f", float_num); } else { dstate_setinfo("ups.load", "%s", "not available"); } #ifdef EXTRADATA dstate_setinfo("output.power", "%d", int_num); #endif /* voltage */ int_num = get_word(&my_answer[3]); if (int_num > 0) dstate_setinfo("output.voltage", "%d", int_num); if (int_num == -1) dstate_setinfo("output.voltage", "%s", "overrange"); if (int_num == -2) dstate_setinfo("output.voltage", "%s", "not available"); /* current */ float_num = get_word(&my_answer[5]); if (float_num == -1) dstate_setinfo("output.current", "%s", "overrange"); if (float_num == -2) dstate_setinfo("output.current", "%s", "not available"); if (float_num > 0) { float_num = (float)(float_num/10); dstate_setinfo("output.current", "%2.2f", float_num); } #ifdef EXTRADATA /* peak current */ float_num = get_word(&my_answer[7]); if (float_num == -1) dstate_setinfo("output.current.peak", "%s", "overrange"); if (float_num == -2) dstate_setinfo("output.current.peak", "%s", "not available"); if (float_num > 0) { float_num = (float)(float_num/10); dstate_setinfo("output.current.peak", "%2.2f", float_num); } #endif } /* GET Input data */ res = command_read_sequence(UPS_INPUT_DATA, my_answer); if (res < 0){ printf("Could not communicate with the ups"); dstate_datastale(); } else { #ifdef EXTRADATA /* Active power */ int_num = get_word(&my_answer[1]); if (int_num > 0) dstate_setinfo("input.power", "%d", int_num); if (int_num == -1) dstate_setinfo("input.power", "%s", "overrange"); if (int_num == -2) dstate_setinfo("input.power", "%s", "not available"); #endif /* voltage */ int_num = get_word(&my_answer[3]); if (int_num > 0) dstate_setinfo("input.voltage", "%d", int_num); if (int_num == -1) dstate_setinfo("input.voltage", "%s", "overrange"); if (int_num == -2) dstate_setinfo("input.voltage", "%s", "not available"); #ifdef EXTRADATA /* current */ float_num = get_word(&my_answer[5]); if (float_num == -1) dstate_setinfo("input.current", "%s", "overrange"); if (float_num == -2) dstate_setinfo("input.current", "%s", "not available"); if (float_num > 0) { float_num = (float)(float_num/10); dstate_setinfo("input.current", "%2.2f", float_num); } /* peak current */ float_num = get_word(&my_answer[7]); if (float_num == -1) dstate_setinfo("input.current.peak", "%s", "overrange"); if (float_num == -2) dstate_setinfo("input.current.peak", "%s", "not available"); if (float_num > 0) { float_num = (float)(float_num/10); dstate_setinfo("input.current.peak", "%2.2f", float_num); } #endif } /* GET Battery data */ res = command_read_sequence(UPS_BATTERY_DATA, my_answer); if (res < 0) { printf("Could not communicate with the ups"); dstate_datastale(); } else { /* Actual value */ float_num = get_word(&my_answer[1]); float_num = (float)(float_num/10); dstate_setinfo("battery.voltage", "%2.2f", float_num); #ifdef EXTRADATA /* reserve threshold */ float_num = get_word(&my_answer[3]); float_num = (float)(float_num/10); dstate_setinfo("battery.voltage.low", "%2.2f", float_num); /* exhaust threshold */ float_num = get_word(&my_answer[5]); float_num = (float)(float_num/10); dstate_setinfo("battery.voltage.exhaust", "%2.2f", float_num); #endif } #ifdef EXTRADATA /* GET history data */ res = command_read_sequence(UPS_HISTORY_DATA, my_answer); if (res < 0) { printf("Could not communicate with the ups"); dstate_datastale(); } else { /* ups total runtime */ long_num = get_long(&my_answer[1]); day = (int)(long_num / 86400); long_num -= (long)(day*86400); hour = (int)(long_num / 3600); long_num -= (long)(hour*3600); minute = (int)(long_num / 60); long_num -= (minute*60); dstate_setinfo("ups.total.runtime", "%d days %dh %dm %lds", day, hour, minute, long_num); /* ups inverter runtime */ long_num = get_long(&my_answer[5]); day = (int)(long_num / 86400); long_num -= (long)(day*86400); hour = (int)(long_num / 3600); long_num -= (long)(hour*3600); minute = (int)(long_num / 60); long_num -= (minute*60); dstate_setinfo("ups.inverter.runtime", "%d days %dh %dm %lds", day, hour, minute, long_num); /* ups inverter interventions */ dstate_setinfo("ups.inverter.interventions", "%d", get_word(&my_answer[9])); /* battery full discharges */ dstate_setinfo("battery.full.discharges", "%d", get_word(&my_answer[11])); /* ups bypass / stabilizer interventions */ int_num = get_word(&my_answer[13]); if (int_num == -2) dstate_setinfo("ups.bypass.interventions", "%s", "not avaliable"); if (int_num >= 0) dstate_setinfo("ups.bypass.interventions", "%d", int_num); /* ups overheatings */ int_num = get_word(&my_answer[15]); if (int_num == -2) dstate_setinfo("ups.overheatings", "%s", "not avalilable"); if (int_num >= 0) dstate_setinfo("ups.overheatings", "%d", int_num); } #endif /* GET times on battery */ res = command_read_sequence(UPS_GET_TIMES_ON_BATTERY, my_answer); if (res < 0) { printf("Could not communicate with the ups"); dstate_datastale(); } else { autorestart = my_answer[5]; } /* GET schedule */ res = command_read_sequence(UPS_GET_SCHEDULING, my_answer); if (res < 0) { printf("Could not communicate with the ups"); dstate_datastale(); } else { /* time remaining to shutdown */ long_num = get_long(&my_answer[1]); if (long_num == -1) { dstate_setinfo("ups.delay.shutdown", "%d", 120); } else { dstate_setinfo("ups.delay.shutdown", "%ld", long_num); } /* time remaining to restart */ long_num = get_long(&my_answer[5]); if (long_num == -1) { dstate_setinfo("ups.delay.start", "%d", 0); } else { dstate_setinfo("ups.delay.start", "%ld", long_num); } } /* GET ups status */ res = command_read_sequence(UPS_STATUS, my_answer); if (res < 0) { printf("Could not communicate with the ups"); dstate_datastale(); } else { /* ups temperature */ my_answer[3] -=128; if (my_answer[3] > 0) { dstate_setinfo("ups.temperature", "%d", my_answer[3]); } else { dstate_setinfo("ups.temperature", "%s", "not available"); } /* Status */ status_init(); switch (my_answer[1]) { /* byte 1 = STATUS */ case 0x00: status_set("OL"); /* running on mains power */ break; case 0x01: status_set("OB"); /* running on battery power */ break; case 0x02: status_set("LB"); /* battery reserve */ break; case 0x03: /* bypass engaged */ case 0x04: /* manual bypass engaged */ status_set("BY"); break; default: printf("status unknown \n"); break; } switch (my_answer[2]) { /* byte 2 = FAULTS */ case 0x00: /* all right */ break; case 0x01: /* overload */ status_set("OVER"); break; case 0x02: /* overheat */ break; case 0x03: /* hardware fault */ break; case 0x04: /* battery charger failure (overcharging) */ break; case 0x05: /* replace batteries */ status_set("RB"); break; default: printf("status unknown \n"); break; } status_commit(); dstate_dataok(); } return; }
void upsdrv_updateinfo(void) { typedef struct { const unsigned char cmd[6]; const char *var; const char *fmt; const int multindex; } cmd_s; static cmd_s vartab[] = { /* common vars */ { { 1,149,2,1,1,154 }, "battery.runtime", "%.0f", M_BAT_RUNTIME }, { { 1,149,2,1,2,155 }, "battery.voltage", "%.1f", M_VOLT_DC }, { { 1,149,2,1,3,156 }, "battery.current", "%.2f", M_CURRENT_DC }, { { 1,161,2,1,13,178 }, "battery.voltage.nominal", "%.1f", M_VOLT_DC }, { { 1,149,2,1,12,165 }, "battery.temperature", "%.1f", M_TEMPERATURE }, { { 1,149,2,1,14,167 }, "ups.temperature", "%.1f", M_TEMPERATURE }, { { 1,161,2,1,8,173 }, "ups.power.nominal", "%.0f", M_NOMPOWER }, { { 1,161,2,1,4,169 }, "ups.delay.start", "%.0f", M_10 }, { { 1,161,2,1,14,179 },"battery.runtime.low", "%.0f", M_BAT_RUNTIME }, { { 1,149,2,1,8,161 }, "input.frequency", "%.1f", M_FREQUENCY }, { { 1,149,2,1,10,163 }, "input.bypass.frequency", "%.1f", M_FREQUENCY }, { { 1,161,2,1,9,174 }, "input.frequency.nominal", "%.1f", M_FREQUENCY }, { { 1,149,2,1,9,162 }, "output.frequency", "%.1f", M_FREQUENCY }, { { 1,161,2,1,10,175 }, "output.frequency.nominal", "%.1f", M_FREQUENCY }, { { 0 }, NULL, NULL, 0 } }; static cmd_s vartab1o[] = { /* 1-phase out */ { { 1,149,2,1,7,160 }, "ups.load", "%.0f", M_LOADPERC }, { { 1,149,2,1,6,159 }, "ups.power", "%.0f", M_POWER }, { { 1,149,2,1,5,158 }, "ups.realpower", "%.0f", M_POWER }, { { 1,144,2,1,3,151 }, "output.voltage", "%.1f", M_VOLTAGE_O }, { { 1,144,2,1,4,152 }, "output.current", "%.1f", M_CURRENT_O }, { { 0 }, NULL, NULL, 0 } }; static cmd_s vartab1i[] = { /* 1-phase in*/ { { 1,144,2,1,1,149 }, "input.voltage", "%.1f", M_VOLTAGE_I }, { { 1,144,2,1,5,153 }, "input.bypass.voltage", "%.1f", M_VOLTAGE_B }, { { 1,144,2,1,6,154 }, "input.bypass.current", "%.1f", M_CURRENT_B }, { { 0 }, NULL, NULL, 0 } }; static cmd_s vartab3o[] = { /*3-phase out */ { { 1,144,2,1,24,172 }, "ups.L1.load", "%.0f", M_LOADPERC }, { { 1,145,2,1,24,173 }, "ups.L2.load", "%.0f", M_LOADPERC }, { { 1,146,2,1,24,174 }, "ups.L3.load", "%.0f", M_LOADPERC }, { { 1,144,2,1,22,170 }, "ups.L1.power", "%.0f", M_POWER }, { { 1,145,2,1,22,171 }, "ups.L2.power", "%.0f", M_POWER }, { { 1,146,2,1,22,172 }, "ups.L3.power", "%.0f", M_POWER }, { { 1,144,2,1,21,169 }, "ups.L1.realpower", "%.0f", M_POWER }, { { 1,145,2,1,21,170 }, "ups.L2.realpower", "%.0f", M_POWER }, { { 1,146,2,1,21,171 }, "ups.L3.realpower", "%.0f", M_POWER }, { { 1,144,2,1,3,151 }, "output.L1-N.voltage", "%.1f", M_VOLTAGE_O }, { { 1,145,2,1,3,152 }, "output.L2-N.voltage", "%.1f", M_VOLTAGE_O }, { { 1,146,2,1,3,153 }, "output.L3-N.voltage", "%.1f", M_VOLTAGE_O }, { { 1,144,2,1,14,162 }, "output.L1.crestfactor", "%.1f", M_0_1 }, { { 1,145,2,1,14,163 }, "output.L2.crestfactor", "%.1f", M_0_1 }, { { 1,146,2,1,14,164 }, "output.L3.crestfactor", "%.1f", M_0_1 }, { { 0 }, NULL, NULL, 0 } }; static cmd_s vartab3i[] = { /*3-phase in */ { { 1,144,2,1,1,149 }, "input.L1-N.voltage", "%.1f", M_VOLTAGE_I }, { { 1,145,2,1,1,150 }, "input.L2-N.voltage", "%.1f", M_VOLTAGE_I }, { { 1,146,2,1,1,151 }, "input.L3-N.voltage", "%.1f", M_VOLTAGE_I }, { { 1,144,2,1,5,153 }, "input.L1-N.bypass.voltage", "%.1f", M_VOLTAGE_B }, { { 1,145,2,1,5,154 }, "input.L2-N.bypass.voltage", "%.1f", M_VOLTAGE_B }, { { 1,146,2,1,5,155 }, "input.L3-N.bypass.voltage", "%.1f", M_VOLTAGE_B }, { { 1,144,2,1,6,154 }, "input.L1-N.bypass.current", "%.1f", M_CURRENT_B }, { { 1,145,2,1,6,155 }, "input.L2-N.bypass.current", "%.1f", M_CURRENT_B }, { { 1,146,2,1,6,156 }, "input.L3-N.bypass.current", "%.1f", M_CURRENT_B }, { { 1,144,2,1,2,150 }, "input.L1.current", "%.1f", M_CURRENT_I }, { { 1,145,2,1,2,151 }, "input.L2.current", "%.1f", M_CURRENT_I }, { { 1,146,2,1,2,152 }, "input.L3.current", "%.1f", M_CURRENT_I }, { { 0 }, NULL, NULL, 0 } }; static cmd_s * cmdin_p; static cmd_s * cmdout_p; const char *val; char reply[8]; int ret, i; for (i = 0; vartab[i].var; i++) { int16_t val; ret = do_command(vartab[i].cmd, reply, 6); if (ret < 8) { continue; } val = (unsigned char)reply[5]; val <<= 8; val += (unsigned char)reply[6]; dstate_setinfo(vartab[i].var, vartab[i].fmt, val * multi[vartab[i].multindex]); } if (num_inphases>1){ cmdin_p=vartab3i; } else { cmdin_p=vartab1i; } if (num_outphases>1){ cmdout_p=vartab3o; } else { cmdout_p=vartab1o; } for (i = 0; cmdin_p[i].var; i++) { int16_t val; ret = do_command(cmdin_p[i].cmd, reply, 6); if (ret < 8) { continue; } val = (unsigned char)reply[5]; val <<= 8; val += (unsigned char)reply[6]; dstate_setinfo(cmdin_p[i].var, cmdin_p[i].fmt, val * multi[cmdin_p[i].multindex]); } for (i = 0; cmdout_p[i].var; i++) { int16_t val; ret = do_command(cmdout_p[i].cmd, reply, 6); if (ret < 8) { continue; } val = (unsigned char)reply[5]; val <<= 8; val += (unsigned char)reply[6]; dstate_setinfo(cmdout_p[i].var, cmdout_p[i].fmt, val * multi[cmdout_p[i].multindex]); } status_init(); ret = do_command(cmd_bitfield1, reply, 6); if (ret < 8) { upslogx(LOG_ERR, "Failed reading bitfield #1"); dstate_datastale(); return; } if (reply[5] & (1<<0)) { /* ON_BATTERY */ status_set("OB"); } else { status_set("OL"); } val = dstate_getinfo("battery.current"); if (val) { if (atof(val) > 0.05) { status_set("CHRG"); } if (atof(val) < -0.05) { status_set("DISCHRG"); } } ret = do_command(cmd_bitfield2, reply, 6); if (ret < 8) { upslogx(LOG_ERR, "Failed reading bitfield #2"); dstate_datastale(); return; } if (reply[6] & (1<<0)) { /* ON_BYPASS */ status_set("BYPASS"); } if (reply[6] & (1<<5)) { /* REPLACE_BATTERY */ status_set("RB"); } if (reply[6] & (1<<6)) { /* BOOST_ON */ status_set("BOOST"); } if (reply[5] & (1<<1)) { /* BUCK_ON */ status_set("TRIM"); } ret = do_command(cmd_bitfield3, reply, 6); if (ret < 8) { upslogx(LOG_ERR, "Failed reading bitfield #3"); dstate_datastale(); return; } if (reply[6] & (1<<0) ) { /* UPS_OVERLOAD */ status_set("OVER"); } if (reply[6] & (1<<5) ) { /* LOW_BATTERY */ status_set("LB"); } status_commit(); dstate_dataok(); }
void upsdrv_updateinfo(void) { char response[MAX_RESPONSE_LENGTH]; char *ptr, *ptr2; int i; int flags; int contacts_set; int low_battery; status_init(); if (do_command(POLL, STATUS_OUTPUT, "", response) <= 0) { dstate_datastale(); return; } ptr = field(response, 0); /* require output status field to exist */ if (!ptr) { dstate_datastale(); return; } switch (atoi(ptr)) { case 0: status_set("OL"); break; case 1: status_set("OB"); break; case 2: status_set("BYPASS"); break; case 3: status_set("OL"); status_set("TRIM"); break; case 4: status_set("OL"); status_set("BOOST"); break; case 5: status_set("BYPASS"); break; case 6: break; case 7: status_set("OFF"); break; default: break; } ptr = field(response, 6); if (ptr) dstate_setinfo("ups.load", "%d", atoi(ptr)); ptr = field(response, 3); if (ptr) dstate_setinfo("output.voltage", "%03.1f", (double) atoi(ptr) / 10.0); ptr = field(response, 1); if (ptr) dstate_setinfo("output.frequency", "%03.1f", (double) atoi(ptr) / 10.0); ptr = field(response, 4); if (ptr) dstate_setinfo("output.current", "%03.1f", (double) atoi(ptr) / 10.0); low_battery = 0; if (do_command(POLL, STATUS_BATTERY, "", response) <= 0) { dstate_datastale(); return; } ptr = field(response, 0); if (ptr && atoi(ptr) == 2) status_set("RB"); ptr = field(response, 1); if (ptr && atoi(ptr)) low_battery = 1; ptr = field(response, 8); if (ptr) dstate_setinfo("battery.temperature", "%d", atoi(ptr)); ptr = field(response, 9); if (ptr) { dstate_setinfo("battery.charge", "%d", atoi(ptr)); ptr2 = getval("lowbatt"); if (ptr2 && atoi(ptr2) > 0 && atoi(ptr2) <= 99 && atoi(ptr) <= atoi(ptr2)) low_battery = 1; } ptr = field(response, 6); if (ptr) dstate_setinfo("battery.voltage", "%03.1f", (double) atoi(ptr) / 10.0); ptr = field(response, 7); if (ptr) dstate_setinfo("battery.current", "%03.1f", (double) atoi(ptr) / 10.0); if (low_battery) status_set("LB"); if (do_command(POLL, STATUS_ALARM, "", response) <= 0) { dstate_datastale(); return; } ptr = field(response, 3); if (ptr && atoi(ptr)) status_set("OVER"); if (do_command(POLL, STATUS_INPUT, "", response) > 0) { ptr = field(response, 2); if (ptr) dstate_setinfo("input.voltage", "%03.1f", (double) atoi(ptr) / 10.0); ptr = field(response, 1); if (ptr) dstate_setinfo("input.frequency", "%03.1f", (double) atoi(ptr) / 10.0); } if (do_command(POLL, TEST_RESULT, "", response) > 0) { int r; size_t trsize; r = atoi(response); trsize = sizeof(test_result_names) / sizeof(test_result_names[0]); if ((r < 0) || (r >= (int) trsize)) r = 0; dstate_setinfo("ups.test.result", "%s", test_result_names[r]); } if (do_command(POLL, ENVIRONMENT_INFORMATION, "", response) > 0) { ptr = field(response, 0); if (ptr) dstate_setinfo("ambient.temperature", "%d", atoi(ptr)); ptr = field(response, 1); if (ptr) dstate_setinfo("ambient.humidity", "%d", atoi(ptr)); flags = 0; contacts_set = 0; for (i = 0; i < 4; i++) { ptr = field(response, 2 + i); if (ptr) { contacts_set = 1; if (*ptr == '1') flags |= 1 << i; } } if (contacts_set) dstate_setinfo("ups.contacts", "%02X", flags); } /* if we are here, status is valid */ status_commit(); dstate_dataok(); }
void upsdrv_updateinfo(void) { time_t now; int ok; float load; if (status & UPSC_STAT_NOTINIT) { upsdrv_initinfo(); } if (status & UPSC_STAT_NOTINIT) { return; } status = 0; ok = upsc_getparams("UPDS", simple); time(&now); if (ok && now - last_full > full_update_timer) { last_full = now; ok = upsc_getparams("UPDV", nominal); if (ok && can_upbs) ok = upsc_getparams("UPBS", battery); } if (!ok) { dstate_datastale(); last_full = 0; return; } if (!inited_phaseinfo) { if (dstate_getinfo("input.L3-L1.voltage") || dstate_getinfo("input.L3-N.voltage")) { num_inphases = 3; change_name(simple, "input.current", "input.L1.current"); change_name(simple, "input.realpower", "input.L1.realpower"); change_name(simple, "input.power", "input.L1.power"); change_name(simple, "input.voltage", "input.L1-N.voltage"); } if (dstate_getinfo("output.L3-L1.voltage") || dstate_getinfo("output.L3-N.voltage")) { const char *s; num_outphases = 3; if ((s=dstate_getinfo("ups.model")) && (!strncmp(s, "UPS9075", 7) || !strncmp(s, "UPS9100", 7) || !strncmp(s, "UPS9150", 7) || !strncmp(s, "UPS9200", 7) || !strncmp(s, "UPS9250", 7) || !strncmp(s, "UPS9300", 7) || !strncmp(s, "UPS9400", 7) || !strncmp(s, "UPS9500", 7) || !strncmp(s, "UPS9600", 7)) ) { /* Insert kludges for Fiskars UPS9000 here */ upslogx(LOG_INFO, "Fiskars UPS9000 detected, protocol kludges activated"); batt_volt_nom = 384; dstate_setinfo("battery.voltage.nominal", "%.0f", batt_volt_nom); } else { outpwr_factor *= 3; } change_name(simple, "output.current", "output.L1.current"); change_name(simple, "output.current.peak", "output.L1.current.peak"); change_name(simple, "output.realpower", "output.L1.realpower"); change_name(simple, "output.power", "output.L1.power"); change_name(simple, "output.voltage", "output.L1-N.voltage"); } dstate_setinfo("input.phases", "%d", num_inphases); dstate_setinfo("output.phases", "%d", num_outphases); inited_phaseinfo=1; } load = calc_upsload(); if (load >= 0) { upsdebugx(2, "ups.load: %.1f", load*100); dstate_setinfo("ups.load", "%.1f", load*100); } else { upsdebugx(2, "ups.load: No value"); } /* TODO/FIXME: Set UPS date/time on startup and daily if needed */ if (can_updt) { char dtbuf[UPSC_BUFLEN]; if (upsc_getvalue("UPDT", "0", "ACDT", NULL, dtbuf)) { dstate_setinfo("ups.date", "%s", dtbuf); } } if (can_uptm) { char tmbuf[UPSC_BUFLEN]; if (upsc_getvalue("UPTM", "0", "ACTM", NULL, tmbuf)) { dstate_setinfo("ups.time", "%s", tmbuf); } } if (batt_charge < 0) { if (batt_current < 0) { /* Reset battery current history if discharging */ numbatthist = lastbatthist = 0; } batt_charge = batt_charge_pct(); } if (batt_charge >= 0) { dstate_setinfo("battery.charge", "%.1f", batt_charge); } else { dstate_delinfo("battery.charge"); } /* 9999 == unknown value */ if (batt_runtime >= 0 && batt_runtime < 9999) { dstate_setinfo("battery.runtime", "%.0f", batt_runtime*60); } else if (load > 0 && batt_disch_curr_max != 0) { float est_battcurr = load * abs(batt_disch_curr_max); /* Peukert equation */ float runtime = (batt_cap_nom*3600)/pow(est_battcurr, 1.35); upsdebugx(2, "Calculated runtime: %.0f seconds", runtime); if (batt_runtime_max > 0 && runtime > batt_runtime_max*60) { runtime = batt_runtime_max*60; } dstate_setinfo("battery.runtime", "%.0f", runtime); } else if (batt_runtime_max > 0) { /* Show max possible runtime as reported by UPS */ dstate_setinfo("battery.runtime", "%.0f", batt_runtime_max*60); } else { dstate_delinfo("battery.runtime"); } /* Some UPSen only provides this when on battery, so reset between * each iteration to make sure we use the right value */ batt_charge = -1; batt_runtime = -1; if (!(status & UPSC_STAT_ONBATT)) status |= UPSC_STAT_ONLINE; upsc_setstatus(status); dstate_dataok(); ser_comm_good(); }
void upsdrv_updateinfo(void) { CFPropertyListRef power_dictionary; CFStringRef power_source_state; CFNumberRef battery_voltage, battery_runtime; CFNumberRef current_capacity; CFBooleanRef is_charging; double max_capacity_value = 100.0, current_capacity_value; upsdebugx(1, "upsdrv_updateinfo()"); power_dictionary = copy_power_dictionary( g_power_key ); assert(power_dictionary); /* TODO: call dstate_datastale()? */ status_init(); /* Retrieve OL/OB state */ power_source_state = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSPowerSourceStateKey)); assert(power_source_state); CFRetain(power_source_state); upsdebugx(3, "Power Source State:"); if(nut_debug_level >= 3) CFShow(power_source_state); if(!CFStringCompare(power_source_state, CFSTR(kIOPSACPowerValue), 0)) { status_set("OL"); } else { status_set("OB"); } CFRelease(power_source_state); /* Retrieve CHRG state */ is_charging = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSIsChargingKey)); if(is_charging) { Boolean is_charging_value; is_charging_value = CFBooleanGetValue(is_charging); if(is_charging_value) { status_set("CHRG"); } } status_commit(); /* Retrieve battery voltage */ battery_voltage = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSVoltageKey)); if(battery_voltage) { int battery_voltage_value; CFNumberGetValue(battery_voltage, kCFNumberIntType, &battery_voltage_value); upsdebugx(2, "battery_voltage = %d mV", battery_voltage_value); dstate_setinfo("battery.voltage", "%.3f", battery_voltage_value/1000.0); } /* Retrieve battery runtime */ battery_runtime = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSTimeToEmptyKey)); if(battery_runtime) { double battery_runtime_value; CFNumberGetValue(battery_runtime, kCFNumberDoubleType, &battery_runtime_value); upsdebugx(2, "battery_runtime = %.f minutes", battery_runtime_value); if(battery_runtime_value > 0) { dstate_setinfo("battery.runtime", "%d", (int)(battery_runtime_value*60)); } else { dstate_delinfo("battery.runtime"); } } else { dstate_delinfo("battery.runtime"); } /* Retrieve current capacity */ current_capacity = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSCurrentCapacityKey)); if(current_capacity) { CFNumberGetValue(current_capacity, kCFNumberDoubleType, ¤t_capacity_value); upsdebugx(2, "Current Capacity = %.f/%.f units", current_capacity_value, max_capacity_value); if(max_capacity_value > 0) { dstate_setinfo("battery.charge", "%.f", 100.0 * current_capacity_value / max_capacity_value); } } /* TODO: it should be possible to set poll_interval (and maxage in the * server) to an absurdly large value, and use notify(3) to get * updates. */ /* * poll_interval = 2; */ dstate_dataok(); CFRelease(power_dictionary); }
/* update information */ void upsdrv_updateinfo(void) { char val[32]; if (!ups_getinfo()){ return; } /* input.frequency */ upsdebugx(3, "input.frequency (raw data): [raw: %u]", raw_data[INPUT_FREQUENCY]); dstate_setinfo("input.frequency", "%02.2f", input_freq()); upsdebugx(2, "input.frequency: %s", dstate_getinfo("input.frequency")); /* output.frequency */ upsdebugx(3, "output.frequency (raw data): [raw: %u]", raw_data[OUTPUT_FREQUENCY]); dstate_setinfo("output.frequency", "%02.2f", output_freq()); upsdebugx(2, "output.frequency: %s", dstate_getinfo("output.frequency")); /* ups.load */ upsdebugx(3, "ups.load (raw data): [raw: %u]", raw_data[UPS_LOAD]); dstate_setinfo("ups.load", "%03.1f", load_level()); upsdebugx(2, "ups.load: %s", dstate_getinfo("ups.load")); /* battery.charge */ upsdebugx(3, "battery.charge (raw data): [raw: %u]", raw_data[BATTERY_CHARGE]); dstate_setinfo("battery.charge", "%03.1f", batt_level()); upsdebugx(2, "battery.charge: %s", dstate_getinfo("battery.charge")); /* input.voltage */ upsdebugx(3, "input.voltage (raw data): [raw: %u]", raw_data[INPUT_VOLTAGE]); dstate_setinfo("input.voltage", "%03.1f",input_voltage()); upsdebugx(2, "input.voltage: %s", dstate_getinfo("input.voltage")); /* output.voltage */ upsdebugx(3, "output.voltage (raw data): [raw: %u]", raw_data[OUTPUT_VOLTAGE]); dstate_setinfo("output.voltage", "%03.1f",output_voltage()); upsdebugx(2, "output.voltage: %s", dstate_getinfo("output.voltage")); status_init(); *val = 0; if (!(raw_data[STATUS_A] & MAINS_FAILURE)) { !(raw_data[STATUS_A] & OFF) ? status_set("OL") : status_set("OFF"); } else { status_set("OB"); } if (raw_data[STATUS_A] & LOW_BAT) status_set("LB"); if (raw_data[STATUS_A] & AVR_ON) { input_voltage() < linevoltage ? status_set("BOOST") : status_set("TRIM"); } if (raw_data[STATUS_A] & OVERLOAD) status_set("OVER"); if (raw_data[STATUS_B] & BAD_BAT) status_set("RB"); if (raw_data[STATUS_B] & TEST) status_set("TEST"); status_commit(); upsdebugx(2, "STATUS: %s", dstate_getinfo("ups.status")); dstate_dataok(); }
static int instcmd(const char *cmdname, const char *extra) { unsigned char command[10], answer[10]; int res; if (!strcasecmp(cmdname, "beeper.off")) { /* compatibility mode for old command */ upslogx(LOG_WARNING, "The 'beeper.off' command has been renamed to 'beeper.mute' for this driver"); return instcmd("beeper.mute", NULL); } if (!strcasecmp(cmdname, "beeper.on")) { /* compatibility mode for old command */ upslogx(LOG_WARNING, "The 'beeper.on' command has been renamed to 'beeper.enable'"); return instcmd("beeper.enable", NULL); } if (!strcasecmp(cmdname, "shutdown.return")) { /* Same stuff as upsdrv_shutdown() */ if (! autorestart) { command[0]=UPS_SET_TIMES_ON_BATTERY; command[1]=0x00; /* max time on */ command[2]=0x00; /* battery */ command[3]=0x00; /* max time after */ command[4]=0x00; /* battery reserve */ command[5]=0x01; /* autorestart after battery depleted enabled */ command_write_sequence(command, 6, answer); } /* shedule a shutdown in 30 seconds */ command[0]=UPS_SET_SCHEDULING; command[1]=0x1e; /* remaining */ command[2]=0x00; /* time */ command[3]=0x00; /* to */ command[4]=0x00; /* shutdown 30 secs */ command[5]=0x01; /* programmed */ command[6]=0x00; /* time */ command[7]=0x00; /* to */ command[8]=0x00; /* restart 1 sec */ command_write_sequence(command, 9, answer); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "shutdown.stayoff")) { /* shedule a shutdown in 30 seconds with no restart (-1) */ command[0]=UPS_SET_SCHEDULING; command[1]=0x1e; /* remaining */ command[2]=0x00; /* time */ command[3]=0x00; /* to */ command[4]=0x00; /* shutdown 150 secs */ command[5]=0xff; /* programmed */ command[6]=0xff; /* time */ command[7]=0xff; /* to */ command[8]=0xff; /* restart -1 no restart*/ command_write_sequence(command, 9, answer); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "shutdown.stop")) { /* set shutdown and restart time to -1 (no shutdown, no restart) */ command[0]=UPS_SET_SCHEDULING; command[1]=0xff; /* remaining */ command[2]=0xff; /* time */ command[3]=0xff; /* to */ command[4]=0xff; /* shutdown -1 (no shutdown) */ command[5]=0xff; /* programmed */ command[6]=0xff; /* time */ command[7]=0xff; /* to */ command[8]=0xff; /* restart -1 no restart */ command_write_sequence(command, 9, answer); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "test.failure.start")) { /* force ups on battery power */ command[0]=UPS_SET_BATTERY_TEST; command[1]=0x01; /* 0 = perform battery test 1 = force UPS on battery power 2 = restore standard mode (mains power) */ command_write_sequence(command, 2, answer); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "test.failure.stop")) { /* restore standard mode (mains power) */ command[0]=UPS_SET_BATTERY_TEST; command[1]=0x02; /* 0 = perform battery test 1 = force UPS on battery power 2 = restore standard mode (mains power) */ command_write_sequence(command, 2, answer); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "test.battery.start")) { /* launch battery test */ command[0]=UPS_SET_BATTERY_TEST; command[1]=0x00; /* 0 = perform battery test 1 = force UPS on battery power 2 = restore standard mode (mains power) */ send_write_command(command, 2); sleep(15); res = get_answer(answer); switch (answer[1]) { /* byte 1 = Test result */ case 0x00: /* all right */ dstate_setinfo("ups.test.result", "OK"); break; case 0x01: dstate_setinfo("ups.test.result", "Battery charge: 20%%"); break; case 0x02: dstate_setinfo("ups.test.result", "Battery charge: 40%%"); break; case 0x03: dstate_setinfo("ups.test.result", "Battery charge: 60%%"); break; case 0x04: dstate_setinfo("ups.test.result", "Battery charge: 80%%"); break; case 0x05: dstate_setinfo("ups.test.result", "Battery charge: 100%%"); break; case 0xfe: dstate_setinfo("ups.test.result", "Bad battery pack: replace"); break; default: dstate_setinfo("ups.test.result", "Impossible to test"); break; } dstate_dataok(); upslogx(LOG_NOTICE, "instcmd: test battery returned with %d bytes", res); upslogx(LOG_NOTICE, "test battery byte 1 = %x", answer[1]); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "beeper.enable")) { /* set buzzer to not muted */ command[0]=UPS_SET_BUZZER_MUTE; command[1]=0x00; /* 0 = not muted 1 = muted 2 = read current status */ command_write_sequence(command, 2, answer); return STAT_INSTCMD_HANDLED; } if (!strcasecmp(cmdname, "beeper.mute")) { /* set buzzer to muted */ command[0]=UPS_SET_BUZZER_MUTE; command[1]=0x01; /* 0 = not muted 1 = muted 2 = read current status */ command_write_sequence(command, 2, answer); return STAT_INSTCMD_HANDLED; } upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname); return STAT_INSTCMD_UNKNOWN; }
void upsdrv_initinfo(void) { /* try to detect the PSU here - call fatal_with_errno(EXIT_FAILURE, ) if it fails */ upsdebugx(1, "upsdrv_initinfo..."); /* print what we detected during IPMI open */ upsdebugx(1, "Detected a PSU: %s/%s", ipmi_dev.manufacturer ? ipmi_dev.manufacturer : "unknown", ipmi_dev.product ? ipmi_dev.product : "unknown"); dstate_setinfo ("device.type", "psu"); /* Publish information from the IPMI structure */ if (ipmi_dev.manufacturer) dstate_setinfo("device.mfr", "%s", ipmi_dev.manufacturer); if (ipmi_dev.product) dstate_setinfo("device.model", "%s", ipmi_dev.product); if (ipmi_dev.serial) dstate_setinfo("device.serial", "%s", ipmi_dev.serial); if (ipmi_dev.part) dstate_setinfo("device.part", "%s", ipmi_dev.part); if (ipmi_dev.date) dstate_setinfo("device.mfr.date", "%s", ipmi_dev.date); /* FIXME: move to device.id */ dstate_setinfo("ups.id", "%i", ipmi_id); /* FIXME: move to device.realpower.nominal */ if (ipmi_dev.overall_capacity != -1) dstate_setinfo("ups.realpower.nominal", "%i", ipmi_dev.overall_capacity); if (ipmi_dev.input_minvoltage != -1) dstate_setinfo("input.voltage.minimum", "%i", ipmi_dev.input_minvoltage); if (ipmi_dev.input_maxvoltage != -1) dstate_setinfo("input.voltage.maximum", "%i", ipmi_dev.input_maxvoltage); if (ipmi_dev.input_minfreq != -1) dstate_setinfo("input.frequency.low", "%i", ipmi_dev.input_minfreq); if (ipmi_dev.input_maxfreq != -1) dstate_setinfo("input.frequency.high", "%i", ipmi_dev.input_maxfreq); /* FIXME: move to device.voltage */ if (ipmi_dev.voltage != -1) dstate_setinfo("ups.voltage", "%i", ipmi_dev.voltage); if (nut_ipmi_monitoring_init() != 0) fatalx(EXIT_FAILURE, "Can't initialize IPMI monitoring"); if (nut_ipmi_get_sensors_status(&ipmi_dev) != 0) { upsdebugx(1, "Error while updating sensors values"); dstate_datastale(); } else { dstate_dataok(); } /* upsh.instcmd = instcmd; */ }
/* normal idle loop - keep up with the current state of the UPS */ void upsdrv_updateinfo(void) { unsigned char c; unsigned int ob, lb; static unsigned int ob_state = 0, ob_last = 0, ob_ctr = 0; static unsigned int lb_state = 0, lb_last = 0, lb_ctr = 0; ob = lb = 0; /* the UPS connects RX to TX when on battery, so test for loopback */ ser_flush_in(upsfd, "", 0); c = ML_ONBATTERY; ser_send_char(upsfd, c); if (ser_get_char(upsfd, &c, 1, 0) == 1) { while (ser_get_char(upsfd, &c, 1, 0) == 1) continue; if (c == ML_ONBATTERY) ob = 1; } if (ser_get_dcd(upsfd)) lb = 1; /* state machine below to ensure status changes are debounced */ /* OB/OL state change: reset counter */ if (ob_last != ob) ob_ctr = 0; else ob_ctr++; upsdebugx(2, "OB: state %d last %d now %d ctr %d", ob_state, ob_last, ob, ob_ctr); if (ob_ctr >= DEBOUNCE) { if (ob != ob_state) { upsdebugx(2, "OB: toggling state"); if (ob_state == 0) ob_state = 1; else ob_state = 0; } } ob_last = ob; /* now do it again for LB */ /* state change: reset counter */ if (lb_last != lb) lb_ctr = 0; else lb_ctr++; upsdebugx(2, "LB: state %d last %d now %d ctr %d", lb_state, lb_last, lb, lb_ctr); if (lb_ctr >= DEBOUNCE) { if (lb != lb_state) { upsdebugx(2, "LB: toggling state"); if (lb_state == 0) lb_state = 1; else lb_state = 0; } } lb_last = lb; status_init(); if (ob_state == 1) status_set("OB"); /* on battery */ else status_set("OL"); /* on line */ if (lb_state == 1) status_set("LB"); /* low battery */ status_commit(); dstate_dataok(); }
void upsdrv_updateinfo(void) { int ret, errors = 0; /* We really should be dealing with alarms through a separate callback, so that we can keep the * processing of alarms and polling for data separated. Currently, this isn't supported by the * driver main body, so we'll have to revert to polling each time we're called, unless the * socket indicates we're no longer connected. */ if (testvar("subscribe")) { char buf[LARGEBUF]; ret = ne_sock_read(sock, buf, sizeof(buf)); if (ret > 0) { /* alarm message received */ ne_xml_parser *parser = ne_xml_create(); upsdebugx(2, "%s: ne_sock_read(%d bytes) => %s", __func__, ret, buf); ne_xml_push_handler(parser, subdriver->startelm_cb, subdriver->cdata_cb, subdriver->endelm_cb, NULL); ne_xml_parse(parser, buf, strlen(buf)); ne_xml_destroy(parser); time(&lastheard); } else if ((ret == NE_SOCK_TIMEOUT) && (difftime(time(NULL), lastheard) < 180)) { /* timed out */ upsdebugx(2, "%s: ne_sock_read(timeout)", __func__); } else { /* connection closed or unknown error */ upslogx(LOG_ERR, "NSM connection with '%s' lost", uri.host); upsdebugx(2, "%s: ne_sock_read(%d) => %s", __func__, ret, ne_sock_error(sock)); ne_sock_close(sock); if (netxml_alarm_subscribe(subdriver->subscribe) == NE_OK) { extrafd = ne_sock_fd(sock); time(&lastheard); return; } dstate_datastale(); extrafd = -1; return; } } /* get additional data */ ret = netxml_get_page(subdriver->getobject); if (ret != NE_OK) { errors++; } ret = netxml_get_page(subdriver->summary); if (ret != NE_OK) { errors++; } if (errors > 1) { dstate_datastale(); return; } status_init(); alarm_init(); netxml_alarm_set(); alarm_commit(); netxml_status_set(); status_commit(); dstate_dataok(); }
void upsdrv_updateinfo(void) { char fstring[512]; if (! fc.valid) { fprintf(stderr, "upsupdate run before ups_ident() read ups config\n"); assert(0); } if (execute("f\r", fstring, sizeof(fstring)) > 0) { int inverter=0, charger=0, vin=0, vout=0, btimeleft=0, linestat=0, alstat=0, vaout=0; double ampsout=0.0, vbatt=0.0, battpercent=0.0, loadpercent=0.0, hstemp=0.0, acfreq=0.0, ambtemp=0.0; char tmp[16]; /* Inverter status. 0=off 1=on */ memcpy(tmp, fstring+16, 2); tmp[2] = '\0'; inverter = atoi(tmp); /* Charger status. 0=off 1=on */ memcpy(tmp, fstring+18, 2); tmp[2] = '\0'; charger = atoi(tmp); /* Input Voltage. integer number */ memcpy(tmp, fstring+24, 4); tmp[4] = '\0'; vin = atoi(tmp); /* Output Voltage. integer number */ memcpy(tmp, fstring+28, 4); tmp[4] = '\0'; vout = atoi(tmp); /* Iout. int times 10 */ memcpy(tmp, fstring+36, 4); tmp[4] = '\0'; ampsout = ((double)(atoi(tmp)) / 10.0); /* Battery voltage. int times 10 */ memcpy(tmp, fstring+50, 4); tmp[4] = '\0'; vbatt = ((double)(atoi(tmp)) / 10.0); /* Volt-amps out. int */ memcpy(tmp, fstring+40, 6); tmp[6] = '\0'; vaout = atoi(tmp); /* Line status. Bitmask */ memcpy(tmp, fstring+72, 2); tmp[2] = '\0'; linestat = atoi(tmp); /* Alarm status reg 1. Bitmask */ memcpy(tmp, fstring+20, 2); tmp[2] = '\0'; alstat = atoi(tmp); /* Alarm status reg 2. Bitmask */ memcpy(tmp, fstring+22, 2); tmp[2] = '\0'; alstat = alstat | (atoi(tmp) << 8); /* AC line frequency */ memcpy(tmp, fstring+54, 4); tmp[4]= '\0'; acfreq = ((double)(atoi(tmp)) / 100.0); /* Runtime remaining */ memcpy(tmp, fstring+58, 4); tmp[4]= '\0'; btimeleft = atoi(tmp); /* UPS Temperature */ memcpy(tmp, fstring+62, 4); tmp[4]= '\0'; ambtemp = (double)(atoi(tmp)); /* Percent Load */ switch(fc.model) { case ME3100: if (execute("d 16\r", fstring, sizeof(fstring)) > 0) { int l; sscanf(fstring, "16 FullLoad%% %d", &l); loadpercent = (double) l; } break; case RE1800: if (execute("d 16\r", fstring, sizeof(fstring)) > 0) { int l; sscanf(fstring, "16 FullLoad%% %d", &l); loadpercent = (double) l; } if (execute("d 12\r", fstring, sizeof(fstring)) > 0) { int l; sscanf(fstring, "12 HS Temp %dC", &l); hstemp = (double) l; } break; case MD1KVA: if (execute("d 22\r", fstring, sizeof(fstring)) > 0) { int l; sscanf(fstring, "22 FullLoad%% %d", &l); loadpercent = (double) l; } break; default: /* Will never happen, caught in upsdrv_initups() */ fatalx(EXIT_FAILURE, "Unknown model in upsdrv_updateinfo()"); } /* Compute battery percent left based on battery voltages. */ battpercent = ((vbatt - fc.emptyvolts) / (fc.fullvolts - fc.emptyvolts) * 100.0); if (battpercent < 0.0) battpercent = 0.0; else if (battpercent > 100.0) battpercent = 100.0; /* Compute status string */ { int lowbatt, overload, replacebatt, boosting, trimming; lowbatt = alstat & (1<<1); overload = alstat & (1<<6); replacebatt = alstat & (1<<10); boosting = inverter && (linestat & (1<<2)) && (vin < 115); trimming = inverter && (linestat & (1<<2)) && (vin > 115); status_init(); if (inverter) status_set("OB"); else status_set("OL"); if (lowbatt) status_set("LB"); if (trimming) status_set("TRIM"); if (boosting) status_set("BOOST"); if (replacebatt) status_set("RB"); if (overload) status_set("OVER"); status_commit(); } if (debugging) { fprintf(stderr, "Poll: inverter %d charger %d vin %d vout %d vaout %d btimeleft %d\n", inverter, charger, vin, vout, vaout, btimeleft); fprintf(stderr, " ampsout %5.1f vbatt %5.1f batpcnt %5.1f loadpcnt %5.1f upstemp %5.1f acfreq %5.2f ambtemp %5.1f\n", ampsout, vbatt, battpercent, loadpercent, hstemp, acfreq, ambtemp); } /* Stuff information into info structures */ dstate_setinfo("input.voltage", "%05.1f", (double)vin); dstate_setinfo("output.voltage", "%05.1f", (double)vout); dstate_setinfo("battery.charge", "%02.1f", battpercent); dstate_setinfo("ups.load", "%02.1f", loadpercent); dstate_setinfo("battery.voltage", "%02.1f", vbatt); dstate_setinfo("input.frequency", "%05.2f", (double)acfreq); dstate_setinfo("ups.temperature", "%05.1f", (double)hstemp); dstate_setinfo("battery.runtime", "%d", btimeleft); dstate_setinfo("ambient.temperature", "%05.1f", (double)ambtemp); dstate_dataok(); /* Tim: With out this return, it always falls over to the datastate() at the end of the function */ return; } else { dstate_datastale(); } /* if (execute("f\r", fstring, sizeof(fstring)) > 0) */ dstate_datastale(); return; }
void upsdrv_updateinfo(void) { static int CommTry = COMM_TRIES; /* Comm loss counter */ char buffer[256]; /* Main response buffer */ char buffer2[32]; /* Conversion buffer */ char s; int RetValue; int timevalue; /* Start with EG/ON information */ ser_flush_in(upsfd,"",0); /*just in case*/ ser_send (upsfd,"%c%s", GET_ALL, COMMAND_END); if (strncmp(UpsFamily, FAMILY_EG, FAMILY_SIZE) == 0) { RetValue = OneacGetResponse (buffer,sizeof(buffer),GETALL_EG_RESP_SIZE); } else { RetValue = OneacGetResponse (buffer, sizeof(buffer), GETALL_RESP_SIZE); } if ((RetValue != 0) && (CommTry == 0)) { ser_comm_fail("Oneac UPS Comm failure continues on port %s", device_path); } else if (RetValue != 0) { if (--CommTry == 0) { ser_comm_fail("Oneac UPS Comm failure on port %s",device_path); dstate_datastale(); } upsdebugx(2,"Oneac: Update serial comm retry value: %d", CommTry); return; } else { CommTry = COMM_TRIES; /* Reset serial retries */ s = buffer[12]; status_init(); alarm_init(); /*take care of the UPS status information*/ if (s == '@') { status_set("OL"); } else { if (s & 0x01) /* On Battery */ { status_set("OB"); } else { status_set("OL"); } if (s & 0x02) /* Low Battery */ status_set("LB"); if (s & 0x04) /* General fault */ { dstate_setinfo("ups.test.result","UPS Internal Failure"); } else { dstate_setinfo("ups.test.result","Normal"); } if (s & 0x08) /* Replace Battery */ status_set("RB"); /* if (s & 0x10) */ /* High Line */ if (s & 0x20) /* Unit is hot */ alarm_set("OVERHEAT"); } /*take care of the reason why the UPS last transferred to battery*/ switch (buffer[13]) { case XFER_BLACKOUT : dstate_setinfo("input.transfer.reason", "Blackout"); break; case XFER_LOW_VOLT : dstate_setinfo("input.transfer.reason", "Low Input Voltage"); break; case XFER_HI_VOLT : dstate_setinfo("input.transfer.reason", "High Input Voltage"); break; case NO_VALUE_YET : dstate_setinfo("input.transfer.reason", "No transfer yet."); break; default : upslogx(LOG_INFO,"Oneac: Unknown reason for UPS battery" " transfer [%c]", buffer[13]); } /* now update info for only the non-EG families of UPS*/ if (strncmp(UpsFamily, FAMILY_EG, FAMILY_SIZE) != 0) { dstate_setinfo("ups.load", "0%.2s",buffer+31); /* Output ON or OFF? */ if(buffer[27] == NO_VALUE_YET) status_set("OFF"); /*battery charge*/ if(buffer[10] == YES) dstate_setinfo("battery.charge", "0%.2s",buffer+33); else dstate_setinfo("battery.charge", "100"); EliminateLeadingZeroes (buffer+35, 3, buffer2, sizeof(buffer2)); dstate_setinfo("input.voltage", "%s",buffer2); EliminateLeadingZeroes (buffer+38, 3, buffer2, sizeof(buffer2)); dstate_setinfo("input.voltage.minimum", "%s",buffer2); EliminateLeadingZeroes (buffer+41, 3, buffer2, sizeof(buffer2)); dstate_setinfo("input.voltage.maximum", "%s",buffer2); EliminateLeadingZeroes (buffer+44, 3, buffer2, sizeof(buffer2)); dstate_setinfo("output.voltage", "%s",buffer2); if (buffer[15] == NO_VALUE_YET) { dstate_delinfo("ups.timer.shutdown"); } else { /* A shutdown is underway! */ status_set("FSD"); if(buffer[15] != HIGH_COUNT) { EliminateLeadingZeroes (buffer+15, 3, buffer2, sizeof(buffer2)); dstate_setinfo("ups.timer.shutdown", "%s", buffer2); } else { dstate_setinfo("ups.timer.shutdown", "999"); } } if (buffer[47] == YES) status_set("BOOST"); } /* Now update info for only the OZ/OB families of UPS */ if ((strncmp(UpsFamily, FAMILY_OZ, FAMILY_SIZE) == 0) || (strncmp(UpsFamily, FAMILY_OB, FAMILY_SIZE) == 0)) { ser_flush_in(upsfd,"",0); /*just in case*/ ser_send (upsfd,"%c%s",GETX_ALL_1,COMMAND_END); RetValue = OneacGetResponse (buffer, sizeof(buffer), GETX_ALL1_RESP_SIZE); if(RetValue) { if (--CommTry == 0) { ser_comm_fail("Oneac (OZ) UPS Comm failure on port %s", device_path); dstate_datastale(); } upsdebugx(2,"Oneac: " "Update (OZ) serial comm retry value: %d", CommTry); } else { CommTry = COMM_TRIES; /* Reset count */ EliminateLeadingZeroes (buffer+57, 5, buffer2, sizeof(buffer2)); dstate_setinfo("ups.realpower", "%s",buffer2); dstate_setinfo("input.frequency", "%.2s.%c", buffer+42,buffer[44]); dstate_setinfo("output.frequency", "%.2s.%c", buffer+76, buffer[78]); EliminateLeadingZeroes (buffer+29, 3, buffer2, sizeof(buffer2)); dstate_setinfo("battery.voltage", "%s.%c",buffer2, buffer[32]); dstate_setinfo("ups.temperature", "%.2s",buffer+13); dstate_setinfo("ups.load", "%.3s",buffer+73); strncpy(buffer2, buffer+19, 4); buffer2[4]='\0'; timevalue = atoi(buffer2) * 60; /* Change mins to secs */ dstate_setinfo("battery.runtime", "%d",timevalue); /* Now some individual requests... */ /* Battery replace date */ ser_send (upsfd,"%c%s",GETX_BATT_REPLACED,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), GETX_DATE_RESP_SIZE)) dstate_setinfo("battery.date", "%.6s (yymmdd)", buffer); /* Low and high output trip points */ ser_send (upsfd,"%c%s",GETX_LOW_OUT_ALLOW,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), GETX_ALLOW_RESP_SIZE)) { EliminateLeadingZeroes (buffer, 3, buffer2,sizeof(buffer2)); dstate_setinfo("input.transfer.low", "%s", buffer2); } ser_send (upsfd,"%c%s",GETX_HI_OUT_ALLOW,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), GETX_ALLOW_RESP_SIZE)) dstate_setinfo("input.transfer.high", "%s", buffer); /* Restart delay */ ser_send (upsfd,"%c%s",GETX_RESTART_DLY,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), GETX_RSTRT_RESP_SIZE)) { EliminateLeadingZeroes (buffer, 4, buffer2, sizeof(buffer2)); dstate_setinfo("ups.delay.start", "%s", buffer2); } /* Buzzer state */ ser_send (upsfd,"%s%s",GETX_BUZZER_WHAT,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), 1)) { switch (buffer[0]) { case BUZZER_ENABLED : dstate_setinfo("ups.beeper.status", "enabled"); break; case BUZZER_DISABLED : dstate_setinfo("ups.beeper.status", "disabled"); break; case BUZZER_MUTED : dstate_setinfo("ups.beeper.status", "muted"); break; default : dstate_setinfo("ups.beeper.status", "enabled"); } } /* Auto start setting */ ser_send (upsfd,"%s%s",GETX_AUTO_START,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), 1)) { if (buffer[0] == '0') dstate_setinfo("ups.start.auto", "yes"); else dstate_setinfo("ups.start.auto", "no"); } /* Low Batt at time */ ser_send (upsfd,"%c%s",GETX_LOW_BATT_TIME,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), 2)) { strncpy(buffer2, buffer, 2); buffer2[2]='\0'; timevalue = atoi(buffer2) * 60; /* Mins to secs */ dstate_setinfo("battery.runtime.low", "%d",timevalue); } /* Shutdown timer */ ser_send (upsfd,"%c%s",GETX_SHUTDOWN,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), GETX_SHUTDOWN_RESP_SIZE)) { /* ON would have handled NO_VALUE_YET and setting FSD * above so only deal with counter value here. */ if (buffer[0] != NO_VALUE_YET) { EliminateLeadingZeroes (buffer, 5, buffer2, sizeof(buffer2)); dstate_setinfo("ups.timer.shutdown", "%s", buffer2); } } /* Restart timer */ ser_send (upsfd,"%s%s",GETX_RESTART_COUNT,COMMAND_END); if(!OneacGetResponse (buffer, sizeof(buffer), GETX_RSTRT_RESP_SIZE)) { if (atoi(buffer) == 0) { dstate_delinfo("ups.timer.start"); } else { EliminateLeadingZeroes (buffer, 4, buffer2, sizeof(buffer2)); dstate_setinfo("ups.timer.start", "%s", buffer2); } } } } alarm_commit(); status_commit(); /* If the comm retry counter is zero then datastale has been set. * We don't want to set dataok or ser_comm_good if that is the case. */ if (CommTry != 0) { dstate_dataok(); ser_comm_good(); } } }
void upsdrv_updateinfo(void) { uint8_t getextendedOK; static int countlost = 0; int stat; upsdebugx(1, "countlost %d",countlost); if (countlost > 0){ upsdebugx(1, "Communication with UPS is lost: status read failed!"); if (countlost == COUNTLOST) { dstate_datastale(); upslogx(LOG_WARNING, "Communication with UPS is lost: status read failed!"); } } if (typeRielloProtocol == DEV_RIELLOGPSER) stat = get_ups_status(); else stat = get_ups_sentr(); if (stat < 0) { if (countlost < COUNTLOST) countlost++; return; } if (typeRielloProtocol == DEV_RIELLOGPSER) { if (get_ups_extended() == 0) getextendedOK = 1; else getextendedOK = 0; } else getextendedOK = 1; if (countlost == COUNTLOST) upslogx(LOG_NOTICE, "Communication with UPS is re-established!"); dstate_setinfo("input.frequency", "%.2f", DevData.Finp/10.0); dstate_setinfo("input.bypass.frequency", "%.2f", DevData.Fbypass/10.0); dstate_setinfo("output.frequency", "%.2f", DevData.Fout/10.0); dstate_setinfo("battery.voltage", "%.1f", DevData.Ubat/10.0); dstate_setinfo("battery.charge", "%u", DevData.BatCap); dstate_setinfo("battery.runtime", "%u", DevData.BatTime*60); dstate_setinfo("ups.temperature", "%u", DevData.Tsystem); if (input_monophase) { dstate_setinfo("input.voltage", "%u", DevData.Uinp1); dstate_setinfo("input.bypass.voltage", "%u", DevData.Ubypass1); } else { dstate_setinfo("input.L1-N.voltage", "%u", DevData.Uinp1); dstate_setinfo("input.L2-N.voltage", "%u", DevData.Uinp2); dstate_setinfo("input.L3-N.voltage", "%u", DevData.Uinp3); dstate_setinfo("input.bypass.L1-N.voltage", "%u", DevData.Ubypass1); dstate_setinfo("input.bypass.L2-N.voltage", "%u", DevData.Ubypass2); dstate_setinfo("input.bypass.L3-N.voltage", "%u", DevData.Ubypass3); } if (output_monophase) { dstate_setinfo("output.voltage", "%u", DevData.Uout1); dstate_setinfo("output.power.percent", "%u", DevData.Pout1); dstate_setinfo("ups.load", "%u", DevData.Pout1); } else { dstate_setinfo("output.L1-N.voltage", "%u", DevData.Uout1); dstate_setinfo("output.L2-N.voltage", "%u", DevData.Uout2); dstate_setinfo("output.L3-N.voltage", "%u", DevData.Uout3); dstate_setinfo("output.L1.power.percent", "%u", DevData.Pout1); dstate_setinfo("output.L2.power.percent", "%u", DevData.Pout2); dstate_setinfo("output.L3.power.percent", "%u", DevData.Pout3); dstate_setinfo("ups.load", "%u", (DevData.Pout1+DevData.Pout2+DevData.Pout3)/3); } status_init(); /* AC Fail */ if (riello_test_bit(&DevData.StatusCode[0], 1)) status_set("OB"); else status_set("OL"); /* LowBatt */ if ((riello_test_bit(&DevData.StatusCode[0], 1)) && (riello_test_bit(&DevData.StatusCode[0], 0))) status_set("LB"); /* Standby */ if (!riello_test_bit(&DevData.StatusCode[0], 3)) status_set("OFF"); /* On Bypass */ if (riello_test_bit(&DevData.StatusCode[1], 3)) status_set("BYPASS"); /* Overload */ if (riello_test_bit(&DevData.StatusCode[4], 2)) status_set("OVER"); /* Buck */ if (riello_test_bit(&DevData.StatusCode[1], 0)) status_set("TRIM"); /* Boost */ if (riello_test_bit(&DevData.StatusCode[1], 1)) status_set("BOOST"); /* Replace battery */ if (riello_test_bit(&DevData.StatusCode[2], 0)) status_set("RB"); /* Charging battery */ if (riello_test_bit(&DevData.StatusCode[2], 2)) status_set("CHRG"); status_commit(); dstate_dataok(); if (getextendedOK) { dstate_setinfo("output.L1.power", "%u", DevData.Pout1VA); dstate_setinfo("output.L2.power", "%u", DevData.Pout2VA); dstate_setinfo("output.L3.power", "%u", DevData.Pout3VA); dstate_setinfo("output.L1.realpower", "%u", DevData.Pout1W); dstate_setinfo("output.L2.realpower", "%u", DevData.Pout2W); dstate_setinfo("output.L3.realpower", "%u", DevData.Pout3W); dstate_setinfo("output.L1.current", "%u", DevData.Iout1); dstate_setinfo("output.L2.current", "%u", DevData.Iout2); dstate_setinfo("output.L3.current", "%u", DevData.Iout3); } poll_interval = 2; countlost = 0; /* if (get_ups_statuscode() != 0) upsdebugx(2, "Communication is lost"); else { }*/ /* * poll_interval = 2; */ }
void upsdrv_initinfo(void) { dummy_info_t *item; switch (mode) { case MODE_DUMMY: /* Initialise basic essential variables */ for ( item = nut_data ; item->info_type != NULL ; item++ ) { if (item->drv_flags & DU_FLAG_INIT) { dstate_setinfo(item->info_type, "%s", item->default_value); dstate_setflags(item->info_type, item->info_flags); /* Set max length for strings, if needed */ if (item->info_flags & ST_FLAG_STRING) dstate_setaux(item->info_type, item->info_len); } } /* Now get user's defined variables */ if (parse_data_file(upsfd) < 0) upslogx(LOG_NOTICE, "Unable to parse the definition file %s", device_path); /* Initialize handler */ upsh.setvar = setvar; dstate_dataok(); break; case MODE_META: case MODE_REPEATER: /* Obtain the target name */ if (upscli_splitname(device_path, &client_upsname, &hostname, &port) != 0) { fatalx(EXIT_FAILURE, "Error: invalid UPS definition.\nRequired format: upsname[@hostname[:port]]"); } /* Connect to the target */ ups = xmalloc(sizeof(*ups)); if (upscli_connect(ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) { fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } else { upsdebugx(1, "Connected to %s@%s", client_upsname, hostname); } if (upsclient_update_vars() < 0) { /* check for an old upsd */ if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) { fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query"); } fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups)); } /* FIXME: commands and settable variable! */ break; default: case MODE_NONE: fatalx(EXIT_FAILURE, "no suitable definition found!"); break; } upsh.instcmd = instcmd; dstate_addcmd("load.off"); }