Files
intelligence-terminal/apis/sources/epa.mjs
calesthio ef2c6470fb Initial release — Crucix Intelligence Engine v2.0.0
26-source OSINT intelligence engine with live Jarvis dashboard,
auto-refresh via SSE, optional LLM layer (4 providers), delta/memory
system, and Telegram breaking news alerts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:45:46 -07:00

207 lines
6.7 KiB
JavaScript

// EPA RadNet — Radiation Monitoring Network
// No auth required. Government open data via Envirofacts REST API.
// Monitors ambient radiation levels across the US via fixed monitoring stations.
// Complements Safecast (citizen science) with official government readings.
import { safeFetch } from '../utils/fetch.mjs';
const BASE = 'https://enviro.epa.gov/enviro/efservice';
// RadNet analytical results endpoint
const RADNET_ANALYTICAL = `${BASE}/RADNET_ANALYTICAL_RESULTS`;
// RadNet auxiliary data
const RADNET_AUX = `${BASE}/RADNET_AUX`;
// Key US cities with RadNet monitoring stations
const MONITORING_STATIONS = {
washingtonDC: { label: 'Washington, DC', state: 'DC' },
newYork: { label: 'New York, NY', state: 'NY' },
losAngeles: { label: 'Los Angeles, CA', state: 'CA' },
chicago: { label: 'Chicago, IL', state: 'IL' },
seattle: { label: 'Seattle, WA', state: 'WA' },
denver: { label: 'Denver, CO', state: 'CO' },
honolulu: { label: 'Honolulu, HI', state: 'HI' },
anchorage: { label: 'Anchorage, AK', state: 'AK' },
miami: { label: 'Miami, FL', state: 'FL' },
sanFrancisco: { label: 'San Francisco, CA', state: 'CA' },
};
// Analyte types that indicate concerning radiation
const KEY_ANALYTES = [
'GROSS BETA',
'GROSS ALPHA',
'IODINE-131',
'CESIUM-137',
'CESIUM-134',
'STRONTIUM-90',
'TRITIUM',
'URANIUM',
'PLUTONIUM',
];
// Normal background radiation thresholds (pCi/L or pCi/m3 depending on medium)
const THRESHOLDS = {
'GROSS BETA': { normal: 1.0, elevated: 5.0, unit: 'pCi/m3' },
'GROSS ALPHA': { normal: 0.05, elevated: 0.15, unit: 'pCi/m3' },
'IODINE-131': { normal: 0.01, elevated: 0.1, unit: 'pCi/m3' },
'CESIUM-137': { normal: 0.01, elevated: 0.1, unit: 'pCi/m3' },
'CESIUM-134': { normal: 0.001, elevated: 0.01, unit: 'pCi/m3' },
};
// Get recent RadNet analytical results (JSON)
export async function getAnalyticalResults(opts = {}) {
const { rows = 50, startRow = 0 } = opts;
return safeFetch(
`${RADNET_ANALYTICAL}/ROWS/${startRow}:${startRow + rows}/JSON`,
{ timeout: 25000 }
);
}
// Get results filtered by state
export async function getResultsByState(state, opts = {}) {
const { rows = 25, startRow = 0 } = opts;
return safeFetch(
`${RADNET_ANALYTICAL}/ANA_STATE/${state}/ROWS/${startRow}:${startRow + rows}/JSON`,
{ timeout: 25000 }
);
}
// Get results filtered by analyte type
export async function getResultsByAnalyte(analyte, opts = {}) {
const { rows = 25, startRow = 0 } = opts;
const encoded = encodeURIComponent(analyte);
return safeFetch(
`${RADNET_ANALYTICAL}/ANA_TYPE/${encoded}/ROWS/${startRow}:${startRow + rows}/JSON`,
{ timeout: 25000 }
);
}
// Compact a reading for briefing output
function compactReading(r) {
return {
location: r.ANA_CITY || r.LOCATION || 'Unknown',
state: r.ANA_STATE || r.STATE || null,
analyte: r.ANA_TYPE || r.ANALYTE_NAME || null,
result: r.ANA_RESULT != null ? parseFloat(r.ANA_RESULT) : null,
unit: r.RESULT_UNIT || r.ANA_UNIT || null,
collectDate: r.COLLECT_DATE || r.SAMPLE_DATE || null,
medium: r.SAMPLE_TYPE || r.MEDIUM || null,
};
}
// Check a reading against known thresholds
function checkReading(reading) {
if (reading.result === null || reading.result <= 0) return null;
const threshold = THRESHOLDS[reading.analyte?.toUpperCase()];
if (!threshold) return null;
if (reading.result > threshold.elevated) {
return {
level: 'ELEVATED',
reading,
threshold: threshold.elevated,
ratio: (reading.result / threshold.elevated).toFixed(1),
};
}
if (reading.result > threshold.normal * 3) {
return {
level: 'ABOVE_NORMAL',
reading,
threshold: threshold.normal,
ratio: (reading.result / threshold.normal).toFixed(1),
};
}
return null;
}
// Briefing — get recent radiation readings from EPA network, flag anomalies
export async function briefing() {
const readings = [];
const signals = [];
// Fetch recent analytical results (broad pull)
const recentData = await getAnalyticalResults({ rows: 100 });
const recentRecords = Array.isArray(recentData) ? recentData : [];
// Compact all readings
const allReadings = recentRecords.map(compactReading);
readings.push(...allReadings);
// Also try to pull key analytes specifically
const analyteResults = await Promise.all(
['GROSS BETA', 'IODINE-131', 'CESIUM-137'].map(async analyte => {
const data = await getResultsByAnalyte(analyte, { rows: 20 });
const records = Array.isArray(data) ? data : [];
return { analyte, records: records.map(compactReading) };
})
);
for (const { analyte, records } of analyteResults) {
// Add any records not already in our list
for (const r of records) {
if (!readings.some(existing =>
existing.location === r.location &&
existing.collectDate === r.collectDate &&
existing.analyte === r.analyte
)) {
readings.push(r);
}
}
}
// Check all readings against thresholds
for (const reading of readings) {
const alert = checkReading(reading);
if (alert) {
if (alert.level === 'ELEVATED') {
signals.push(
`ELEVATED ${reading.analyte} at ${reading.location}, ${reading.state}: ` +
`${reading.result} ${reading.unit || ''} (${alert.ratio}x threshold) [${reading.collectDate}]`
);
} else {
signals.push(
`ABOVE NORMAL ${reading.analyte} at ${reading.location}, ${reading.state}: ` +
`${reading.result} ${reading.unit || ''} (${alert.ratio}x normal) [${reading.collectDate}]`
);
}
}
}
// Summarize by state
const byState = {};
for (const r of readings) {
const st = r.state || 'UNK';
if (!byState[st]) byState[st] = { count: 0, analytes: new Set() };
byState[st].count++;
if (r.analyte) byState[st].analytes.add(r.analyte);
}
// Convert sets to arrays for JSON
const stateSummary = Object.fromEntries(
Object.entries(byState).map(([st, info]) => [
st,
{ count: info.count, analytes: [...info.analytes] },
])
);
return {
source: 'EPA RadNet',
timestamp: new Date().toISOString(),
totalReadings: readings.length,
readings: readings.slice(0, 50), // cap for briefing size
stateSummary,
signals: signals.length > 0
? signals
: ['All EPA RadNet readings within normal background levels'],
monitoredAnalytes: KEY_ANALYTES,
thresholds: THRESHOLDS,
note: 'RadNet data may lag by hours to days. Near-real-time gamma data updates more frequently.',
};
}
// Run standalone
if (process.argv[1]?.endsWith('epa.mjs')) {
const data = await briefing();
console.log(JSON.stringify(data, null, 2));
}