Folder reorganize 1
This commit is contained in:
17
includes/ETDapronFPM.php
Normal file
17
includes/ETDapronFPM.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000524'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue / 10, 2);
|
||||
?>
|
||||
17
includes/Vapor2.php
Normal file
17
includes/Vapor2.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000542'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/WTDapronFPM.php
Normal file
17
includes/WTDapronFPM.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000522'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue / 10, 2);
|
||||
?>
|
||||
309
includes/alerts.php
Normal file
309
includes/alerts.php
Normal file
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
/**
|
||||
* System-wide alerts include
|
||||
*
|
||||
* Include this file in data pages to display conditional alerts.
|
||||
* Expects $value array to be populated from items.php or shared endpoint.
|
||||
*
|
||||
* Usage: require __DIR__ . '/../includes/alerts.php';
|
||||
*/
|
||||
|
||||
$alerts = [];
|
||||
|
||||
// ============================================================================
|
||||
// Database Connection for Alerts (singleton)
|
||||
// ============================================================================
|
||||
function getAlertConnection() {
|
||||
static $connection = null;
|
||||
|
||||
if ($connection === null) {
|
||||
$connection = mysqli_connect('192.168.0.16', 'lasucaai', 'is413#dfslw', 'controls');
|
||||
if ($connection) {
|
||||
mysqli_set_charset($connection, 'utf8mb4');
|
||||
|
||||
// Create tables if not exists
|
||||
$createLogTable = "CREATE TABLE IF NOT EXISTS alert_log (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
alert_type VARCHAR(50) NOT NULL,
|
||||
alert_tag VARCHAR(100) NOT NULL,
|
||||
alert_value DECIMAL(18,4) NULL,
|
||||
threshold_value DECIMAL(18,4) NULL,
|
||||
alert_message VARCHAR(500) NOT NULL,
|
||||
source_page VARCHAR(255) NULL,
|
||||
logged_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_alert_type (alert_type),
|
||||
INDEX idx_alert_tag (alert_tag),
|
||||
INDEX idx_logged_at (logged_at)
|
||||
)";
|
||||
mysqli_query($connection, $createLogTable);
|
||||
|
||||
// Create throttle table to track last log time per alert
|
||||
$createThrottleTable = "CREATE TABLE IF NOT EXISTS alert_throttle (
|
||||
alert_key VARCHAR(150) PRIMARY KEY,
|
||||
last_logged DATETIME NOT NULL,
|
||||
INDEX idx_last_logged (last_logged)
|
||||
)";
|
||||
mysqli_query($connection, $createThrottleTable);
|
||||
|
||||
// Create condition state table to track duration
|
||||
$createStateTable = "CREATE TABLE IF NOT EXISTS alert_condition_state (
|
||||
alert_key VARCHAR(150) PRIMARY KEY,
|
||||
condition_started DATETIME NOT NULL,
|
||||
last_seen DATETIME NOT NULL,
|
||||
INDEX idx_last_seen (last_seen)
|
||||
)";
|
||||
mysqli_query($connection, $createStateTable);
|
||||
}
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Check if condition has persisted for required duration (in seconds)
|
||||
// Returns true if condition has been active for >= duration seconds
|
||||
// ============================================================================
|
||||
function checkAlertDuration($alertKey, $conditionMet, $durationSeconds = 0) {
|
||||
if ($durationSeconds <= 0) {
|
||||
// No duration requirement - trigger immediately
|
||||
return $conditionMet;
|
||||
}
|
||||
|
||||
$conn = getAlertConnection();
|
||||
if (!$conn) {
|
||||
return $conditionMet; // Fallback to immediate if no DB
|
||||
}
|
||||
|
||||
$now = date('Y-m-d H:i:s');
|
||||
|
||||
if ($conditionMet) {
|
||||
// Condition is currently true - check/update state
|
||||
$stmt = mysqli_prepare($conn,
|
||||
"SELECT condition_started FROM alert_condition_state WHERE alert_key = ?"
|
||||
);
|
||||
|
||||
if ($stmt) {
|
||||
mysqli_stmt_bind_param($stmt, 's', $alertKey);
|
||||
mysqli_stmt_execute($stmt);
|
||||
$result = mysqli_stmt_get_result($stmt);
|
||||
$row = mysqli_fetch_assoc($result);
|
||||
mysqli_stmt_close($stmt);
|
||||
|
||||
if ($row) {
|
||||
// Condition already being tracked - update last_seen
|
||||
$updateStmt = mysqli_prepare($conn,
|
||||
"UPDATE alert_condition_state SET last_seen = ? WHERE alert_key = ?"
|
||||
);
|
||||
if ($updateStmt) {
|
||||
mysqli_stmt_bind_param($updateStmt, 'ss', $now, $alertKey);
|
||||
mysqli_stmt_execute($updateStmt);
|
||||
mysqli_stmt_close($updateStmt);
|
||||
}
|
||||
|
||||
// Check if duration has been met
|
||||
$started = strtotime($row['condition_started']);
|
||||
$elapsed = time() - $started;
|
||||
|
||||
return $elapsed >= $durationSeconds;
|
||||
} else {
|
||||
// First time seeing this condition - start tracking
|
||||
$insertStmt = mysqli_prepare($conn,
|
||||
"INSERT INTO alert_condition_state (alert_key, condition_started, last_seen)
|
||||
VALUES (?, ?, ?)"
|
||||
);
|
||||
if ($insertStmt) {
|
||||
mysqli_stmt_bind_param($insertStmt, 'sss', $alertKey, $now, $now);
|
||||
mysqli_stmt_execute($insertStmt);
|
||||
mysqli_stmt_close($insertStmt);
|
||||
}
|
||||
|
||||
return false; // Just started, duration not met yet
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Condition is false - clear the tracking state
|
||||
$deleteStmt = mysqli_prepare($conn,
|
||||
"DELETE FROM alert_condition_state WHERE alert_key = ?"
|
||||
);
|
||||
if ($deleteStmt) {
|
||||
mysqli_stmt_bind_param($deleteStmt, 's', $alertKey);
|
||||
mysqli_stmt_execute($deleteStmt);
|
||||
mysqli_stmt_close($deleteStmt);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $conditionMet;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Alert Logging Function (throttled to once per minute per alert)
|
||||
// ============================================================================
|
||||
function logAlert($alertType, $alertTag, $alertValue, $alertMessage, $threshold = null) {
|
||||
$conn = getAlertConnection();
|
||||
if (!$conn) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Check throttle - only log once per minute per alert type+tag
|
||||
$alertKey = $alertType . ':' . $alertTag;
|
||||
$throttleCheck = mysqli_prepare($conn,
|
||||
"SELECT last_logged FROM alert_throttle
|
||||
WHERE alert_key = ? AND last_logged > DATE_SUB(NOW(), INTERVAL 1 MINUTE)"
|
||||
);
|
||||
|
||||
if ($throttleCheck) {
|
||||
mysqli_stmt_bind_param($throttleCheck, 's', $alertKey);
|
||||
mysqli_stmt_execute($throttleCheck);
|
||||
$result = mysqli_stmt_get_result($throttleCheck);
|
||||
$recentLog = mysqli_fetch_assoc($result);
|
||||
mysqli_stmt_close($throttleCheck);
|
||||
|
||||
if ($recentLog) {
|
||||
return; // Skip - already logged within last minute
|
||||
}
|
||||
}
|
||||
|
||||
// Log the alert
|
||||
$sourcePage = $_SERVER['PHP_SELF'] ?? 'unknown';
|
||||
|
||||
$stmt = mysqli_prepare($conn,
|
||||
"INSERT INTO alert_log (alert_type, alert_tag, alert_value, threshold_value, alert_message, source_page)
|
||||
VALUES (?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
|
||||
if ($stmt) {
|
||||
mysqli_stmt_bind_param($stmt, 'ssddss',
|
||||
$alertType,
|
||||
$alertTag,
|
||||
$alertValue,
|
||||
$threshold,
|
||||
$alertMessage,
|
||||
$sourcePage
|
||||
);
|
||||
mysqli_stmt_execute($stmt);
|
||||
mysqli_stmt_close($stmt);
|
||||
|
||||
// Update throttle timestamp
|
||||
$throttleUpdate = mysqli_prepare($conn,
|
||||
"INSERT INTO alert_throttle (alert_key, last_logged) VALUES (?, NOW())
|
||||
ON DUPLICATE KEY UPDATE last_logged = NOW()"
|
||||
);
|
||||
if ($throttleUpdate) {
|
||||
mysqli_stmt_bind_param($throttleUpdate, 's', $alertKey);
|
||||
mysqli_stmt_execute($throttleUpdate);
|
||||
mysqli_stmt_close($throttleUpdate);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Silent fail - logging should never break the page
|
||||
error_log('Alert logging failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Alert Definitions (Now managed via alerts-admin.php)
|
||||
// ============================================================================
|
||||
// All alerts are now loaded from the alert_definitions table below.
|
||||
// Use the admin panel at /alerts-admin.php to add, edit, or disable alerts.
|
||||
|
||||
// ============================================================================
|
||||
// Database-Driven Alerts (from alerts-admin.php)
|
||||
// ============================================================================
|
||||
$alertConn = getAlertConnection();
|
||||
if ($alertConn) {
|
||||
$defResult = mysqli_query($alertConn,
|
||||
"SELECT * FROM alert_definitions WHERE is_active = 1"
|
||||
);
|
||||
|
||||
if ($defResult) {
|
||||
while ($def = mysqli_fetch_assoc($defResult)) {
|
||||
$tagName = $def['tag_name'];
|
||||
$tagValue = $value[$tagName] ?? null;
|
||||
|
||||
if ($tagValue === null) {
|
||||
continue; // Tag not found in current data
|
||||
}
|
||||
|
||||
// Evaluate condition based on comparison operator
|
||||
$conditionMet = false;
|
||||
$threshold = floatval($def['threshold_value']);
|
||||
|
||||
switch ($def['comparison']) {
|
||||
case '<':
|
||||
$conditionMet = ($tagValue < $threshold);
|
||||
break;
|
||||
case '<=':
|
||||
$conditionMet = ($tagValue <= $threshold);
|
||||
break;
|
||||
case '>':
|
||||
$conditionMet = ($tagValue > $threshold);
|
||||
break;
|
||||
case '>=':
|
||||
$conditionMet = ($tagValue >= $threshold);
|
||||
break;
|
||||
case '=':
|
||||
$conditionMet = ($tagValue == $threshold);
|
||||
break;
|
||||
case '!=':
|
||||
$conditionMet = ($tagValue != $threshold);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check duration requirement
|
||||
$alertKey = 'db_' . $def['id'] . '_' . $tagName;
|
||||
$durationMet = checkAlertDuration($alertKey, $conditionMet, intval($def['duration_seconds']));
|
||||
|
||||
if ($durationMet) {
|
||||
// Build message from template
|
||||
$alertMessage = str_replace(
|
||||
['{value}', '{threshold}', '{tag}'],
|
||||
[$tagValue, $threshold, $tagName],
|
||||
$def['message_template']
|
||||
);
|
||||
|
||||
$alerts[] = [
|
||||
'type' => $def['alert_type'],
|
||||
'icon' => $def['icon'],
|
||||
'tag' => $tagName,
|
||||
'value' => $tagValue,
|
||||
'threshold' => $threshold,
|
||||
'display' => $def['display_alert'],
|
||||
'message' => htmlspecialchars($alertMessage, ENT_QUOTES, 'UTF-8')
|
||||
];
|
||||
|
||||
logAlert($def['alert_type'], $tagName, $tagValue, $alertMessage, $threshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Render Alerts (info alerts are logged only, not displayed)
|
||||
// ============================================================================
|
||||
if (!empty($alerts)) {
|
||||
foreach ($alerts as $alert) {
|
||||
// Skip info alerts - they are logged but not displayed
|
||||
if ($alert['type'] === 'info') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip alerts with display=0 (database-driven alerts can disable display)
|
||||
if (isset($alert['display']) && !$alert['display']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bgColor = '#c62828'; // danger (red)
|
||||
if ($alert['type'] === 'warning') {
|
||||
$bgColor = '#f57c00'; // warning (orange)
|
||||
}
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td colspan="4" style="background: ' . $bgColor . '; color: white; text-align: center; font-weight: bold; padding: 10px;">';
|
||||
echo $alert['icon'] . ' ' . $alert['message'];
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
34
includes/apronFPM.php
Normal file
34
includes/apronFPM.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* Fetch both apron FPM values in a single database connection.
|
||||
*
|
||||
* Populates:
|
||||
* $etdApronFPM - East Truck Dump Apron FPM (ID 0000524)
|
||||
* $wtdApronFPM - West Truck Dump Apron FPM (ID 0000522)
|
||||
*/
|
||||
|
||||
include __DIR__ . '/../dbinfo3.php';
|
||||
|
||||
$con = mysqli_connect($host, $username, $password, $database);
|
||||
|
||||
$etdApronFPM = 0;
|
||||
$wtdApronFPM = 0;
|
||||
|
||||
if ($con) {
|
||||
// Fetch both values in one query
|
||||
$query = "SELECT ID, Value FROM items WHERE ID IN ('0000522', '0000524')";
|
||||
$result = mysqli_query($con, $query);
|
||||
|
||||
if ($result) {
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$rawValue = (float) $row['Value'];
|
||||
if ($row['ID'] === '0000524') {
|
||||
$etdApronFPM = round($rawValue / 10, 2);
|
||||
} elseif ($row['ID'] === '0000522') {
|
||||
$wtdApronFPM = round($rawValue / 10, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_close($con);
|
||||
}
|
||||
42
includes/archive-db.php
Normal file
42
includes/archive-db.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
|
||||
/**
|
||||
* Create a PDO connection to the archive SQL Server instance that hosts dbo.id_names.
|
||||
*
|
||||
* @throws \RuntimeException When the required PDO sqlsrv driver is unavailable.
|
||||
*/
|
||||
function archive_db_connect(): \PDO
|
||||
{
|
||||
if (!class_exists(\PDO::class)) {
|
||||
throw new \RuntimeException('PDO is required to connect to the archive database.');
|
||||
}
|
||||
|
||||
if (!in_array('sqlsrv', \PDO::getAvailableDrivers(), true)) {
|
||||
throw new \RuntimeException('The sqlsrv PDO driver is not available. Enable it to query the archive database.');
|
||||
}
|
||||
|
||||
static $cachedConnection = null;
|
||||
|
||||
if ($cachedConnection instanceof \PDO) {
|
||||
return $cachedConnection;
|
||||
}
|
||||
|
||||
$server = getenv('ARCHIVE_DB_SERVER') ?: '192.168.0.13\SQLEXPRESS';
|
||||
$database = getenv('ARCHIVE_DB_NAME') ?: 'history';
|
||||
$username = getenv('ARCHIVE_DB_USER') ?: 'opce';
|
||||
$password = getenv('ARCHIVE_DB_PASSWORD') ?: 'opcelasuca';
|
||||
|
||||
$dsn = sprintf('sqlsrv:Server=%s;Database=%s;LoginTimeout=5', $server, $database);
|
||||
|
||||
$cachedConnection = new \PDO(
|
||||
$dsn,
|
||||
$username,
|
||||
$password,
|
||||
[
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
|
||||
]
|
||||
);
|
||||
|
||||
return $cachedConnection;
|
||||
}
|
||||
71
includes/boilers24hrstmtotavg.php
Normal file
71
includes/boilers24hrstmtotavg.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
$username="corey";
|
||||
$password="41945549";
|
||||
$database="controls";
|
||||
|
||||
mysql_connect('127.0.0.1',$username,$password);
|
||||
@mysql_select_db($database) or die( "Unable to select database");
|
||||
$query = "SELECT * FROM boilerstm24hravg WHERE TIME(time) = '04:59:59' ORDER BY id DESC";
|
||||
$result=mysql_query($query);
|
||||
|
||||
$num=mysql_numrows($result);
|
||||
|
||||
mysql_close();
|
||||
?>
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="4">
|
||||
<tr>
|
||||
<td colspan="13" id="title">Boilers Total Steam Flow 24 Hour Average</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="14%" id="title" colspan="2" bgcolor="#FFFFFF" align="center" width="16.6%"><font color="#000000">Date</font></td>
|
||||
<td width="13.2%" id="title" colspan="2" bgcolor="#FFFFFF" align="center" width="16.6%"><font color="#000000">Boiler 1</font></td>
|
||||
<td width="13.2%" id="title" colspan="2" bgcolor="#FFFFFF" align="center" width="16.6%"><font color="#000000">Boiler 2</font></td>
|
||||
<td width="13.2%" id="title" colspan="2" bgcolor="#FFFFFF" align="center" width="16.6%"><font color="#000000">Boiler 3</font></td>
|
||||
<td width="13.2%" id="title" colspan="2" bgcolor="#FFFFFF" align="center" width="16.6%"><font color="#000000">Boiler 4</font></td>
|
||||
<td width="13.2%" id="title" colspan="2" bgcolor="#FFFFFF" align="center" width="16.6%"><font color="#000000">Boiler 5</font></td>
|
||||
<td width="13.2%" id="title" colspan="2" bgcolor="#FFFFFF" align="center" width="16.6%"><font color="#000000">Boiler 6</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
$i=0;
|
||||
while ($i < $num) {
|
||||
$f1=mysql_result($result,$i,"BLR1TOTSF");
|
||||
$f2=mysql_result($result,$i,"BLR2TOTSF");
|
||||
$f3=mysql_result($result,$i,"BLR3TOTSF");
|
||||
$f4=mysql_result($result,$i,"BLR4TOTSF");
|
||||
$f5=mysql_result($result,$i,"BLR5TOTSF");
|
||||
$f6=mysql_result($result,$i,"BLR6TOTSF");
|
||||
$f7=mysql_result($result,$i,"TIME");
|
||||
?>
|
||||
|
||||
|
||||
|
||||
|
||||
<div id="stories">
|
||||
|
||||
|
||||
<table width="100%" border="1" cellspacing="0" cellpadding="4">
|
||||
|
||||
<tr>
|
||||
<td width="14%" id="vtitle" bgcolor="#FFFFFF" align="left"><font color="#000000" ><?php echo $f7; ?></font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="left"><font color="#000000"><?php echo $f1; ?></font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="right"><font color="#000000">KPPH</font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="left"><font color="#000000"><?php echo $f2; ?></font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="right"><font color="#000000">KPPH</font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="left"><font color="#000000"><?php echo $f3; ?></font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="right"><font color="#000000">KPPH</font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="left"><font color="#000000"><?php echo $f4; ?></font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="right"><font color="#000000">KPPH</font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="left"><font color="#000000"><?php echo $f5; ?></font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="right"><font color="#000000">KPPH</font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="left"><font color="#000000"><?php echo $f6; ?></font></td>
|
||||
<td width="6.6%" id="vtitle" bgcolor="#FFFFFF" align="right"><font color="#000000">KPPH</font></td>
|
||||
</tr>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$i++;
|
||||
}
|
||||
?>
|
||||
172
includes/control-logger.php
Normal file
172
includes/control-logger.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/db.php';
|
||||
|
||||
if (!function_exists('control_log_write')) {
|
||||
/**
|
||||
* Persist a control write audit entry into the configured log store.
|
||||
*
|
||||
* @param array<string, mixed> $entry
|
||||
*
|
||||
* @return array{success:bool, driver:?string, error:?string, path:?string}
|
||||
*/
|
||||
function control_log_write(array $entry): array
|
||||
{
|
||||
static $tableName;
|
||||
static $fallbackPath;
|
||||
/** @var array<string, array<int, string>> $columnsCache */
|
||||
static $columnsCache = [];
|
||||
|
||||
$result = [
|
||||
'success' => false,
|
||||
'driver' => null,
|
||||
'error' => null,
|
||||
'path' => null,
|
||||
];
|
||||
|
||||
$settings = include __DIR__ . '/../config/control-settings.php';
|
||||
|
||||
if ($tableName === null) {
|
||||
$configuredTable = $settings['log_table'] ?? null;
|
||||
|
||||
if (!is_string($configuredTable) || trim($configuredTable) === '') {
|
||||
$result['error'] = 'Control log table name is not configured.';
|
||||
error_log('Control write log insert failed: ' . $result['error']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
$tableName = trim($configuredTable);
|
||||
}
|
||||
|
||||
if ($fallbackPath === null) {
|
||||
$configuredFallback = $settings['log_fallback_path'] ?? '';
|
||||
if (is_string($configuredFallback) && trim($configuredFallback) !== '') {
|
||||
$fallbackPath = $configuredFallback;
|
||||
} else {
|
||||
$fallbackPath = '';
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$connection = controls_db_connect();
|
||||
$tableKey = $tableName;
|
||||
|
||||
if (!isset($columnsCache[$tableKey])) {
|
||||
$tableEscaped = $connection->real_escape_string($tableName);
|
||||
$columnsResult = $connection->query('SHOW COLUMNS FROM `' . $tableEscaped . '`');
|
||||
|
||||
if ($columnsResult === false) {
|
||||
throw new RuntimeException('Unable to determine columns for control write log table.');
|
||||
}
|
||||
|
||||
$columns = [];
|
||||
while ($column = $columnsResult->fetch_assoc()) {
|
||||
if (isset($column['Field'])) {
|
||||
$columns[] = $column['Field'];
|
||||
}
|
||||
}
|
||||
|
||||
$columnsResult->free();
|
||||
$columnsCache[$tableKey] = $columns;
|
||||
}
|
||||
|
||||
$availableColumns = $columnsCache[$tableKey] ?? [];
|
||||
|
||||
if ($availableColumns === []) {
|
||||
throw new RuntimeException('No columns available on control write log table.');
|
||||
}
|
||||
|
||||
$insertData = [];
|
||||
foreach ($entry as $column => $value) {
|
||||
if (in_array($column, $availableColumns, true)) {
|
||||
$insertData[$column] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($insertData === []) {
|
||||
$result['error'] = 'None of the provided fields matched the log table columns.';
|
||||
error_log('Control write log insert skipped: ' . $result['error']);
|
||||
} else {
|
||||
$fields = [];
|
||||
$values = [];
|
||||
foreach ($insertData as $column => $value) {
|
||||
$fields[] = '`' . $connection->real_escape_string($column) . '`';
|
||||
|
||||
if ($value === null) {
|
||||
$values[] = 'NULL';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
$values[] = $value ? "'1'" : "'0'";
|
||||
continue;
|
||||
}
|
||||
|
||||
$values[] = "'" . $connection->real_escape_string((string) $value) . "'";
|
||||
}
|
||||
|
||||
$tableEscaped = $connection->real_escape_string($tableName);
|
||||
$sql = sprintf(
|
||||
'INSERT INTO `%s` (%s) VALUES (%s)',
|
||||
$tableEscaped,
|
||||
implode(', ', $fields),
|
||||
implode(', ', $values)
|
||||
);
|
||||
|
||||
$connection->query($sql);
|
||||
|
||||
$result['success'] = true;
|
||||
$result['driver'] = 'database';
|
||||
$result['error'] = null;
|
||||
return $result;
|
||||
}
|
||||
} catch (Throwable $exception) {
|
||||
$result['error'] = $exception->getMessage();
|
||||
error_log('Control write log insert failed: ' . $exception->getMessage());
|
||||
}
|
||||
|
||||
if ($fallbackPath === '') {
|
||||
return $result;
|
||||
}
|
||||
|
||||
try {
|
||||
$directory = dirname($fallbackPath);
|
||||
if ($directory !== '' && !is_dir($directory)) {
|
||||
if (!mkdir($directory, 0775, true) && !is_dir($directory)) {
|
||||
throw new RuntimeException('Unable to create fallback log directory: ' . $directory);
|
||||
}
|
||||
}
|
||||
|
||||
$record = [
|
||||
'timestamp' => gmdate('c'),
|
||||
'entry' => $entry,
|
||||
'error' => $result['error'],
|
||||
];
|
||||
|
||||
$json = json_encode($record, JSON_THROW_ON_ERROR);
|
||||
file_put_contents($fallbackPath, $json . PHP_EOL, FILE_APPEND | LOCK_EX);
|
||||
|
||||
$result['success'] = true;
|
||||
$result['driver'] = 'file';
|
||||
$result['path'] = $fallbackPath;
|
||||
|
||||
error_log('Control write log stored in fallback file: ' . $fallbackPath);
|
||||
} catch (Throwable $fallbackException) {
|
||||
$result['driver'] = 'none';
|
||||
$result['path'] = null;
|
||||
|
||||
$fallbackMessage = $fallbackException->getMessage();
|
||||
if ($result['error'] !== null) {
|
||||
$result['error'] .= '; ' . $fallbackMessage;
|
||||
} else {
|
||||
$result['error'] = $fallbackMessage;
|
||||
}
|
||||
|
||||
error_log('Control write log fallback failed: ' . $fallbackMessage);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
200
includes/control-tags.php
Normal file
200
includes/control-tags.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if (!function_exists('control_tags_raw')) {
|
||||
/**
|
||||
* Load the raw tag configuration array from config/control-tags.php.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
function control_tags_raw(): array
|
||||
{
|
||||
static $cache;
|
||||
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$configPath = __DIR__ . '/../config/control-tags.php';
|
||||
|
||||
if (!file_exists($configPath)) {
|
||||
throw new RuntimeException('Tag configuration file not found at config/control-tags.php');
|
||||
}
|
||||
|
||||
$data = include $configPath;
|
||||
|
||||
if (!is_array($data)) {
|
||||
throw new RuntimeException('Tag configuration file must return an array.');
|
||||
}
|
||||
|
||||
$cache = $data;
|
||||
|
||||
return $cache;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('control_tag_resolve_mode')) {
|
||||
/**
|
||||
* Resolve the control mode (numeric or boolean) for a tag configuration entry.
|
||||
*
|
||||
* @param array<string, mixed> $meta
|
||||
*/
|
||||
function control_tag_resolve_mode(array $meta): string
|
||||
{
|
||||
$modeHint = $meta['mode'] ?? $meta['control_mode'] ?? null;
|
||||
|
||||
if (is_string($modeHint)) {
|
||||
$normalized = strtolower(trim($modeHint));
|
||||
|
||||
if (in_array($normalized, ['boolean', 'bool', 'toggle', 'switch', 'binary', 'onoff'], true)) {
|
||||
return 'boolean';
|
||||
}
|
||||
|
||||
if (in_array($normalized, ['numeric', 'number', 'float', 'analog'], true)) {
|
||||
return 'numeric';
|
||||
}
|
||||
}
|
||||
|
||||
$typeHint = $meta['type'] ?? $meta['type_hint'] ?? null;
|
||||
|
||||
if (is_string($typeHint)) {
|
||||
$compact = preg_replace('/[^a-z0-9]+/', '', strtolower($typeHint)) ?? '';
|
||||
|
||||
foreach (['bool', 'boolean', 'binary', 'switch', 'toggle', 'onoff', 'startstop', 'runstop'] as $token) {
|
||||
if ($token !== '' && strpos($compact, $token) !== false) {
|
||||
return 'boolean';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 'numeric';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('control_tags_normalize')) {
|
||||
/**
|
||||
* Normalise and enrich the configured tags for convenient consumption.
|
||||
*
|
||||
* @return array<string, array<string, mixed>>
|
||||
*/
|
||||
function control_tags_normalize(): array
|
||||
{
|
||||
$raw = control_tags_raw();
|
||||
$normalised = [];
|
||||
|
||||
foreach ($raw as $rawId => $meta) {
|
||||
if (is_string($meta)) {
|
||||
$meta = ['name' => $meta];
|
||||
} elseif (!is_array($meta)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (array_key_exists('enabled', $meta) && !$meta['enabled']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidateId = is_string($rawId) && $rawId !== '' ? $rawId : (
|
||||
is_string($meta['id'] ?? null) ? $meta['id'] : (
|
||||
is_string($meta['tag'] ?? null) ? $meta['tag'] : null
|
||||
)
|
||||
);
|
||||
|
||||
if (!is_string($candidateId) || trim($candidateId) === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tagId = trim($candidateId);
|
||||
$name = isset($meta['name']) && is_string($meta['name']) && trim($meta['name']) !== ''
|
||||
? trim($meta['name'])
|
||||
: $tagId;
|
||||
|
||||
$typeLabel = isset($meta['type']) && is_string($meta['type']) && trim($meta['type']) !== ''
|
||||
? trim($meta['type'])
|
||||
: 'General';
|
||||
|
||||
$typeKey = strtolower(preg_replace('/[^a-z0-9]+/', '-', $typeLabel));
|
||||
$typeKey = $typeKey !== '' ? $typeKey : 'general';
|
||||
|
||||
$mode = control_tag_resolve_mode($meta);
|
||||
|
||||
$step = isset($meta['step']) && is_numeric($meta['step']) ? (float) $meta['step'] : null;
|
||||
$min = isset($meta['min']) && is_numeric($meta['min']) ? (float) $meta['min'] : null;
|
||||
$max = isset($meta['max']) && is_numeric($meta['max']) ? (float) $meta['max'] : null;
|
||||
|
||||
$precision = null;
|
||||
if (isset($meta['precision']) && is_numeric($meta['precision'])) {
|
||||
$precision = (int) $meta['precision'];
|
||||
} elseif (isset($meta['decimals']) && is_numeric($meta['decimals'])) {
|
||||
$precision = (int) $meta['decimals'];
|
||||
}
|
||||
|
||||
$normalised[$tagId] = [
|
||||
'id' => $tagId,
|
||||
'name' => $name,
|
||||
'type_label' => $typeLabel,
|
||||
'type_key' => $typeKey,
|
||||
'control_mode' => $mode,
|
||||
'control' => 1,
|
||||
'config' => $meta,
|
||||
'step' => $step,
|
||||
'min' => $min,
|
||||
'max' => $max,
|
||||
'precision' => $precision,
|
||||
'units' => isset($meta['units']) && is_string($meta['units']) ? trim($meta['units']) : null,
|
||||
'description' => isset($meta['description']) && is_string($meta['description'])
|
||||
? trim($meta['description'])
|
||||
: null,
|
||||
];
|
||||
}
|
||||
|
||||
uasort(
|
||||
$normalised,
|
||||
static function (array $left, array $right): int {
|
||||
$typeComparison = strcasecmp($left['type_label'], $right['type_label']);
|
||||
|
||||
if ($typeComparison !== 0) {
|
||||
return $typeComparison;
|
||||
}
|
||||
|
||||
return strcasecmp($left['name'], $right['name']);
|
||||
}
|
||||
);
|
||||
|
||||
return $normalised;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('control_tag_find')) {
|
||||
/**
|
||||
* Retrieve a single normalised tag definition by its identifier.
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
function control_tag_find(string $tagId): ?array
|
||||
{
|
||||
$tags = control_tags_normalize();
|
||||
|
||||
return $tags[$tagId] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('control_format_timestamp')) {
|
||||
/**
|
||||
* Format an ISO-8601 timestamp for display.
|
||||
*/
|
||||
function control_format_timestamp(?string $timestamp): ?string
|
||||
{
|
||||
if ($timestamp === null || $timestamp === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$date = new DateTimeImmutable($timestamp);
|
||||
} catch (Throwable $exception) {
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
return $date->format('M j, Y g:i:s A');
|
||||
}
|
||||
}
|
||||
29
includes/cropday.php
Normal file
29
includes/cropday.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
$serverName = "CBM2K12\SQLEXPRESS";
|
||||
$uid = "cbmclient";
|
||||
$pwd = "ascbm2k";
|
||||
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
|
||||
|
||||
/* Connect using SQL Server Authentication. */
|
||||
$conn = sqlsrv_connect( $serverName, $connectionInfo);
|
||||
if( $conn === false )
|
||||
{
|
||||
echo "Unable to connect.</br>";
|
||||
die( print_r( sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
$sql = "SELECT CropDay FROM Parameters";
|
||||
|
||||
$stmt = sqlsrv_query( $conn, $sql );
|
||||
if( $stmt === false) {
|
||||
die( print_r( sqlsrv_errors(), true) );
|
||||
}
|
||||
|
||||
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
|
||||
echo $row['CropDay'];
|
||||
}
|
||||
|
||||
sqlsrv_free_stmt( $stmt);
|
||||
sqlsrv_close( $conn);
|
||||
?>
|
||||
33
includes/db.php
Normal file
33
includes/db.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// phpcs:ignoreFile
|
||||
|
||||
require_once __DIR__ . '/../config.php';
|
||||
|
||||
/**
|
||||
* Create and return a new mysqli connection using the shared configuration.
|
||||
*
|
||||
* @return mysqli
|
||||
*/
|
||||
function controls_db_connect()
|
||||
{
|
||||
if (!defined('DB_HOST') || !defined('DB_USER') || !defined('DB_PASSWORD') || !defined('DB_DATABASE')) {
|
||||
$configPath = __DIR__ . '/../config.php';
|
||||
if (file_exists($configPath)) {
|
||||
require $configPath;
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined('DB_HOST') || !defined('DB_USER') || !defined('DB_PASSWORD') || !defined('DB_DATABASE')) {
|
||||
throw new RuntimeException('Database configuration constants are not defined.');
|
||||
}
|
||||
|
||||
if (!function_exists('mysqli_report')) {
|
||||
throw new RuntimeException('The mysqli extension is not available.');
|
||||
}
|
||||
|
||||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
|
||||
$connection = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
|
||||
$connection->set_charset('utf8mb4');
|
||||
|
||||
return $connection;
|
||||
}
|
||||
6
includes/dbinfo.php
Normal file
6
includes/dbinfo.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
$host="192.168.0.10";
|
||||
$username="corey";
|
||||
$password="41945549";
|
||||
$database="controls";
|
||||
?>
|
||||
6
includes/dbinfo2.php
Normal file
6
includes/dbinfo2.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
$host="192.168.0.9";
|
||||
$username="corey";
|
||||
$password="41945549";
|
||||
$database="controls";
|
||||
?>
|
||||
6
includes/dbinfo3.php
Normal file
6
includes/dbinfo3.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
$host="192.168.0.16";
|
||||
$username="corey";
|
||||
$password="41945549";
|
||||
$database="controls";
|
||||
?>
|
||||
19
includes/dumptimen.php
Normal file
19
includes/dumptimen.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT TIMEDIFF ((SELECT date FROM plc GROUP BY totnorth ORDER BY id DESC LIMIT 1),(SELECT date FROM plc GROUP BY totnorth ORDER BY id DESC LIMIT 1, 1)) AS time";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include2=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
<?php echo $include2['time']; ?>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
19
includes/dumptimes.php
Normal file
19
includes/dumptimes.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT TIMEDIFF ((SELECT date FROM plc GROUP BY totsouth ORDER BY id DESC LIMIT 1),(SELECT date FROM plc GROUP BY totsouth ORDER BY id DESC LIMIT 1, 1)) AS time";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
<?php echo $include4['time']; ?>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
19
includes/dumptimew2.php
Normal file
19
includes/dumptimew2.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT TIMEDIFF ((SELECT date FROM plc GROUP BY totwest2 ORDER BY id DESC LIMIT 1),(SELECT date FROM plc GROUP BY totwest2 ORDER BY id DESC LIMIT 1, 1)) AS time";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include2=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
<?php echo $include2['time']; ?>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
15
includes/east15minavg.php
Normal file
15
includes/east15minavg.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT ((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 899, 1))*4 AS eastavg";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['eastavg']); ?>
|
||||
|
||||
14
includes/easttotal.php
Normal file
14
includes/easttotal.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT DISTINCT EastTotal FROM mill_ytd_totals ORDER BY ID DESC LIMIT 1";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include1['EastTotal']); ?>
|
||||
52
includes/heaters.php
Normal file
52
includes/heaters.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
require "itemsAI.php";
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td colspan="4" id="title">Shell & Heater Tubes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1" width="30%"></a></td>
|
||||
<td id="vtitle" id="padded">Temp:</a></td>
|
||||
<td id="vtitle" id="padded">Setpoint:</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1" width="40%">Heater 1:</a></td>
|
||||
<td id="sum-count"><?php echo $ID['0000344']; ?></td>
|
||||
<td id="vtitle"><?php echo $value['TubeHeater1SP']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1">Heater 2:</a></td>
|
||||
<td id="sum-count"><?php echo $rounded['TubeHeater2Temp']; ?></td>
|
||||
<td id="vtitle"><?php echo $value['TubeHeater2SP']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1">Heater 3:</a></td>
|
||||
<td id="sum-count"><?php echo $rounded['TubeHeater3Temp']; ?></td>
|
||||
<td id="vtitle"><?php echo $value['TubeHeater3SP']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1">Heater 4:</a></td>
|
||||
<td id="sum-count"><?php echo $rounded['TubeHeater4Temp']; ?></td>
|
||||
<td id="vtitle"><?php echo $value['TubeHeater4SP']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1">Heater 5:</a></td>
|
||||
<td id="sum-count"><?php echo $rounded['TubeHeater5Temp']; ?></td>
|
||||
<td id="vtitle"><?php echo $value['TubeHeater5SP']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1">Heater 6:</a></td>
|
||||
<td id="sum-count"><?php echo $rounded['TubeHeater6Temp']; ?></td>
|
||||
<td id="vtitle"><?php echo $value['TubeHeater6SP']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded" colspan="1">Heater 7:</a></td>
|
||||
<td id="sum-count"><?php echo $rounded['TubeHeater7Temp']; ?></td>
|
||||
<td id="vtitle"><?php echo $value['TubeHeater7SP']; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="vtitle" id="padded">Heater 8:</a></td>
|
||||
<td id="sum-count"><?php echo $rounded['TubeHeater8TempPV']; ?></td>
|
||||
<td id="sum-count"><?php echo $value['TubeHeater8TempSP']; ?></td>
|
||||
</tr>
|
||||
17
includes/heatersp1.php
Normal file
17
includes/heatersp1.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000638'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/heatersp2.php
Normal file
17
includes/heatersp2.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000636'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/heatersp3.php
Normal file
17
includes/heatersp3.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000634'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/heatersp4.php
Normal file
17
includes/heatersp4.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000632'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/heatersp5.php
Normal file
17
includes/heatersp5.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000630'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/heatersp6.php
Normal file
17
includes/heatersp6.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000628'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/heatersp7.php
Normal file
17
includes/heatersp7.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000626'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/heatersp8.php
Normal file
17
includes/heatersp8.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
include("../dbinfo3.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT Value FROM items where ID = '0000624'";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php
|
||||
$rawValue = isset($include1['Value']) ? (float) $include1['Value'] : 0.0;
|
||||
echo round($rawValue, 2);
|
||||
?>
|
||||
17
includes/items.php
Normal file
17
includes/items.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
$con=mysqli_connect('192.168.0.10', 'corey', '41945549', 'controls');
|
||||
$query="SELECT ID, Name, ROUND(Value, 0) AS Value, ROUND(Value, 1) AS RoundedValue1, ROUND(Value, 2) AS RoundedValue, Timestamp FROM items ORDER BY ID ASC";
|
||||
$result=mysqli_query($con, $query);
|
||||
|
||||
mysqli_close($con);
|
||||
|
||||
while ($row=mysqli_fetch_array($result, MYSQLI_ASSOC)) {
|
||||
$value[$row['Name']] = $row['Value'];
|
||||
$rounded[$row['Name']] = $row['RoundedValue'];
|
||||
$time[$row['Name']] = $row['Timestamp'];
|
||||
$ID[$row['ID']] = $row['Value'];
|
||||
$roundedid[$row['ID']] = $row['RoundedValue'];
|
||||
$rounded1[$row['ID']] = $row['RoundedValue1'];
|
||||
$rounded1[$row['Name']] = $row['RoundedValue1'];
|
||||
}
|
||||
?>
|
||||
13
includes/items2dec.php
Normal file
13
includes/items2dec.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
$con=mysqli_connect('192.168.0.10', 'corey', '41945549', 'controls');
|
||||
$query="SELECT ID, Name, ROUND(Value, 2) AS Value, Timestamp FROM items ORDER BY ID ASC";
|
||||
$result=mysqli_query($con, $query);
|
||||
|
||||
mysqli_close($con);
|
||||
|
||||
while ($row=mysqli_fetch_array($result, MYSQLI_ASSOC)) {
|
||||
$value[$row['Name']] = $row['Value'];
|
||||
$time[$row['Name']] = $row['Timestamp'];
|
||||
$ID[$row['ID']] = $row['Value'];
|
||||
}
|
||||
?>
|
||||
17
includes/itemsAI.php
Normal file
17
includes/itemsAI.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
$con=mysqli_connect('192.168.0.16', 'corey', '41945549', 'controls');
|
||||
$query="SELECT ID, Name, ROUND(Value, 0) AS Value, ROUND(Value, 1) AS RoundedValue1, ROUND(Value, 2) AS RoundedValue, Timestamp FROM items ORDER BY ID ASC";
|
||||
$result=mysqli_query($con, $query);
|
||||
|
||||
mysqli_close($con);
|
||||
|
||||
while ($row=mysqli_fetch_array($result, MYSQLI_ASSOC)) {
|
||||
$value[$row['Name']] = $row['Value'];
|
||||
$rounded[$row['Name']] = $row['RoundedValue'];
|
||||
$time[$row['Name']] = $row['Timestamp'];
|
||||
$ID[$row['ID']] = $row['Value'];
|
||||
$roundedid[$row['ID']] = $row['RoundedValue'];
|
||||
$rounded1[$row['ID']] = $row['RoundedValue1'];
|
||||
$rounded1[$row['Name']] = $row['RoundedValue1'];
|
||||
}
|
||||
?>
|
||||
12
includes/itemsinclude.php
Normal file
12
includes/itemsinclude.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
$con=mysqli_connect('192.168.0.10', 'corey', '41945549', 'controls');
|
||||
$query="SELECT ID, Name, ROUND(Value, 2) AS Value, Timestamp FROM items ORDER BY ID ASC";
|
||||
$result=mysqli_query($con, $query);
|
||||
|
||||
while ($row=mysqli_fetch_array($result, MYSQLI_ASSOC)) {
|
||||
$value[$row['Name']] = $row['Value'];
|
||||
$time[$row['Name']] = $row['Timestamp'];
|
||||
}
|
||||
echo $value['FD Temp'];
|
||||
echo $time['FD Temp'];
|
||||
?>
|
||||
238
includes/kepware-rest.php
Normal file
238
includes/kepware-rest.php
Normal file
@@ -0,0 +1,238 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../config/control-settings.php';
|
||||
|
||||
/**
|
||||
* Procedural helper functions for talking to the Kepware IoT Gateway REST API.
|
||||
*/
|
||||
|
||||
if (!function_exists('kepware_config')) {
|
||||
/**
|
||||
* Retrieve Kepware REST configuration values.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
function kepware_config(): array
|
||||
{
|
||||
static $config;
|
||||
|
||||
if ($config === null) {
|
||||
$settings = include __DIR__ . '/../config/control-settings.php';
|
||||
$config = $settings['kepware'] ?? [];
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('kepware_rest_request')) {
|
||||
/**
|
||||
* Issue an HTTP request to the Kepware REST server.
|
||||
*
|
||||
* @param string $method HTTP verb (GET, POST, ...).
|
||||
* @param string $path Relative REST path.
|
||||
* @param array<string, mixed>|null $body Optional JSON payload.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
function kepware_rest_request(string $method, string $path, ?array $body = null): array
|
||||
{
|
||||
$config = kepware_config();
|
||||
$baseUrl = rtrim((string) ($config['base_url'] ?? ''), '/');
|
||||
if ($baseUrl === '') {
|
||||
throw new RuntimeException('Kepware base URL is not configured.');
|
||||
}
|
||||
|
||||
$url = $baseUrl . '/' . ltrim($path, '/');
|
||||
$username = (string) ($config['username'] ?? '');
|
||||
$password = (string) ($config['password'] ?? '');
|
||||
$timeout = (float) ($config['timeout'] ?? 5.0);
|
||||
$verify = (bool) ($config['verify_tls'] ?? false);
|
||||
$attempts = (int) ($config['retry_attempts'] ?? 1);
|
||||
if ($attempts < 1) {
|
||||
$attempts = 1;
|
||||
}
|
||||
|
||||
$retryDelay = (float) ($config['retry_delay'] ?? 0.0);
|
||||
if ($retryDelay < 0) {
|
||||
$retryDelay = 0.0;
|
||||
}
|
||||
|
||||
$postFields = null;
|
||||
if ($body !== null) {
|
||||
$postFields = json_encode($body, JSON_THROW_ON_ERROR);
|
||||
}
|
||||
|
||||
$options = [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_CUSTOMREQUEST => strtoupper($method),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_USERPWD => $username . ':' . $password,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/json',
|
||||
'Accept: application/json',
|
||||
],
|
||||
CURLOPT_TIMEOUT => $timeout,
|
||||
CURLOPT_CONNECTTIMEOUT => $timeout,
|
||||
CURLOPT_SSL_VERIFYPEER => $verify,
|
||||
CURLOPT_SSL_VERIFYHOST => $verify ? 2 : 0,
|
||||
];
|
||||
|
||||
if ($postFields !== null) {
|
||||
$options[CURLOPT_POSTFIELDS] = $postFields;
|
||||
}
|
||||
|
||||
$retryableCurlErrors = [
|
||||
CURLE_COULDNT_CONNECT,
|
||||
CURLE_COULDNT_RESOLVE_HOST,
|
||||
CURLE_COULDNT_RESOLVE_PROXY,
|
||||
CURLE_GOT_NOTHING,
|
||||
CURLE_OPERATION_TIMEDOUT,
|
||||
CURLE_PARTIAL_FILE,
|
||||
CURLE_RECV_ERROR,
|
||||
CURLE_SEND_ERROR,
|
||||
CURLE_SSL_CONNECT_ERROR,
|
||||
];
|
||||
|
||||
for ($attempt = 1; $attempt <= $attempts; $attempt++) {
|
||||
$handle = curl_init();
|
||||
if ($handle === false) {
|
||||
throw new RuntimeException('Unable to initialise cURL for Kepware request.');
|
||||
}
|
||||
|
||||
curl_setopt_array($handle, $options);
|
||||
|
||||
$response = curl_exec($handle);
|
||||
$error = curl_error($handle);
|
||||
$errno = curl_errno($handle);
|
||||
$status = (int) curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
||||
curl_close($handle);
|
||||
|
||||
if ($response === false) {
|
||||
$shouldRetry = in_array($errno, $retryableCurlErrors, true) && $attempt < $attempts;
|
||||
if ($shouldRetry) {
|
||||
error_log(sprintf(
|
||||
'Kepware request to %s attempt %d failed with cURL error %d: %s. Retrying in %.2f seconds.',
|
||||
$path,
|
||||
$attempt,
|
||||
$errno,
|
||||
$error,
|
||||
$retryDelay
|
||||
));
|
||||
|
||||
if ($retryDelay > 0.0) {
|
||||
usleep((int) round($retryDelay * 1_000_000));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new RuntimeException('Kepware request failed: ' . $error, $errno);
|
||||
}
|
||||
|
||||
$decoded = json_decode($response, true);
|
||||
if (!is_array($decoded)) {
|
||||
$snippet = substr($response, 0, 200);
|
||||
error_log('Kepware returned a non-JSON payload: ' . $snippet);
|
||||
|
||||
if ($attempt < $attempts) {
|
||||
if ($retryDelay > 0.0) {
|
||||
usleep((int) round($retryDelay * 1_000_000));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new RuntimeException('Invalid JSON response from Kepware: ' . $snippet);
|
||||
}
|
||||
|
||||
if ($status >= 400) {
|
||||
if ($status >= 500 && $status < 600 && $attempt < $attempts) {
|
||||
error_log(sprintf(
|
||||
'Kepware request to %s attempt %d returned HTTP %d. Retrying in %.2f seconds.',
|
||||
$path,
|
||||
$attempt,
|
||||
$status,
|
||||
$retryDelay
|
||||
));
|
||||
|
||||
if ($retryDelay > 0.0) {
|
||||
usleep((int) round($retryDelay * 1_000_000));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new RuntimeException('Kepware request error (HTTP ' . $status . ').');
|
||||
}
|
||||
|
||||
if ($attempt > 1) {
|
||||
error_log(sprintf('Kepware request to %s succeeded on attempt %d.', $path, $attempt));
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
throw new RuntimeException('Kepware request failed after ' . $attempts . ' attempts.');
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('kepware_read')) {
|
||||
/**
|
||||
* Read tag values from Kepware.
|
||||
*
|
||||
* @param string[] $tagIds List of tag identifiers.
|
||||
*
|
||||
* @return array<string, array<string, mixed>>
|
||||
*/
|
||||
function kepware_read(array $tagIds): array
|
||||
{
|
||||
if ($tagIds === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$query = http_build_query(['ids' => implode(',', $tagIds)]);
|
||||
$payload = kepware_rest_request('GET', 'read?' . $query);
|
||||
|
||||
$results = [];
|
||||
foreach ($payload['readResults'] ?? [] as $result) {
|
||||
if (!isset($result['id'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$results[$result['id']] = [
|
||||
'value' => $result['v'] ?? null,
|
||||
'timestamp' => $result['t'] ?? null,
|
||||
'status' => $result['s'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('kepware_write')) {
|
||||
/**
|
||||
* Write tag values via Kepware.
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $writeRequest
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
function kepware_write(array $writeRequest): array
|
||||
{
|
||||
if ($writeRequest === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$payload = kepware_rest_request('POST', 'write', $writeRequest);
|
||||
|
||||
if (isset($payload['writeResults']) && is_array($payload['writeResults'])) {
|
||||
return $payload['writeResults'];
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
}
|
||||
14
includes/layout/footer.php
Normal file
14
includes/layout/footer.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php // phpcs:ignoreFile ?>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="app-footer">
|
||||
<div class="app-footer__inner">
|
||||
<p>© <?php echo date('Y'); ?> Louisiana Sugarcane Cooperative, Inc. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
<button type="button" data-back-to-top aria-label="Back to top">Top</button>
|
||||
</div>
|
||||
<script src="<?php echo htmlspecialchars($assetBasePath ?? ''); ?>assets/js/mobile-header.js?v=<?php echo rawurlencode($assetVersion ?? '2025.10.02'); ?>" defer></script>
|
||||
<script src="<?php echo htmlspecialchars($assetBasePath ?? ''); ?>assets/js/refresh.js?v=<?php echo rawurlencode($assetVersion ?? '2025.10.02'); ?>" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
88
includes/layout/header.php
Normal file
88
includes/layout/header.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
|
||||
$pageTitle = $pageTitle ?? 'LASUCA Controls';
|
||||
$pageSubtitle = $pageSubtitle ?? 'Real-time operations dashboard';
|
||||
$pageDescription = $pageDescription ?? 'Monitoring suite for mill, boilers, and fabrication systems.';
|
||||
$layoutWithoutSidebar = $layoutWithoutSidebar ?? false;
|
||||
$layoutReturnUrl = $layoutReturnUrl ?? null;
|
||||
$layoutReturnLabel = $layoutReturnLabel ?? 'Back to overview';
|
||||
$layoutCloseWindowLabel = $layoutCloseWindowLabel ?? null;
|
||||
$shellClasses = 'app-shell' . ($layoutWithoutSidebar ? ' app-shell--no-sidebar' : '');
|
||||
$assetVersion = $assetVersion ?? '2025.10.06.3';
|
||||
$assetBasePath = $assetBasePath ?? '';
|
||||
if ($assetBasePath !== '' && substr($assetBasePath, -1) !== '/') {
|
||||
$assetBasePath .= '/';
|
||||
}
|
||||
|
||||
// Fetch crop day stats for header display
|
||||
$headerCropDay = null;
|
||||
$headerPassedHours = null;
|
||||
$headerRemainingHours = null;
|
||||
|
||||
$cropDayFile = __DIR__ . '/../../includes/cropday.php';
|
||||
$passedHoursFile = __DIR__ . '/../../includes/passedhours.php';
|
||||
$remainingHoursFile = __DIR__ . '/../../includes/remaininghours.php';
|
||||
|
||||
if (is_file($cropDayFile)) {
|
||||
ob_start();
|
||||
include $cropDayFile;
|
||||
$headerCropDay = trim(ob_get_clean());
|
||||
}
|
||||
if (is_file($passedHoursFile)) {
|
||||
ob_start();
|
||||
include $passedHoursFile;
|
||||
$headerPassedHours = trim(ob_get_clean());
|
||||
}
|
||||
if (is_file($remainingHoursFile)) {
|
||||
ob_start();
|
||||
include $remainingHoursFile;
|
||||
$headerRemainingHours = trim(ob_get_clean());
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="<?php echo htmlspecialchars($pageDescription); ?>">
|
||||
<title><?php echo htmlspecialchars($pageTitle); ?> | LASUCA Controls</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="<?php echo htmlspecialchars($assetBasePath); ?>style.css?v=<?php echo rawurlencode($assetVersion); ?>">
|
||||
</head>
|
||||
<body>
|
||||
<div class="<?php echo $shellClasses; ?>">
|
||||
<header class="app-header">
|
||||
<div class="app-header__inner">
|
||||
<div class="branding">
|
||||
<h1><?php echo htmlspecialchars($pageTitle); ?></h1>
|
||||
<?php if (!empty($pageSubtitle)) : ?>
|
||||
<p><?php echo htmlspecialchars($pageSubtitle); ?></p>
|
||||
<?php endif; ?>
|
||||
<div class="header-stats">
|
||||
<span class="header-stat"><strong>Crop Day:</strong> <?php echo $headerCropDay ?: '—'; ?></span>
|
||||
<span class="header-stat"><strong>Hours Passed:</strong> <?php echo $headerPassedHours ? number_format((float)$headerPassedHours, 1) : '—'; ?></span>
|
||||
<span class="header-stat"><strong>Hours Remaining:</strong> <?php echo $headerRemainingHours ? number_format((float)$headerRemainingHours, 1) : '—'; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<?php include __DIR__ . '/../../darkmode.php'; ?>
|
||||
<?php if ($layoutWithoutSidebar && $layoutCloseWindowLabel) : ?>
|
||||
<button type="button" class="button button--ghost" onclick="window.close();">
|
||||
<?php echo htmlspecialchars($layoutCloseWindowLabel); ?>
|
||||
</button>
|
||||
<?php elseif ($layoutWithoutSidebar && $layoutReturnUrl) : ?>
|
||||
<a class="button button--ghost" href="<?php echo htmlspecialchars($layoutReturnUrl); ?>">
|
||||
← <?php echo htmlspecialchars($layoutReturnLabel); ?>
|
||||
</a>
|
||||
<?php elseif (!$layoutWithoutSidebar) : ?>
|
||||
<button type="button" data-menu-toggle aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span aria-hidden="true">☰</span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="app-layout">
|
||||
<div class="app-layout__inner">
|
||||
17
includes/legacy/items.php
Normal file
17
includes/legacy/items.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
|
||||
$con = mysqli_connect('192.168.0.10', 'corey', '41945549', 'controls');
|
||||
$query = "SELECT ID, Name, ROUND(Value, 0) AS Value, ROUND(Value, 1) AS RoundedValue1, ROUND(Value, 2) AS RoundedValue, Timestamp FROM items ORDER BY ID ASC";
|
||||
$result = mysqli_query($con, $query);
|
||||
|
||||
mysqli_close($con);
|
||||
|
||||
while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
|
||||
$value[$row['Name']] = $row['Value'];
|
||||
$rounded[$row['Name']] = $row['RoundedValue'];
|
||||
$time[$row['Name']] = $row['Timestamp'];
|
||||
$ID[$row['ID']] = $row['Value'];
|
||||
$roundedid[$row['ID']] = $row['RoundedValue'];
|
||||
$rounded1[$row['ID']] = $row['RoundedValue1'];
|
||||
$rounded1[$row['Name']] = $row['RoundedValue1'];
|
||||
}
|
||||
150
includes/log_query.php
Normal file
150
includes/log_query.php
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
/**
|
||||
* Query logging helper for NL2SQL few-shot seeding.
|
||||
*
|
||||
* Usage:
|
||||
* require_once __DIR__ . '/includes/log_query.php';
|
||||
* logControlsQuery($userQuery, $sqlTemplate, $params, $sourceForm, $executionMs, $rowCount);
|
||||
*/
|
||||
|
||||
// Logging database connection (separate from historian)
|
||||
function getLoggingPdo(): ?PDO
|
||||
{
|
||||
static $pdo = null;
|
||||
|
||||
if ($pdo !== null) {
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
$servername = '192.168.0.16';
|
||||
$username = 'lasucaai';
|
||||
$password = 'is413#dfslw';
|
||||
$dbname = 'lasucaai';
|
||||
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"sqlsrv:Server=$servername;Database=$dbname",
|
||||
$username,
|
||||
$password,
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]
|
||||
);
|
||||
return $pdo;
|
||||
} catch (PDOException $e) {
|
||||
error_log('getLoggingPdo connection error: ' . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a query to dbo.controls_query_log for NL2SQL training.
|
||||
*
|
||||
* @param string $userQuery Natural-language description of the search.
|
||||
* @param string $sqlTemplate Parameterized SQL with placeholders.
|
||||
* @param array|null $params Associative array of parameter values.
|
||||
* @param string|null $sourceForm Originating form identifier.
|
||||
* @param int|null $executionMs Query runtime in milliseconds.
|
||||
* @param int|null $rowCount Number of rows returned.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function logControlsQuery(
|
||||
string $userQuery,
|
||||
string $sqlTemplate,
|
||||
?array $params = null,
|
||||
?string $sourceForm = null,
|
||||
?int $executionMs = null,
|
||||
?int $rowCount = null
|
||||
): bool {
|
||||
// Silently skip if inputs are empty
|
||||
if (trim($userQuery) === '' || trim($sqlTemplate) === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$pdo = getLoggingPdo();
|
||||
if ($pdo === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = "
|
||||
INSERT INTO dbo.controls_query_log
|
||||
(user_query, sql_template, params, source_form, user_session, execution_ms, row_count)
|
||||
VALUES
|
||||
(:user_query, :sql_template, :params, :source_form, :user_session, :execution_ms, :row_count)
|
||||
";
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$result = $stmt->execute([
|
||||
':user_query' => mb_substr($userQuery, 0, 1000),
|
||||
':sql_template' => $sqlTemplate,
|
||||
':params' => $params !== null ? json_encode($params, JSON_UNESCAPED_UNICODE) : null,
|
||||
':source_form' => $sourceForm,
|
||||
':user_session' => session_id() ?: null,
|
||||
':execution_ms' => $executionMs,
|
||||
':row_count' => $rowCount,
|
||||
]);
|
||||
return $result;
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a natural-language description from form inputs.
|
||||
*
|
||||
* @param string $searchType 'single_name' or 'multiple_names'.
|
||||
* @param string $searchName Single tag name (if applicable).
|
||||
* @param array $selectedTags Array of tag names for multi-tag search.
|
||||
* @param string $startDate Start datetime string.
|
||||
* @param string $endDate End datetime string.
|
||||
* @param int $limit Row limit.
|
||||
* @param int $timeInterval Sampling interval in seconds.
|
||||
* @return string Human-readable query description.
|
||||
*/
|
||||
function buildUserQueryDescription(
|
||||
string $searchType,
|
||||
string $searchName,
|
||||
array $selectedTags,
|
||||
string $startDate,
|
||||
string $endDate,
|
||||
int $limit,
|
||||
int $timeInterval
|
||||
): string {
|
||||
$parts = [];
|
||||
|
||||
// Tag(s)
|
||||
if ($searchType === 'single_name' && $searchName !== '') {
|
||||
$parts[] = "Show data for tag \"{$searchName}\"";
|
||||
} elseif ($searchType === 'multiple_names' && !empty($selectedTags)) {
|
||||
$tagList = implode(', ', array_map(fn($t) => "\"{$t}\"", $selectedTags));
|
||||
$parts[] = "Compare tags {$tagList}";
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Date range
|
||||
if ($startDate !== '' && $endDate !== '') {
|
||||
$parts[] = "from {$startDate} to {$endDate}";
|
||||
} elseif ($startDate !== '') {
|
||||
$parts[] = "starting from {$startDate}";
|
||||
} elseif ($endDate !== '') {
|
||||
$parts[] = "up until {$endDate}";
|
||||
}
|
||||
|
||||
// Sampling
|
||||
if ($timeInterval > 1) {
|
||||
if ($timeInterval >= 60) {
|
||||
$minutes = (int) ($timeInterval / 60);
|
||||
$parts[] = "sampled every {$minutes} minute" . ($minutes > 1 ? 's' : '');
|
||||
} else {
|
||||
$parts[] = "sampled every {$timeInterval} seconds";
|
||||
}
|
||||
}
|
||||
|
||||
// Limit
|
||||
$parts[] = "limit {$limit} rows";
|
||||
|
||||
return implode(' ', $parts);
|
||||
}
|
||||
62
includes/millingprojeced60min_test.php
Normal file
62
includes/millingprojeced60min_test.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
include '../dbinfo.php';
|
||||
include '../dbinfo2.php';
|
||||
|
||||
$con = mysqli_connect('192.168.0.10', 'corey', '41945549', 'controls');
|
||||
|
||||
// Second connection for west mill data (dbinfo2.php)
|
||||
$con2 = mysqli_connect('192.168.0.9', 'corey', '41945549', 'controls');
|
||||
|
||||
function fetchLatestAndHourAgo(mysqli $con, string $table, string $column): ?array
|
||||
{
|
||||
$sql = "
|
||||
SELECT $column AS value, timestamp
|
||||
FROM $table
|
||||
ORDER BY id DESC
|
||||
LIMIT 3600
|
||||
";
|
||||
$result = mysqli_query($con, $sql);
|
||||
if (!$result) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
|
||||
if (count($rows) === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$latest = $rows[0];
|
||||
$hourAgo = $rows[min(count($rows) - 1, 3599)]; // fall back if fewer than 3600 rows
|
||||
|
||||
return [
|
||||
'latest' => (float) $latest['value'],
|
||||
'hourAgo' => (float) $hourAgo['value'],
|
||||
'elapsedH' => max(
|
||||
1,
|
||||
(strtotime($latest['timestamp']) - strtotime($hourAgo['timestamp'])) / 3600
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
$east = fetchLatestAndHourAgo($con, 'easttotalground', 'easttotground');
|
||||
$west = $con2 ? fetchLatestAndHourAgo($con2, 'westtotalground', 'MODBUSENET_TABLE900_WTOTGROUND_VALUE') : null;
|
||||
|
||||
$totalToday = (float) mysqli_fetch_column(mysqli_query(
|
||||
$con,
|
||||
"SELECT MillTotalGround FROM mill_total_ground ORDER BY id DESC LIMIT 1"
|
||||
));
|
||||
|
||||
mysqli_close($con);
|
||||
if ($con2) {
|
||||
mysqli_close($con2);
|
||||
}
|
||||
|
||||
$hoursSinceFive = (time() < strtotime('5:00'))
|
||||
? (time() + 86400 - strtotime('5:00')) / 3600
|
||||
: (time() - strtotime('5:00')) / 3600;
|
||||
$hoursRemaining = max(0, 24 - $hoursSinceFive);
|
||||
|
||||
$eastProjected = $east ? ($east['latest'] - $east['hourAgo']) / $east['elapsedH'] * $hoursRemaining : 0;
|
||||
$westProjected = $west ? ($west['latest'] - $west['hourAgo']) / $west['elapsedH'] * $hoursRemaining : 0;
|
||||
|
||||
echo number_format($totalToday + $eastProjected + $westProjected, 0);
|
||||
80
includes/millnames.php
Normal file
80
includes/millnames.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php // phpcs:ignoreFile
|
||||
/**
|
||||
* Mill Names Helper - Functions to retrieve mill display names
|
||||
*
|
||||
* Usage:
|
||||
* require_once __DIR__ . '/millnames.php';
|
||||
* $millNames = getMillNames($conn); // Pass existing sqlsrv connection
|
||||
* $displayName = getMillDisplayName($millNames, 'EastMill'); // Returns 'East Mill' or original
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get all active mill names from the lookup table
|
||||
*
|
||||
* @param resource $conn SQL Server connection
|
||||
* @return array Associative array: mill_code => display_name
|
||||
*/
|
||||
function getMillNames($conn) {
|
||||
$sql = "SELECT mill_code, display_name FROM mill_names WHERE is_active = 1 ORDER BY sort_order";
|
||||
$result = sqlsrv_query($conn, $sql);
|
||||
|
||||
$names = [];
|
||||
if ($result) {
|
||||
while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
|
||||
$names[$row['mill_code']] = $row['display_name'];
|
||||
}
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display name for a mill code, with fallback to original code
|
||||
*
|
||||
* @param array $millNames Array from getMillNames()
|
||||
* @param string $millCode The raw mill code from data
|
||||
* @return string Display name or original code if not found
|
||||
*/
|
||||
function getMillDisplayName($millNames, $millCode) {
|
||||
return isset($millNames[$millCode]) ? $millNames[$millCode] : $millCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all mill names including inactive ones
|
||||
*
|
||||
* @param resource $conn SQL Server connection
|
||||
* @return array Full rows with all columns
|
||||
*/
|
||||
function getAllMillNames($conn) {
|
||||
$sql = "SELECT * FROM mill_names ORDER BY sort_order, mill_code";
|
||||
$result = sqlsrv_query($conn, $sql);
|
||||
|
||||
$names = [];
|
||||
if ($result) {
|
||||
while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
|
||||
$names[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sort order for a mill code (for ordering display)
|
||||
*
|
||||
* @param resource $conn SQL Server connection
|
||||
* @return array Associative array: mill_code => sort_order
|
||||
*/
|
||||
function getMillSortOrders($conn) {
|
||||
$sql = "SELECT mill_code, sort_order FROM mill_names WHERE is_active = 1 ORDER BY sort_order";
|
||||
$result = sqlsrv_query($conn, $sql);
|
||||
|
||||
$orders = [];
|
||||
if ($result) {
|
||||
while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
|
||||
$orders[$row['mill_code']] = $row['sort_order'];
|
||||
}
|
||||
}
|
||||
|
||||
return $orders;
|
||||
}
|
||||
24
includes/millprojected.php
Normal file
24
includes/millprojected.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT (SELECT milltotalground FROM mill_total_ground ORDER BY id DESC LIMIT 1) /
|
||||
(SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600 AS hours)
|
||||
*24
|
||||
AS millprojected";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['millprojected']); ?>
|
||||
|
||||
39
includes/millprojected15min.php
Normal file
39
includes/millprojected15min.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT ROUND(
|
||||
(((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 899, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600))))
|
||||
+
|
||||
(((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 899, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600)))))*4
|
||||
+
|
||||
(SELECT MillTotalGround FROM mill_total_ground ORDER BY id DESC LIMIT 1)
|
||||
AS millprojected";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['millprojected']); ?>
|
||||
|
||||
39
includes/millprojected30min.php
Normal file
39
includes/millprojected30min.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT ROUND(
|
||||
(((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1799, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600))))
|
||||
+
|
||||
(((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1799, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600)))))*2
|
||||
+
|
||||
(SELECT MillTotalGround FROM mill_total_ground ORDER BY id DESC LIMIT 1)
|
||||
AS millprojected";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['millprojected']); ?>
|
||||
|
||||
39
includes/millprojected5min.php
Normal file
39
includes/millprojected5min.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT ROUND(
|
||||
(((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 299, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600))))
|
||||
+
|
||||
(((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 299, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600)))))*12
|
||||
+
|
||||
(SELECT MillTotalGround FROM mill_total_ground ORDER BY id DESC LIMIT 1)
|
||||
AS millprojected";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['millprojected']); ?>
|
||||
|
||||
63
includes/millprojected60_min_tempfix.php
Normal file
63
includes/millprojected60_min_tempfix.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
include("../dbinfo2.php");
|
||||
|
||||
// Connection 1: East mill data (dbinfo.php - 192.168.0.10)
|
||||
$con = mysqli_connect('192.168.0.10', 'corey', '41945549', 'controls');
|
||||
|
||||
// Connection 2: West mill data (192.168.0.9)
|
||||
$con2 = mysqli_connect('192.168.0.9', 'corey', '41945549', 'controls');
|
||||
|
||||
// Calculate hours remaining until 5am
|
||||
$hoursSinceFive = (time() < strtotime('5:00'))
|
||||
? (time() + 86400 - strtotime('5:00')) / 3600
|
||||
: (time() - strtotime('5:00')) / 3600;
|
||||
$hoursRemaining = max(0, 24 - $hoursSinceFive);
|
||||
|
||||
// Get east mill data from primary server
|
||||
$eastLatest = 0;
|
||||
$eastHourAgo = 0;
|
||||
$eastResult = mysqli_query($con, "SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1");
|
||||
if ($eastResult && $row = mysqli_fetch_assoc($eastResult)) {
|
||||
$eastLatest = (float) $row['easttotground'];
|
||||
}
|
||||
$eastHourAgoResult = mysqli_query($con, "SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 3599, 1");
|
||||
if ($eastHourAgoResult && $row = mysqli_fetch_assoc($eastHourAgoResult)) {
|
||||
$eastHourAgo = (float) $row['easttotground'];
|
||||
}
|
||||
|
||||
// Get west mill data from secondary server (192.168.0.9)
|
||||
$westLatest = 0;
|
||||
$westHourAgo = 0;
|
||||
if ($con2) {
|
||||
$westResult = mysqli_query($con2, "SELECT MODBUSENET_TABLE900_WTOTGROUND_VALUE FROM westtotalground ORDER BY id DESC LIMIT 1");
|
||||
if ($westResult && $row = mysqli_fetch_assoc($westResult)) {
|
||||
$westLatest = (float) $row['MODBUSENET_TABLE900_WTOTGROUND_VALUE'];
|
||||
}
|
||||
$westHourAgoResult = mysqli_query($con2, "SELECT MODBUSENET_TABLE900_WTOTGROUND_VALUE FROM westtotalground ORDER BY id DESC LIMIT 3599, 1");
|
||||
if ($westHourAgoResult && $row = mysqli_fetch_assoc($westHourAgoResult)) {
|
||||
$westHourAgo = (float) $row['MODBUSENET_TABLE900_WTOTGROUND_VALUE'];
|
||||
}
|
||||
}
|
||||
|
||||
// Get current day total from primary server
|
||||
$totalToday = 0;
|
||||
$totalResult = mysqli_query($con, "SELECT MillTotalGround FROM mill_total_ground ORDER BY id DESC LIMIT 1");
|
||||
if ($totalResult && $row = mysqli_fetch_assoc($totalResult)) {
|
||||
$totalToday = (float) $row['MillTotalGround'];
|
||||
}
|
||||
|
||||
mysqli_close($con);
|
||||
if ($con2) {
|
||||
mysqli_close($con2);
|
||||
}
|
||||
|
||||
// Calculate projections
|
||||
$eastProjected = ($eastLatest - $eastHourAgo) * $hoursRemaining;
|
||||
$westProjected = ($westLatest - $westHourAgo) * $hoursRemaining;
|
||||
$millProjected = $totalToday + $eastProjected + $westProjected;
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($millProjected); ?>
|
||||
|
||||
39
includes/millprojected60min.php
Normal file
39
includes/millprojected60min.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT ROUND(
|
||||
(((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 3599, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600))))
|
||||
+
|
||||
(((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (
|
||||
SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 3599, 1))*(24
|
||||
-
|
||||
((SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600)))))*1
|
||||
+
|
||||
(SELECT MillTotalGround FROM mill_total_ground ORDER BY id DESC LIMIT 1)
|
||||
AS millprojected";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['millprojected']); ?>
|
||||
|
||||
129
includes/millprojected60min_mssql.php
Normal file
129
includes/millprojected60min_mssql.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* Mill Projected Total - MSSQL Version (60 minute window)
|
||||
*
|
||||
* Uses SQL Server archive table (row-based storage) instead of MySQL
|
||||
*
|
||||
* Tags:
|
||||
* - WTOTGROUND (ID: 342) - West Mill Total Ground
|
||||
* - CANETOT (ID: 218) - East Mill Total Ground
|
||||
* - TotalGround (ID: 230) - Total Ground Since 5 AM
|
||||
*/
|
||||
|
||||
$servername = "192.168.0.13\\SQLEXPRESS";
|
||||
$username = "opce";
|
||||
$password = "opcelasuca";
|
||||
$dbname = "history";
|
||||
|
||||
try {
|
||||
$pdo = new PDO(
|
||||
"sqlsrv:Server=$servername;Database=$dbname",
|
||||
$username,
|
||||
$password,
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
echo "0";
|
||||
return;
|
||||
}
|
||||
|
||||
// Tag IDs
|
||||
$eastId = 218; // CANETOT
|
||||
$westId = 342; // WTOTGROUND
|
||||
$totalId = 230; // TotalGround
|
||||
|
||||
$query = "
|
||||
DECLARE @now DATETIME = GETDATE();
|
||||
DECLARE @oneHourAgo DATETIME = DATEADD(HOUR, -1, @now);
|
||||
|
||||
-- Calculate hours remaining until 5 AM
|
||||
-- If before 5 AM, time until 5 AM today
|
||||
-- If after 5 AM, time until 5 AM tomorrow
|
||||
DECLARE @hoursRemaining FLOAT;
|
||||
DECLARE @targetTime DATETIME;
|
||||
|
||||
IF CAST(@now AS TIME) < '05:00:00'
|
||||
SET @targetTime = CAST(CAST(@now AS DATE) AS DATETIME) + CAST('05:00:00' AS DATETIME)
|
||||
ELSE
|
||||
SET @targetTime = CAST(DATEADD(DAY, 1, CAST(@now AS DATE)) AS DATETIME) + CAST('05:00:00' AS DATETIME)
|
||||
|
||||
SET @hoursRemaining = DATEDIFF(SECOND, @now, @targetTime) / 3600.0;
|
||||
|
||||
-- Get latest East value
|
||||
DECLARE @eastLatest FLOAT = (
|
||||
SELECT TOP 1 Value
|
||||
FROM dbo.archive
|
||||
WHERE ID = :eastId
|
||||
ORDER BY TimeStamp DESC
|
||||
);
|
||||
|
||||
-- Get East value from ~60 minutes ago
|
||||
DECLARE @eastOld FLOAT = (
|
||||
SELECT TOP 1 Value
|
||||
FROM dbo.archive
|
||||
WHERE ID = :eastId2 AND TimeStamp <= @oneHourAgo
|
||||
ORDER BY TimeStamp DESC
|
||||
);
|
||||
|
||||
-- Get latest West value
|
||||
DECLARE @westLatest FLOAT = (
|
||||
SELECT TOP 1 Value
|
||||
FROM dbo.archive
|
||||
WHERE ID = :westId
|
||||
ORDER BY TimeStamp DESC
|
||||
);
|
||||
|
||||
-- Get West value from ~60 minutes ago
|
||||
DECLARE @westOld FLOAT = (
|
||||
SELECT TOP 1 Value
|
||||
FROM dbo.archive
|
||||
WHERE ID = :westId2 AND TimeStamp <= @oneHourAgo
|
||||
ORDER BY TimeStamp DESC
|
||||
);
|
||||
|
||||
-- Get current total ground
|
||||
DECLARE @totalGround FLOAT = (
|
||||
SELECT TOP 1 Value
|
||||
FROM dbo.archive
|
||||
WHERE ID = :totalId
|
||||
ORDER BY TimeStamp DESC
|
||||
);
|
||||
|
||||
-- Calculate rates (tons per hour)
|
||||
DECLARE @eastRate FLOAT = COALESCE(@eastLatest, 0) - COALESCE(@eastOld, 0);
|
||||
DECLARE @westRate FLOAT = COALESCE(@westLatest, 0) - COALESCE(@westOld, 0);
|
||||
|
||||
-- Handle negative rates (mill reset or bad data)
|
||||
IF @eastRate < 0 SET @eastRate = 0;
|
||||
IF @westRate < 0 SET @westRate = 0;
|
||||
|
||||
-- Calculate projection
|
||||
SELECT ROUND(
|
||||
((@eastRate + @westRate) * @hoursRemaining) + COALESCE(@totalGround, 0),
|
||||
0
|
||||
) AS millprojected;
|
||||
";
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare($query);
|
||||
$stmt->execute([
|
||||
':eastId' => $eastId,
|
||||
':eastId2' => $eastId,
|
||||
':westId' => $westId,
|
||||
':westId2' => $westId,
|
||||
':totalId' => $totalId,
|
||||
]);
|
||||
|
||||
$result = $stmt->fetch();
|
||||
$projected = $result ? round($result['millprojected']) : 0;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$projected = 0;
|
||||
}
|
||||
|
||||
$pdo = null;
|
||||
?>
|
||||
<?php echo $projected; ?>
|
||||
14
includes/milltotal.php
Normal file
14
includes/milltotal.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT DISTINCT MillTotal FROM mill_ytd_totals ORDER BY ID DESC LIMIT 1";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include1['MillTotal'] + 3705); ?>
|
||||
21
includes/passedhours.php
Normal file
21
includes/passedhours.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
include("dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600 AS hoursleft";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo ($include4['hoursleft']); ?>
|
||||
|
||||
39
includes/prevtonsscale.php
Normal file
39
includes/prevtonsscale.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
$serverName = "CBM2K12\SQLEXPRESS";
|
||||
$uid = "cbmclient";
|
||||
$pwd = "ascbm2k";
|
||||
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
|
||||
|
||||
/* Connect using SQL Server Authentication. */
|
||||
$conn = sqlsrv_connect( $serverName, $connectionInfo);
|
||||
if( $conn === false )
|
||||
{
|
||||
echo "Unable to connect.</br>";
|
||||
die( print_r( sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
$sql = "SELECT DISTINCT CropDay, ROUND (Tons,0) AS Tons FROM LoadData ORDER BY CropDay DESC";
|
||||
|
||||
$stmt = sqlsrv_query( $conn, $sql );
|
||||
if( $stmt === false) {
|
||||
die( print_r( sqlsrv_errors(), true) );
|
||||
}
|
||||
echo "<select name='Tons' id='Tons'>";
|
||||
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
|
||||
{
|
||||
$tonsin += $row['Tons'];
|
||||
$cropday += $row['CropDay'];
|
||||
}
|
||||
{
|
||||
echo "<option value='" . $tonsin . "' >" . $tonsin . " " . $cropday . "</option>";
|
||||
}
|
||||
|
||||
echo "</select>";
|
||||
|
||||
//end
|
||||
?>
|
||||
<?
|
||||
$db = null;
|
||||
?>
|
||||
|
||||
14
includes/record.php
Normal file
14
includes/record.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT DISTINCT record FROM record ORDER BY record DESC LIMIT 1";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include1['record']); ?>
|
||||
14
includes/recorddate.php
Normal file
14
includes/recorddate.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT DISTINCT record, timestamp FROM record ORDER BY record DESC LIMIT 1";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo date('M, d', strtotime('-1 day', strtotime($include1['timestamp']))); ?>
|
||||
21
includes/remaininghours.php
Normal file
21
includes/remaininghours.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
include("dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT 24-TIME_TO_SEC(
|
||||
TIMEDIFF(
|
||||
CASE
|
||||
WHEN CURRENT_TIME() < '5:00:00'
|
||||
THEN ADDTIME(CURRENT_TIME(), '240000')
|
||||
ELSE CURRENT_TIME() END,
|
||||
'05:00:00'))/3600 AS hoursleft";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo ($include4['hoursleft']); ?>
|
||||
|
||||
183
includes/section_layout.php
Normal file
183
includes/section_layout.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../dbinfo.php';
|
||||
|
||||
if (!function_exists('lasuca_normalise_panel_key')) {
|
||||
/**
|
||||
* Normalises a dashboard panel key for consistent storage.
|
||||
*/
|
||||
function lasuca_normalise_panel_key(string $key): string
|
||||
{
|
||||
return trim($key);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('lasuca_get_section_layout_connection')) {
|
||||
/**
|
||||
* Opens a MySQL connection configured for the section layouts table.
|
||||
*/
|
||||
function lasuca_get_section_layout_connection(): mysqli|false
|
||||
{
|
||||
$connection = mysqli_connect($GLOBALS['DB_SERVER'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASS']);
|
||||
if (!$connection) {
|
||||
error_log('lasuca_get_section_layout_connection: cannot connect to MySQL server: ' . mysqli_connect_error());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mysqli_select_db($connection, $GLOBALS['DB_NAME'])) {
|
||||
error_log('lasuca_get_section_layout_connection: cannot select database: ' . mysqli_error($connection));
|
||||
mysqli_close($connection);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mysqli_set_charset($connection, 'utf8mb4')) {
|
||||
error_log('lasuca_get_section_layout_connection: cannot set charset: ' . mysqli_error($connection));
|
||||
mysqli_close($connection);
|
||||
return false;
|
||||
}
|
||||
|
||||
return $connection;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('lasuca_get_section_order')) {
|
||||
/**
|
||||
* Retrieves the saved section order for a member/panel combination.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
function lasuca_get_section_order(mysqli $connection, string $sectionKey, string $memberId): array
|
||||
{
|
||||
$normalisedKey = lasuca_normalise_panel_key($sectionKey);
|
||||
$safeMemberId = trim($memberId);
|
||||
|
||||
$sql = 'SELECT section_order FROM section_layouts WHERE panel_key = ? AND member_id = ? LIMIT 1';
|
||||
$statement = mysqli_prepare($connection, $sql);
|
||||
if (!$statement) {
|
||||
error_log('lasuca_get_section_order: failed to prepare statement: ' . mysqli_error($connection));
|
||||
return [];
|
||||
}
|
||||
|
||||
mysqli_stmt_bind_param($statement, 'ss', $normalisedKey, $safeMemberId);
|
||||
|
||||
if (!mysqli_stmt_execute($statement)) {
|
||||
error_log('lasuca_get_section_order: failed to execute statement: ' . mysqli_stmt_error($statement));
|
||||
mysqli_stmt_close($statement);
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = mysqli_stmt_get_result($statement);
|
||||
mysqli_stmt_close($statement);
|
||||
|
||||
if (!$result instanceof mysqli_result) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$row = mysqli_fetch_assoc($result);
|
||||
mysqli_free_result($result);
|
||||
|
||||
if (!$row) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$decoded = json_decode((string) $row['section_order'], true);
|
||||
if (!is_array($decoded)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_values(array_filter($decoded, static fn($value): bool => is_string($value) && $value !== ''));
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('lasuca_save_section_order')) {
|
||||
/**
|
||||
* Persists a member's preferred section ordering.
|
||||
*/
|
||||
function lasuca_save_section_order(mysqli $connection, string $sectionKey, string $memberId, array $sectionOrder): bool
|
||||
{
|
||||
$normalisedKey = lasuca_normalise_panel_key($sectionKey);
|
||||
$safeMemberId = trim($memberId);
|
||||
$sanitisedOrder = array_values(array_filter($sectionOrder, static fn($value): bool => is_string($value) && $value !== ''));
|
||||
|
||||
$payload = json_encode($sanitisedOrder, JSON_THROW_ON_ERROR);
|
||||
|
||||
$sql = 'INSERT INTO section_layouts (panel_key, member_id, section_order, updated_at)
|
||||
VALUES (?, ?, ?, NOW())
|
||||
ON DUPLICATE KEY UPDATE section_order = VALUES(section_order), updated_at = NOW()';
|
||||
|
||||
$statement = mysqli_prepare($connection, $sql);
|
||||
if (!$statement) {
|
||||
error_log('lasuca_save_section_order: failed to prepare statement: ' . mysqli_error($connection));
|
||||
return false;
|
||||
}
|
||||
|
||||
mysqli_stmt_bind_param($statement, 'sss', $normalisedKey, $safeMemberId, $payload);
|
||||
|
||||
if (!mysqli_stmt_execute($statement)) {
|
||||
error_log('lasuca_save_section_order: failed to execute statement: ' . mysqli_stmt_error($statement));
|
||||
mysqli_stmt_close($statement);
|
||||
return false;
|
||||
}
|
||||
|
||||
$affected = mysqli_stmt_affected_rows($statement);
|
||||
mysqli_stmt_close($statement);
|
||||
|
||||
return $affected > 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('lasuca_reset_section_order')) {
|
||||
/**
|
||||
* Removes any persisted ordering for the user/panel.
|
||||
*/
|
||||
function lasuca_reset_section_order(mysqli $connection, string $sectionKey, string $memberId): bool
|
||||
{
|
||||
$normalisedKey = lasuca_normalise_panel_key($sectionKey);
|
||||
$safeMemberId = trim($memberId);
|
||||
|
||||
$sql = 'DELETE FROM section_layouts WHERE panel_key = ? AND member_id = ?';
|
||||
$statement = mysqli_prepare($connection, $sql);
|
||||
if (!$statement) {
|
||||
error_log('lasuca_reset_section_order: failed to prepare statement: ' . mysqli_error($connection));
|
||||
return false;
|
||||
}
|
||||
|
||||
mysqli_stmt_bind_param($statement, 'ss', $normalisedKey, $safeMemberId);
|
||||
|
||||
if (!mysqli_stmt_execute($statement)) {
|
||||
error_log('lasuca_reset_section_order: failed to execute statement: ' . mysqli_stmt_error($statement));
|
||||
mysqli_stmt_close($statement);
|
||||
return false;
|
||||
}
|
||||
|
||||
$affected = mysqli_stmt_affected_rows($statement);
|
||||
mysqli_stmt_close($statement);
|
||||
|
||||
return $affected > 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('lasuca_section_layout_health_check')) {
|
||||
/**
|
||||
* Performs a lightweight connectivity check for diagnostics.
|
||||
*/
|
||||
function lasuca_section_layout_health_check(): bool
|
||||
{
|
||||
$connection = lasuca_get_section_layout_connection();
|
||||
if (!$connection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = mysqli_query($connection, 'SELECT 1');
|
||||
if ($result instanceof mysqli_result) {
|
||||
mysqli_free_result($result);
|
||||
mysqli_close($connection);
|
||||
return true;
|
||||
}
|
||||
|
||||
mysqli_close($connection);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
18
includes/sincen.php
Normal file
18
includes/sincen.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT TIMEDIFF ((SELECT NOW()),(SELECT date FROM plc GROUP BY totnorth ORDER BY id DESC LIMIT 1)) AS time";
|
||||
$result=mysqli_query($con,$query);
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
<?php echo $include1['time']; ?>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
18
includes/sinces.php
Normal file
18
includes/sinces.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT TIMEDIFF ((SELECT NOW()),(SELECT date FROM plc GROUP BY totsouth ORDER BY id DESC LIMIT 1)) AS time";
|
||||
$result=mysqli_query($con,$query);
|
||||
$include3=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
<?php echo $include3['time']; ?>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
18
includes/sincew2.php
Normal file
18
includes/sincew2.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT TIMEDIFF ((SELECT NOW()),(SELECT date FROM plc GROUP BY totwest2 ORDER BY id DESC LIMIT 1)) AS time";
|
||||
$result=mysqli_query($con,$query);
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
<?php echo $include1['time']; ?>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
18
includes/stablerate.php
Normal file
18
includes/stablerate.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT(((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 29, 1))*120
|
||||
+
|
||||
((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 29, 1))*120)
|
||||
AS stablerate";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['stablerate']); ?>
|
||||
|
||||
18
includes/stablerate30.php
Normal file
18
includes/stablerate30.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT(((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 29, 1))*120
|
||||
+
|
||||
((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 29, 1))*120)
|
||||
AS stablerate";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['stablerate']); ?>
|
||||
|
||||
18
includes/stablerate60.php
Normal file
18
includes/stablerate60.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT(((SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 1) - (SELECT easttotground FROM easttotalground ORDER BY id DESC LIMIT 59, 1))*60
|
||||
+
|
||||
((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 59, 1))*60)
|
||||
AS stablerate";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['stablerate']); ?>
|
||||
|
||||
6
includes/timetest.php
Normal file
6
includes/timetest.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
$d1= new DateTime("05:00:00am"); // first date
|
||||
$d2= new \DateTime("now"); // second date
|
||||
$interval= $d1->diff($d2); // get difference between two dates
|
||||
echo $interval->h; // convert days to hours and add hours from difference
|
||||
?>
|
||||
35
includes/tonsin.php
Normal file
35
includes/tonsin.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
$serverName = "CBM2K12\SQLEXPRESS";
|
||||
$uid = "cbmclient";
|
||||
$pwd = "ascbm2k";
|
||||
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
|
||||
|
||||
/* Connect using SQL Server Authentication. */
|
||||
$conn = sqlsrv_connect( $serverName, $connectionInfo);
|
||||
if( $conn === false )
|
||||
{
|
||||
echo "Unable to connect.</br>";
|
||||
die( print_r( sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
$sql = "SELECT ROUND (Tons,0) AS Tons FROM LoadData WHERE CropDay = ( SELECT Max(CropDay) FROM LoadData)";
|
||||
|
||||
$stmt = sqlsrv_query( $conn, $sql );
|
||||
if( $stmt === false) {
|
||||
die( print_r( sqlsrv_errors(), true) );
|
||||
}
|
||||
$tonsin = 0;
|
||||
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
|
||||
{
|
||||
$tonsin += $row['Tons'];
|
||||
|
||||
}
|
||||
|
||||
//end
|
||||
|
||||
?>
|
||||
<?php echo $tonsin; ?>
|
||||
<?
|
||||
$db = null;
|
||||
?>
|
||||
36
includes/tonsinprev.php
Normal file
36
includes/tonsinprev.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
$serverName = "CBM2K12\SQLEXPRESS";
|
||||
$uid = "cbmclient";
|
||||
$pwd = "ascbm2k";
|
||||
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
|
||||
|
||||
/* Connect using SQL Server Authentication. */
|
||||
$conn = sqlsrv_connect( $serverName, $connectionInfo);
|
||||
if( $conn === false )
|
||||
{
|
||||
echo "Unable to connect.</br>";
|
||||
die( print_r( sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
$sql = "SELECT ROUND (Tons,0) AS Tons FROM LoadData WHERE CropDay = ( SELECT Max(CropDay)-1 FROM LoadData)";
|
||||
|
||||
$stmt = sqlsrv_query( $conn, $sql );
|
||||
if( $stmt === false) {
|
||||
die( print_r( sqlsrv_errors(), true) );
|
||||
}
|
||||
$tonsin = 0;
|
||||
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
|
||||
{
|
||||
$tonsin += $row['Tons'];
|
||||
|
||||
}
|
||||
|
||||
//end
|
||||
|
||||
?>
|
||||
|
||||
<?php echo $tonsin; ?>
|
||||
<?
|
||||
$db = null;
|
||||
?>
|
||||
35
includes/tonsintot.php
Normal file
35
includes/tonsintot.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
$serverName = "CBM2K12\SQLEXPRESS";
|
||||
$uid = "cbmclient";
|
||||
$pwd = "ascbm2k";
|
||||
$connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd,'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8', "Database"=>"SugarCaneScale" );
|
||||
|
||||
/* Connect using SQL Server Authentication. */
|
||||
$conn = sqlsrv_connect( $serverName, $connectionInfo);
|
||||
if( $conn === false )
|
||||
{
|
||||
echo "Unable to connect.</br>";
|
||||
die( print_r( sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
$sql = "SELECT ROUND (Tons,0) AS Tons FROM LoadData ORDER BY DateIn DESC";
|
||||
|
||||
$stmt = sqlsrv_query( $conn, $sql );
|
||||
if( $stmt === false) {
|
||||
die( print_r( sqlsrv_errors(), true) );
|
||||
}
|
||||
$tonsin = 0;
|
||||
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) )
|
||||
{
|
||||
$tonsin += $row['Tons'];
|
||||
|
||||
}
|
||||
|
||||
//end
|
||||
|
||||
?>
|
||||
<?php echo $tonsin; ?>
|
||||
<?
|
||||
$db = null;
|
||||
?>
|
||||
15
includes/west15minavg.php
Normal file
15
includes/west15minavg.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT ((SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 1) - (SELECT westtotground FROM westtotalground ORDER BY id DESC LIMIT 899, 1))*4 AS westavg";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include4=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include4['westavg']); ?>
|
||||
|
||||
14
includes/westtotal.php
Normal file
14
includes/westtotal.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
include("../dbinfo.php");
|
||||
|
||||
$con=mysqli_connect($host,$username,$password,$database);
|
||||
$query = "SELECT DISTINCT WestTotal FROM mill_ytd_totals ORDER BY ID DESC LIMIT 1";
|
||||
$result=mysqli_query($con,$query);
|
||||
|
||||
$include1=mysqli_fetch_array($result,MYSQLI_ASSOC);
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
|
||||
<?php echo round($include1['WestTotal']); ?>
|
||||
Reference in New Issue
Block a user