0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ESP32をSNMPエージェントにする

0
Last updated at Posted at 2026-01-12

ESP32の稼働状態を外部から把握できるように、SNMPエージェントにします。

以下のライブラリを使わせていただきました。

0neblock/SNMP_Agent

ソース

こんな感じ

lib_snmp.cpp
#include <Arduino.h>
#include "main_config.h"

#ifdef _SNMP_AGENT_ENABLE_

#include <WiFi.h>
#include <WiFiUdp.h>
#include <SPIFFS.h>
#include <SNMP_Agent.h>
#include "wifi_utils.h"
#include "storage_info.h"

#include "quickjs_esp32.h"

#define IDEAL_LOOP_PERIOD 8000

static WiFiUDP udp;
static SNMPAgent snmp("public");

extern ESP32QuickJS qjs;

#define hrStorageOther        ".1.3.6.1.2.1.25.2.1.1"
#define hrStorageRam          ".1.3.6.1.2.1.25.2.1.2"
#define hrStorageVirtualMemory ".1.3.6.1.2.1.25.2.1.3"
#define hrStorageFixedDisk    ".1.3.6.1.2.1.25.2.1.4"
#define hrStorageFlashMemory  ".1.3.6.1.2.1.25.2.1.9"

static uint32_t lastLoopMicros = 0;
static int cpuLoadRaw = 0;

// 多重平均
static float avgFast = 0;
static float avgMid  = 0;
static float avgSlow = 0;

