Sample: merged live-data feed (cieng_feed.ps1) replaces trend_feed.ps1
- feed/cieng_feed.ps1: -Seconds (default, LEVEL +/-25 %), -UntilFlag (DEMO.FEED_ON for the display Start/Stop), -Alarms (+/-33 %, crosses L/H), -System (SYSTEM.* items, skipped while the monitoring processes run); single-copy lock; log in %TLS_LST_PATH%\cieng_feed.log - feed/cieng_feed_start.cmd, feed/install_feed.ps1: installed to C:\Users\Public\CI-Eng-Sample\feed (outside the CI Server package) for the server-side display command - Item CI-Eng-Sample.DEMO.FEED_ON in 02_item_df.qli / 91_remove_item_df.qli - Tested on CI Server R1.03.00 2026-10-06: default run, single copy, start wrapper with flag stop, system items written and skipped with a monitor process present Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a298fdebc1
commit
d299bdf312
6 changed files with 105 additions and 16 deletions
|
|
@ -20,5 +20,6 @@ LOW_LOW_LIMIT,LOW_LIMIT,HIGH_LIMIT,HIGH_HIGH_LIMIT,SCALE_LOW_LIMIT,SCALE_HIGH_LI
|
|||
"CI-Eng-Sample.SYSTEM.PING_LOCALHOST","localhost reachable, from inttcpmon","Integer","9",0,0,0,0,0,1
|
||||
"CI-Eng-Sample.SYSTEM.PROC_ALM","ALARM process (alm) running, from intmon","Integer","9",0,0,0,0,0,1
|
||||
"CI-Eng-Sample.DEMO.COUNTER","Counter 1..100 driven by object DEMO.INCR1","Integer","999",0,0,0,0,0,100
|
||||
"CI-Eng-Sample.DEMO.FEED_ON","Live-data feed running (1 = on), written by feed\cieng_feed.ps1","Boolean","",0,0,0,0,0,0
|
||||
"CI-Eng-Sample.PLC1.COMM_OK","Station CIENG_PLC communication (1 = good), status item","Boolean","",0,0,0,0,0,0
|
||||
"CI-Eng-Sample.UA.COMM_OK","Station CIENG_UA communication (1 = good), status item","Boolean","",0,0,0,0,0,0
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ NAME
|
|||
"CI-Eng-Sample.SYSTEM.PING_LOCALHOST"
|
||||
"CI-Eng-Sample.SYSTEM.PROC_ALM"
|
||||
"CI-Eng-Sample.DEMO.COUNTER"
|
||||
"CI-Eng-Sample.DEMO.FEED_ON"
|
||||
"CI-Eng-Sample.PLC1.COMM_OK"
|
||||
"CI-Eng-Sample.UA.COMM_OK"
|
||||
"CI-Eng-Sample.TEMPLATES.TPL_REAL"
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
# Feed test values into the CI-Eng-Sample tank items so trends have a moving line.
|
||||
# CI Server R1.03.00. TANK1.LEVEL and TANK1.INFLOW are internal items: after a restart they
|
||||
# stay NOT INIT until something writes them. Writes every 5 s with itmval; stop with Ctrl+C.
|
||||
# LEVEL = 50 +/- 25 % (period 10 min, stays inside the L 20 / H 80 alarm limits)
|
||||
# INFLOW = 250 +/- 150 m3/h (period 4 min)
|
||||
param([int]$Seconds = 3600)
|
||||
|
||||
$end = (Get-Date).AddSeconds($Seconds)
|
||||
while ((Get-Date) -lt $end) {
|
||||
$t = [double]((Get-Date) - (Get-Date).Date).TotalSeconds
|
||||
$level = [math]::Round(50 + 25 * [math]::Sin(2 * [math]::PI * $t / 600), 1)
|
||||
$inflow = [math]::Round(250 + 150 * [math]::Sin(2 * [math]::PI * $t / 240), 1)
|
||||
itmval -p -n CI-Eng-Sample.TANK1.LEVEL -v $level > $null
|
||||
itmval -p -n CI-Eng-Sample.TANK1.INFLOW -v $inflow > $null
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
79
examples/CI-Eng-Sample/feed/cieng_feed.ps1
Normal file
79
examples/CI-Eng-Sample/feed/cieng_feed.ps1
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# CI-Eng-Sample live data: writes test values into the sample items so displays, trends and alarms
|
||||
# move (internal items stay NOT INIT after a CI Server start). CI Server R1.03.00. Replaces
|
||||
# displays\trend_feed.ps1. Not part of the CI Server package: installed with install_feed.ps1 into
|
||||
# C:\Users\Public\CI-Eng-Sample\feed, from where the display button "Start" runs it.
|
||||
#
|
||||
# Usage: powershell -ExecutionPolicy Bypass -File cieng_feed.ps1 [-Seconds 3600] [-UntilFlag] [-Alarms] [-System] [-Cycle 5]
|
||||
# (default) run for -Seconds (3600)
|
||||
# -UntilFlag run while CI-Eng-Sample.DEMO.FEED_ON = 1 (display buttons Start / Stop); sets it to 1
|
||||
# at start and 0 at the end
|
||||
# -Alarms LEVEL 50 +/- 33 % (crosses L 20 and H 80: alarms that need an acknowledgement);
|
||||
# without it 50 +/- 25 % (stays inside the limits)
|
||||
# -System also write SYSTEM.CPU_LOAD / DISK_C / PING_LOCALHOST / PROC_ALM with this PC's real
|
||||
# values - skipped automatically while the monitoring processes (intcpumon, intdskmon,
|
||||
# inttcpmon, intmon; see ..\monitoring) are running, so they do not overwrite each other
|
||||
# Every cycle (default 5 s): TANK1.LEVEL (sine, 10 min), TANK1.INFLOW (250 +/- 150 m3/h, 4 min);
|
||||
# PUMP1.RUNNING = 1 while INFLOW > 250, only in auto mode (PUMP1.MODE = 1).
|
||||
# Only one copy runs at a time; log: %TLS_LST_PATH%\cieng_feed.log (start / stop lines).
|
||||
param([int]$Seconds = 3600, [switch]$UntilFlag, [switch]$Alarms, [switch]$System, [int]$Cycle = 5)
|
||||
|
||||
$itmval = 'itmval'
|
||||
if ($env:TLS_ROOT_PATH) {
|
||||
$exe = Join-Path $env:TLS_ROOT_PATH 'tls\exe\itmval.exe'
|
||||
if (Test-Path $exe) { $itmval = $exe }
|
||||
}
|
||||
$S = 'CI-Eng-Sample.'
|
||||
$logDir = $env:TLS_LST_PATH
|
||||
if (-not $logDir) { $logDir = $PSScriptRoot }
|
||||
$log = Join-Path $logDir 'cieng_feed.log'
|
||||
|
||||
function Get-Val([string]$name) {
|
||||
$out = & $itmval -g -n ($S + $name) 2>$null
|
||||
foreach ($l in $out) { if ($l -match '^Value\s*=\s*(.+)$') { return $Matches[1].Trim() } }
|
||||
return $null
|
||||
}
|
||||
function Put([string]$name, $value) { & $itmval -p -n ($S + $name) -v $value > $null 2>&1 }
|
||||
function Write-Log([string]$text) {
|
||||
try { Add-Content -Path $log -Value ('{0} {1}' -f (Get-Date -Format s), $text) } catch { }
|
||||
}
|
||||
|
||||
$created = $false
|
||||
$mutex = New-Object Threading.Mutex($true, 'Global\CIENG_FEED', [ref]$created)
|
||||
if (-not $created) { Write-Log 'already running - this copy exits'; exit 0 }
|
||||
|
||||
$amp = 25
|
||||
if ($Alarms) { $amp = 33 }
|
||||
$monitors = @('intcpumon', 'intdskmon', 'inttcpmon', 'intmon')
|
||||
$mode = 'seconds=' + $Seconds
|
||||
if ($UntilFlag) { $mode = 'until FEED_ON = 0' }
|
||||
$end = (Get-Date).AddSeconds($Seconds)
|
||||
try {
|
||||
Write-Log ('start ({0}, alarms={1}, system={2}, user {3})' -f $mode, [bool]$Alarms, [bool]$System, [Environment]::UserName)
|
||||
if ($UntilFlag) { Put 'DEMO.FEED_ON' 1 }
|
||||
while ($true) {
|
||||
if ($UntilFlag) { if ((Get-Val 'DEMO.FEED_ON') -ne '1') { break } }
|
||||
elseif ((Get-Date) -ge $end) { break }
|
||||
$t = [double]((Get-Date) - (Get-Date).Date).TotalSeconds
|
||||
$level = [math]::Round(50 + $amp * [math]::Sin(2 * [math]::PI * $t / 600), 1)
|
||||
$inflow = [math]::Round(250 + 150 * [math]::Sin(2 * [math]::PI * $t / 240), 1)
|
||||
Put 'TANK1.LEVEL' $level
|
||||
Put 'TANK1.INFLOW' $inflow
|
||||
if ((Get-Val 'PUMP1.MODE') -eq '1') { Put 'PUMP1.RUNNING' ([int]($inflow -gt 250)) }
|
||||
if ($System -and -not (Get-Process -Name $monitors -ErrorAction SilentlyContinue)) {
|
||||
try {
|
||||
$cpus = @(Get-CimInstance Win32_Processor)
|
||||
$cpu = 0; foreach ($c in $cpus) { $cpu += $c.LoadPercentage }; $cpu = $cpu / [math]::Max(1, $cpus.Count)
|
||||
Put 'SYSTEM.CPU_LOAD' ([math]::Round($cpu, 1))
|
||||
$d = Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'"
|
||||
Put 'SYSTEM.DISK_C' ([math]::Round(100 * ($d.Size - $d.FreeSpace) / $d.Size, 1))
|
||||
Put 'SYSTEM.PING_LOCALHOST' ([int](Test-Connection -ComputerName localhost -Count 1 -Quiet))
|
||||
Put 'SYSTEM.PROC_ALM' ([int]([bool](Get-Process alm -ErrorAction SilentlyContinue)))
|
||||
} catch { }
|
||||
}
|
||||
Start-Sleep -Seconds $Cycle
|
||||
}
|
||||
} finally {
|
||||
if ($UntilFlag) { Put 'DEMO.FEED_ON' 0 }
|
||||
Write-Log 'stop'
|
||||
$mutex.ReleaseMutex()
|
||||
}
|
||||
6
examples/CI-Eng-Sample/feed/cieng_feed_start.cmd
Normal file
6
examples/CI-Eng-Sample/feed/cieng_feed_start.cmd
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
@echo off
|
||||
rem Starts cieng_feed.ps1 in the background (CI Server R1.03.00). Called by the display button
|
||||
rem "Start" (server-side command, runs as the CI Server service account CIX_PROCESS) from the
|
||||
rem fixed install folder C:\Users\Public\CI-Eng-Sample\feed (install_feed.ps1). Returns at once;
|
||||
rem the feed runs until the button "Stop" writes CI-Eng-Sample.DEMO.FEED_ON = 0.
|
||||
start "" /b powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File "%~dp0cieng_feed.ps1" -UntilFlag -Alarms -System
|
||||
18
examples/CI-Eng-Sample/feed/install_feed.ps1
Normal file
18
examples/CI-Eng-Sample/feed/install_feed.ps1
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Install or remove the CI-Eng-Sample live-data feed (CI Server R1.03.00).
|
||||
# Copies cieng_feed.ps1 and cieng_feed_start.cmd to C:\Users\Public\CI-Eng-Sample\feed: a fixed folder
|
||||
# outside the CI Server installation (the feed is not part of the CI Server package) that the CI
|
||||
# Server service account can read. The display button "Start" calls the .cmd there.
|
||||
# No admin rights needed. Usage: powershell -ExecutionPolicy Bypass -File install_feed.ps1 [-Remove]
|
||||
param([switch]$Remove)
|
||||
$dest = 'C:\Users\Public\CI-Eng-Sample\feed'
|
||||
if ($Remove) {
|
||||
if (Test-Path $dest) { Remove-Item -LiteralPath $dest -Recurse -Force }
|
||||
$parent = Split-Path $dest
|
||||
if ((Test-Path $parent) -and -not (Get-ChildItem -LiteralPath $parent -Force)) { Remove-Item -LiteralPath $parent -Force }
|
||||
'Feed removed from ' + $dest
|
||||
return
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $dest > $null
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'cieng_feed.ps1') -Destination $dest -Force
|
||||
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'cieng_feed_start.cmd') -Destination $dest -Force
|
||||
'Feed installed in ' + $dest
|
||||
Loading…
Add table
Reference in a new issue