Add UDC Performance Dashboard and Tool Health features
- Add displayudc.asp with Dashboard tab containing: - Production Trend chart (daily parts) - OOT Rate Trend chart (daily OOT %) - Machine Utilization chart (top 10 by runtime hours) - Top Operators chart (top 10 by parts produced) - Add tabs for drill-down: Live Activity, Operators, Machines, Parts, Quality/OOT, Timing, Activity Log, Tool Health, Uptime, IT Diagnostics - Add Tool Health section to displaymachine.asp UDC tab: - Summary cards (tools monitored, measurements, OOT count) - Tool status table with health indicators - Recent OOT events display - Add UDC API endpoints in api.asp: - getUDCPartRuns, getUDCOperatorStats, getUDCMachineStats, getUDCManualTiming - Add sql/udctables.sql schema for UDC data storage - Update docs/API.md with UDC endpoint documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
360
api.asp
360
api.asp
@@ -49,10 +49,14 @@ Select Case action
|
||||
GetRecordedIP()
|
||||
Case "updateMachinePositions"
|
||||
UpdateMachinePositions()
|
||||
Case "logDNCEvent"
|
||||
LogDNCEvent()
|
||||
Case "getDNCStats"
|
||||
GetDNCStats()
|
||||
Case "getUDCPartRuns"
|
||||
GetUDCPartRuns()
|
||||
Case "getUDCOperatorStats"
|
||||
GetUDCOperatorStats()
|
||||
Case "getUDCMachineStats"
|
||||
GetUDCMachineStats()
|
||||
Case "getUDCManualTiming"
|
||||
GetUDCManualTiming()
|
||||
Case Else
|
||||
SendError "Invalid action: " & action
|
||||
End Select
|
||||
@@ -2546,99 +2550,47 @@ Sub UpdateMachinePositions()
|
||||
End Sub
|
||||
|
||||
' ============================================================================
|
||||
' eDNC SPECIAL CHARACTER FIX - LOGGING
|
||||
' UDC LOG DATA ENDPOINTS
|
||||
' ============================================================================
|
||||
|
||||
Sub LogDNCEvent()
|
||||
Sub GetUDCPartRuns()
|
||||
On Error Resume Next
|
||||
|
||||
' Get parameters
|
||||
Dim hostname, filename, eventAction, bytesRemoved, version, message
|
||||
hostname = Trim(Request.Form("hostname") & "")
|
||||
filename = Trim(Request.Form("filename") & "")
|
||||
eventAction = Trim(Request.Form("eventType") & "")
|
||||
bytesRemoved = Request.Form("bytesRemoved")
|
||||
version = Trim(Request.Form("version") & "")
|
||||
message = Trim(Request.Form("message") & "")
|
||||
' Get optional filters
|
||||
Dim machinenumber, startdate, enddate, badgenumber
|
||||
machinenumber = Trim(Request.QueryString("machinenumber") & "")
|
||||
startdate = Trim(Request.QueryString("startdate") & "")
|
||||
enddate = Trim(Request.QueryString("enddate") & "")
|
||||
badgenumber = Trim(Request.QueryString("badgenumber") & "")
|
||||
|
||||
' Validate required fields
|
||||
If hostname = "" Or eventAction = "" Then
|
||||
SendError "hostname and eventType are required"
|
||||
Exit Sub
|
||||
' Build query
|
||||
Dim sql, conditions
|
||||
sql = "SELECT p.partrunid, s.machinenumber, p.partnumber, p.opernumber, p.serialnumber, " & _
|
||||
"p.programname, p.jobnumber, p.badgenumber, p.programstart, p.programend, " & _
|
||||
"p.cycletime, p.changeover, p.measurementcount, p.manualcount, p.probecount, p.ootcount " & _
|
||||
"FROM udcparts p " & _
|
||||
"JOIN udcsessions s ON p.sessionid = s.sessionid "
|
||||
|
||||
conditions = ""
|
||||
If machinenumber <> "" Then
|
||||
conditions = conditions & " AND s.machinenumber = '" & Replace(machinenumber, "'", "''") & "'"
|
||||
End If
|
||||
If startdate <> "" Then
|
||||
conditions = conditions & " AND p.programstart >= '" & Replace(startdate, "'", "''") & "'"
|
||||
End If
|
||||
If enddate <> "" Then
|
||||
conditions = conditions & " AND p.programstart <= '" & Replace(enddate, "'", "''") & " 23:59:59'"
|
||||
End If
|
||||
If badgenumber <> "" Then
|
||||
conditions = conditions & " AND p.badgenumber = '" & Replace(badgenumber, "'", "''") & "'"
|
||||
End If
|
||||
|
||||
' Default bytesRemoved to 0 if not numeric
|
||||
If Not IsNumeric(bytesRemoved) Or bytesRemoved = "" Then bytesRemoved = 0
|
||||
|
||||
' Get machineid from hostname (required for logging)
|
||||
Dim safeHostname, machineid, rsLookup
|
||||
safeHostname = Replace(hostname, "'", "''")
|
||||
Set rsLookup = objConn.Execute("SELECT machineid FROM machines WHERE UPPER(hostname) = UPPER('" & safeHostname & "') AND pctypeid IS NOT NULL LIMIT 1")
|
||||
|
||||
If rsLookup.EOF Then
|
||||
rsLookup.Close
|
||||
Set rsLookup = Nothing
|
||||
SendError "Unknown hostname: " & hostname
|
||||
Exit Sub
|
||||
If conditions <> "" Then
|
||||
sql = sql & " WHERE 1=1 " & conditions
|
||||
End If
|
||||
sql = sql & " ORDER BY p.programstart DESC LIMIT 1000"
|
||||
|
||||
machineid = CLng(rsLookup("machineid"))
|
||||
rsLookup.Close
|
||||
Set rsLookup = Nothing
|
||||
|
||||
' Sanitize remaining inputs
|
||||
Dim safeFilename, safeAction, safeVersion, safeMessage
|
||||
safeFilename = Replace(filename, "'", "''")
|
||||
safeAction = Replace(eventAction, "'", "''")
|
||||
safeVersion = Replace(version, "'", "''")
|
||||
safeMessage = Replace(message, "'", "''")
|
||||
|
||||
' Insert log entry using machineid
|
||||
Dim insertSQL
|
||||
insertSQL = "INSERT INTO ednclogs (machineid, filename, action, bytes_removed, version, message) " & _
|
||||
"VALUES (" & machineid & ", '" & safeFilename & "', '" & safeAction & "', " & _
|
||||
CLng(bytesRemoved) & ", '" & safeVersion & "', '" & safeMessage & "')"
|
||||
objConn.Execute insertSQL
|
||||
|
||||
If Err.Number <> 0 Then
|
||||
SendError "Failed to log event: " & Err.Description
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
' Track in installedapps (appid 79 = eDNC Special Character Fix)
|
||||
Dim edncAppId, rsApp
|
||||
edncAppId = 79
|
||||
|
||||
' Check if already in installedapps
|
||||
Set rsApp = objConn.Execute("SELECT installedappid FROM installedapps WHERE machineid = " & machineid & " AND appid = " & edncAppId)
|
||||
If rsApp.EOF Then
|
||||
' Insert new record
|
||||
objConn.Execute "INSERT INTO installedapps (appid, machineid, isactive) VALUES (" & edncAppId & ", " & machineid & ", 1)"
|
||||
End If
|
||||
rsApp.Close
|
||||
Set rsApp = Nothing
|
||||
|
||||
' Send success response
|
||||
Response.Write "{""success"":true,""message"":""Event logged""}"
|
||||
End Sub
|
||||
|
||||
Sub GetDNCStats()
|
||||
On Error Resume Next
|
||||
|
||||
' Get stats derived from ednclogs, joined to machines for hostname
|
||||
Dim sql, rs
|
||||
sql = "SELECT m.hostname, " & _
|
||||
"(SELECT version FROM ednclogs WHERE machineid = l.machineid ORDER BY created DESC LIMIT 1) AS version, " & _
|
||||
"MIN(l.created) AS first_seen, " & _
|
||||
"MAX(l.created) AS last_seen, " & _
|
||||
"SUM(CASE WHEN l.action = 'cleaned' THEN 1 ELSE 0 END) AS total_cleaned, " & _
|
||||
"SUM(CASE WHEN l.action = 'failed' THEN 1 ELSE 0 END) AS total_failed, " & _
|
||||
"(SELECT COUNT(*) FROM ednclogs WHERE machineid = l.machineid AND created > DATE_SUB(NOW(), INTERVAL 24 HOUR)) AS events_24h " & _
|
||||
"FROM ednclogs l " & _
|
||||
"INNER JOIN machines m ON l.machineid = m.machineid " & _
|
||||
"GROUP BY l.machineid, m.hostname " & _
|
||||
"ORDER BY last_seen DESC"
|
||||
|
||||
Dim rs
|
||||
Set rs = objConn.Execute(sql)
|
||||
|
||||
If Err.Number <> 0 Then
|
||||
@@ -2648,7 +2600,7 @@ Sub GetDNCStats()
|
||||
|
||||
' Build JSON response
|
||||
Dim json, first
|
||||
json = "{""success"":true,""installations"":["
|
||||
json = "{""success"":true,""partruns"":["
|
||||
first = True
|
||||
|
||||
Do While Not rs.EOF
|
||||
@@ -2656,22 +2608,236 @@ Sub GetDNCStats()
|
||||
first = False
|
||||
|
||||
json = json & "{" & _
|
||||
"""hostname"":""" & (rs("hostname") & "") & """," & _
|
||||
"""version"":""" & (rs("version") & "") & """," & _
|
||||
"""firstSeen"":""" & (rs("first_seen") & "") & """," & _
|
||||
"""lastSeen"":""" & (rs("last_seen") & "") & """," & _
|
||||
"""totalCleaned"":" & (rs("total_cleaned") + 0) & "," & _
|
||||
"""totalFailed"":" & (rs("total_failed") + 0) & "," & _
|
||||
"""events24h"":" & (rs("events_24h") + 0) & _
|
||||
"""partrunid"":" & CLng(rs("partrunid") & "0") & "," & _
|
||||
"""machinenumber"":""" & (rs("machinenumber") & "") & """," & _
|
||||
"""partnumber"":""" & (rs("partnumber") & "") & """," & _
|
||||
"""opernumber"":""" & (rs("opernumber") & "") & """," & _
|
||||
"""serialnumber"":""" & (rs("serialnumber") & "") & """," & _
|
||||
"""programname"":""" & (rs("programname") & "") & """," & _
|
||||
"""jobnumber"":""" & (rs("jobnumber") & "") & """," & _
|
||||
"""badgenumber"":""" & (rs("badgenumber") & "") & """," & _
|
||||
"""programstart"":""" & (rs("programstart") & "") & """," & _
|
||||
"""programend"":""" & (rs("programend") & "") & """," & _
|
||||
"""cycletime"":" & CLng(rs("cycletime") & "0") & "," & _
|
||||
"""changeover"":" & CLng(rs("changeover") & "0") & "," & _
|
||||
"""measurementcount"":" & CLng(rs("measurementcount") & "0") & "," & _
|
||||
"""manualcount"":" & CLng(rs("manualcount") & "0") & "," & _
|
||||
"""probecount"":" & CLng(rs("probecount") & "0") & "," & _
|
||||
"""ootcount"":" & CLng(rs("ootcount") & "0") & _
|
||||
"}"
|
||||
rs.MoveNext
|
||||
Loop
|
||||
|
||||
json = json & "]}"
|
||||
|
||||
rs.Close
|
||||
Set rs = Nothing
|
||||
|
||||
Response.ContentType = "application/json"
|
||||
Response.Write json
|
||||
End Sub
|
||||
|
||||
Sub GetUDCOperatorStats()
|
||||
On Error Resume Next
|
||||
|
||||
Dim startdate, enddate
|
||||
startdate = Trim(Request.QueryString("startdate") & "")
|
||||
enddate = Trim(Request.QueryString("enddate") & "")
|
||||
|
||||
Dim sql, conditions
|
||||
sql = "SELECT p.badgenumber, COUNT(*) AS partsrun, " & _
|
||||
"AVG(p.cycletime) AS avgcycletime, AVG(p.changeover) AS avgchangeover, " & _
|
||||
"SUM(p.measurementcount) AS totalmeasurements, SUM(p.manualcount) AS totalmanual, " & _
|
||||
"SUM(p.ootcount) AS totaloot, MIN(p.programstart) AS firstrun, MAX(p.programend) AS lastrun, " & _
|
||||
"(SELECT AVG(mr.responseseconds) FROM udcmanualrequests mr " & _
|
||||
" JOIN udcparts p2 ON mr.partrunid = p2.partrunid WHERE p2.badgenumber = p.badgenumber) AS avgmanualtime " & _
|
||||
"FROM udcparts p " & _
|
||||
"WHERE p.badgenumber IS NOT NULL AND p.badgenumber != '' "
|
||||
|
||||
If startdate <> "" Then
|
||||
sql = sql & " AND p.programstart >= '" & Replace(startdate, "'", "''") & "'"
|
||||
End If
|
||||
If enddate <> "" Then
|
||||
sql = sql & " AND p.programstart <= '" & Replace(enddate, "'", "''") & " 23:59:59'"
|
||||
End If
|
||||
|
||||
sql = sql & " GROUP BY p.badgenumber ORDER BY partsrun DESC"
|
||||
|
||||
Dim rs
|
||||
Set rs = objConn.Execute(sql)
|
||||
|
||||
If Err.Number <> 0 Then
|
||||
SendError "Database error: " & Err.Description
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Dim json, first
|
||||
Dim avgCycle, avgChange, avgManual
|
||||
json = "{""success"":true,""operators"":["
|
||||
first = True
|
||||
|
||||
Do While Not rs.EOF
|
||||
If Not first Then json = json & ","
|
||||
first = False
|
||||
|
||||
If IsNull(rs("avgcycletime")) Then avgCycle = 0 Else avgCycle = Round(CDbl(rs("avgcycletime")), 0)
|
||||
If IsNull(rs("avgchangeover")) Then avgChange = 0 Else avgChange = Round(CDbl(rs("avgchangeover")), 0)
|
||||
If IsNull(rs("avgmanualtime")) Then avgManual = 0 Else avgManual = Round(CDbl(rs("avgmanualtime")), 0)
|
||||
|
||||
json = json & "{" & _
|
||||
"""badgenumber"":""" & (rs("badgenumber") & "") & """," & _
|
||||
"""partsrun"":" & CLng(rs("partsrun") & "0") & "," & _
|
||||
"""avgcycletime"":" & avgCycle & "," & _
|
||||
"""avgchangeover"":" & avgChange & "," & _
|
||||
"""avgmanualtime"":" & avgManual & "," & _
|
||||
"""totalmeasurements"":" & CLng(rs("totalmeasurements") & "0") & "," & _
|
||||
"""totalmanual"":" & CLng(rs("totalmanual") & "0") & "," & _
|
||||
"""totaloot"":" & CLng(rs("totaloot") & "0") & "," & _
|
||||
"""firstrun"":""" & (rs("firstrun") & "") & """," & _
|
||||
"""lastrun"":""" & (rs("lastrun") & "") & """" & _
|
||||
"}"
|
||||
rs.MoveNext
|
||||
Loop
|
||||
|
||||
json = json & "]}"
|
||||
rs.Close
|
||||
Set rs = Nothing
|
||||
|
||||
Response.ContentType = "application/json"
|
||||
Response.Write json
|
||||
End Sub
|
||||
|
||||
Sub GetUDCMachineStats()
|
||||
On Error Resume Next
|
||||
|
||||
Dim startdate, enddate
|
||||
startdate = Trim(Request.QueryString("startdate") & "")
|
||||
enddate = Trim(Request.QueryString("enddate") & "")
|
||||
|
||||
Dim sql
|
||||
sql = "SELECT s.machinenumber, COUNT(*) AS partsrun, " & _
|
||||
"AVG(p.cycletime) AS avgcycletime, AVG(p.changeover) AS avgchangeover, " & _
|
||||
"SUM(p.measurementcount) AS totalmeasurements, SUM(p.ootcount) AS totaloot, " & _
|
||||
"MIN(p.programstart) AS firstrun, MAX(p.programend) AS lastrun " & _
|
||||
"FROM udcparts p " & _
|
||||
"JOIN udcsessions s ON p.sessionid = s.sessionid "
|
||||
|
||||
If startdate <> "" Or enddate <> "" Then
|
||||
sql = sql & " WHERE 1=1 "
|
||||
If startdate <> "" Then
|
||||
sql = sql & " AND p.programstart >= '" & Replace(startdate, "'", "''") & "'"
|
||||
End If
|
||||
If enddate <> "" Then
|
||||
sql = sql & " AND p.programstart <= '" & Replace(enddate, "'", "''") & " 23:59:59'"
|
||||
End If
|
||||
End If
|
||||
|
||||
sql = sql & " GROUP BY s.machinenumber ORDER BY partsrun DESC"
|
||||
|
||||
Dim rs
|
||||
Set rs = objConn.Execute(sql)
|
||||
|
||||
If Err.Number <> 0 Then
|
||||
SendError "Database error: " & Err.Description
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Dim json, first
|
||||
Dim avgCycle, avgChange
|
||||
json = "{""success"":true,""machines"":["
|
||||
first = True
|
||||
|
||||
Do While Not rs.EOF
|
||||
If Not first Then json = json & ","
|
||||
first = False
|
||||
|
||||
If IsNull(rs("avgcycletime")) Then avgCycle = 0 Else avgCycle = Round(CDbl(rs("avgcycletime")), 0)
|
||||
If IsNull(rs("avgchangeover")) Then avgChange = 0 Else avgChange = Round(CDbl(rs("avgchangeover")), 0)
|
||||
|
||||
json = json & "{" & _
|
||||
"""machinenumber"":""" & (rs("machinenumber") & "") & """," & _
|
||||
"""partsrun"":" & CLng(rs("partsrun") & "0") & "," & _
|
||||
"""avgcycletime"":" & avgCycle & "," & _
|
||||
"""avgchangeover"":" & avgChange & "," & _
|
||||
"""totalmeasurements"":" & CLng(rs("totalmeasurements") & "0") & "," & _
|
||||
"""totaloot"":" & CLng(rs("totaloot") & "0") & "," & _
|
||||
"""firstrun"":""" & (rs("firstrun") & "") & """," & _
|
||||
"""lastrun"":""" & (rs("lastrun") & "") & """" & _
|
||||
"}"
|
||||
rs.MoveNext
|
||||
Loop
|
||||
|
||||
json = json & "]}"
|
||||
rs.Close
|
||||
Set rs = Nothing
|
||||
|
||||
Response.ContentType = "application/json"
|
||||
Response.Write json
|
||||
End Sub
|
||||
|
||||
Sub GetUDCManualTiming()
|
||||
On Error Resume Next
|
||||
|
||||
Dim machinenumber, startdate, enddate
|
||||
machinenumber = Trim(Request.QueryString("machinenumber") & "")
|
||||
startdate = Trim(Request.QueryString("startdate") & "")
|
||||
enddate = Trim(Request.QueryString("enddate") & "")
|
||||
|
||||
Dim sql, conditions
|
||||
sql = "SELECT mr.requestid, p.badgenumber, s.machinenumber, " & _
|
||||
"mr.requesttime, mr.responsetime, mr.responseseconds, mr.description " & _
|
||||
"FROM udcmanualrequests mr " & _
|
||||
"JOIN udcparts p ON mr.partrunid = p.partrunid " & _
|
||||
"JOIN udcsessions s ON p.sessionid = s.sessionid "
|
||||
|
||||
conditions = ""
|
||||
If machinenumber <> "" Then
|
||||
conditions = conditions & " AND s.machinenumber = '" & Replace(machinenumber, "'", "''") & "'"
|
||||
End If
|
||||
If startdate <> "" Then
|
||||
conditions = conditions & " AND mr.requesttime >= '" & Replace(startdate, "'", "''") & "'"
|
||||
End If
|
||||
If enddate <> "" Then
|
||||
conditions = conditions & " AND mr.requesttime <= '" & Replace(enddate, "'", "''") & " 23:59:59'"
|
||||
End If
|
||||
|
||||
If conditions <> "" Then
|
||||
sql = sql & " WHERE 1=1 " & conditions
|
||||
End If
|
||||
sql = sql & " ORDER BY mr.requesttime DESC LIMIT 1000"
|
||||
|
||||
Dim rs
|
||||
Set rs = objConn.Execute(sql)
|
||||
|
||||
If Err.Number <> 0 Then
|
||||
SendError "Database error: " & Err.Description
|
||||
Exit Sub
|
||||
End If
|
||||
|
||||
Dim json, first
|
||||
json = "{""success"":true,""manualrequests"":["
|
||||
first = True
|
||||
|
||||
Do While Not rs.EOF
|
||||
If Not first Then json = json & ","
|
||||
first = False
|
||||
|
||||
json = json & "{" & _
|
||||
"""requestid"":" & CLng(rs("requestid") & "0") & "," & _
|
||||
"""badgenumber"":""" & (rs("badgenumber") & "") & """," & _
|
||||
"""machinenumber"":""" & (rs("machinenumber") & "") & """," & _
|
||||
"""requesttime"":""" & (rs("requesttime") & "") & """," & _
|
||||
"""responsetime"":""" & (rs("responsetime") & "") & """," & _
|
||||
"""responseseconds"":" & CLng(rs("responseseconds") & "0") & "," & _
|
||||
"""description"":""" & Replace(rs("description") & "", """", "\""") & """" & _
|
||||
"}"
|
||||
rs.MoveNext
|
||||
Loop
|
||||
|
||||
json = json & "]}"
|
||||
rs.Close
|
||||
Set rs = Nothing
|
||||
|
||||
Response.ContentType = "application/json"
|
||||
Response.Write json
|
||||
End Sub
|
||||
|
||||
|
||||
Reference in New Issue
Block a user