#include #include #include #include #include "inverter.h" #include "tools.h" #include "main.h" #include #include cInverter::cInverter(std::string devicename, int qpiri) { device = devicename; status1[0] = 0; status2[0] = 0; warnings[0] = 0; mode = 0; qpiri = qpiri; } string *cInverter::GetQpigsStatus() { m.lock(); string *result = new string(status1); m.unlock(); return result; } string *cInverter::GetQpiriStatus() { m.lock(); string *result = new string(status2); m.unlock(); return result; } string *cInverter::GetWarnings() { m.lock(); string *result = new string(warnings); m.unlock(); return result; } void cInverter::SetMode(char newmode) { m.lock(); if (mode && newmode != mode) ups_status_changed = true; mode = newmode; m.unlock(); } int cInverter::GetMode() { int result; m.lock(); switch (mode) { case 'P': result = 1; break; // Power_On case 'S': result = 2; break; // Standby case 'L': result = 3; break; // Line case 'B': result = 4; break; // Battery case 'F': result = 5; break; // Fault case 'H': result = 6; break; // Power_Saving default: result = 0; break; // Unknown } m.unlock(); return result; } bool cInverter::query(const char *cmd, int replysize) { time_t started; int fd; int i=0, n; fd = open(this->device.data(), O_RDWR | O_NONBLOCK); if (fd == -1) { lprintf("INVERTER: Unable to open device file (errno=%d %s)", errno, strerror(errno)); sleep(5); return false; } // Once connected, set the baud rate and other serial config (Don't rely on this being correct on the system by default...) speed_t baud = B2400; // Speed settings (in this case, 2400 8N1) struct termios settings; tcgetattr(fd, &settings); cfsetospeed(&settings, baud); // baud rate settings.c_cflag &= ~PARENB; // no parity settings.c_cflag &= ~CSTOPB; // 1 stop bit settings.c_cflag &= ~CSIZE; settings.c_cflag |= CS8 | CLOCAL; // 8 bits // settings.c_lflag = ICANON; // canonical mode settings.c_oflag &= ~OPOST; // raw output tcsetattr(fd, TCSANOW, &settings); // apply the settings tcflush(fd, TCOFLUSH); // --------------------------------------------------------------- // Generating CRC for a command uint16_t crc = cal_crc_half((uint8_t*)cmd, strlen(cmd)); n = strlen(cmd); memcpy(&buf, cmd, n); lprintf("INVERTER: Current CRC: %X %X", crc >> 8, crc & 0xff); buf[n++] = crc >> 8; buf[n++] = crc & 0xff; buf[n++] = 0x0d; //send a command write(fd, &buf, n); time(&started); do { n = read(fd, (void*)buf+i, replysize-i); if (n < 0) { if (time(NULL) - started > 2) { lprintf("INVERTER: %s read timeout", cmd); break; } else { usleep(10); continue; } } i += n; } while (i>8))>>4; crc<<=4; crc^=crc_ta[da^(*ptr>>4)]; da=((uint8_t)(crc>>8))>>4; crc<<=4; crc^=crc_ta[da^(*ptr&0x0f)]; ptr++; } bCRCLow = crc; bCRCHign= (uint8_t)(crc>>8); if(bCRCLow==0x28||bCRCLow==0x0d||bCRCLow==0x0a) bCRCLow++; if(bCRCHign==0x28||bCRCHign==0x0d||bCRCHign==0x0a) bCRCHign++; crc = ((uint16_t)bCRCHign)<<8; crc += bCRCLow; return(crc); } bool cInverter::CheckCRC(unsigned char *data, int len) { uint16_t crc = cal_crc_half(data, len-3); return data[len-3]==(crc>>8) && data[len-2]==(crc&0xff); }