static int do_command(const unsigned char *command, char *reply, int cmd_len) { int ret; ret = ser_send_buf(upsfd, command, cmd_len); if (ret < 0) { upsdebug_with_errno(2, "send"); return -1; } else if (ret < cmd_len) { upsdebug_hex(2, "send: truncated", command, ret); return -1; } upsdebug_hex(2, "send", command, ret); ret = ser_get_buf_len(upsfd, reply, 8, 1, 0); /* it needs that this driver works with USB to Serial cable */ if (ret < 0) { upsdebug_with_errno(2, "read"); return -1; } else if (ret < 6) { upsdebug_hex(2, "read: truncated", reply, ret); return -1; } else if (reply[7] != cksum(reply, 7)) { upsdebug_hex(2, "read: checksum error", reply, ret); return -1; } upsdebug_hex(2, "read", reply, ret); return ret; }
static void getupdateinfo(void) { unsigned char temp[256]; int tam; temp[0] = 0; /* flush temp buffer */ tam = ser_get_buf_len(upsfd, temp, pacsize, 3, 0); CommReceive(temp, tam); }
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(); }
/* get the answer of a command from the ups */ int get_answer(unsigned char *data) { unsigned char my_buf[255]; /* packet has a maximum length of 256 bytes */ int packet_length, checksum, i, res; /* Read STX byte */ res = ser_get_char(upsfd, my_buf, 1, 0); if (res < 1) { ser_comm_fail("Receive error (STX): %d!!!\n", res); return -1; } if (my_buf[0] != 0x02) { ser_comm_fail("Receive error (STX): packet not on start!!\n"); return -1; } /* Read data length byte */ res = ser_get_char(upsfd, my_buf, 1, 0); if (res < 1) { ser_comm_fail("Receive error (length): %d!!!\n", res); return -1; } packet_length = my_buf[0]; if (packet_length < 2) { ser_comm_fail("Receive error (length): packet length %d!!!\n", packet_length); return -1; } /* Try to read all the remainig bytes (packet_length) */ res = ser_get_buf_len(upsfd, my_buf, packet_length, 1, 0); if (res != packet_length) { ser_comm_fail("Receive error (data): got %d bytes instead of %d!!!\n", res, packet_length); return -1; } /* now we have the whole answer from the ups, we can checksum it checksum byte is equal to the sum modulus 256 of all the data bytes + packet_length (no STX no checksum byte itself) */ checksum = packet_length; for (i = 0; i < (packet_length - 1); i++) checksum += my_buf[i]; checksum = checksum % 256; if (my_buf[packet_length-1] != checksum) { ser_comm_fail("checksum error! got %x instad of %x, received %d bytes \n", my_buf[packet_length - 1], checksum, packet_length); dump_buffer(my_buf, packet_length); return -1; } packet_length-=1; /* get rid of the checksum byte */ memcpy(data, my_buf, packet_length); return packet_length; }
/* get info from ups */ static int ups_getinfo(void) { int i, c; /* send trigger char to UPS */ if (ser_send_char (upsfd, SEND_DATA) != 1) { upslogx(LOG_NOTICE, "writing error"); dstate_datastale(); return 0; } else { upsdebugx(5, "Num of bytes requested for reading from UPS: %d", types[type].num_of_bytes_from_ups); c = ser_get_buf_len(upsfd, raw_data, types[type].num_of_bytes_from_ups, 3, 0); if (c != types[type].num_of_bytes_from_ups) { upslogx(LOG_NOTICE, "data receiving error (%d instead of %d bytes)", c, types[type].num_of_bytes_from_ups); dstate_datastale(); return 0; } else upsdebugx(5, "Num of bytes received from UPS: %d", c); }; /* optional dump of raw data */ if (nut_debug_level > 4) { /* FIXME: use upsdebug_hex() ? */ printf("Raw data from UPS:\n"); for (i = 0; i < types[type].num_of_bytes_from_ups; i++) { printf("%2d 0x%02x (%c)\n", i, raw_data[i], raw_data[i]>=0x20 ? raw_data[i] : ' '); }; }; /* validate raw data for correctness */ if (validate_raw_data() != 0) { upslogx(LOG_NOTICE, "data receiving error (validation check)"); dstate_datastale(); return 0; }; return 1; }
static int do_command(char type, const char *command, const char *parameters, char *response) { char buffer[SMALLBUF]; int count, ret; ser_flush_io(upsfd); if (response) { *response = '\0'; } snprintf(buffer, sizeof(buffer), "~00%c%03d%s%s", type, (int)(strlen(command) + strlen(parameters)), command, parameters); ret = ser_send_pace(upsfd, 10000, "%s", buffer); if (ret <= 0) { upsdebug_with_errno(3, "do_command: send [%s]", buffer); return -1; } upsdebugx(3, "do_command: %d bytes sent [%s] -> OK", ret, buffer); ret = ser_get_buf_len(upsfd, (unsigned char *)buffer, 4, 3, 0); if (ret < 0) { upsdebug_with_errno(3, "do_command: read"); return -1; } if (ret == 0) { upsdebugx(3, "do_command: read -> TIMEOUT"); return -1; } buffer[ret] = '\0'; upsdebugx(3, "do_command: %d byted read [%s]", ret, buffer); if (!strcmp(buffer, "~00D")) { ret = ser_get_buf_len(upsfd, (unsigned char *)buffer, 3, 3, 0); if (ret < 0) { upsdebug_with_errno(3, "do_command: read"); return -1; } if (ret == 0) { upsdebugx(3, "do_command: read -> TIMEOUT"); return -1; } buffer[ret] = '\0'; upsdebugx(3, "do_command: %d bytes read [%s]", ret, buffer); count = atoi(buffer); if (count >= MAX_RESPONSE_LENGTH) { upsdebugx(3, "do_command: response exceeds expected size!"); return -1; } if (count && !response) { upsdebugx(3, "do_command: response not expected!"); return -1; } if (count == 0) { return 0; } ret = ser_get_buf_len(upsfd, (unsigned char *)response, count, 3, 0); if (ret < 0) { upsdebug_with_errno(3, "do_command: read"); return -1; } if (ret == 0) { upsdebugx(3, "do_command: read -> TIMEOUT"); return -1; } response[ret] = '\0'; upsdebugx(3, "do_command: %d bytes read [%s]", ret, response); /* Tripp Lite pads their string responses with spaces. I don't like that, so I remove them. This is safe to do with all responses for this protocol, so I just do that here. */ rtrim(response, ' '); return ret; } if (!strcmp(buffer, "~00A")) { return 0; } return -1; }
/* get the answer of a command from the ups. And check that the answer is for this command */ int get_answer(unsigned char *data, unsigned char command) { unsigned char my_buf[128]; /* packet has a maximum length of 121+5 bytes */ int length, end_length = 0, res, endblock = 0, start = 0; unsigned char block_number, sequence, pre_sequence = 0; while (endblock != 1){ do { /* Read PW_COMMAND_START_BYTE byte */ res = ser_get_char(upsfd, my_buf, 1, 0); if (res != 1) { upsdebugx(1,"Receive error (PW_COMMAND_START_BYTE): %d, cmd=%x!!!\n", res, command); return -1; } start++; } while ((my_buf[0] != PW_COMMAND_START_BYTE) && (start < 128)); if (start == 128) { ser_comm_fail("Receive error (PW_COMMAND_START_BYTE): packet not on start!!%x\n", my_buf[0]); return -1; } /* Read block number byte */ res = ser_get_char(upsfd, my_buf+1, 1, 0); if (res != 1) { ser_comm_fail("Receive error (Block number): %d!!!\n", res); return -1; } block_number = (unsigned char)my_buf[1]; if (command <= 0x43) { if ((command - 0x30) != block_number){ ser_comm_fail("Receive error (Request command): %x!!!\n", block_number); return -1; } } if (command >= 0x89) { if ((command == 0xA0) && (block_number != 0x01)){ ser_comm_fail("Receive error (Requested only mode command): %x!!!\n", block_number); return -1; } if ((command != 0xA0) && (block_number != 0x09)){ ser_comm_fail("Receive error (Control command): %x!!!\n", block_number); return -1; } } /* Read data length byte */ res = ser_get_char(upsfd, my_buf+2, 1, 0); if (res != 1) { ser_comm_fail("Receive error (length): %d!!!\n", res); return -1; } length = (unsigned char)my_buf[2]; if (length < 1) { ser_comm_fail("Receive error (length): packet length %x!!!\n", length); return -1; } /* Read sequence byte */ res = ser_get_char(upsfd, my_buf+3, 1, 0); if (res != 1) { ser_comm_fail("Receive error (sequence): %d!!!\n", res); return -1; } sequence = (unsigned char)my_buf[3]; if ((sequence & 0x80) == 0x80) { endblock = 1; } if ((sequence & 0x07) != (pre_sequence + 1)) { ser_comm_fail("Not the right sequence received %x!!!\n", sequence); return -1; } pre_sequence = sequence; /* Try to read all the remainig bytes */ res = ser_get_buf_len(upsfd, my_buf+4, length, 1, 0); if (res != length) { ser_comm_fail("Receive error (data): got %d bytes instead of %d!!!\n", res, length); return -1; } /* Get the checksum byte */ res = ser_get_char(upsfd, my_buf+(4+length), 1, 0); if (res != 1) { ser_comm_fail("Receive error (checksum): %x!!!\n", res); return -1; } /* now we have the whole answer from the ups, we can checksum it */ if (!checksum_test(my_buf)) { ser_comm_fail("checksum error! "); return -1; } memcpy(data+end_length, my_buf+4, length); end_length += length; } upsdebug_hex (5, "get_answer", data, end_length); ser_comm_good(); return end_length; }
static void getbaseinfo(void) { unsigned char temp[256]; unsigned char Pacote[37]; int tam, i, j=0; time_t tmt; struct tm *now; const char *Model; time( &tmt ); now = localtime( &tmt ); dian = now->tm_mday; mesn = now->tm_mon+1; anon = now->tm_year+1900; weekn = now->tm_wday; /* trying detect rhino model */ while ( ( !detected ) && ( j < 10 ) ) { temp[0] = 0; /* flush temp buffer */ tam = ser_get_buf_len(upsfd, temp, pacsize, 3, 0); if( tam == 37 ) { for( i = 0 ; i < tam ; i++ ) { Pacote[i] = temp[i]; } } j++; if( tam == 37) CommReceive(Pacote, tam); else CommReceive(temp, tam); } if( (!detected) ) { fatalx(EXIT_FAILURE, NO_RHINO ); } switch( RhinoModel ) { case 0xC0: { Model = "Rhino 20.0 kVA"; PotenciaNominal = 20000; break; } case 0xC1: { Model = "Rhino 10.0 kVA"; PotenciaNominal = 10000; break; } case 0xC2: { Model = "Rhino 6.0 kVA"; PotenciaNominal = 6000; break; } case 0xC3: { Model = "Rhino 7.5 kVA"; PotenciaNominal = 7500; break; } default: { Model = "Rhino unknown model"; PotenciaNominal = 0; break; } } /* manufacturer and model */ dstate_setinfo("ups.mfr", "%s", "Microsol"); dstate_setinfo("ups.model", "%s", Model); /* dstate_setinfo("input.transfer.low", "%03.1f", InDownLim); LimInfBattInv ? dstate_setinfo("input.transfer.high", "%03.1f", InUpLim); LimSupBattInv ? */ dstate_addcmd("shutdown.stayoff"); /* CMD_SHUT */ /* there is no reserved words for CMD_INON and CMD_INOFF yet */ /* dstate_addcmd("input.on"); */ /* CMD_INON = 1 */ /* dstate_addcmd("input.off"); */ /* CMD_INOFF = 2 */ dstate_addcmd("load.on"); /* CMD_OUTON = 3 */ dstate_addcmd("load.off"); /* CMD_OUTOFF = 4 */ dstate_addcmd("bypass.start"); /* CMD_PASSON = 5 */ dstate_addcmd("bypass.stop"); /* CMD_PASSOFF = 6 */ printf("Detected %s on %s\n", dstate_getinfo("ups.model"), device_path); }