Показаны сообщения с ярлыком Wonderware. Показать все сообщения
Показаны сообщения с ярлыком Wonderware. Показать все сообщения

вторник, 13 августа 2013 г.

Порты фаервола для SP и Historian буду дополнять если не все сразу нашел :)




Хисториан
File and printer sharing445/tcp
SQL Server Browser1434/udp
SQL TCP1433/tcp/udp
Remote IDAS uses35 thru 139(TCP/UDP) and Port 45 (tCP and UDP)/udp
Платформа
DCOM135/tcp
File and printer sharing445/tcp
SQL TCP1433/tcp
SQL Server Browser1434/udp
  • и вот это  похоже тоже надо Ports 1024 to 65535  :)
    (вообще странно но в Tech Note 876 это есть)
не обязательно
DAS SI Direct 102
DAS MBTCP 502
DAS ABTCP 2221
DAS ABTCP 2222
DAS ABTCP 2223
S/L DA Servers 5413
DAS ABCIP 44818

желательно
ICMP

взял из "Checklist for System Platform implementations"

а если серьезно то рекомендую деалть отдельный VLAN для общения компонетов системы между собой и отдельный для клиентов

среда, 24 июля 2013 г.

вот тут SMC хранит информацию о соседних платформах

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ArchestrA\Framework\Platform\PlatformNodes

именно SMC :) иногда .. ,при восстановления бекапа галактики на другой машине например, надо эту ветку пеенести со старой машины 

понедельник, 15 июля 2013 г.

ping скриптами System Platform

Собственно все очень просто :

периодический асинхронный скрипт

dim pingSender as System.Net.NetworkInformation.Ping;
pingSender = new System.Net.NetworkInformation.Ping();

dim reply as System.Net.NetworkInformation.PingReply;
reply = pingSender.Send( me.targIPorHostName, 2500 );

if reply.Status == System.Net.NetworkInformation.IPStatus.Success then
me.result = 0;
me.PingErr = False;
me.RoundtripTime = reply.RoundtripTime;
else 
me.result = me.result +1;
me.RoundtripTime = reply.RoundtripTime;  
endif;

и еще один скрипт который следит за количеством пропущенных пингов

WhileTrue по этому условию me.result > me.pingErrLimit

me.PingErr = True;

ну а дальше на me.PingErr вешаем все что нам нужно

P.S.: 2500 - таймаут для пинга ... если не поставить то скрипт будет ну очень долго ждать результата, а это в System Platform неприемлемо.

среда, 22 мая 2013 г.

Один из множества вариантов выгрузки данных из Historian

      Часто возникает необходимость выгружать данные для каких либо внешних систем ... впринципе есть много разных способов это сделать ...
      Ниже я приведу SQL запрос кторый читает список тегов из одной таблицы и по этому списку читает среднее за пол часа из Historian. Чтение сделано курсором .. не самый эфективный вариант с точки зрения производительности но если нужно выгружать не много и не часто то пойдет. А если нет то можно оптимизировать, но это уже отдельный вопрос :)

если кому тема интересна но непонятна ... пишите, прокоментирую :)


SET NOCOUNT ON

DECLARE @StartDate DateTime;
DECLARE @EndDate DateTime;

SET @StartDate =  convert(nvarchar,  (SELECT ISNULL(Max([DateTime]),DateAdd(HH,-24,GetDate())) FROM testExportDB.dbo.data ), 21);


SET @EndDate = GetDate()
SET NOCOUNT OFF
select @StartDate,@EndDate
DECLARE @TagName nvarchar(256);


DECLARE tags_cursor CURSOR LOCAL FOR 
SELECT     TagName
FROM         testExportDB.dbo.Tags
WHERE     (ScheduleNumber = 1);

OPEN tags_cursor
FETCH NEXT FROM tags_cursor INTO @TagName; 
WHILE @@FETCH_STATUS = 0
BEGIN

--INSERT INTO testExportDB.dbo.data

SELECT temp.TagName ,Description ,DateTime  ,Value ,Unit = ISNULL(Cast(EngineeringUnit.Unit as VarChar(20)),'N/A')  ,QualityString  From (
SELECT  * 
 FROM Runtime.dbo.History
 WHERE History.TagName IN (@TagName)
 AND wwRetrievalMode = 'Average'
 AND wwResolution = 1800000
 AND wwVersion = 'Latest'
 AND DateTime >= @StartDate
 AND DateTime <= @EndDate) temp
