Стартовая страница › Форумы › Понять, как работает ПО › Формулы › Функции (формулы) для Rapid SCADA
- В этой теме 149 ответов, 17 участников, последнее обновление 1 год, 4 месяца назад сделано
Oleg.
-
АвторЗаписи
-
16.02.2024 в 09:48 #31119
manjey73УчастникЧто-то я не уверен, что можно скриптом со связью на мнемосхемах на данном моменте.
Мнемосхемы еще от 5-й версии, каких-то нововведений вроде не было.16.02.2024 в 10:03 #31120Michael
УчастникЧто-то я не уверен, что можно скриптом со связью на мнемосхемах на данном моменте.
Тут вопрос больше, как в скрипте использовать возможности c# по открытию ссылки в дефолтном браузере, код типа
ProcessStartInfo sInfo = new ProcessStartInfo("http://example.com/"); Process.Start(sInfo);16.02.2024 в 10:21 #31121
a80808УчастникИз скриптов мне процесс запустить не удавалось…
16.02.2024 в 10:39 #31122
manjey73УчастникСкрипты работают от системного пользователя, там кажется с этим связаны проблемы запуска сторонних приложений.
Может быть есть обходные пути через bat файлы, но опять же не уверен.
Вообще было бы полезным что-то запускать. Может Михаил подскажет как это обойти.
Например точно можно создать файл из скрипта, например это будет bat файл.
А уже средствами системы как-то его запустить ????
Например в Linux через crontab точно можно сварганить подобное легко.Scada создает любой файл с текстом банально true — false а сриптом через crontab проверять и что-то запускать.
В Windows хз, не страдал, но думаю через планировщик и свой bat тоже можно сделать.16.02.2024 в 11:35 #31126
a80808УчастникПробовал через bat — не получается. Там похоже нет возможности новый процесс запустить…
16.02.2024 в 11:37 #31127
a80808УчастникПланировщик в Виндах тоже есть. Не пробовал. Не успел…
Подвисал программный шлюз, я хотел анализировать метку времени. Если не меняется — перезагрузка.16.02.2024 в 11:39 #31128
a80808УчастникА собственно ссылку открыть через «Пустой документ» или в Дэшбордах можно..
Вот только как там разные ссылки открывать?16.02.2024 в 11:40 #31129Michael
УчастникНапример точно можно создать файл из скрипта, например это будет bat файл.
Код поскажете на будущее? Вдруг пригодится (но мы все равно будем ждать Михаила )))
16.02.2024 в 11:54 #31130
manjey73Участник@Michael делал для передачи каналов по SNMP — смотрите запись в файл здесь.
Это для Linux, для Windows другой путь надо указывать в строке path…// Список каналов создается формулой SnmpData(Cnl) для входных каналов // string pathSnmp = @"/var/log/scada/ScadaServer/Log/snmpdata.txt"; protected Dictionary<int, double> snmpData = new Dictionary<int, double>(); public double SnmpData (double res) { if (!snmpData.ContainsKey(CnlNum)) { snmpData.Add(CnlNum, res); } else { snmpData[CnlNum] = res; } return res; } public double SnmpRead(int cnlNum) { return snmpData[cnlNum]; } // Сохранить данные выбранных каналов в файл данных SNMP public double SaveSnmpData() { File.WriteAllLines(pathSnmp, snmpData .Select(pair => String.Join(" ", pair.Key, pair.Value.ToString().Replace(",",".")))); return snmpData.Count; }16.02.2024 в 11:56 #31131
manjey73УчастникСмысл в том, что записать файл из формул можно, как на Linux так и на Windows.
Что в этот файл писать уже дело десятое.А вот свой скрипт в планировщике уже ваять так как вам надо с проверкой файла, который вам будет писать Scada.
Еще поищите скрипты retain, я выкладывал ранее, там тоже запись и чтение файла было.
-
Ответ изменён 2 года, 6 месяцев назад пользователем
manjey73.
16.02.2024 в 11:59 #31133
manjey73Участник// Чтение датчиков Dallas ds18b20 из файла, созданного скриптом в crontab string pathLog = @"/var/log/scada/ScadaComm/Log/"; public double ds18b20(string dsID) { double res = Double.NaN; string filePath = Path.Combine(pathLog, dsID); if (File.Exists(filePath)) { string[] DataDs = File.ReadAllLines(filePath, Encoding.UTF8); int iOfChar = DataDs[1].IndexOf("t="); int temp = int.Parse(DataDs[1].Substring(iOfChar+2)); res = Convert.ToDouble(temp)/1000; } if (res == Double.NaN) SetStat(CnlNum, 0); return res; }Вот пример чтения файла и запись данных в каналы из формул Scada. Я так датчики температуры читаю. Скрипт в crontab файл с данными записывает, а scada читает.
16.02.2024 в 12:01 #31134
manjey73Участник#!/bin/bash pathfile="/opt/scada/ScadaComm/Config/ds1820.txt" dssave="/var/log/scada/ScadaComm/Log/" declare -a dsname unset dsname readarray -t dsname < $pathfile #let i=0 #while IFS=$'\n' read -r line_data; do # dsname[i]="${line_data}" # ((++i)) #done < $pathfile for ((i=0; i < ${#dsname[*]}; i++ )); do cat /sys/bus/w1/devices/${dsname[i]}/w1_slave > $dssave${dsname[i]} done exit 0Собственно скрипт для чтения датчиков на моей OrangePi+ 2E
Правда его надо положить в какое-то место, чтобы scada его не затирала и назначить права на исполнение.И входная формула в канале датчика
ds18b20("28-031683f5c0ff")— пример. файл создается с именем = серийнику датчика.-
Ответ изменён 2 года, 6 месяцев назад пользователем
manjey73.
16.02.2024 в 13:12 #31136Algomus
УчастникГенераратор импульсов длительностью 1 цикл программы DelGen.
Может быть полезен для периодического опроса.
Циклограмма:
__—————-_____ Вх
_____-___-___-______ Выхint[] DelGenNum = new int[1];
long[] DelGenST = new long[1];
bool[] DelGenFlag = new bool[1];
public bool DelGen(double DelGenIn, long DelGenPT)
{
long ET = 0L;
bool q = Val(CnlNum) > 0;
bool delgen_in = DelGenIn > 0;int res = Array.IndexOf(DelGenNum, CnlNum);
if (res == -1)
{
res = DelGenNum.Length;
Array.Resize(ref DelGenNum, res+1);
Array.Resize(ref DelGenST, res+1);
Array.Resize(ref DelGenFlag, res+1);
DelGenNum[res] = CnlNum;
}if (!delgen_in || q)
{
q = false;
DelGenFlag[res] = false;
DelGenST[res] = 0L;
}
else
{
if (!DelGenFlag[res])
{
DelGenFlag[res] = true;
DelGenST[res] = Ticks();
}
else
{
if (!q) ET = Ticks() — DelGenST[res];
}if (ET >= DelGenPT) q = true;
}
return q;
}DelGen(значение канала в double, время в миллисекундах)
Пример: в канале 152 используем формулу DelGen(Val(150), 5000) — при появлении 1 на входном канале 150 на канале 152 через 5000 мсек будут появляться импульсы длительностью 1 цикл программы.-
Ответ изменён 2 года, 6 месяцев назад пользователем
Algomus.
16.02.2024 в 13:52 #31138
manjey73УчастникСейчас пробую сделать тот же Ton используя не массивы а словари.
По количеству строк может и не меньше сильно, но как-то красивее что ли 🙂Как проверю, выложу.
16.02.2024 в 14:08 #31139
manjey73УчастникНу вроде работает, тут так же есть Ticks сразу, так что в каком-то месте удалите при копировании если уже были какие-то таймеры.
// Таймеры МЭК и другие public static long Ticks() { DateTime now = DateTime.Now; long time = now.Ticks/10000; return time; } protected class UtilTimer { public long et; public bool flag; } protected Dictionary<int, UtilTimer> CDSTimer = new Dictionary<int, UtilTimer>(); // Таймер с задержкой включения TON public double TON(double IN, double PT) { var ut = new UtilTimer() {et = 0L, flag = false}; long ET = 0L; long _pt = Convert.ToInt64(PT); bool q = Val(CnlNum) > 0; bool _in = IN > 0; if (!CDSTimer.ContainsKey(CnlNum)) { CDSTimer.Add(CnlNum, ut); } if (!_in) { q = false; CDSTimer[CnlNum].flag = false; CDSTimer[CnlNum].et = 0L; } else { if (!CDSTimer[CnlNum].flag) { CDSTimer[CnlNum].flag = true; CDSTimer[CnlNum].et = Ticks(); } else { if (!q) ET = Ticks() - CDSTimer[CnlNum].et; } if (ET >= _pt) q = true; } return Convert.ToDouble(q); }Пока только TON — сделал заглавными буквами, если оставить один Ticks то не должен конфликтовать с Ton
Так же класс UtilTimer и словарь CDSTimer будет использоваться для остальных таймеров. -
Ответ изменён 2 года, 6 месяцев назад пользователем
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.