long snmp_initialize(void)
{
  if( !wifi_is_connected() )
    return -1;

  snmp.setUDP(&udp);
  snmp.begin();

  // system.sysDescr
  snmp.addReadOnlyStaticStringHandler(
    ".1.3.6.1.2.1.1.1.0",
    std::string("ESP32 SNMP Agent")
  );
  // system.sysObjectID
  snmp.addOIDHandler(
    ".1.3.6.1.2.1.1.2.0",
    ".1.3.6.1.4.1.8072.3.2.255"
  );
  // system.sysUpTime
  snmp.addDynamicReadOnlyTimestampHandler(
    ".1.3.6.1.2.1.1.3.0",
    []() -> uint32_t {
        return millis() / 10;
    }
  );
  // system.sysName
  snmp.addReadOnlyStaticStringHandler(
    ".1.3.6.1.2.1.1.5.0",
    std::string(MDNS_NAME)
  );
  // system.sysServices
  snmp.addReadOnlyIntegerHandler(
    ".1.3.6.1.2.1.1.7.0",
    72
  );
  // interface.ifNumber
  snmp.addReadOnlyIntegerHandler(
    ".1.3.6.1.2.1.2.1.0",
    1
  );
  // interface.ifIndex
  snmp.addReadOnlyIntegerHandler(
    ".1.3.6.1.2.1.2.2.1.1.1",
    1
  );
  // interface.ifDescr
  snmp.addReadOnlyStaticStringHandler(
    ".1.3.6.1.2.1.2.2.1.2.1",
    std::string("wifi")
  );
  // interface.ifType
  snmp.addReadOnlyIntegerHandler(
    ".1.3.6.1.2.1.2.2.1.3.1",
    71
  );
  // interface.ifMtu
  snmp.addReadOnlyIntegerHandler(
    ".1.3.6.1.2.1.2.2.1.4.1",
    1500
  );
  uint8_t mac[6];
  WiFi.macAddress(mac);
  // interface.ifPhysAddress
  snmp.addReadOnlyStaticStringHandler(
    ".1.3.6.1.2.1.2.2.1.6.1",
    std::string((char*)mac, sizeof(mac))
  );
  // interface.ifAdminStatus
  snmp.addReadOnlyIntegerHandler(
    ".1.3.6.1.2.1.2.2.1.7.1",
    1
  );
  // interface.ifOperStatus
  snmp.addDynamicIntegerHandler(
    ".1.3.6.1.2.1.2.2.1.8.1",
    []() -> int {
        return (WiFi.status() == WL_CONNECTED) ? 1 : 2; 
    }
  );

  // 1:flash, 2:spiffs, 3:ram, 4:heap, 5:psram, 6:stack
  // hrStorageType
  snmp.addOIDHandler(".1.3.6.1.2.1.25.2.3.1.2.1", hrStorageFlashMemory);
  snmp.addOIDHandler(".1.3.6.1.2.1.25.2.3.1.2.2", hrStorageFixedDisk);
  snmp.addOIDHandler(".1.3.6.1.2.1.25.2.3.1.2.3", hrStorageRam);
  snmp.addOIDHandler(".1.3.6.1.2.1.25.2.3.1.2.4", hrStorageRam);
  snmp.addOIDHandler(".1.3.6.1.2.1.25.2.3.1.2.5", hrStorageRam);
  snmp.addOIDHandler(".1.3.6.1.2.1.25.2.3.1.2.6", hrStorageRam);

  // hrStorageDescr
  snmp.addReadOnlyStaticStringHandler (".1.3.6.1.2.1.25.2.3.1.3.1", std::string("flash"));
  snmp.addReadOnlyStaticStringHandler (".1.3.6.1.2.1.25.2.3.1.3.2", std::string("spiffs"));
  snmp.addReadOnlyStaticStringHandler (".1.3.6.1.2.1.25.2.3.1.3.3", std::string("ram"));
  snmp.addReadOnlyStaticStringHandler (".1.3.6.1.2.1.25.2.3.1.3.4", std::string("heap"));
  snmp.addReadOnlyStaticStringHandler (".1.3.6.1.2.1.25.2.3.1.3.5", std::string("psram"));
  snmp.addReadOnlyStaticStringHandler (".1.3.6.1.2.1.25.2.3.1.3.6", std::string("stack"));

  // hrStorageAllocationUnits
  snmp.addReadOnlyIntegerHandler (".1.3.6.1.2.1.25.2.3.1.4.1", 1);
  snmp.addReadOnlyIntegerHandler (".1.3.6.1.2.1.25.2.3.1.4.2", 1);
  snmp.addReadOnlyIntegerHandler (".1.3.6.1.2.1.25.2.3.1.4.3", 1);
  snmp.addReadOnlyIntegerHandler (".1.3.6.1.2.1.25.2.3.1.4.4", 1);
  snmp.addReadOnlyIntegerHandler (".1.3.6.1.2.1.25.2.3.1.4.5", 1);
  snmp.addReadOnlyIntegerHandler (".1.3.6.1.2.1.25.2.3.1.4.6", 1);
  
  // hrStorageSize
  snmp.addReadOnlyIntegerHandler(".1.3.6.1.2.1.25.2.3.1.5.1", getFlashSize());
  snmp.addReadOnlyIntegerHandler(".1.3.6.1.2.1.25.2.3.1.5.2", SPIFFS.totalBytes());
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.5.3",
    []() -> int {
      return getRamTotal();
    }
  );
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.5.4",
    []() -> int {
      return ESP.getHeapSize();
    }
  );
  snmp.addReadOnlyIntegerHandler(".1.3.6.1.2.1.25.2.3.1.5.5", ESP.getPsramSize());
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.5.6", 
    []() -> int {
      JSMemoryUsage usage;
      qjs.getMemoryUsage(&usage);
      return usage.malloc_limit;
    }
  );

  // hrStorageUsed
  snmp.addReadOnlyIntegerHandler(".1.3.6.1.2.1.25.2.3.1.6.1", getPartitionApplication());
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.6.2", 
    []() -> int {
      return SPIFFS.usedBytes();
    }
  );
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.6.3",
    []() -> int {
      return getRamUsed();
    }
  );
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.6.4",
    []() -> int {
      return ESP.getFreeHeap();
    }
  );
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.6.5",
    []() -> int {
      return ESP.getFreePsram();
    }
  );
  snmp.addDynamicIntegerHandler(".1.3.6.1.2.1.25.2.3.1.6.6",
    []() -> int {
      JSMemoryUsage usage;
      qjs.getMemoryUsage(&usage);
      return usage.malloc_size;
    }
  );

  // hrProcessorLoad
  snmp.addDynamicIntegerHandler(
    ".1.3.6.1.2.1.25.3.3.1.2.1",
    []() -> int {
      return (int)(avgSlow + 0.5);
    }
  );

  lastLoopMicros = micros();

  return 0;
}

