Add Machine Data seed (tables, stored procedures, sample data) and fix SA password for shell compatibility
This commit is contained in:
330
infra/mssql/machinedata_seed.sql
Normal file
330
infra/mssql/machinedata_seed.sql
Normal file
@@ -0,0 +1,330 @@
|
||||
-- ScadaLink Machine Data Database seed script
|
||||
-- Populates ScadaLinkMachineData with realistic SCADA/MES tables,
|
||||
-- sample data, and stored procedures for development and testing.
|
||||
--
|
||||
-- Run after setup.sql:
|
||||
-- docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
|
||||
-- -S localhost -U sa -P 'ScadaLink_Dev1#' -C \
|
||||
-- -i /docker-entrypoint-initdb.d/machinedata_seed.sql
|
||||
|
||||
USE ScadaLinkMachineData;
|
||||
GO
|
||||
|
||||
-- =========================================================================
|
||||
-- Tables
|
||||
-- =========================================================================
|
||||
|
||||
-- Tag history: time-series data collected from OPC UA / custom protocols
|
||||
IF OBJECT_ID('dbo.TagHistory', 'U') IS NULL
|
||||
CREATE TABLE dbo.TagHistory (
|
||||
Id BIGINT IDENTITY(1,1) PRIMARY KEY,
|
||||
TagPath NVARCHAR(256) NOT NULL,
|
||||
Timestamp DATETIME2(3) NOT NULL,
|
||||
Value FLOAT NULL,
|
||||
StringValue NVARCHAR(512) NULL,
|
||||
Quality TINYINT NOT NULL DEFAULT 192, -- 192 = Good
|
||||
SiteId NVARCHAR(64) NOT NULL,
|
||||
INDEX IX_TagHistory_TagPath_Timestamp (TagPath, Timestamp DESC),
|
||||
INDEX IX_TagHistory_SiteId_Timestamp (SiteId, Timestamp DESC)
|
||||
);
|
||||
GO
|
||||
|
||||
-- Production counts: shift/line production totals
|
||||
IF OBJECT_ID('dbo.ProductionCounts', 'U') IS NULL
|
||||
CREATE TABLE dbo.ProductionCounts (
|
||||
Id BIGINT IDENTITY(1,1) PRIMARY KEY,
|
||||
SiteId NVARCHAR(64) NOT NULL,
|
||||
LineName NVARCHAR(128) NOT NULL,
|
||||
ShiftDate DATE NOT NULL,
|
||||
ShiftNumber TINYINT NOT NULL,
|
||||
GoodCount INT NOT NULL DEFAULT 0,
|
||||
RejectCount INT NOT NULL DEFAULT 0,
|
||||
Efficiency DECIMAL(5,2) NULL,
|
||||
RecordedAt DATETIME2(3) NOT NULL DEFAULT SYSUTCDATETIME(),
|
||||
INDEX IX_ProductionCounts_Site_Date (SiteId, ShiftDate DESC)
|
||||
);
|
||||
GO
|
||||
|
||||
-- Equipment events: state changes, faults, maintenance
|
||||
IF OBJECT_ID('dbo.EquipmentEvents', 'U') IS NULL
|
||||
CREATE TABLE dbo.EquipmentEvents (
|
||||
Id BIGINT IDENTITY(1,1) PRIMARY KEY,
|
||||
SiteId NVARCHAR(64) NOT NULL,
|
||||
EquipmentId NVARCHAR(128) NOT NULL,
|
||||
EventType NVARCHAR(32) NOT NULL, -- 'StateChange', 'Fault', 'Maintenance', 'Alarm'
|
||||
PreviousState NVARCHAR(64) NULL,
|
||||
NewState NVARCHAR(64) NOT NULL,
|
||||
Description NVARCHAR(512) NULL,
|
||||
Timestamp DATETIME2(3) NOT NULL,
|
||||
INDEX IX_EquipmentEvents_Equipment_Time (EquipmentId, Timestamp DESC),
|
||||
INDEX IX_EquipmentEvents_Site_Type (SiteId, EventType, Timestamp DESC)
|
||||
);
|
||||
GO
|
||||
|
||||
-- Batch records: production batch tracking
|
||||
IF OBJECT_ID('dbo.BatchRecords', 'U') IS NULL
|
||||
CREATE TABLE dbo.BatchRecords (
|
||||
Id BIGINT IDENTITY(1,1) PRIMARY KEY,
|
||||
BatchId NVARCHAR(64) NOT NULL UNIQUE,
|
||||
SiteId NVARCHAR(64) NOT NULL,
|
||||
RecipeId NVARCHAR(64) NOT NULL,
|
||||
Status NVARCHAR(32) NOT NULL DEFAULT 'InProgress', -- 'InProgress', 'Complete', 'Aborted'
|
||||
StartTime DATETIME2(3) NOT NULL,
|
||||
EndTime DATETIME2(3) NULL,
|
||||
TotalQuantity DECIMAL(10,2) NULL,
|
||||
Operator NVARCHAR(128) NULL,
|
||||
Notes NVARCHAR(1024) NULL,
|
||||
INDEX IX_BatchRecords_Site_Status (SiteId, Status),
|
||||
INDEX IX_BatchRecords_StartTime (StartTime DESC)
|
||||
);
|
||||
GO
|
||||
|
||||
-- Alarm history: historical alarm events
|
||||
IF OBJECT_ID('dbo.AlarmHistory', 'U') IS NULL
|
||||
CREATE TABLE dbo.AlarmHistory (
|
||||
Id BIGINT IDENTITY(1,1) PRIMARY KEY,
|
||||
SiteId NVARCHAR(64) NOT NULL,
|
||||
AlarmName NVARCHAR(256) NOT NULL,
|
||||
Severity TINYINT NOT NULL, -- 1=Low, 2=Medium, 3=High, 4=Critical
|
||||
State NVARCHAR(32) NOT NULL, -- 'Active', 'Acknowledged', 'Cleared'
|
||||
ActivatedAt DATETIME2(3) NOT NULL,
|
||||
AcknowledgedAt DATETIME2(3) NULL,
|
||||
ClearedAt DATETIME2(3) NULL,
|
||||
AcknowledgedBy NVARCHAR(128) NULL,
|
||||
Message NVARCHAR(512) NULL,
|
||||
INDEX IX_AlarmHistory_Site_Active (SiteId, State, ActivatedAt DESC),
|
||||
INDEX IX_AlarmHistory_Severity (Severity, ActivatedAt DESC)
|
||||
);
|
||||
GO
|
||||
|
||||
-- =========================================================================
|
||||
-- Stored Procedures
|
||||
-- =========================================================================
|
||||
|
||||
-- Get tag history for a tag path within a date range
|
||||
IF OBJECT_ID('dbo.usp_GetTagHistory', 'P') IS NOT NULL DROP PROCEDURE dbo.usp_GetTagHistory;
|
||||
GO
|
||||
CREATE PROCEDURE dbo.usp_GetTagHistory
|
||||
@TagPath NVARCHAR(256),
|
||||
@StartTime DATETIME2(3),
|
||||
@EndTime DATETIME2(3),
|
||||
@MaxRows INT = 10000
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT TOP (@MaxRows)
|
||||
TagPath, Timestamp, Value, StringValue, Quality, SiteId
|
||||
FROM dbo.TagHistory
|
||||
WHERE TagPath = @TagPath
|
||||
AND Timestamp >= @StartTime
|
||||
AND Timestamp <= @EndTime
|
||||
ORDER BY Timestamp DESC;
|
||||
END;
|
||||
GO
|
||||
|
||||
-- Get production summary for a site over a date range
|
||||
IF OBJECT_ID('dbo.usp_GetProductionSummary', 'P') IS NOT NULL DROP PROCEDURE dbo.usp_GetProductionSummary;
|
||||
GO
|
||||
CREATE PROCEDURE dbo.usp_GetProductionSummary
|
||||
@SiteId NVARCHAR(64),
|
||||
@StartDate DATE,
|
||||
@EndDate DATE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT
|
||||
LineName,
|
||||
SUM(GoodCount) AS TotalGood,
|
||||
SUM(RejectCount) AS TotalReject,
|
||||
SUM(GoodCount) + SUM(RejectCount) AS TotalProduced,
|
||||
CASE
|
||||
WHEN SUM(GoodCount) + SUM(RejectCount) > 0
|
||||
THEN CAST(SUM(GoodCount) * 100.0 / (SUM(GoodCount) + SUM(RejectCount)) AS DECIMAL(5,2))
|
||||
ELSE 0
|
||||
END AS YieldPercent,
|
||||
AVG(Efficiency) AS AvgEfficiency,
|
||||
COUNT(DISTINCT ShiftDate) AS DaysReported
|
||||
FROM dbo.ProductionCounts
|
||||
WHERE SiteId = @SiteId
|
||||
AND ShiftDate >= @StartDate
|
||||
AND ShiftDate <= @EndDate
|
||||
GROUP BY LineName
|
||||
ORDER BY LineName;
|
||||
END;
|
||||
GO
|
||||
|
||||
-- Insert a batch record (used by CachedWrite from scripts)
|
||||
IF OBJECT_ID('dbo.usp_InsertBatchRecord', 'P') IS NOT NULL DROP PROCEDURE dbo.usp_InsertBatchRecord;
|
||||
GO
|
||||
CREATE PROCEDURE dbo.usp_InsertBatchRecord
|
||||
@BatchId NVARCHAR(64),
|
||||
@SiteId NVARCHAR(64),
|
||||
@RecipeId NVARCHAR(64),
|
||||
@TotalQuantity DECIMAL(10,2) = NULL,
|
||||
@Operator NVARCHAR(128) = NULL,
|
||||
@Notes NVARCHAR(1024) = NULL
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
INSERT INTO dbo.BatchRecords (BatchId, SiteId, RecipeId, Status, StartTime, TotalQuantity, Operator, Notes)
|
||||
VALUES (@BatchId, @SiteId, @RecipeId, 'InProgress', SYSUTCDATETIME(), @TotalQuantity, @Operator, @Notes);
|
||||
|
||||
SELECT SCOPE_IDENTITY() AS Id, @BatchId AS BatchId;
|
||||
END;
|
||||
GO
|
||||
|
||||
-- Complete or abort a batch
|
||||
IF OBJECT_ID('dbo.usp_CompleteBatch', 'P') IS NOT NULL DROP PROCEDURE dbo.usp_CompleteBatch;
|
||||
GO
|
||||
CREATE PROCEDURE dbo.usp_CompleteBatch
|
||||
@BatchId NVARCHAR(64),
|
||||
@Status NVARCHAR(32), -- 'Complete' or 'Aborted'
|
||||
@TotalQuantity DECIMAL(10,2) = NULL,
|
||||
@Notes NVARCHAR(1024) = NULL
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
UPDATE dbo.BatchRecords
|
||||
SET Status = @Status,
|
||||
EndTime = SYSUTCDATETIME(),
|
||||
TotalQuantity = COALESCE(@TotalQuantity, TotalQuantity),
|
||||
Notes = COALESCE(@Notes, Notes)
|
||||
WHERE BatchId = @BatchId
|
||||
AND Status = 'InProgress';
|
||||
|
||||
IF @@ROWCOUNT = 0
|
||||
THROW 50001, 'Batch not found or not in progress.', 1;
|
||||
|
||||
SELECT BatchId, Status, StartTime, EndTime, TotalQuantity
|
||||
FROM dbo.BatchRecords
|
||||
WHERE BatchId = @BatchId;
|
||||
END;
|
||||
GO
|
||||
|
||||
-- Get recent equipment events
|
||||
IF OBJECT_ID('dbo.usp_GetEquipmentEvents', 'P') IS NOT NULL DROP PROCEDURE dbo.usp_GetEquipmentEvents;
|
||||
GO
|
||||
CREATE PROCEDURE dbo.usp_GetEquipmentEvents
|
||||
@SiteId NVARCHAR(64),
|
||||
@EquipmentId NVARCHAR(128) = NULL,
|
||||
@EventType NVARCHAR(32) = NULL,
|
||||
@Hours INT = 24
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
DECLARE @Since DATETIME2(3) = DATEADD(HOUR, -@Hours, SYSUTCDATETIME());
|
||||
|
||||
SELECT
|
||||
EquipmentId, EventType, PreviousState, NewState, Description, Timestamp
|
||||
FROM dbo.EquipmentEvents
|
||||
WHERE SiteId = @SiteId
|
||||
AND Timestamp >= @Since
|
||||
AND (@EquipmentId IS NULL OR EquipmentId = @EquipmentId)
|
||||
AND (@EventType IS NULL OR EventType = @EventType)
|
||||
ORDER BY Timestamp DESC;
|
||||
END;
|
||||
GO
|
||||
|
||||
-- Get active alarms for a site
|
||||
IF OBJECT_ID('dbo.usp_GetActiveAlarms', 'P') IS NOT NULL DROP PROCEDURE dbo.usp_GetActiveAlarms;
|
||||
GO
|
||||
CREATE PROCEDURE dbo.usp_GetActiveAlarms
|
||||
@SiteId NVARCHAR(64),
|
||||
@MinSeverity TINYINT = 1
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
SELECT
|
||||
AlarmName, Severity, State, ActivatedAt, AcknowledgedAt,
|
||||
AcknowledgedBy, Message
|
||||
FROM dbo.AlarmHistory
|
||||
WHERE SiteId = @SiteId
|
||||
AND State IN ('Active', 'Acknowledged')
|
||||
AND Severity >= @MinSeverity
|
||||
ORDER BY Severity DESC, ActivatedAt DESC;
|
||||
END;
|
||||
GO
|
||||
|
||||
-- =========================================================================
|
||||
-- Sample Data
|
||||
-- =========================================================================
|
||||
|
||||
-- Tag history (last few hours of data for two sites)
|
||||
DECLARE @now DATETIME2(3) = SYSUTCDATETIME();
|
||||
|
||||
INSERT INTO dbo.TagHistory (TagPath, Timestamp, Value, Quality, SiteId) VALUES
|
||||
('SiteA/Pump-001/Pressure', DATEADD(MINUTE, -120, @now), 45.2, 192, 'SiteA'),
|
||||
('SiteA/Pump-001/Pressure', DATEADD(MINUTE, -110, @now), 46.1, 192, 'SiteA'),
|
||||
('SiteA/Pump-001/Pressure', DATEADD(MINUTE, -100, @now), 44.8, 192, 'SiteA'),
|
||||
('SiteA/Pump-001/Pressure', DATEADD(MINUTE, -90, @now), 47.3, 192, 'SiteA'),
|
||||
('SiteA/Pump-001/Pressure', DATEADD(MINUTE, -80, @now), 45.9, 192, 'SiteA'),
|
||||
('SiteA/Pump-001/Flow', DATEADD(MINUTE, -120, @now), 120.5, 192, 'SiteA'),
|
||||
('SiteA/Pump-001/Flow', DATEADD(MINUTE, -110, @now), 121.2, 192, 'SiteA'),
|
||||
('SiteA/Pump-001/Flow', DATEADD(MINUTE, -100, @now), 119.8, 192, 'SiteA'),
|
||||
('SiteA/Tank-001/Level', DATEADD(MINUTE, -120, @now), 72.0, 192, 'SiteA'),
|
||||
('SiteA/Tank-001/Level', DATEADD(MINUTE, -110, @now), 73.5, 192, 'SiteA'),
|
||||
('SiteA/Tank-001/Level', DATEADD(MINUTE, -100, @now), 75.1, 192, 'SiteA'),
|
||||
('SiteA/Tank-001/Level', DATEADD(MINUTE, -90, @now), 76.8, 192, 'SiteA'),
|
||||
('SiteA/Tank-001/Temperature', DATEADD(MINUTE, -120, @now), 65.3, 192, 'SiteA'),
|
||||
('SiteA/Tank-001/Temperature', DATEADD(MINUTE, -110, @now), 65.5, 192, 'SiteA'),
|
||||
('SiteA/Conv-001/Speed', DATEADD(MINUTE, -120, @now), 2.4, 192, 'SiteA'),
|
||||
('SiteA/Conv-001/Speed', DATEADD(MINUTE, -110, @now), 0.0, 0, 'SiteA'), -- Bad quality (stopped)
|
||||
('SiteA/Conv-001/Speed', DATEADD(MINUTE, -100, @now), 2.3, 192, 'SiteA'),
|
||||
('SiteB/Mixer-001/RPM', DATEADD(MINUTE, -120, @now), 450.0, 192, 'SiteB'),
|
||||
('SiteB/Mixer-001/RPM', DATEADD(MINUTE, -110, @now), 452.0, 192, 'SiteB'),
|
||||
('SiteB/Mixer-001/RPM', DATEADD(MINUTE, -100, @now), 448.0, 192, 'SiteB'),
|
||||
('SiteB/Mixer-001/Temperature',DATEADD(MINUTE, -120, @now), 82.1, 192, 'SiteB'),
|
||||
('SiteB/Mixer-001/Temperature',DATEADD(MINUTE, -110, @now), 83.0, 192, 'SiteB');
|
||||
|
||||
-- Production counts (last 3 days, 2 shifts per day)
|
||||
DECLARE @today DATE = CAST(SYSUTCDATETIME() AS DATE);
|
||||
|
||||
INSERT INTO dbo.ProductionCounts (SiteId, LineName, ShiftDate, ShiftNumber, GoodCount, RejectCount, Efficiency) VALUES
|
||||
('SiteA', 'Line-1', DATEADD(DAY, -2, @today), 1, 4100, 82, 92.5),
|
||||
('SiteA', 'Line-1', DATEADD(DAY, -2, @today), 2, 3900, 95, 91.2),
|
||||
('SiteA', 'Line-2', DATEADD(DAY, -2, @today), 1, 3050, 120, 88.1),
|
||||
('SiteA', 'Line-2', DATEADD(DAY, -2, @today), 2, 2900, 105, 87.5),
|
||||
('SiteA', 'Line-1', DATEADD(DAY, -1, @today), 1, 4200, 75, 93.1),
|
||||
('SiteA', 'Line-1', DATEADD(DAY, -1, @today), 2, 4050, 88, 92.0),
|
||||
('SiteA', 'Line-2', DATEADD(DAY, -1, @today), 1, 3100, 98, 89.2),
|
||||
('SiteA', 'Line-2', DATEADD(DAY, -1, @today), 2, 3000, 110, 88.0),
|
||||
('SiteA', 'Line-1', @today, 1, 2100, 40, 93.5),
|
||||
('SiteA', 'Line-2', @today, 1, 1550, 65, 88.8),
|
||||
('SiteB', 'Mixing', DATEADD(DAY, -1, @today), 1, 850, 12, 95.0),
|
||||
('SiteB', 'Mixing', DATEADD(DAY, -1, @today), 2, 820, 15, 94.2),
|
||||
('SiteB', 'Packing', DATEADD(DAY, -1, @today), 1, 1600, 45, 90.5),
|
||||
('SiteB', 'Packing', DATEADD(DAY, -1, @today), 2, 1550, 50, 89.8);
|
||||
|
||||
-- Equipment events
|
||||
INSERT INTO dbo.EquipmentEvents (SiteId, EquipmentId, EventType, PreviousState, NewState, Description, Timestamp) VALUES
|
||||
('SiteA', 'PUMP-001', 'StateChange', 'Idle', 'Running', 'Shift start', DATEADD(HOUR, -8, @now)),
|
||||
('SiteA', 'PUMP-001', 'Fault', 'Running', 'Faulted', 'Overcurrent detected', DATEADD(HOUR, -5, @now)),
|
||||
('SiteA', 'PUMP-001', 'StateChange', 'Faulted', 'Running', 'Manual reset by operator', DATEADD(HOUR, -4, @now)),
|
||||
('SiteA', 'TANK-001', 'Alarm', NULL, 'HighLevel','Tank level exceeded 90%', DATEADD(HOUR, -3, @now)),
|
||||
('SiteA', 'TANK-001', 'Alarm', NULL, 'Normal', 'Tank level returned to normal',DATEADD(HOUR, -2, @now)),
|
||||
('SiteA', 'CONV-001', 'Maintenance', 'Running', 'Maintenance', 'Scheduled belt inspection', DATEADD(HOUR, -6, @now)),
|
||||
('SiteA', 'CONV-001', 'StateChange', 'Maintenance', 'Running', 'Maintenance complete', DATEADD(HOUR, -5, @now)),
|
||||
('SiteB', 'MIXER-001','StateChange', 'Idle', 'Running', 'Batch R-100 started', DATEADD(HOUR, -7, @now)),
|
||||
('SiteB', 'MIXER-001','StateChange', 'Running', 'Idle', 'Batch R-100 complete', DATEADD(HOUR, -3, @now));
|
||||
|
||||
-- Batch records
|
||||
INSERT INTO dbo.BatchRecords (BatchId, SiteId, RecipeId, Status, StartTime, EndTime, TotalQuantity, Operator, Notes) VALUES
|
||||
('BATCH-20260314-001', 'SiteA', 'R-100', 'Complete', DATEADD(HOUR, -26, @now), DATEADD(HOUR, -22, @now), 450.00, 'jsmith', 'Normal run'),
|
||||
('BATCH-20260314-002', 'SiteA', 'R-200', 'Complete', DATEADD(HOUR, -20, @now), DATEADD(HOUR, -16, @now), 380.50, 'jsmith', 'Slight yield loss on Material-B'),
|
||||
('BATCH-20260315-001', 'SiteB', 'R-100', 'Complete', DATEADD(HOUR, -10, @now), DATEADD(HOUR, -6, @now), 445.00, 'mdoe', NULL),
|
||||
('BATCH-20260315-002', 'SiteA', 'R-150', 'Aborted', DATEADD(HOUR, -8, @now), DATEADD(HOUR, -7, @now), NULL, 'jsmith', 'Material-A out of spec, aborted early'),
|
||||
('BATCH-20260316-001', 'SiteA', 'R-100', 'InProgress', DATEADD(HOUR, -2, @now), NULL, NULL, 'bwilson', 'Current batch');
|
||||
|
||||
-- Alarm history
|
||||
INSERT INTO dbo.AlarmHistory (SiteId, AlarmName, Severity, State, ActivatedAt, AcknowledgedAt, ClearedAt, AcknowledgedBy, Message) VALUES
|
||||
('SiteA', 'Tank-001 High Level', 3, 'Cleared', DATEADD(HOUR, -3, @now), DATEADD(HOUR, -3, @now), DATEADD(HOUR, -2, @now), 'jsmith', 'Level exceeded 90% setpoint'),
|
||||
('SiteA', 'Pump-001 Overcurrent', 4, 'Cleared', DATEADD(HOUR, -5, @now), DATEADD(HOUR, -5, @now), DATEADD(HOUR, -4, @now), 'jsmith', 'Current draw 15.2A (limit 12A)'),
|
||||
('SiteA', 'Conv-001 Belt Slip', 2, 'Active', DATEADD(HOUR, -1, @now), NULL, NULL, NULL, 'Belt speed deviation >5%'),
|
||||
('SiteA', 'Tank-001 Temperature High', 3, 'Acknowledged', DATEADD(MINUTE, -30, @now), DATEADD(MINUTE, -25, @now), NULL, 'bwilson', 'Temperature 68.2C (limit 65C)'),
|
||||
('SiteB', 'Mixer-001 Vibration', 2, 'Active', DATEADD(HOUR, -2, @now), NULL, NULL, NULL, 'Vibration level elevated');
|
||||
GO
|
||||
|
||||
PRINT 'ScadaLinkMachineData seed complete.';
|
||||
PRINT 'Tables: TagHistory, ProductionCounts, EquipmentEvents, BatchRecords, AlarmHistory';
|
||||
PRINT 'Stored Procedures: usp_GetTagHistory, usp_GetProductionSummary, usp_InsertBatchRecord, usp_CompleteBatch, usp_GetEquipmentEvents, usp_GetActiveAlarms';
|
||||
GO
|
||||
Reference in New Issue
Block a user