-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHighPriSensorCodeStatistics.R
More file actions
178 lines (140 loc) · 5.72 KB
/
Copy pathHighPriSensorCodeStatistics.R
File metadata and controls
178 lines (140 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
###############################################################################
# Title: High-Priority Sensor Code Window Statistics
#
# Purpose:
# Exploratory sensor-code branch of the pipeline. For each high-priority
# sanitized sensor code and each source SQLite database, this script:
# • Extracts Telemetry rows where SensorValue exceeds a threshold
# • Computes consecutive high-value windows (durations < 10 minutes)
# • Aggregates per-window statistics (min/max/delta sensor value, total time)
# • Writes per-sensor summary tables to SQLite
#
# This advances the data by surfacing which sensors exhibit meaningful
# excursions, providing an additional signal for sensor/feature selection.
#
# Skills shown:
# • Parallelized scanning of many SQLite databases
# • Sliding-window and duration calculations for time-series data
# • Programmatic table creation and aggregation per sensor code
#
# Inputs:
# • All telemetry SQLite databases under <DATALAKEDIR> (recursive)
# • Sanitized list of sensor codes (SensorC–SensorJ defined in script)
#
# Outputs:
# • Per-DB sensor-window SQLite files:
# <PID>_SensorWindow.sqlite
# containing:
# - SensorWindowStats_<SensorCode> table
#
# Author: Skylar Furey
###############################################################################
# Libraries -------------------------------------------------------------------
packages <- c("RSQLite", "dplyr", "doParallel")
installed <- packages %in% rownames(installed.packages())
if (any(!installed)) install.packages(packages[!installed])
invisible(lapply(packages, library, character.only = TRUE))
# Inputs ----------------------------------------------------------------------
cmdArgs <- commandArgs()
data_root <- cmdArgs[grep("DATALAKEDIR", cmdArgs) + 1]
output_root <- file.path(system("echo $HOME", intern = TRUE), "Projects/telemetry_event_correlation/HiPriSensors")
db_files <- list.files(
path = file.path(data_root, "SQLITE_FILES"),
pattern = "\\.db$",
full.names = TRUE,
recursive = TRUE
)
# Sanitized sensor label codes
sensor_codes <- c(
"SensorC", "SensorD", "SensorE", "SensorF",
"SensorG", "SensorH", "SensorI", "SensorJ"
)
# Parallel Setup ---------------------------------------------------------------
cl <- makeCluster(4, type = "FORK")
registerDoParallel(cl)
foreach(db = db_files, .packages = c("RSQLite", "dplyr")) %dopar% {
log_file <- file.path(system("echo $WORKDIR", intern = TRUE),
paste0("Projects/telemetry_event_correlation/", basename(db), "_HiPri_log.txt")),
cat("Processing:", db, file = log_file, append = TRUE, sep = "\n")
con <- dbConnect(SQLite(), db, flags = SQLITE_RO)
out_db_file <- paste0(output_root, Sys.getpid(), "_SensorWindow.db")
out_con <- dbConnect(SQLite(), out_db_file)
cat("Output DB initialized", file = log_file, append = TRUE, sep = "\n")
# Process each sanitized sensor code ----------------------------------------
for (sensor_code in sensor_codes) {
cat("Sensor:", sensor_code, file = log_file, append = TRUE, sep = "\n")
# Extract high-value sensor readings
query <- sprintf(
'SELECT RecordID, Timestamp, SensorValue
FROM Telemetry
WHERE SensorName = "%s"
AND CAST(SensorValue AS REAL) > 25
ORDER BY RecordID, Timestamp;',
sensor_code
)
sensor_raw <- dbGetQuery(con, query)
if (nrow(sensor_raw) < 2) next
# Create lagged dataset for consecutive timing
lagged <- rbind(NA, sensor_raw[1:(nrow(sensor_raw) - 1), ])
colnames(lagged) <- paste0("Lag_", colnames(sensor_raw))
combined <- cbind(sensor_raw, lagged)
combined$ValidPair <- combined$Lag_RecordID == combined$RecordID
combined$Duration <- combined$Timestamp - combined$Lag_Timestamp
# Filter to consecutive readings within 10 minutes
sensor_windows <- combined[combined$ValidPair & combined$Duration < 600, ]
sensor_windows <- sensor_windows[complete.cases(sensor_windows), ]
# Create working temp table
dbExecute(out_con,
'CREATE TEMP TABLE SensorTemp (
RecordID INTEGER,
Timestamp REAL,
SensorValue REAL,
Lag_RecordID INTEGER,
Lag_Timestamp REAL,
Lag_SensorValue REAL,
Duration REAL
);'
)
dbWriteTable(out_con, "SensorTemp", sensor_windows, append = TRUE)
# Create final destination table for this sensor
stats_table <- paste0("SensorWindowStats_", sensor_code)
dbExecute(
out_con,
sprintf(
'CREATE TABLE IF NOT EXISTS %s (
RecordID INTEGER,
MinSensorValue REAL,
MaxSensorValue REAL,
DeltaSensorValue REAL,
TotalDuration REAL,
SourceDB TEXT
);',
stats_table
)
)
# Insert aggregate statistics
insert_query <- sprintf(
'INSERT INTO %s
SELECT
RecordID,
Timestamp AS StartTimeStamp,
MIN(SensorValue) AS MinSensorValue,
MAX(SensorValue) AS MaxSensorValue,
(Lag_SensorValue - SensorValue) AS DeltaSensorValue,
SUM(Duration) AS TotalDuration,
"%s" AS SourceDB
FROM SensorTemp
GROUP BY RecordID;',
stats_table,
basename(db)
)
dbExecute(out_con, insert_query)
# Cleanup temp table
dbRemoveTable(out_con, "SensorTemp")
cat("Completed sensor:", sensor_code,
file = log_file, append = TRUE, sep = "\n")
}
dbDisconnect(con)
dbDisconnect(out_con)
}
stopCluster(cl)