static void snmp_perform(void) {
  uint32_t now = micros();
  uint32_t diff = now - lastLoopMicros;
  lastLoopMicros = now;

  const uint32_t ideal = IDEAL_LOOP_PERIOD;
  if (diff <= ideal) {
    cpuLoadRaw = 0;
  } else {
    uint32_t over = diff - ideal;
    cpuLoadRaw = over * 100 / ideal;
    if (cpuLoadRaw > 100) cpuLoadRaw = 100;
  }

  avgFast = avgFast * 0.7 + cpuLoadRaw * 0.3;
  avgMid  = avgMid  * 0.85 + avgFast * 0.15;
  avgSlow = avgSlow * 0.95 + avgMid  * 0.05;
}

long snmp_loop(void)
{
  snmp_perform();
  snmp.loop();

  return 0;
}

#endif

ストレージ情報

storage_info.cpp
#include "esp_ota_ops.h"
#include "esp_partition.h"
#include "esp_heap_caps.h"

unsigned long getRamUsed(void) {
  multi_heap_info_t info;
  heap_caps_get_info(&info, MALLOC_CAP_DEFAULT);

  unsigned long used  = info.total_allocated_bytes;
  return used;
}

unsigned long getRamTotal(void) {
  multi_heap_info_t info;
  heap_caps_get_info(&info, MALLOC_CAP_DEFAULT);

  unsigned long total = info.total_free_bytes + info.total_allocated_bytes;
  return total;
}

unsigned long getPartitionApplication(void) {
  const esp_partition_t* running = esp_ota_get_running_partition();
  return running->size;
}

unsigned long getFlashSize(void) {
  uint32_t flash_size = 0;
  esp_flash_get_size(NULL, &flash_size);
  return flash_size;
}

返している情報

MIB OID 内容
system.sysDescr .1.3.6.1.2.1.1.1.0 ”ESP32 SNMP Agent”
system.sysObjectID .1.3.6.1.2.1.1.2.0 unknown
system.sysUpTime .1.3.6.1.2.1.1.3.0 起動してからの時間
system.sysName .1.3.6.1.2.1.1.5.0 MDNS_NAME
system.sysServices .1.3.6.1.2.1.1.7.0 72
interface.ifNumber .1.3.6.1.2.1.2.1.0 1
interface.ifIndex .1.3.6.1.2.1.2.2.1.1.1 1
interface.ifDescr .1.3.6.1.2.1.2.2.1.2.1 "wifi"
interface.ifType .1.3.6.1.2.1.2.2.1.3.1 71
interface.ifMtu .1.3.6.1.2.1.2.2.1.4.1 1500
interface.ifPhysAddress .1.3.6.1.2.1.2.2.1.6.1 MAC アドレス
interface.ifAdminStatus .1.3.6.1.2.1.2.2.1.7.1 1
interface.ifOperStatus .1.3.6.1.2.1.2.2.1.8.1 WiFi 接続状態
hrProcessorLoad .1.3.6.1.2.1.25.3.3.1.2.1 CPU 負荷
hrStorageIndex hrStorageType hrStorageDescr ストレージ種別
1 hrStorageFlashMemory "flash" フラッシュ
2 hrStorageFixedDisk "spiffs" SPIFFS
3 hrStorageRam "ram" RAM
4 hrStorageRam "heap" ヒープ
5 hrStorageRam "psram" PSRAM
6 hrStorageRam "stack" スタック(Javascript)
MIB OID(X=1~6) 内容
hrStorageType .1.3.6.1.2.1.25.2.3.1.2.X ストレージタイプ
hrStorageDescr .1.3.6.1.2.1.25.2.3.1.3.X ストレージ名
hrStorageSize .1.3.6.1.2.1.25.2.3.1.5.X 全体ストレージサイズ
hrStorageUsed .1.3.6.1.2.1.25.2.3.1.6.X 使用済みストレージサイズ