LEFT JOIN Runtime.dbo.Tag ON Tag.TagName =temp.TagName
LEFT JOIN Runtime.dbo.AnalogTag ON AnalogTag.TagName =temp.TagName
LEFT JOIN Runtime.dbo.EngineeringUnit ON AnalogTag.EUKey = EngineeringUnit.EUKey
LEFT JOIN Runtime.dbo.QualityMap ON QualityMap.QualityDetail = temp.QualityDetail
 WHERE temp.StartDateTime >= @StartDate


FETCH NEXT FROM tags_cursor INTO @TagName
END

CLOSE tags_cursor
DEALLOCATE tags_cursor

а вот этот запрос выгружает таблицу в CSV файл


DECLARE @FileCSV VARCHAR(100),
@Query VARCHAR(256),
@FileNameDT DateTime;
SET @FileNameDT = DateAdd(HH,-24,GetDate());

SET @FileCSV = 'c:\tmp\data' + convert(nvarchar, @FileNameDT, 112)  + '-0000.csv'
SET @Query = 'SQLCMD -S . -d testExportDB -Q "SELECT * FROM testExportDB.dbo.data" -s "," -o ' + @FileCSV

EXEC xp_cmdshell @Query


а этот (прямо из мсдн скопировал)разрешает работу предидущего


-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO

среда, 17 апреля 2013 г.

Преобразование строки в ДатуВремя

Столкнулся тут с "забавной" особенностью ... Особенность:
Если создать галактику на локализованной версии (например русской) Windows и потом перенести бекап на не локализованную (английскую), то тип UDA DateTime в нашей галактике будет инициализироваться в русском формате (т.е. 16.04.2013 14:28:06.951) а например в BTL он используется для выполнения задержки перед построением модели и там есть вот такая строка:

deployTime = System.DateTime.Parse(Me.BTL.Deploy.LastTime);

System.DateTime.Parse ждет на входе строку в формате en-US (4/16/2013 2:28:06 PM) а получает  в формате ru-RU, и вполне предсказуемо скрипт у нас вылетает с критической ошибкой :(
вот такой:
chAppEngineBase_001.testParse: Script performed an illegal operation.
chAppEngineBase_001.testParse: mscorlib: String was not recognized as a valid DateTime.

в BTL 2012R2 эту строку заменили на более сложный вариант:


If NOT System.DateTime.TryParse(Me.BTL.Deploy.LastTime, deployTime) THEN 
deployTime = System.DateTime.ParseExact(Me.BTL.Deploy.LastTime, "M/d/yyyy h:mm:ss.fff tt", System.Globalization.CultureInfo.InvariantCulture); 
EndIf;

Но он в моем случае тоже не работает .... пока что я пришел к такому варианту :


Dim deployTime as System.DateTime;
deployTime = System.DateTime.Parse(Me.BTL.Deploy.LastTime,System.Globalization.CultureInfo("ru-RU",true));



Но он к сожалению требует прямого указания входной локали .... зато работает :) 

вторник, 26 марта 2013 г.

Работа с большими числами в SP побайтно

Появилась задача получить из контролера и обработать в платформе параметр типа Double, но в ПЛК такого типа нет и сам ПЛК читает этот параметр со счетчика ....  ПЛК получает байты в обратном порядке, и нам нужно их развернуть. Сделал разборку double на 2 integer и разворот и сборку обратно ... работает но вот правильно или нет это вопрос ....
 Дальше скрипт разборки на 2 части


'массивы байт
dim bytes8 [8] as System.Byte;
dim bytes1 [4] as System.Byte;
dim bytes2 [4] as System.Byte;
'системные переменные для работы
dim sysdouble as System.Double;
dim sysint64 as System.int64;
dim sysint32 as System.int32;
'берем число типа double из атрибута и конвертируем в масив байт
sysdouble = System.Convert.ToDouble(me.inputDouble);
bytes8[] = System.BitConverter.GetBytes(sysdouble);

