Weather Station / ECOWITT / DNT
0

Configure Feed

Select the types of activity you want to include in your feed.

at stats2.0 4.2 kB View raw
1import { promises as fs } from "fs"; 2import path from "path"; 3 4/** 5 * The absolute path to the DNT directory where CSV files are stored. 6 */ 7export const DNT_DIR = path.join(process.cwd(), "DNT"); 8 9/** 10 * Lists all CSV files in the DNT directory. 11 * @returns {Promise<string[]>} A promise that resolves to an array of CSV filenames. 12 */ 13export async function listDntFiles(): Promise<string[]> { 14 const items = await fs.readdir(DNT_DIR); 15 return items.filter((f) => f.toLowerCase().endsWith(".csv")); 16} 17 18/** 19 * Converts a Date object to a YYYYMM number. 20 * @param {Date} [d] - The date to convert. 21 * @returns {number | null} The date as a YYYYMM number, or null if the date is not provided. 22 * @private 23 */ 24function ymOf(d?: Date): number | null { 25 if (!d) return null; 26 return d.getFullYear() * 100 + (d.getMonth() + 1); 27} 28 29/** 30 * Gets all 'allsensors' CSV files within a given date range. 31 * @param {Date} [start] - The start date of the range. 32 * @param {Date} [end] - The end date of the range. 33 * @returns {Promise<string[]>} A promise that resolves to an array of filenames. 34 */ 35export async function getAllsensorsFilesInRange(start?: Date, end?: Date): Promise<string[]> { 36 const files = await listDntFiles(); 37 // match case-insensitively: 202501Allsensors_A.csv / .CSV 38 const list = files 39 .filter((f) => /^\d{6}allsensors_a\.csv$/.test(f.toLowerCase())) 40 .sort(); 41 const ys = ymOf(start); 42 const ye = ymOf(end); 43 if (!ys && !ye) return list; 44 return list.filter((f) => { 45 const ym = Number(f.slice(0, 6)); 46 if (ys && ym < ys) return false; 47 if (ye && ym > ye) return false; 48 return true; 49 }); 50} 51 52/** 53 * Gets all 'main' CSV files within a given date range. 54 * @param {Date} [start] - The start date of the range. 55 * @param {Date} [end] - The end date of the range. 56 * @returns {Promise<string[]>} A promise that resolves to an array of filenames. 57 */ 58export async function getMainFilesInRange(start?: Date, end?: Date): Promise<string[]> { 59 const files = await listDntFiles(); 60 // match case-insensitively: 202501A.csv / .CSV 61 const list = files 62 .filter((f) => /^\d{6}a\.csv$/.test(f.toLowerCase())) 63 .sort(); 64 const ys = ymOf(start); 65 const ye = ymOf(end); 66 if (!ys && !ye) return list; 67 return list.filter((f) => { 68 const ym = Number(f.slice(0, 6)); 69 if (ys && ym < ys) return false; 70 if (ye && ym > ye) return false; 71 return true; 72 }); 73} 74 75/** 76 * Finds the latest file in the DNT directory that matches a regular expression. 77 * @param {RegExp} rxLower - The regular expression to match against lowercase filenames. 78 * @returns {Promise<string | null>} A promise that resolves to the filename, or null if no match is found. 79 */ 80export async function latestFileMatching(rxLower: RegExp): Promise<string | null> { 81 const files = await listDntFiles(); 82 const m = files.filter((f) => rxLower.test(f.toLowerCase())).sort(); 83 return m.length ? m[m.length - 1] : null; 84} 85 86/** 87 * Gets the 'allsensors' filename for a specific month, or the latest one if no month is provided. 88 * @param {string} [month] - The month in YYYYMM format. 89 * @returns {Promise<string | null>} A promise that resolves to the filename, or null if not found. 90 */ 91export async function getAllsensorsFilename(month?: string): Promise<string | null> { 92 const files = await listDntFiles(); 93 if (month && /^\d{6}$/.test(month)) { 94 const targetLower = `${month}allsensors_a.csv`; 95 const found = files.find((f) => f.toLowerCase() === targetLower); 96 if (found) return found; 97 } 98 return latestFileMatching(/^\d{6}allsensors_a\.csv$/); 99} 100 101/** 102 * Gets the 'main' filename for a specific month, or the latest one if no month is provided. 103 * @param {string} [month] - The month in YYYYMM format. 104 * @returns {Promise<string | null>} A promise that resolves to the filename, or null if not found. 105 */ 106export async function getMainFilename(month?: string): Promise<string | null> { 107 const files = await listDntFiles(); 108 if (month && /^\d{6}$/.test(month)) { 109 const targetLower = `${month}a.csv`; 110 const found = files.find((f) => f.toLowerCase() === targetLower); 111 if (found) return found; 112 } 113 return latestFileMatching(/^\d{6}a\.csv$/); 114}