Команды для получения параметров raspberry

Тема в разделе "Raspberry Pi", создана пользователем Andrey12, 27 янв 2021.

Метки:
  1. Andrey12

    Andrey12 Гик

    Вот я и купил пару малинок, предыстория длинная рассказывать не буду никому это не интересно.

    В наличии raspberry 4b с 4gb памяти, флешки 32gb. Плюс установил вентилятор охлаждения, написал простенькую программу, вентилятор крутит не всегда а при превышении температуры системы 45 градусов, использую ШИМ.
    Для Raspberry в node red, есть такой вот Flow- https://flows.nodered.org/flow/fa6e4749ff7f9067fd6b5330bc54f9e3
    То есть в дашборде можно отображать состояние ресурсов. Выглядит примерно так
    upload_2021-1-27_12-49-31.png
    На второй Raspberry нет смысла ставить nodered, вот и решил написать небольшую программку которая бы публиковала параметры загрузки малинки в MQTT топик, а на нодеред подписаться на этот топик и выводить информацию.

    ну и собственно сам вопрос, я нашел как считать параметры устройств
    загрузка системы: cat /proc/loadavg (это не загрузка процессора)
    память: cat /proc/meminfo
    время работы: cat /proc/uptime
    температура системы: cat /sys/devices/virtual/thermal/thermal_zone0/temp

    Осталось получить размер диска и размер свободного места на нем.
    можно получить так df -h но хотелось бы именно получить состояние из /proc/ или /sys .
    Я ничего подходящего не нашел. Если кто в курсе подскажите, может не все посмотрел что то упустил?
     
  2. Un_ka

    Un_ka Гуру

    Вот что я нашёл, забив
    И судя по заголовку вы не первый, задавшийся этим вопросом.
    Но там только размер диска.
    Зато глянув, что находится в /proc , я обнаружил:
    Код (Bash):
    cat /proc/diskstats
     
    Andrey12 нравится это.
  3. Andrey12

    Andrey12 Гик

    Все /proc я перелопатил, есть например
    Код (C++):
    cat /proc/partitions
    ... ... ...
    179        0   62367744 mmcblk0
    179        1     262144 mmcblk0p1
    179        2   62101504 mmcblk0p2
     
    тут можно получить общий объем диска
    а вот
    Код (C++):
    cat /proc/diskstats
    выдаёт операции с диском, то есть количество успешно считанных записанных, время считывания текущие операции, все что угодно но вот указания занятого или свободного места на диске я не нашел.
    Например команда df -h дает вполне себе форматированную таблицу, но запускать программу это несколько иное чем получить данные из /proc /sys
    Код (C++):
    df -h

    Filesystem      Size  Used Avail Use% Mounted on
    /dev/root        59G  1.7G   55G   3% /
    devtmpfs        1.8G     0  1.8G   0% /dev
    tmpfs           1.9G     0  1.9G   0% /dev/shm
    tmpfs           1.9G  8.5M  1.9G   1% /run
    tmpfs           5.0M  4.0K  5.0M   1% /run/lock
    tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
    tmpfs           200M     0  200M   0% /var/tmp
    tmpfs           200M  1.3M  199M   1% /var/log
    /dev/mmcblk0p1  253M   46M  207M  18% /boot
    tmpfs           383M     0  383M   0% /run/user/1000
     
  4. ZAZ-965

    ZAZ-965 Гуру

    @Andrey12, а на чем вы пишете программу?
    Из команды df можно выдернуть только нужные цифры
    Код (Bash):
    df  --block-size=M  --output=size "$PWD"  |tail -n1 |sed 's/^ *//g'
    df  --block-size=M  --output=used "$PWD"  |tail -n1 |sed 's/^ *//g'
    df  --block-size=M  --output=avail "$PWD" |tail -n1 |sed 's/^ *//g'
     
    Последнее редактирование: 27 янв 2021
    Andrey12 и Igor68 нравится это.
  5. Andrey12

    Andrey12 Гик

    Пишу на С++. Да в принципе и ответ от df -h разобрать несложно.
    Было интересно сделать именно однообразные запросы через cat proc....
    Понято, что в том, что я написал нет пока обработки ошибок, но это вторая программа на С++ для линукса, потихоньку буду доводить до ума :)
    За подсказку с df благодарю. Я знаю, что в линуксах огромные возможности командной строки со всеми этими tail, awk и регулярными выражениями, поэтому можно все написать и просто скриптом. Но пока написал на С++, благо что для этого в системе уже все есть, ничего дополнительно не надо ставить.
     
  6. Igor68

    Igor68 Гуру

    Простите за вмешательство! Я сам писал(пишу) на Си в комплексе с Bash. Такой вот бутерброд из нескольких исполняемых файлов выходит. Не брезгую между ними делать обмен через /dev/shm... и/или socket. Soket особенно удобен когда несколько устройств в одной сети.
    А по сему вопрос:
    В связи с тем, что не применяю (swap) насколько оправдано применение малин с 4 Гб? Ну конечно если у вас есть опыт эксплуатации. Меня интересует большое ОЗУ и реализация моста wifi-ethernet и по доступ по ssh. Wifi должен раздавать сеть (dhcp). Вот и думаю купить четвёртую, одну из пяти третьих подарил племяннику. Так, что сейчас без "моста" на третьей малине (нужен на работе в качестве "удлиннителя" и wifi точки). Ну и другого.
    Спасибо!
     
    Andrey12 нравится это.
  7. ZAZ-965

    ZAZ-965 Гуру

    Andrey12 нравится это.
  8. Andrey12

    Andrey12 Гик

    std::filesystem - то что надо, благодарю!
    Библиотеку посмотрю, пока отправляю через mosquitto_pub. сейчас запустил, пока 3 часа полет нормальный.
     
  9. Andrey12

    Andrey12 Гик

    Ну точно не ко мне, пользую неделю только, 4 гига взял с перепугу, в принципе под мои задачи хватит и двух, хотя серьезно еще не грузил, только разобрался с установкой.
    WiFi порадовал, кладешь в корень диска с установкой wpa_supplicant.conf с параметрами сети и малинка сама прицепилась. Так же и с ssh, кладу в корень пустой ssh.txt и сразу есть доступ по ssh. Но вот про мосты и прочее не скажу, У меня проще, роутер раздает сеть с DHCP и на нем же VPN сервер, доступ внутрь только по VPN.
    3 малинки потому как на одной WEB сервер и он смотрит наружу. Только хочу сказать на струю карту sandisk все вставало хорошо, кроме CMS Joomla, приходилось тайминги ожидания отклика Nginx и php-fm увеличить, но купил новые sandisk и, сразу небо и земля, все летает. А что у вас на 5ти установлено если не секрет?
    Всего малинки 3, на одной node red, mosquitto, grafana, mariadb, на второй Nginx, PHP , третья под эксперименты.
    Попробую объединить все устройства общающиеся по MQTT, и мало мальское управление и вывод статистики сделать,
    Вот такой монстрик:

    2021-01-22 18-38-09.JPG
     
    Un_ka, Igor68, ZAZ-965 и ещё 1-му нравится это.
  10. AlexU

    AlexU Гуру

    Вы реально используете вызов 'cat proc...' из C++-программы?
    Или просто проверяете в терминале с помощью 'cat' содержимое файлов и потом в программе вычитываете эти файлы с помощью стандартных операций работы с файлами (например, iostream)?
     
    Andrey12 нравится это.
  11. Andrey12

    Andrey12 Гик

    Сейчас проверю что у меня там со вчерашнего дня программа наприсылала :)
    Вот вроде работает, 15 часов после вчерашней перезагрузки.

    Код (C++):
    {"SystemTemp":"44","SystemLoad":{"p0":"0.00","p1":"0.00","p2":"0.00","p3":"2","p4":"124","p5":"3151"},"Memory":{"Total":"3919","Free":"3693"},"UpTime":{"Day":"0","Time":"15:40"},"HDDInfo":{"p0":"59","p1":"1.7","p2":"55","p3":"3%"}}
    Насколько я понял в /proc/ это не совсем файлы. но как файлы открываются. и содержимое считывается.
    Я не выполняю cat proc , я открываю файл и считываю содержимое, потом разбираю, формирую json для отправки по mqtt

    Вот такой нехитрый код, сразмером буферов надо еще разбираться, и чтоб хватало и чтоб лишнего не резервировать, с fread еще поразбираюсь что то там я с размерами буфера намудрил, и как посоветовали объем диска попробую по другому получать, а так же применить библиотеку mqtt вместо вызова mosquitto_pub


    Код (C++):
    #include <stdio.h>
    #include <unistd.h>
    #include <fstream>
    #include <stdlib.h>
    #include <sys/wait.h>
    #include <string.h>

    #define TEMPBUFF 96

    using namespace std;

    //# получим температуру процессора
    void getTemperature(char *aBuffer, int aBuffSize) {
      static fstream lFile;
      int lTemp = 0;
      lFile.open("/sys/devices/virtual/thermal/thermal_zone0/temp", ios_base::in);
      lFile >> lTemp;
      lFile.close();
      //# вернем полученное значение деленное на 1000, будет результат в градусах
      sprintf(aBuffer, "\"SystemTemp\":\"%d\"",lTemp/1000);
    }

    //# получим загрузку системы
    void getSystemLoad(char *aBuffer, int aBuffSize) {
      static fstream lFile;
      char lSystemLoad[TEMPBUFF];
      char * pch;

      lFile.open("/proc/loadavg", ios_base::in);
      lFile.getline (lSystemLoad,aBuffSize);
      lFile.close();

      //# Преобразуем в json
      aBuffer[0] = '\0';
      pch = strtok (lSystemLoad," ");
      strcpy (aBuffer,"\"SystemLoad\":{\"p0\":\"");
      strcat (aBuffer,pch);
      uint i = 0;
      while (pch != NULL)
      {
        pch = strtok (NULL, " /");
        if (pch != NULL){
          char lKey[16];
          i++;
          sprintf(lKey, "\",\"p%d\":\"" ,i);
          //printf("lKey %s\n", lKey);
          strcat(aBuffer,lKey);
          strcat(aBuffer,pch);
          //printf("aBuffer %s\n", aBuffer);
        }
      }
      //printf("aBuffer %s\n", aBuffer);
      strcat(aBuffer,"\"}");
    }

    //# получим память всего и свободно
    void getMemory(char *aBuffer, int aBuffSize) {
      static fstream lFile;
      char lMemory[32];
      char lTmpBuff[32];
      uint lMemoryTotal = 0;
      uint lMemoryFree = 0;
      char * pch;
      uint lStartPos = 0;

      lFile.open("/proc/meminfo", ios_base::in);
      lFile.getline (lMemory,aBuffSize);
      pch=strchr(lMemory,' ');
      lStartPos = pch - lMemory;
      for(uint i = lStartPos;i < strlen(lMemory); i++){
          lTmpBuff[i - lStartPos] = lMemory[i];
          lTmpBuff[i - lStartPos + 1] ='\0';
      }
      lMemoryTotal = atoi(lTmpBuff)/1000;
      lFile.getline (lMemory,aBuffSize);
      pch=strchr(lMemory,' ');
      lStartPos = pch - lMemory;
      for(uint i = lStartPos;i < strlen(lMemory); i++){
          lTmpBuff[i - lStartPos] = lMemory[i];
          lTmpBuff[i - lStartPos + 1] ='\0';
      }
      lMemoryFree = atoi(lTmpBuff)/1000;
      lFile.close();
      sprintf(aBuffer, "\"Memory\":{\"Total\":\"%d\",\"Free\":\"%d\"}",lMemoryTotal,lMemoryFree);
    }

    //# получим размер диска и занятое место на диске
    void getHDDInfo(char *aBuffer, int aBuffSize) {
      FILE * lFile;
      char lTmpBuff[96];
      int lStrLen;

      lFile = popen("df -h", "r");
      lStrLen = fread(lTmpBuff, 1, 92, lFile);
      lTmpBuff[lStrLen] = '\0';
      pclose(lFile);
      char lKeys[] = "1234567890";
      char lParseStr[128];
      char * pch;
      //# задача получить из строки 4 параметра ищем цифры
      int lStartStr = 0;
      lStartStr = strcspn (lTmpBuff,lKeys);
      for(uint i = 0; i < strlen(lTmpBuff); i++){
        if (lTmpBuff[i + lStartStr] == '\n'){
          lParseStr[i] = '\0';
          break;
        }
        lParseStr[i] = lTmpBuff[i + lStartStr];
      }

      pch = strtok (lParseStr," G/");
      strcpy (aBuffer,"\"HDDInfo\":{\"p0\":\"");
      strcat (aBuffer,pch);
      uint i = 0;
      while (pch != NULL){
        pch = strtok (NULL, " G/");
        if (pch != NULL){
          char lKey[16];
          i++;
            sprintf(lKey, "\",\"p%d\":\"" ,i);
          //printf("lKey %s\n", lKey);
          strcat(aBuffer,lKey);
          strcat(aBuffer,pch);
          //printf("aBuffer %s\n", aBuffer);
        }
      }
      strcat(aBuffer,"\"}");
      // printf("aBuffer = {%s}\n", aBuffer);
    }

    //# получим время работы с последней загрузки
    void getUpTime(char *aBuffer, int aBuffSize) {
      static fstream lFile;
      char lTmpBuff[24];

      lFile.open("/proc/uptime", ios_base::in);
      lFile.getline (lTmpBuff, aBuffSize);
      lFile.close();
      int lUpTime = atoi(lTmpBuff);
      sprintf(aBuffer, "\"UpTime\":{\"Day\":\"%d\",\"Time\":\"%d:%d\"}", (lUpTime / 86400) % 365, (lUpTime / 3600) % 24, (lUpTime / 60) % 60);
    }


    int main(void) {
      char lTmpBuff[TEMPBUFF];
      char lMQTTTopic[128];
      char lMQTTStr[256];
      FILE * lFileMQTT;

      //# топик формируем при старте
      //# tele/<имя компьютера>/rpi
      fstream lFile;
      lFile.open("/etc/hostname", ios_base::in);
      lFile.getline (lTmpBuff, 12);
      lFile.close();
      sprintf(lMQTTTopic,"tele/%s/rpi",lTmpBuff);

      //pid_t child_pid, wpid;
      //int status = 0;
      while (1){
        lMQTTStr[0] = '\0';
        strcpy(lMQTTStr,"{");
        lTmpBuff[0] = '\0';
        getTemperature(lTmpBuff, TEMPBUFF);
        strcat(lMQTTStr,lTmpBuff);
        strcat(lMQTTStr,",");
       //printf("Температура %s\n", lTmpBuff);
        lTmpBuff[0] = '\0';
        getSystemLoad(lTmpBuff, TEMPBUFF);
        strcat(lMQTTStr,lTmpBuff);
        strcat(lMQTTStr,",");
       //printf("Загрузка %s\n", lTmpBuff);
        lTmpBuff[0] = '\0';
        getMemory(lTmpBuff, TEMPBUFF);
        strcat(lMQTTStr,lTmpBuff);
        strcat(lMQTTStr,",");
       //printf("Память %s\n", lTmpBuff);
        lTmpBuff[0] = '\0';
        getUpTime(lTmpBuff, TEMPBUFF);
        strcat(lMQTTStr,lTmpBuff);
        strcat(lMQTTStr,",");
       //printf("Время работы %s\n", lTmpBuff);
        lTmpBuff[0] = '\0';
        getHDDInfo(lTmpBuff, TEMPBUFF);
        strcat(lMQTTStr,lTmpBuff);
        strcat(lMQTTStr,"}'");
       //printf("Жесткий диск %s\n", lTmpBuff);

       //printf("MQTT %s\n", lMQTTStr);

        char lMQTTCommand[512];
        strcpy(lMQTTCommand,"mosquitto_pub -h 192.168.1.254 -p 1883 -u XXX -P 'XXX' -q 2 -t ");
        strcat(lMQTTCommand,lMQTTTopic);
        strcat(lMQTTCommand," -m '");
        strcat(lMQTTCommand,lMQTTStr);
     
        lFileMQTT = popen(lMQTTCommand, "r");
        //lStrLen = fread(lTmpBuff, 1, 128, lFile);
        pclose(lFileMQTT);

        printf("Ret - %s\n",lMQTTCommand);

     
        //# засыпаем на 600 секунд 10 минут
        usleep(600000 * 1000);
      }
    }

     
    Сейчас пока полученное в dashboard node red попробую вывести, может что еще доработать нужно будет.
     
    Последнее редактирование: 28 янв 2021
  12. AlexU

    AlexU Гуру

    Andrey12 нравится это.
  13. Igor68

    Igor68 Гуру

    Тогда наверное куплю. Думаю только ещё про корпус какой-нибудь устойчивый к внешним средам для четвертой малины.
    Спасибо!
     
    Andrey12 нравится это.
  14. Andrey12

    Andrey12 Гик

    Еще ссылка в копилку :) В принципе у меня несложный json, можно и руками сложить.

    А не проще взять обычный корпус с IP67, подходящего размера, и в него малину? Но вот как с теплоотводом быть?

    Я еще думаю как быть с бесперебойным питанием, хочу Bover bank подключить, как раз вроде 5 вольт. По времени работы протестирую.
     
    Igor68 нравится это.
  15. SergeiL

    SergeiL Оракул Модератор

    Так вариантов много, смотря на сколько нужно, и что есть в наличии.
    Дома редко свет пропадает и обычно не на долго отключают. Был обычный UPS APC-500 с севшей батареей. Поменял батарею - работает. ;)
    А на даче свет могут и на неделю отключить. Там все от 12В работает, от тяговых аккумуляторов.
    А 5В получаю из 12В таким преобразователем.
    A 12В из 12В - был куплен Мастер Китовский. На нем и 5В есть, но так как разнесено по аккумуляторам, то 5В не используется.
     
    ИгорьК и Andrey12 нравится это.
  16. Andrey12

    Andrey12 Гик

    Как раз неиспользуемый power bank есть в наличии, надо только аккумуляторы ему поменять.
    Тома тоже свет пропадает редко, ну может мигнет, от этого и вся защита, да и на даче не часто раза 2-4 в год, самое большое на 4 часа было отключение.
     
  17. Un_ka

    Un_ka Гуру

    Для "удлинителя" wifi не нужно столько оперативной памяти, но нужен достаточной мощности WiFi роутер с антеннами.
    Если вам нужен Ethernet to WiFi мост и только, то Raspberry pi для этого, мне кажется, избыточна.
     
  18. Igor68

    Igor68 Гуру

    Ну и понятия:confused: Я что должен только как удлинитель wifi его купить? Там надо и WireShark, и Zenmap, и gcc, и редактор да и много чего ещё... и в основном по ssh и ssh +X. Просто для удлинителя можно и что-то попроще самой малины.:)
    Меня интересует некий инструмент максимально универсальный. В тройке отключал swap, а четвёрка интересует как в полном отсутствии нужды в нём... даже в намёке на необходимость. И RAM диск применяю часто... вот и хочу что бы ОЗУ было потолще.
     
    Последнее редактирование: 2 фев 2021
  19. a0639

    a0639 Нерд

    Системные параметры мониторить это хорошо, но вы забыли важные оперативные/технологические параметры, те собственно зачем вообще raspberry понадобился.
    Например, текущий/интегральный расход раствора, состояние клапанов и насосов;
    число монет в монетоприемнике;
    или для сервера VPN - число активных клиентов, их список...
    Да много чего
     
  20. a0639

    a0639 Нерд

    У меня, кстати еще температура в корпусе контроллера мониторится. Блок питания мощный, сволочь, греется. Он питает кроме Raspberry еще кучу всего.