5  Databases

5.1 hwConfig.db

hwConfig.db contains only id, key and value tables.
We treat as read only for the mobile web interface.
Tables are not growing, but updated on events.

ALL slots are written here, even if they are not detected.
The mobile web interface will decide. e.g. slots 0,1 are always shown, others not if sensor_type is empty or UNKN_E.

This is a quasi static database, written by the firmware. Not much in here
The database is created / updated on boot or “sensor detection”.
You find the serial numbers here.
The sensors will be detected and updated bydetect sensors” in the system menu. Slots 0 and 1 can be set manually, for example if you use current clamps instead of electrodes, by loading the user configuration.
The mobile web interface can only work with detected sensors, except slots 0 and 1.

5.1.1 adu

About the systems and their capabilities.
Sample frequencies and digital filter apply to ALL channels, so they are here.
As fixed value the disk size is here, to converted to int later. This is the total size at all of the data partition.

{
  "board_type": "ADU-11e",
  "serial": 0,
  "disk_size_mb_sd": 80000000
}
CREATE TABLE "adu" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.1.2 con

About the connector board.
The connector board is the same for all ADU-10e / 11e

{
  "board_type:": "ADU-11E-10E-CON",
  "serial": 0
}
CREATE TABLE "con" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.1.3 gps

About the GPS.

{
  "board_type": "ADU-11E-CLK",
  "serial": 0
}
CREATE TABLE "gps" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.1.4 led

About the LEDs or LED board.

{
  "board_type": "ADU-11E-LED",
  "serial": 0
}
CREATE TABLE "led" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.1.5 slot

About the slots and their capabilities.
Gains and channel types are per slot, so they are here. You will find slot0 to slot4 (ADU-10e) or up to slot7 (ADU-11e) depending on your system.

NoteNSLOTS

is 5 for ADU-10e and 8 for ADU-11e and coded in config.php. That avoids scanning the slot tables for each page request.

We have slot0 … slot4 for ADU-10e and slot0 … slot7 for ADU-11e.

{
  "board_type": "ADU-11E-BB",
  "serial": 0,
  "sensor_type": "",
  "sensor_serial": 0
}

The slot aquires the sensor information, so the sensor type and serial number are here.

CREATE TABLE "slot" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

detect sensors” will update the sensor type and serial. For slot0 and slot1 sensor type can be set manually.

5.2 selftestResult.db

selftestResult.db contains only id, key and value tables.
Updated on boot, detect sensors and test.
So these values change only when the user triggers one of these events.
We treat as read only for the mobile web interface.

5.2.1 con

The self test results for the connector board.

{
  "error_code": 0,
  "severity": 0,
  "message": "---"
}
CREATE TABLE "con" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.2.2 cpu

The self test results for the CPU.

CREATE TABLE "cpu" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.2.3 gps

The self test results for the GPS.

{
  "error_code": 0,
  "severity": 0,
  "message": "---"
}
CREATE TABLE "gps" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.2.4 led

The self test results for the LEDs or LED board.

CREATE TABLE "led" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.2.5 main backplane

The self test results for the main backplane.

{
  "error_code": 0,
  "severity": 0,
  "message": "---"
}
CREATE TABLE "main_backplane" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.2.6 slot

The self test results for each slot.

{
  "error_code": 0,
  "severity": 0,
  "message": "---",
  "probe_res": 0,
  "probe_res_gnd_1": 0,
  "probe_res_gnd_2": 0,
  "lsb": 0,
  "max_amplitude": 0,
  "dc_offset": 0,
  "noise_check": 0,
  "gain": 0
}

for slot0 and slot1, you find the important probe resistance here.
Partly you find the results on the channels page of the mobile web interface:
here you can adjust the gain settings and this information is needed here.

CREATE TABLE "slot" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.3 THE LOG TABLES

ALL log tables have the same structure: - “id” INTEGER , created by inserting, - “date_time” INT (UTC timestamp, avoid string parsing, easier to compare and sort) - continued with specific fields for each log type.

These tables are growing row by row and logging the system’s history.
The database reader, different from above, need to know the columns.

5.3.1 gpsLog.db

The GPS log, for example, logs the GPS status and the number of satellites. <br

CREATE TABLE "gpsStatus" (
  "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "date_time" INTEGER,
    "latitude"  INTEGER,
    "longitude" INTEGER,
    "elevation" REAL,
    "sats_tracked"  INTEGER,
    "sync_state"    INTEGER
)

latitude and longitude are in ms (milli seconds) as coming from the module.
elevation is in m (meters) as coming from the module.
sats_tracked is the number of satellites USED by the module. There can be more visible satellites.
sync_state is 0 = no fix, 1 = 2D fix, 2 = 3D fix, 3 = fully synced, 4 = G4Fix includes system sync.
The mobile web interface will show RED until we get 4. You shall only submit jobs when the system is fully synced.

