{
  "spec_version": 1,
  "slug": "hukseflux-sr30",
  "manufacturer": "Hukseflux",
  "model": "SR30-M2-D1 (digital Class A pyranometer)",
  "category": "Sensor",
  "supplier_url": "https://www.hukseflux.com/products/solar-radiation-sensors/pyranometers/sr30-m2-pyranometer",
  "default_configuration": {
    "protocol": "modbus_tcp",
    "port": 502,
    "unit_id": 1,
    "addressing": "zero_based",
    "byte_order": "BigEndian",
    "word_order": "HighFirst",
    "native_interface": "rs485",
    "serial": {
      "parity": "Even",
      "baud_rate": 19200,
      "data_bits": 8,
      "stop_bits": 1
    }
  },
  "coils": [
    {
      "address": 0,
      "count": 1,
      "name": "Restart the sensor",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "RW",
      "description": "Write 1 to restart the sensor."
    },
    {
      "address": 1,
      "count": 1,
      "name": "Heater on/off",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "RW",
      "description": "Write 1 to switch the ventilator/heater on."
    },
    {
      "address": 2,
      "count": 1,
      "name": "Measure sensor electrical resistance",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "RW",
      "description": "Write 1 to run the resistance measurement."
    },
    {
      "address": 3,
      "count": 1,
      "name": "Fan on/off",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "RW",
      "description": "Write 1 to switch the fan on."
    }
  ],
  "discrete_inputs": [],
  "input_registers": [
    {
      "address": 2,
      "count": 2,
      "name": "Irradiance, temperature compensated",
      "data_type": "Int32",
      "units": "W/m2",
      "scale_factor": 0.01,
      "offset": 0,
      "access": "R",
      "description": "Signed 32-bit, x 0.01 W/m2. Registers 2 and 3 must be read in one request."
    },
    {
      "address": 4,
      "count": 2,
      "name": "Irradiance, uncompensated",
      "data_type": "Int32",
      "units": "W/m2",
      "scale_factor": 0.01,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 6,
      "count": 1,
      "name": "Sensor body temperature",
      "data_type": "Int16",
      "units": "°C",
      "scale_factor": 0.01,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 7,
      "count": 1,
      "name": "Sensor electrical resistance",
      "data_type": "UInt16",
      "units": "ohm",
      "scale_factor": 0.1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 8,
      "count": 1,
      "name": "Scaling factor irradiance",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R",
      "description": "Default 100."
    },
    {
      "address": 9,
      "count": 1,
      "name": "Scaling factor temperature",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R",
      "description": "Default 100."
    },
    {
      "address": 10,
      "count": 2,
      "name": "Sensor voltage output",
      "data_type": "Int32",
      "units": "V",
      "scale_factor": 1e-9,
      "offset": 0,
      "access": "R",
      "description": "In 10^-9 V steps."
    },
    {
      "address": 32,
      "count": 4,
      "name": "Sensor model description, part one",
      "data_type": "Ascii",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R",
      "description": "String register block 32-35."
    },
    {
      "address": 36,
      "count": 4,
      "name": "Sensor model description, part two",
      "data_type": "Ascii",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R",
      "description": "String register block 36-39."
    },
    {
      "address": 40,
      "count": 1,
      "name": "Sensor serial number",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 41,
      "count": 2,
      "name": "Sensor sensitivity",
      "data_type": "Float32",
      "units": "V/(W/m2)",
      "scale_factor": 0.000001,
      "offset": 0,
      "access": "R",
      "description": "In 10^-6 V/(W/m2)."
    },
    {
      "address": 43,
      "count": 1,
      "name": "Response time as measured during calibration",
      "data_type": "UInt16",
      "units": "s",
      "scale_factor": 0.1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 44,
      "count": 1,
      "name": "Sensor resistance as measured during calibration",
      "data_type": "UInt16",
      "units": "ohm",
      "scale_factor": 0.1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 46,
      "count": 2,
      "name": "Sensor calibration date",
      "data_type": "UInt32",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R",
      "description": "Date as YYYYMMDD."
    },
    {
      "address": 61,
      "count": 1,
      "name": "Firmware version",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 62,
      "count": 1,
      "name": "Hardware version",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 98,
      "count": 1,
      "name": "Internal relative humidity",
      "data_type": "UInt16",
      "units": "%",
      "scale_factor": 0.01,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 138,
      "count": 1,
      "name": "Internal pressure average",
      "data_type": "UInt16",
      "units": "mbar",
      "scale_factor": 0.03125,
      "offset": 0,
      "access": "R",
      "description": "In 1/32 mbar steps."
    },
    {
      "address": 194,
      "count": 1,
      "name": "Tilt angle",
      "data_type": "UInt16",
      "units": "°",
      "scale_factor": 0.01,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 196,
      "count": 1,
      "name": "Fan speed",
      "data_type": "UInt16",
      "units": "RPM",
      "scale_factor": 1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 198,
      "count": 1,
      "name": "Heater current",
      "data_type": "UInt16",
      "units": "mA",
      "scale_factor": 1,
      "offset": 0,
      "access": "R"
    },
    {
      "address": 199,
      "count": 1,
      "name": "Fan current",
      "data_type": "UInt16",
      "units": "mA",
      "scale_factor": 1,
      "offset": 0,
      "access": "R"
    }
  ],
  "holding_registers": [
    {
      "address": 0,
      "count": 1,
      "name": "Device address",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "RW",
      "description": "Modbus address on the RS-485 network, factory default 1, range 1...247."
    },
    {
      "address": 1,
      "count": 1,
      "name": "Serial communication settings",
      "data_type": "UInt16",
      "units": "",
      "scale_factor": 1,
      "offset": 0,
      "access": "RW",
      "description": "Selects baud rate and parity, factory default 5 (= 19200 bps, 8E1)."
    }
  ],
  "combined_registers": [],
  "notes": "RS-485 device: reach it through a Modbus RTU-to-TCP gateway using the factory serial settings above. Source: Hukseflux \"SR30-M2-D1 user manual\" v2508, section 6.2 (tables 6.2.1 and 6.2.2), section 10.11 (table 10.11.1 supported function codes, table 10.11.2 Modbus registers 0-199, table 10.11.3 coils) and table 3.1.1 (digital communication specifications), published at https://www.hukx.com/uploads/SR30-M2-D1-user-manual.pdf . Factory serial settings from table 3.1.1: 19200 bps, eight data bits, even parity, one stop bit, device address 1 (register 0). The register numbers of the manual are the wire addresses (no offset), and the sensor does not distinguish input from holding registers nor coils from discrete inputs - both function codes 0x03 and 0x04 read the same cells - so the measurements are listed as input registers and the two writable setup cells plus the four control bits are listed as holding registers and coils. Each 32-bit value must be read in a single request; the sensor answers at most five 16-bit registers per request, so longer blocks (for example the two 4-register ASCII model strings) must be split. Bit values, history blocks (48-97), factory-use ranges (12-31, 41-60 reserved parts, 83-97, 100-137, 139-193, 195, 197) and the polynomial temperature coefficients are documented in table 10.11.2 but are not repeated here. Reading registers 0x0002/0x0003 once per second and averaging over 60 s is the vendor's recommended measuring cycle."
}
