Обнаружение события изменения питания / состояния ИБП - PullRequest
0 голосов
/ 27 января 2019

Я хочу определить, когда система включена UPS или просто изменяется состояние питания.

Примерно так:

enter image description here

Я пытался обнаружить его с помощью функции GetSystemPowerStatus:

Код:

    SYSTEM_POWER_STATUS powerStatus;
    bool powerStatusRes = GetSystemPowerStatus(&powerStatus);

    switch (powerStatus.ACLineStatus) {
        case 0:
            std::cout << "Offline" << std::endl;
            break;
        case 1:
            std::cout << "Online" << std::endl;
            break;
        case 255:
            std::cout << "Unknown status" << std::endl;
        default:
            std::cout << "Failed to detect the status" << std::endl;
    }

    switch (powerStatus.BatteryFlag) {
        case 1:
            std::cout << "High — the battery capacity is at more than 66 percent" << std::endl;
            break;
        case 2:
            std::cout << "Low — the battery capacity is at less than 33 percent" << std::endl;
            break;
        case 4:
            std::cout << "Critical — the battery capacity is at less than five percent" << std::endl;
            break;
        case 8:
            std::cout << "Charging" << std::endl;
            break;
        case 128:
            std::cout << "No system battery" << std::endl;
            break;
        case 255:
            std::cout << "Unknown status—unable to read the battery flag information" << std::endl;
            break;
        default:
            std::cout << "Failed to detect the battery flag" << std::endl;
    }

Но возвращается powerStatus.ACLineStatus для UPS или AC как Online и для powerStatus.BatteryFlag - No system battery.

Также я пытался обнаружить UPS с помощью функции GetPwrCapabilities:

Код:

SYSTEM_POWER_CAPABILITIES SysPowerCapabilities = {0};

if (!GetPwrCapabilities(&SysPowerCapabilities)){
    std::cout << "Failed to get System Power information!" << std::endl;
}

if (SysPowerCapabilities.UpsPresent) {
    std::cout << "UPS found" << std::endl;
} else {
    std::cout << "UPS not found" << std::endl;
}

Возвращает - UPS not found(драйвер не доступен для этой UPS модели).

Теперь я пытаюсь обнаружить изменения питания с помощью функции Qt nativeEvent:

bool Test::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    Q_UNUSED(result);
    Q_UNUSED(eventType);
    MSG *msg = static_cast<MSG*>(message);

    if (msg->message == WM_POWERBROADCAST && msg->wParam == PBT_APMPOWERSTATUSCHANGE) {
        qDebug() << "Power changed!!!";
    }

    return false;
}

Но ничего не печатается наконсоль.Есть идеи, как это обнаружить?Спасибо.

Обновлено: 03.02.2019

Я обнаружил, что мне нужно использовать HID API, чтобы получить некоторые значения для UPS.Некоторые значения для UPS из сети.

 0x00840010 = UPS
 0x00840012 = Battery
 0x00840030 = Voltage
 0x00840040 = ConfigVoltage
 0x0084001a = Input
 0x0084005a = AudibleAlarmControl
 0x00840002 = PresentStatus
 0x00850044 = Charging
 0x00850045 = Discharging
 0x008500d0 = ACPresent

Обновленный код:

   QString devicePath = "\\\\?\\HID#VID_....";
   HANDLE fileHandle = CreateFileA(devicePath.toStdString().c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

   if (fileHandle != INVALID_HANDLE_VALUE) {
       std::cout << "Success. Device opened for reading..." << std::endl;
       PHIDP_PREPARSED_DATA preparsedData;
       HIDP_CAPS capabilities;
       HIDD_ATTRIBUTES attributes;
       BOOL hidPreparsedRes = HidD_GetPreparsedData(fileHandle, &preparsedData);

       if (hidPreparsedRes) {
           if (HidD_GetAttributes(fileHandle, &attributes)) {
               std::cout << "Product ID: " << attributes.ProductID << std::endl;
               std::cout << "Size: " << attributes.Size << std::endl;
               std::cout << "Vendor ID: " << attributes.VendorID << std::endl;
               std::cout << "Version number: " << attributes.VersionNumber << std::endl;

              if (HidP_GetCaps(preparsedData, &capabilities) == HIDP_STATUS_SUCCESS) {
                  std::cout << "Caps: " << capabilities.NumberOutputValueCaps << std::endl;
              } else {
                  std::cout << "Failed to return HID capabilities!" << std::endl;
              }
           } else {
              std::cout << "Failed to get HID attributes" << std::endl;
           }

           std::cout << getLastErrorAsString() << std::endl;
       } else {
           std::cout << "Failed to get preparsed data!" << std::endl;
       }

       HidD_FreePreparsedData(preparsedData);
   } else {
       std::cout << "Failed to open device for reading!" << std::endl;
   }

   CloseHandle(fileHandle);

Итак, теперь он возвращает:

Успех.Устройство открыто для чтения ... Идентификатор продукта: 20833 Размер: 12 Идентификатор поставщика: 1637 Номер версии: 2 Колпачки: 1

HIDP_CAPS Структура имеет много разных значений, вопрос в том, какпреобразовать их в UPS значения для проверки изменений питания / UPS состояния?Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...