5.3.2 hwLog.db

The hardware log, for example, logs the system temperature.

CREATE TABLE "hwStatus" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "date_time" INTEGER,
    "batt_state"    INTEGER,
    "batt_voltage_1"    REAL,
    "batt_voltage_2"    REAL,
    "temperature_system"    REAL,
    "temperature_sensor"    REAL,
    "free_disk_space_mb"    REAL,
    "selftest_status"   INTEGER,
    "recording_status"  INTEGER
);

Where recording_status is 0 = idle, 1 = recording.
selftest_status ??

5.3.3 systemLog.db

The system log, for example, logs the system events.

CREATE TABLE "log" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "date_time" INTEGER,
    "priority"  INTEGER,
    "main_index"    INTEGER,
    "sub_index" INTEGER,
    "message"   TEXT
)

main_index and sub_index are for main HW component and sub HW component (detail). A short message is generated by the system and stored in the message field.

priority is MWI

5.4 systemStatus.db

systemStatus.db contains only id, key and value tables.
Updated by the firmware every few seconds or on events.
Treated as read only for the mobile web interface; table is not growing.

5.4.1 adu

The system status for the system.
These tables in systemStatus.db are updated by the firmware every few seconds and show the current status of the system.
The recording status drives the icon on the mobile web interface.

{
  "date_time": "1970-01-01 00:00:00",
  "batt_state": 0,
  "batt_voltage_1": 0.0,
  "batt_voltage_2": 0.0,
  "temperature_system": 0.0,
  "temperature_sensor": 0.0,
  "free_disk_space_mb_sd": 0.0,
  "free_disk_space_mb_usb": 0.0,
  "selftest_status": 0,
  "selftest_active": 0,
  "recording_status": 0,
  "ts_copy_status": -1.0
}
CREATE TABLE "adu" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

selftest_active is 1 when the self test is running, 0 when it is finished.
selftest_status is 0 when ok, 1 when warning, 2 when critical.

5.4.2 gps

The system status for the GPS.
If sync_state is 4, the GPS is fully synced and you can submit jobs, the GPS symbol on the mobile web interface will be green.

{
  "date_time": "1970-01-01 00:00:00",
  "latitude": 0,
  "longitude": 0,
  "elevation": 0.0,
  "sats_tracked": 0,
  "sats_in_view_gps": 0,
  "sats_in_view_glonass": 0,
  "sats_in_view_beidou": 0,
  "sats_in_view_galileo": 0,
  "sync_state": 0,
  "mode": 0
}
CREATE TABLE "gps" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

5.4.3 recording

The detailed system status for the recording.

{
  "sampling_rate": 0,
  "buffer_size": 0,
  "num_buffers": 0,
  "used_slots": "",
  "remaining_job_time": 0,
  "time_to_next_job": 0,
  "target_directory": ""
}
CREATE TABLE "recording" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "key" STRING NOT NULL,
    "value" STRING
    )

The mobile web interface will show the details.

5.5 job.db

This is the essential database for the recording jobs.
When you submit a job, the job parameters are stored here.

CREATE TABLE "job" (
  "id" INTEGER PRIMARY KEY CHECK (id = 1),
    "start_date"    TEXT,
    "start_time"    TEXT,
    "duration"  INTEGER,
    "sampling_rate" INTEGER,
    "digital_filter"    INTEGER,
    "split_main"    INTEGER DEFAULT 0,
    "cal_mode"  TEXT DEFAULT 'off',
    "channel_types" TEXT,
    "choppers"  TEXT,
    "gains" TEXT,
    "dipole_lengths"    TEXT,
    "use_atss"  INTEGER DEFAULT 0,
    "copy_to_usb"   INTEGER DEFAULT 0,
    "sub_cycle" INTEGER,
    "sub_duration"  INTEGER,
    "sub_filter"    INTEGER,
    "split_sub" INTEGER DEFAULT 0,
    "power_off_limit" REAL,
    "station_id" STRING
)

Remark: “slots_on” TEXT and “started” INTEGER are not part of the job.db. They will be appended “on the fly” when the interface submits a job.
Vice versa, when you open a job from the jobs.db for editing, the “slots_on” and “started” (aka copying back to the job.db) are not copied (truncate).
The slots_on logic is: E (0,1) always on, H as detected. You may submit “no electric”, then E (0,1) are off, H as detected. Mostly for airborne measurements.