'заполняем массивы типа integer на 8 и 2 по 4 элемента
'нужны нам для удобства отладки в Object Viewer
me.int8byte[1] =bytes8[1]; me.int1byte[1] =bytes8[8];
me.int8byte[2] =bytes8[2]; me.int1byte[2] =bytes8[7];
me.int8byte[3] =bytes8[3]; me.int1byte[3] =bytes8[6];
me.int8byte[4] =bytes8[4]; me.int1byte[4] =bytes8[5];

me.int8byte[5] =bytes8[5]; me.int2byte[1] =bytes8[4];
me.int8byte[6] =bytes8[6]; me.int2byte[2] =bytes8[3];
me.int8byte[7] =bytes8[7]; me.int2byte[3] =bytes8[2];
me.int8byte[8] =bytes8[8]; me.int2byte[4] =bytes8[1];

'делим наш массив из 8 байт на 2 4х байтных
bytes1[1] =bytes8[8];
bytes1[2] =bytes8[7];
bytes1[3] =bytes8[6];
bytes1[4] =bytes8[5]; 

bytes2[1] =bytes8[4];
bytes2[2] =bytes8[3];
bytes2[3] =bytes8[2];
bytes2[4] =bytes8[1];

'конвертируем 1й массив в переменную типа int32 
sysint32 = System.BitConverter.Toint32(bytes1[], 0);
'и копируем ее в атрибут 
me.int1= sysint32 ;
'конвертируем результат в 16чную и 2ичную строки для удобства отладки
me.hexStrByte1 = System.Convert.ToString( sysint32 , 16 );
me.binStrByte1 = System.Convert.ToString( sysint32 , 2 );

'конвертируем 2й массив в переменную типа int32 
sysint32 = System.BitConverter.Toint32(bytes2[], 0);
'и копируем ее в атрибут 
me.int2= sysint32 ;
'конвертируем результат в 16чную и 2ичную строки для удобства отладки
me.hexStrByte2 = System.Convert.ToString( sysint32 , 16 );
me.binStrByte2 = System.Convert.ToString( sysint32 , 2 );



me.Int1 и me.Int2 - два входных параметра которые мы принимаем в тип Double т.к. Integer для развернутых по байтно чисел может не хватить.

И скрипт сборки обратно


'массивы байт
dim bytes1 [4] as System.Byte;
dim bytes2 [4] as System.Byte;
dim bytes3 [8] as System.Byte;
'системные переменные для работы
dim sysint64 as System.int64;
dim sysdouble as System.Double;
'при конвертировании в масив байт число разворачивается
sysint64= System.Convert.ToInt64(me.Int1);
bytes1[] = System.BitConverter.GetBytes(sysint64);

sysint64= System.Convert.ToInt64(me.Int2);
bytes2[] = System.BitConverter.GetBytes(sysint64);
'заполнение переменных для отладки
me.intFromByte1[1] =bytes2[4]; me.int1FromByte[1] =bytes1[1];
me.intFromByte1[2] =bytes2[3]; me.int1FromByte[2] =bytes1[2];
me.intFromByte1[3] =bytes2[2]; me.int1FromByte[3] =bytes1[3];
me.intFromByte1[4] =bytes2[1]; me.int1FromByte[4] =bytes1[4];

me.intFromByte1[5] =bytes1[4]; me.int2FromByte[1] =bytes2[1];
me.intFromByte1[6] =bytes1[3]; me.int2FromByte[2] =bytes2[2];
me.intFromByte1[7] =bytes1[2]; me.int2FromByte[3] =bytes2[3];
me.intFromByte1[8] =bytes1[1]; me.int2FromByte[4] =bytes2[4];
'копируем масивы байт в 1 и разворачиваем
bytes3[1] =bytes2[4];
bytes3[2] =bytes2[3];
bytes3[3] =bytes2[2];
bytes3[4] =bytes2[1]; 

bytes3[5] =bytes1[4];
bytes3[6] =bytes1[3];
bytes3[7] =bytes1[2];
bytes3[8] =bytes1[1];

sysdouble = System.BitConverter.ToDouble(bytes3[], 0);
'sysint64 = System.BitConverter.Toint64(bytes3[], 0);
me.strResult = sysdouble ;
me.doubleResult = sysdouble ;


И рисунок по которому возможно лучше понятно что происходит


вот только вопрос "Правильно ли это все работает?!" пока открыт :)
велика вероятность что у меня просто четное количество ошибок :( -  НОРМ. РАБОТАЕТ :)

