Skip to content

Campbell

Campbell Scientific dataloggers are industrial measurement loggers, programmed per installation. The adapter reads one through the logger’s own web-service API (command=DataQuery) — no vendor cloud involved — and normalizes two of its tables into a wire document.

vendor: "campbell" selects this adapter. The entry is validated by campbellStationConfigSchema (exported from @azohra/meteo.station/server):

FieldTypeMeaning
idstring, requiredYour feed-local station id — what ?station= and primaryStationId name.
namestring, requiredThe display name carried on the wire.
baseUrlhttp(s) URL, requiredThe logger’s web-service endpoint — the URL that answers ?command=DataQuery.
sourcestring, requiredThe data-source symbol tables are addressed under, e.g. LOGGER01:Wind Station. The segment after the colon must match the station_name the logger reports in table headers — it is verified on every response.
timeZoneIANA zone, requiredThe zone the logger stamps records in. Optional for other vendors, required here: records arrive as naive local time with no offset.
currentTablestring, default "I3Sec"The fast wind table serving the current reading.
historyTablestring, default "I5Min"The aggregate table serving history, temperature, and wind chill.
currentIntervalSecondspositive number, default 3The current table’s own record interval — verified against the table header, and declared as samplingWindowSeconds.
historyPeriodMinutespositive number, default 5The history table’s record interval — verified against the table header, and carried as history.periodMinutes.
currentCacheTtlSecondsnumber ≥ 3, default 15Cache TTL for the current table (history caches for 120 s).
latitude, longitude, elevationMnumbers, optionalPosition claims, carried on the wire.
pageUrlhttp(s) URL, optionalA public page for the station; there is no vendor default — omitted means null.

{ gustLull: true, temperature: true, conditions: false, history: true }.

The pinned field contracts (below) carry wind, temperature, and wind chill — no barometer, so conditions is false and the block never appears (absence stays absent). samplingWindowSeconds is currentIntervalSeconds; recommendedPollSeconds is the larger of currentIntervalSeconds and currentCacheTtlSeconds — polling a three-second table faster than its cache only reheats the cache.

GET <baseUrl>?command=DataQuery&uri=<source>.<table>&format=json&… — the current table with mode=most-recent, the history table with mode=backfill over the requested window. The config carries no credential fields and requests carry only the project User-Agent: access control to the logger is the deployment’s, not the adapter’s. Responses are capped at 512 KiB.

  • Pinned field contracts. The current table must carry Wind_Speed (Avg), Wind_Lull (Min), Wind_Gust (Max) in kilometers/hour and WindDir (Smp) in degrees; the history table must carry Temp and Wind_Chill (Smp, Deg C), WindDir, and WS_kph_Max/Avg/Min. A field whose name, process, type, or units changed throws — a reprogrammed logger degrades to unavailable instead of serving renumbered columns.
  • Header verification. Every response’s station_name (the text after the colon in source), table_name, and record interval must match the config; a response not marked complete (more: false) throws.
  • Naive local time, disambiguated by context. The logger stamps records in station-local time with no offset; the configured IANA zone converts them. A DST fall-back makes one local hour name two instants — history points resolve to the candidate strictly after the previous point, the current reading to the candidate nearest now. A spring-forward names no instant at all — the timestamp resolves to the transition itself.
  • Clock-skew warning. A current reading sitting about an hour from now (within five minutes of exactly one hour) logs a clock_skew warning: loggers are often pinned to standard time year-round while the configured zone observes DST — configure a fixed-offset zone (Etc/GMT+8 for Pacific) instead, or vice versa.
  • History fails soft, current fails hard. Both tables are fetched in parallel. A history failure costs history — and the temperature and wind chill it carries — with the failure logged and the station still ok; a current-table failure degrades the whole station.
  • Air rides the history table. The current table carries wind only. In mode: "current" the adapter reads just the current table and reuses the last full load’s temperature and wind chill from cache (TTL 120 s); beyond that they are null rather than stale.
  • Speeds are validated 0–500 in the vendor’s km/h before conversion to m/s; directions are validated 0–360 and normalized; a calm reading carries a null direction.
import { createStationFeedHandler } from "@azohra/meteo.station/server";
const handler = createStationFeedHandler({
stations: [
{
vendor: "campbell",
id: "summit",
name: "Summit Logger",
baseUrl: "http://logger.example:30001/.",
source: "LOGGER01:Wind Station",
timeZone: "America/Vancouver",
latitude: 49.5,
longitude: -118.5,
},
],
});
export default { fetch: handler };