Syntax: -1 auto, 0 off, 1 on - OR 1, 2, 4, 8 values >= 1.
In the fields (plural) gains for example, the POSITION (-1,-1, 4, …) is equivalent to the slot number. So the first value is for slot0, the second for slot1, and so on.
The same applies for the channel types, dipole_lengths, and choppers.

  • “id” INTEGER , created by inserting,
  • “start_date” 2026-12-31 (UTC, yyyy-mm-dd)
  • “start_time” 16:30:00 (UTC, hh:mm:ss)
  • “duration” 36000 (seconds, example 10 minutes = 600 seconds, 1 hour = 3600 seconds)
  • “sampling_rate” 1024, …, 131072 (Hz), -1 stop job, -2 detect sensors, 3 shutdown system, 4 reboot system.
  • “digital_filter” 32, 8, 4, 0
  • “split_main” 0 (default off, set to >0 to split main job into multiple files, example 409600 for 400 MB files), covered by GUI for main job splitting, but not yet implemented in the system, so no effect for now.
  • “cal_mode” off, (always, not to be changed, use special jobs)
  • “channel_types” “Ex, Ey, Hx, Hy, Hz, Jx, Jx, Jz”
  • “choppers” “-1, -1, -1, -1, -1” : -1 == auto, 0 = off, 1 == on
  • “gains” “-1, -1, -1, -1, -1” : -1 == auto or 1, 2, 4, 8 fixed gain
  • “dipole_lengths” “100.0, 100.0, 0, 0, 0, 0, 0, 0” : in meters, available for slots 0, 1
  • “use_atss” 0 (default off, set to 1 to use ATSS)
  • “copy_to_usb” 0 (default off, set to 1 to copy files to USB after recording, leave the drive connected!)
  • “sub_cycle” 0 (default off, set to >0 to use sub-cycles, example 120 for 2 minutes)
  • “sub_duration” 0 (default off, set to >0 to use sub-cycles, example 32 for 32 seconds)
  • “sub_filter” 0 (default off, set to >0 to use sub-filter, example 32 for a sub job with 64 Hz sample frequency if the main job is 2048 Hz)
  • “split_sub” 0 (default off, set to >0 to split sub job into multiple files, example 102400 for 100 MB files), covered by GUI for sub job splitting, but not yet implemented in the system, so no effect for now.
  • “power_off_limit” 0 (default off, set to >0, for example 10.9 to power off the system when the battery voltage drops below this limit, in Volt. This can be helpful in case your batteries want that. The system may power off at 9.8 V latest.)

5.6 Logic

5.6.1 shots

sub_cycle and sub_duration > 0, sub_filter = 0 AND digital_filter > 0.

graph TD
    A[job <br> sampling_rate 131 kHz <br> duration 3600 s] --> B[sub_cycle 120 s <br> sub_duration32s]
    A --> C[digital_filter 4]
    C --> D[one file set <br>32 kHz ats / atss 3600 s]
    B --> E[ 29 file sets <br> 131 kHz]

5.6.2 filter

sub_filter > 0, sub_cycle and sub_duration = 0 AND digital_filter = 0.
If ONLY sub_filter is set, we get a filtered set of files for *all time**. That is the typical long term recording where you may want to download a low sample frequency version.

graph TD
    A[job <br> sampling_rate 1024 Hz <br> duration N s] --> B[sub_filter 32]
    A --> C[one set of files <br> 1024 Hz]
    B --> E[ one set of files <br> 32 Hz]

5.6.3 straight

sub_cycle and sub_duration = 0, sub_filter = 0 AND digital_filter >= 0.

graph TD
        A[job <br> sampling_rate 1024 Hz <br> duration N s] --> B[one set of files <br> 1024 Hz]

5.7 jobs.db

jobs.db contains the recording jobs.
When you submit a job, the job parameters are stored (copied) here.
If you edit a job, the table row will be copied into job.db for editing, but the original row will stay in job.db.
When the system starts a job, the “started” field will be set to 1 by the system.

CREATE TABLE "jobs" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT,
    "start_date"    TEXT,
    "start_time"    TEXT,
    "duration"  INTEGER,
    "sampling_rate" INTEGER,
    "digital_filter"    INTEGER,
    "split_main"    INTEGER DEFAULT 0,
    "cal_mode"  TEXT DEFAULT 'off',
    "channel_types" TEXT,
    "choppers"  TEXT,
    "gains" TEXT,
    "dipole_lengths"    TEXT,
    "use_atss"  INTEGER DEFAULT 0,
    "copy_to_usb"   INTEGER DEFAULT 0,
    "sub_cycle" INTEGER,
    "sub_duration"  INTEGER,
    "sub_filter"    INTEGER,
    "split_sub" INTEGER DEFAULT 0,
    "station_id" STRING,
    "power_off_limit" REAL,
    "slots_on" TEXT,
    "started"   INTEGER
)

As mentioned above, “slots_on” TEXT and “started” INTEGER are not part of the job.db. They will be appended “on the fly” when the interface submits a job to the jobs.db.