пятница, 15 февраля 2013 г.

Комплексные данные в custom property ? можно даже так !

Вот очень интересный и полезный материал по работе с комплексными данными в системной платформе от "everdyn". Очень рекомендую. :)

  http://www.everdyn.com/storing-complex-datas-in-a-single-custom-property/

И в догонку скрипт как функция. Тоже может быть очень полезно.
http://www.everdyn.com/use-scripts-as-functions-in-archestra-graphics/

вторник, 5 февраля 2013 г.

case в quick script ? а если вот так ? :)


Скрипт в символе по DataChange переменной State

if isGood(State) then

dim TxtStTable as System.Collections.Hashtable;
TxtStTable = new System.Collections.Hashtable;

TxtStTable.Add(0,"Отключена");
TxtStTable.Add(10,"Открыта");
TxtStTable.Add(11,"Закрыта");
TxtStTable.Add(12,"Открытие");
TxtStTable.Add(13,"Закрытие");
TxtStTable.Add(20,"Заклинивание");
TxtStTable.Add(21,"Тепловая защита");

if TxtStTable.ContainsKey( state ) then
Text1.Text = TxtStTable[state];
else
Text1.Text = "Состояние не определено";
endif;

else
Text1.Text = "Quality = Bad";
endif;

среда, 12 декабря 2012 г.

Создание виртуальной машины в VirtualBox

            В предыдущих постах я устанавливал Windows 2008R2 в виртуальную машину VirtualBox, но не показал само создание виртуальной машины. В этом посте я выкладываю видео создания виртуальной машины.
            Размер VHD образа нужно выставлять побольше, гигабайт 60 примерно, (у меня места на диске не было столько :) ). Можно сделать диск динамически расширяемым, но тогда понизится быстродействие виртуальной машины при записи данных.

вторник, 4 декабря 2012 г.

Установка Wonderware System Platform 2012 R2 ПРАВИЛЬНЫЙ вариант :)

Вступление:    
       В предыдущих записях я пытался поставить системную платформу так как будто бы ставил ее в первый раз ... у меня почти получилось :) Но WIS работал, как я и писал, не полостью. Заставить его работать я смог но достаточно нетривиальным путем ... пришлось руками править конфигурационные файлы IIS, и в результате когда я пытался повторить этот путь "под запись" IIS я сломал окончательно :). Поленился сделать бекап одного файлика ... отредактировал его и упс ... :)
 
     Так что восстановил я виртуалку из бекапа и начал все делать последовательно и аккуратненько :) .
   
      Дальше мои действия по пунктам и с видео (видео пока без озвучки ... но там и  так все ясно )


  1. Устанавливаем .Net 3.5.1 , ставим IIS , загружаем и устанавливаем апдейты

  2. После перезагрузки Windows нашла еще немного апдейтов :) , устанавливаем их и дальше ставим MS SQL 2012 x64 (если вам нужна платформа 2012 не R2 то надо ставить MS SQL 2008 x86) .... немного с кодировкой ошибся .. если нужен Alarm DB Logger Manager с русским - надо другую ... видео позже заменю
  3. И снова не забываем установить новенькие апдейты
  4. Запускаем установку непосредственно Wonderware System Platform 2012 R2
  5. После установки нас попросили перегрузиться ... и опять у нас есть парочка свежих апдейтов :) ставим их и дальше конфигурируем сервер лицензий , запускаем конфигуратор Historian , ставим лицензии и запускаем базовую конфигурацию WIS.

      И вот мы получили виртуальную машину с установленными компонентами SP 2012R2 ..... практически весь диск поставили :) 

      WIS мы конфигурировать только начали. В результате он уже работает но пока только самый базовый функционал. Дальше буду разбираться, настраивать, писать видео :) . Отличается WIS 5 от версии 4.5 достаточно существенно.

понедельник, 3 декабря 2012 г.

Установка Wonderware System Platform 2012 R2 - "сходу"

Вступление
      Рекомендуется сначала прочитать инструкцию по инсталляции (в корне диска с дистрибутивом), но если не читать ... то можно и вот так:
Все равно для установки WIS придется немного почитать :)
      В результате выше показанных действий у меня получилась виртуальная машина в которой почти все работало .... WIS работал но ... Data Source Manager например не работал ..была 404.17 ошибка.. :( .
      После непродолжительного общения с google.com выяснилось что это проблема IIS и надо  поставить некоторый хотфикс .... Но все остальное работает :)
   




воскресенье, 2 декабря 2012 г.

Установка sql 2012 для SP 2012R2 - "сходу"

Это первая часть установки ... до перезагрузки :) я стараюсь все делать не по инструкции, а методом "научного тыка" , и таким образом тут записана не быстрая инструкция по установке  а длинная ... с отлавливанием проблем и их решением :)
Вторая часть может рассматривается как отдельно  так и вместе с первой , тк инсталляция sql начинается в ней с самого начала. Ну только отличается немного, тк некоторые компоненты установились в первой части.

Если отчеты и WIS использовать не планируете, то Репортинги можно не ставить.

P.S.: для более ранних версий System Platform нужен sql 2008 x86

System Platform 2012R2

Совсем недавно вышла Wonderware System Platform 2012R2 !

В связи с этим событием мне нужны новые виртуальные машины для тестирования этого программного продукта  , и я решил записать весь процесс создания виртуалок и инсталляции System Platform 2012R2 .... и я буду выкладывать видео с краткими комментариями !

пятница, 16 марта 2012 г.

вольный перевод текноута 825

Давно я ничего не писал сюда .. буду исправляться :)

И Так …  
         В очередной раз столкнулся по работе с настройкой связи между платформами Wonderware Application Server и в частности с резервированием движков на онных платформах …. да и новый текноут по данной теме вышел Tech Note 825 Industrial Application Server Redundancy: Troubleshooting Guidelines. Попробую компактно и по русски  все что там описано законспектировать, без картинок и скоментариями …. картинки в оригинале смотреть  :)
(авторы оригинального текноута P. Karthikeyan and N. Khadikar)


  1. Отключаем UAC (Tech Note 772 ,Tech Note 733)
  2. Убеждаемся что Фаервол везде выключен
  3. Убеждаемся что версия .NET Framework на всех машинах одинаковая
  4. Проверяем пингами связь между резервируемыми машинами и между этими машинами и Галактикой.
    Пинговать по как по
    именам, так  и по IP адресам.
    IP
    адреса сверять с теми что в пингах по именам показывает и по ipconfig /all !
    Имена и IP в hosts файле (если мы  его вместо/вместе DNS используем C:\Windows\System32\drivers\etc\hosts) должны совпадать с именами и адресами на машинах (
    были случаи однако....)
  5. Отключить IPv6 для используемых подключений (пишут что иногда помогает :) )
  6. Проверить порядок привязки сетевых карт в настройках Windows.
    Основная сеть по которой платформы общаются обязательно первой, линк между резервными после основной или дальше.
    Tech Note 773 и Tech Note 368
  7. Проверяем настройки DCOM чтобы убедится что он включен :)
    как это делать в Windows 2000 и 2003 читаем в
    Tech Note 461
    В 7ке и 2008 порядок действий такой
    • открываем  Component Services. (Control Panel\All Control Panel Items\Administrative Tools)
    • Выбираем в дереве компьютор для которого собираемся настраивать DCOM (обычно он там 1 и называется My Computer) и правой кнопкой мышки по нему щелкаем :)
    • в выпвшей меню выбераем Properties
    • далее вкладку  Default Properties
    • если не установлена то ставим галочку Enable Distributed COM on the computer. Authentication Level = Connect. Impersonation Level = Identify. Остальные галочки “uncheck”....
    • OK
  8. Проверяем разрешения для папок
    C:\Program Files\ArchestrA\Framework\Bin\CheckPointer
    C:\Program Files\ArchestrA\Framework\Bin\GalaxyData
    C:\Program Files\ArchestrA\Framework\Bin\GlobalDataCache
    Подробнее в
    Tech Note 461 (постараюсь описать развернуто позже)
  9. Убеждаемся что simple file sharing выключен.
    Проверить можно в любой папке через меню
    Folder OptionsView tab → Advanced settings. В ХР убрать галочку Use simple file sharing (Recommended), в Vista|7 убрать Use Sharing Wizard (Recommended).
  10. Версия Application Server должна быть одинаковая на обоих машинах используемых для резервирования.Тест: Первый деплой резервируемого движка не каскадом и с отмеченной галочкой Include Redundant Partner. Проверить резервирование и только после этого деплоить объекты.
  11. Проверяем конфигурацию платформы
    • configuration → General → Network address используем имя ноды а не IP адрес
    • configuration → General → Redundancy Message Channel IP address вписан собственный IP адрес RMC сети а не адрес второй машины (было и сам путал :) )
  12. Проверяем конфигурацию движка
    • галочка Restart the engine when it fails должна быть убрана
    • время скана - Scan Period выставляем болше стандартного и делаем его разным на разных движках для того чтобы они не падали одновременно
    • Если платформы друг друга видят но есть проблеммы с резервированием рекомендуется увеличить значение configuration → Redundancy → Maximum time to discover partners до 30000
    • После сохранения изменений проверьте разрешилась ли проблема … передеплойте :)
    • При большом количестве объектов на движке (несколько сотен штук или сложных просто очень.... ) необходимо распределять нагрузку. Создайте новые движки и перенесите некоторые объекты на них для равномерного распределения нагрузки
  13. Используйте Object Viewer чтобы проверить работу резервирования. Проверяйте следующие атрибуты:
    • Redundancy.Status
    • Redundancy.PartnerStatus
    • Redundancy.Identity
    • Platform Engine.Objects (опционально но полезно)