M5Stack Fire での実行例

$ snmpwalk -v1 192.168.1.XXX -c public 
SNMPv2-MIB::sysDescr.0 = STRING: ESP32 SNMP Agent 
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-TC::unknown 
DISMAN-EXPRESSION-MIB::sysUpTimeInstance = Timeticks: (10582) 0:01:45.82 
SNMPv2-MIB::sysName.0 = STRING: QuickJS_ESP32_M5Stack 
SNMPv2-MIB::sysServices.0 = INTEGER: 72 
IF-MIB::ifNumber.0 = INTEGER: 1 
IF-MIB::ifIndex.1 = INTEGER: 1 
IF-MIB::ifDescr.1 = STRING: wifi 
IF-MIB::ifType.1 = INTEGER: ieee80211(71) 
IF-MIB::ifMtu.1 = INTEGER: 1500 
IF-MIB::ifPhysAddress.1 = STRING: XX:XX:XX:XX:XX:XX 
IF-MIB::ifAdminStatus.1 = INTEGER: up(1) 
IF-MIB::ifOperStatus.1 = INTEGER: up(1) 
HOST-RESOURCES-MIB::hrStorageType.1  =  OID:  HOST-RESOURCES-TYPES::hrStorageFlashMemory 
HOST-RESOURCES-MIB::hrStorageType.2  =  OID:  HOST-RESOURCES-TYPES::hrStorageFixedDisk 
HOST-RESOURCES-MIB::hrStorageType.3  =  OID:  HOST-RESOURCES-TYPES::hrStorageRam 
HOST-RESOURCES-MIB::hrStorageType.4  =  OID:  HOST-RESOURCES-TYPES::hrStorageRam 
HOST-RESOURCES-MIB::hrStorageType.5  =  OID:  HOST-RESOURCES-TYPES::hrStorageRam 
HOST-RESOURCES-MIB::hrStorageType.6  =  OID:  HOST-RESOURCES-TYPES::hrStorageRam 
HOST-RESOURCES-MIB::hrStorageDescr.1 = STRING: flash 
HOST-RESOURCES-MIB::hrStorageDescr.2 = STRING: spiffs 
HOST-RESOURCES-MIB::hrStorageDescr.3 = STRING: ram 
HOST-RESOURCES-MIB::hrStorageDescr.4 = STRING: heap 
HOST-RESOURCES-MIB::hrStorageDescr.5 = STRING: psram 
HOST-RESOURCES-MIB::hrStorageDescr.6 = STRING: stack 
HOST-RESOURCES-MIB::hrStorageSize.1 = INTEGER: 16777216 
HOST-RESOURCES-MIB::hrStorageSize.2 = INTEGER: 836081 
HOST-RESOURCES-MIB::hrStorageSize.3 = INTEGER: 4445963 
HOST-RESOURCES-MIB::hrStorageSize.4 = INTEGER: 281840 
HOST-RESOURCES-MIB::hrStorageSize.5 = INTEGER: 4192123 
HOST-RESOURCES-MIB::hrStorageSize.6 = INTEGER: 50352 
HOST-RESOURCES-MIB::hrStorageUsed.1 = INTEGER: 3145728 
HOST-RESOURCES-MIB::hrStorageUsed.2 = INTEGER: 4267 
HOST-RESOURCES-MIB::hrStorageUsed.3 = INTEGER: 199004 
HOST-RESOURCES-MIB::hrStorageUsed.4 = INTEGER: 66508 
HOST-RESOURCES-MIB::hrStorageUsed.5 = INTEGER: 4187843 
HOST-RESOURCES-MIB::hrStorageUsed.6 = INTEGER: 9456 
HOST-RESOURCES-MIB::hrProcessorLoad.1 = INTEGER: 0 
HOST-RESOURCES-MIB::hrProcessorLoad.1 = No more variables left in this MIB View (It is past the end of the MIB tree) 

(参考) ESP32で動作するJavascript実行環境

ESP32で動作するJavascript実行環境を公開しています。
この中で実装しています。

「電子書籍:M5StackとJavascriptではじめるIoTデバイス制御」

サポートサイト

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?