вторник, 14 декабря 2010 г.

Динамическое изменение входов объектов а AS

       Динамическая  перепривязка входов очень удобная штука но если ее очень много то возможны проблемы при работе движка.Сейчас я реализовал в одном проекте перепривязку  в соответствии с рекомендациями WW для решения этой проблемы.

    Выглядит это примерно так :
скрипт перепривязки повешен на "WhileTrue"
условие выполнения " MyContainer.ScanState"
Запускается привязка на 1-2 скане при условии что объект контейнер уже задеплоен и работает , тк с него берется путь для привязки.

в конце скрипта я добавил строку
me.SetInput.Disabled=true;
тк менять приязку в моем случае надо только после деплоймента , а при перезапуске привязка сохраняется и это лишняя трата ресурсов.

среда, 8 декабря 2010 г.

XmlDocument и Wonderware Application Server Scripting

            В скриптах AS сейчас нет структуры  case, приходится заменять  ее кучей if. В некоторых задачах приходится в зависимости от значения одной величины менять значение другой или нескольких, и пока вариантов не много это еще выглядит нормально .... но вот если больше 10 то это уже 2 экрана if then elseif ..... некрасиво ... и менять это неудобно :) возникла идея заменить это все какой нибудь структурой но ничего подходящего скрипты в AS не могу :( . 
             
      Это была предыстория :)

      Решил эту проблему сейчас с помощью .NET  System.Xml.XmlDocument. Все получилось очень просто, но пока адаптировал к языку скриптов AS пришлось немного повозится.

Вот результат.

создание объекта и загрузка xml в объект

dim EngUnitDoc as System.Xml.XmlDocument;
EngUnitDoc = new System.Xml.XmlDocument;
EngUnitDoc.load(me.xmlPath);

выгрузка объекта в общее пространство приложения .... правильно называется оно не так но вроде понятно :)


System.AppDomain.CurrentDomain.SetData(Me.Tagname+"XMLDoc",EngUnitDoc);

Все файл прочитали и он доступен для всех объектов... вероятно на том же самом движке , но не уверен еще не проверял. 

Теперь получаем доступ к данным которые мы загрузили из скрипта 

dim EngUnitDoc as System.Xml.XmlDocument;
EngUnitDoc = System.AppDomain.CurrentDomain.GetData(MyContainer.Tagname+"XMLDoc");
if EngUnitDoc <> null then
dim collection as System.Xml.XmlAttributeCollection;
collection = EngUnitDoc.SelectSingleNode("EngUnits/unit[@id='"+Me.Measurment+"']").Attributes;
Me.EngUnits =collection.GetNamedItem("text").Value;
me.accuracy =StringToReal(collection.GetNamedItem("accuracy").Value);
me.ValueOutDesc =collection.GetNamedItem("Description").Value;
'setGood(me.accuracy);
else
Me.EngUnits ="error";
me.accuracy =0.0001;
me.ValueOutDesc = "ERROR: XMLDoc  ";
endif;


вот собственно и все :) 
xml файл использовал примерно такой (не знаю как сюда его вставить в связи с чем заменил < на *  )



*?xml version="1.0" encoding="utf-8"?*
*EngUnits*
  *unit id="1234567" Description="xxxxxxxx" text="emu" accuracy="0.0001"**/unit*
  *unit id="1137" Description="xxxxx" text="xxxx" accuracy="0.001"**/unit*
*/EngUnits*





P.S.: текст этот писал скорее для себя на будущее, в связи с чем все очень кратко. Подробности смотреть в msdn :)
EngUnits/unit[@id='"+Me.Measurment+"']" - XSLT в Гугле или msdn

понедельник, 21 июня 2010 г.

Wonderware TrendClient 3.1sp2patch1

Wonderware AS31_SP2P01 ! TrendClient начал работать почти нормально !
Теперь с вот такой скрипт добавляет перо на тренд и настраивает его ... раньше это все тоже было но не работало или работало не так как хотелось бы :)




'Добавление нового пера
TrendClient1.AddPen(PenName,Expression,HistorySource,HistoryTagName,HistoryTagType);
TrendClient1.Pen.TrendType = 1;
TrendClient1.Pen.TrendHi = Max;
TrendClient1.Pen.TrendLo = Min;
TrendClient1.Pen.Units = Unit;
TrendClient1.Pen.Description = PenDescription;

TrendClient1.Pen.Width = PenWidth;


'если захочется больше перьев на графике то надо бы более красивую конструкцию ....


if TrendClient1.Pen.Index == 0 then TrendClient1.Pen.Color = System.Drawing.Color.FromName("Blue"); endif;

if TrendClient1.Pen.Index == 1 then TrendClient1.Pen.Color = System.Drawing.Color.FromName("Green"); endif;
if TrendClient1.Pen.Index == 2 then TrendClient1.Pen.Color = System.Drawing.Color.FromName("Red"); endif;



Теперь получилось сделать графический символ  шаблон со всеми нужными кнопочками масштабирования и т.д. и т.п. и использовать его везде где нужно ! и даже добавлять нужное количество перьев динамически :)

P.S.: Цвет второго и последующих перьев лучше задавать вручную т.к. первое перо по умолчанию синее , а вот последующие цвета выбираются случайно и они всегда разные ..... могут визуально совпадать с первым (я понимаю что теоретически  цвет не совпадает но на практике глаз не различает их)

четверг, 22 октября 2009 г.

.Net Control-ы для Intouch 10 +

Графические символы дбавленые в 10ом интаче вещь красивая но с ними добавили возможность использования .Net Control! На официальном форуме даже есть рекомендации по их использованию :)
Цитата с оф. форума:
Rickard Norin
I am not aware of any official guidelies. The best thing for you to do is probably to familiarize with the QuickScript.NET scripting language and the ArchestrA datatypes.
These impose a few limitations. The most obvious that come to mind are:


Scripting is not capable of catching exceptions. Catch exceptions internally and expose possible exception messages as a string property of the class.


Scripting does not fare well with some data relationships. For instance, it is not possible to do recusive script calls to traverse a hiearchical structure as the nodes collection of a TreeView. The parsing of such data has to be built into the control.


Scripting is, as far as I know, incapable of generics. This means that you have to use explicit datatypes as avoid properties of types like ObservableCollection or List.

As far as I know, only controls inheriting from System.Windows.Forms.Control namespace are valid. Using Windows Presentation Foundation (System.Windows.Controls namespace) is probably out of the picture.

Other than that, I think that most things are ok. As a scripting language as opposed to programming language (if there is such a distinction =), I find QuickScript.NET very capable. There is a very nice data binding and event subscription implementation for controls.

You can also import %WinDir%\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll and see what you can do with the standard controls out of the box. This will give you some ideas of how controls behave in the ArchestrA symbols.


Но ... ипортировать все контролы сразу я считаю не самая хорошая идя, всетаки их больше 50 , да и работать будут не все :) лучше уж взять и написать потомка от нужного заодно дописав немного функционала Smile например нужные вещи вывести в свойства ... события например данные не все возвращают нормально ...

Например недавно писал потомка TreeView для меню в Интаче... очень красиво получилось ... опишу в следующий раз наверное