diff --git a/VKT5_RemoteConsole/Plugin.cs b/VKT5_RemoteConsole/Plugin.cs
new file mode 100644
index 0000000..63c1fbc
--- /dev/null
+++ b/VKT5_RemoteConsole/Plugin.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Windows.Forms;
+using Lers.Plugins;
+using Lers.UI;
+using Lers.Poll;
+using Lers.Utils;
+using Lers.Interop;
+using System.Collections.Generic;
+using Lers.UI.Tabs;
+using Lers.Core;
+
+namespace Vkt5_RemoteConsole
+{
+ public class Plugin : IPlugin
+ {
+ #region IPlugin Members
+
+ ///
+ /// Инициализация плагина
+ ///
+ ///
+ public void Initialize(IPluginHost pluginHost)
+ {
+ Plugin.Host = pluginHost;
+
+ // Добавляем элементы управления для точек учёта
+ Plugin.Host.MainWindow.RegisterObjectAction(ObjectType.MeasurePoint, "ВКТ-5: Удалённый пульт", Properties.Resources.vkt5_icon, OnRemoteConsoleOpen);
+ }
+
+ #endregion
+
+ ///
+ /// Экземпляр хост-интерфейса клиента
+ ///
+ internal static IPluginHost Host
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Пользователь выбрал пункт меню или навигационного окна "Удалённый пульт"
+ ///
+ ///
+ ///
+ private void OnRemoteConsoleOpen(int actionId, object sender)
+ {
+ MeasurePoint measurePoint = (MeasurePoint)sender;
+
+ // Запрашиваем требуемую для работы информацию
+ measurePoint.Refresh(MeasurePointInfoFlags.Equipment);
+
+ // Проверим, что у точки учёта есть устройство
+ if (measurePoint.Device == null)
+ {
+ MessageBox.Show("У выбранной точки учёта не задано устройство. Выберите точку учёта с поддерживаемым устройством.",
+ "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+
+ return;
+ }
+
+ // Проверим, что мы работаем с ВКТ-5
+ if (!CheckDeviceModel(measurePoint.Device))
+ {
+ MessageBox.Show("Удалённый пульт ВКТ-5 не поддерживает работу с устройствами "
+ + measurePoint.Device.Model.Title, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+
+ return;
+ }
+
+ // Проверим, открыто ли окно с опросом этого устройства
+ Vkt5RemoteConsoleForm currentForm = GetOpenedForm(measurePoint.Device);
+ if (currentForm == null)
+ {
+ // Такого окна нет, открываем
+ NewForm(measurePoint.Device);
+ }
+ else
+ {
+ // Окно уже есть, переводим фокус на него
+ currentForm.Show();
+ currentForm.Focus();
+ }
+ }
+
+
+ ///
+ /// Проверяет, что в выбранной точке учёта указана модель,
+ /// которая поддерживается удалённым пультом
+ ///
+ ///
+ /// true если модель поддерживается, иначе false
+ private bool CheckDeviceModel(Equipment device)
+ {
+ return device.Model.Id == (int)DeviceModel.VKT_5;
+ }
+
+ ///
+ /// Открывает новое окно для управления устройством
+ ///
+ ///
+ private void NewForm(Equipment device)
+ {
+ // Окно для этого устройства ещё не открыто
+ Vkt5RemoteConsoleForm mainForm = new Vkt5RemoteConsoleForm();
+
+ // Заголовок окна
+ mainForm.Text = "Удалённый пульт - " + device.ToString();
+
+ RemoteConsoleFormParams param = new RemoteConsoleFormParams();
+
+ // Параметры базовой формы опроса
+ param.PollConnections = device.PollSettings.Connections;
+ if (param.PollConnections != null && param.PollConnections.Length > 0)
+ {
+ param.SelectedConnection = param.PollConnections[0];
+ }
+
+ // Параметры формы удалённого пульта
+ param.Device = device;
+
+ // Инициализация
+ mainForm.Initialize(param, Plugin.Host.Server);
+
+ Plugin.Host.MainWindow.AddPage(mainForm);
+
+ mainForm.Show();
+
+ mainForm.FormClosed += new System.Windows.Forms.FormClosedEventHandler(currentForm_FormClosed);
+
+ lock (this.visibleForms)
+ {
+ this.visibleForms.Add(mainForm);
+ }
+ }
+
+ ///
+ /// Возвращает открытую форму, работающую с указанным устройством, или null если формы нет
+ ///
+ ///
+ ///
+ private Vkt5RemoteConsoleForm GetOpenedForm(Equipment device)
+ {
+ lock (this.visibleForms)
+ {
+ foreach (Vkt5RemoteConsoleForm form in this.visibleForms)
+ {
+ if (form.Parameters.Device == device)
+ {
+ return form;
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+ ///
+ /// Закрыто окно удалённого пульта. Удаляем его из списка открытых окон.
+ ///
+ ///
+ ///
+ void currentForm_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
+ {
+ lock (this.visibleForms)
+ {
+ this.visibleForms.Remove((Vkt5RemoteConsoleForm)sender);
+ }
+ }
+
+ private List visibleForms = new List();
+ }
+}
\ No newline at end of file
diff --git a/VKT5_RemoteConsole/Properties/AssemblyInfo.cs b/VKT5_RemoteConsole/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..7f4425e
--- /dev/null
+++ b/VKT5_RemoteConsole/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Lers.Plugins;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Удалённый пульт ВКТ-5")]
+[assembly: AssemblyDescription("Внешний модуль ЛЭРС УЧЕТ для удалённого управления теплосчётчиками ВКТ-5")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("ООО \"Хабаровский центр энергоресурсосбережения\" (www.lers.ru)")]
+[assembly: AssemblyProduct("Система диспетчеризации ЛЭРС УЧЕТ")]
+[assembly: AssemblyCopyright("© 2000-2014, Хабаровский центр энергоресурсосбережения")]
+[assembly: AssemblyTrademark("Внимание: Данная компьютерная программа защищена законами об авторских правах и международными соглашениями. Незаконное воспроизведение или распространения данной программы или любой ее части влечет гражданскую и уголовную ответственность.")]
+[assembly: AssemblyCulture("")]
+
+[assembly: AssemblyPlugin("B8837A83-3700-47E1-ADAA-02E7496914F0")]
+[assembly: AssemblyPluginWebsite("http://www.lers.ru")]
+[assembly: AssemblyPluginEmail("support@lers.ru")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("092a73fe-433c-4ab9-b6df-54ca0393806c")]
+
+// Чтобы внешние модули обновлялись автоматически, необходимо увеличивать версию файла.
+// Т.к. мы можем забыть это сделать, то лучше чтобы версия увеличивалась сама. Звездочку можно задать только для версии сборки,
+// для версии файла она не работает. Но если не указать версию файла, то она будет равна версии сборки.
+
+[assembly: AssemblyVersion("1.1.*")]
+//[assembly: AssemblyFileVersion("1.0.0.0")]
+
diff --git a/VKT5_RemoteConsole/Properties/Resources.Designer.cs b/VKT5_RemoteConsole/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..7f3ade7
--- /dev/null
+++ b/VKT5_RemoteConsole/Properties/Resources.Designer.cs
@@ -0,0 +1,153 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Vkt5_RemoteConsole.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Vkt5_RemoteConsole.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap back {
+ get {
+ object obj = ResourceManager.GetObject("back", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap down {
+ get {
+ object obj = ResourceManager.GetObject("down", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap enter {
+ get {
+ object obj = ResourceManager.GetObject("enter", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap left {
+ get {
+ object obj = ResourceManager.GetObject("left", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap menu {
+ get {
+ object obj = ResourceManager.GetObject("menu", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap right {
+ get {
+ object obj = ResourceManager.GetObject("right", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap tab {
+ get {
+ object obj = ResourceManager.GetObject("tab", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap up {
+ get {
+ object obj = ResourceManager.GetObject("up", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap vkt5_icon {
+ get {
+ object obj = ResourceManager.GetObject("vkt5_icon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+ }
+}
diff --git a/VKT5_RemoteConsole/Properties/Resources.resx b/VKT5_RemoteConsole/Properties/Resources.resx
new file mode 100644
index 0000000..dddbd34
--- /dev/null
+++ b/VKT5_RemoteConsole/Properties/Resources.resx
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\Resources\vkt5_icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\back.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\down.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\enter.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\left.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\menu.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\right.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\tab.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\up.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/VKT5_RemoteConsole/Properties/licenses.licx b/VKT5_RemoteConsole/Properties/licenses.licx
new file mode 100644
index 0000000..e69de29
diff --git a/VKT5_RemoteConsole/Resources/PluginImage.png b/VKT5_RemoteConsole/Resources/PluginImage.png
new file mode 100644
index 0000000..ab44f66
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/PluginImage.png differ
diff --git a/VKT5_RemoteConsole/Resources/back.png b/VKT5_RemoteConsole/Resources/back.png
new file mode 100644
index 0000000..c95a0d3
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/back.png differ
diff --git a/VKT5_RemoteConsole/Resources/down.png b/VKT5_RemoteConsole/Resources/down.png
new file mode 100644
index 0000000..bb9bc22
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/down.png differ
diff --git a/VKT5_RemoteConsole/Resources/enter.png b/VKT5_RemoteConsole/Resources/enter.png
new file mode 100644
index 0000000..9531f91
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/enter.png differ
diff --git a/VKT5_RemoteConsole/Resources/left.png b/VKT5_RemoteConsole/Resources/left.png
new file mode 100644
index 0000000..ff63819
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/left.png differ
diff --git a/VKT5_RemoteConsole/Resources/menu.png b/VKT5_RemoteConsole/Resources/menu.png
new file mode 100644
index 0000000..2f90c45
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/menu.png differ
diff --git a/VKT5_RemoteConsole/Resources/right.png b/VKT5_RemoteConsole/Resources/right.png
new file mode 100644
index 0000000..3261053
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/right.png differ
diff --git a/VKT5_RemoteConsole/Resources/tab.png b/VKT5_RemoteConsole/Resources/tab.png
new file mode 100644
index 0000000..4f7e23c
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/tab.png differ
diff --git a/VKT5_RemoteConsole/Resources/up.png b/VKT5_RemoteConsole/Resources/up.png
new file mode 100644
index 0000000..d58d237
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/up.png differ
diff --git a/VKT5_RemoteConsole/Resources/vkt5_icon.png b/VKT5_RemoteConsole/Resources/vkt5_icon.png
new file mode 100644
index 0000000..9c37715
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/vkt5_icon.png differ
diff --git a/VKT5_RemoteConsole/Resources/vkt5_icon1.png b/VKT5_RemoteConsole/Resources/vkt5_icon1.png
new file mode 100644
index 0000000..9c37715
Binary files /dev/null and b/VKT5_RemoteConsole/Resources/vkt5_icon1.png differ
diff --git a/VKT5_RemoteConsole/Vkt5Console.cs b/VKT5_RemoteConsole/Vkt5Console.cs
new file mode 100644
index 0000000..3f1e71b
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5Console.cs
@@ -0,0 +1,333 @@
+using System;
+using Lers;
+using Lers.Poll;
+using System.Collections.Generic;
+
+
+namespace Vkt5_RemoteConsole
+{
+ delegate void VktDataReadEventHandler(byte[] dataByte);
+
+ enum Vkt5Key: byte
+ {
+ Right = 0,
+ Left = 1,
+ Down = 2,
+ Up = 3,
+ Tab = 4,
+ Enter = 5,
+ Back = 6,
+ Menu = 7,
+ LongMenuPress = 9
+ }
+
+
+ ///
+ /// Класс для отправки запросов и считывания ответов от ECL 300
+ /// ВНИМАНИЕ! После считывания ответа перед повторным запросом к прибору нужно выждать 400мс
+ ///
+ class Vkt5Console
+ {
+ #region События и методы для протоколирования
+
+ ///
+ /// Вызвается при ошибке выполнения запроса
+ ///
+ public event EventHandler RequestError;
+
+ private void CallRequestError()
+ {
+ if (this.RequestError != null)
+ this.RequestError(this, EventArgs.Empty);
+ }
+
+ ///
+ /// Событие поднимается когда необходимо запротоколировать ошибку чтения данных
+ ///
+ public event WriteLogEventHandler WriteLog;
+
+ private void LogMessage(string msg)
+ {
+ if (this.WriteLog != null)
+ {
+ this.WriteLog(Importance.Info, msg);
+ }
+ }
+
+ private void LogWarning(string msg)
+ {
+ if (this.WriteLog != null)
+ {
+ this.WriteLog(Importance.Warn, msg);
+ }
+ }
+
+ private void LogError(string msg)
+ {
+ if (this.WriteLog != null)
+ {
+ this.WriteLog(Importance.Error, msg);
+ }
+ }
+
+ #endregion
+
+ ///
+ /// Сетевой адрес прибора
+ ///
+ public int NetworkAddress
+ {
+ get;
+ set;
+ }
+
+ ///
+ /// Конструктор
+ ///
+ ///
+ public Vkt5Console(RemoteConsole remoteConsole)
+ {
+ this.NetworkAddress = 0;
+
+ this.remoteConsole = remoteConsole;
+ this.remoteConsole.DeviceDataReceived += new EventHandler(remoteConsole_DeviceDataReceived);
+ }
+
+ ///
+ /// Сброс состояния объекта в исходную позицию
+ ///
+ public void Reset()
+ {
+ this.handlers.Clear();
+ }
+
+ ///
+ /// Отправляет команду на чтение буфера экрана устройства
+ ///
+ ///
+ public void ReadScreenBuffer(VktDataReadEventHandler readHandler)
+ {
+ byte[] rq = PackRequest(new byte[] { 0x03, 0x0C, 0x00, 0x00, 0x00 });
+ SendRequest(rq, 38, readHandler);
+ }
+
+
+ ///
+ /// Отправляет в устройство команду нажатия клавишы
+ ///
+ ///
+ ///
+ public void SendKeyCode(Vkt5Key key, VktDataReadEventHandler readHandler)
+ {
+ byte[] rq = PackRequest(new byte[] { 0x10, 0x0D, 0x00, 0x00, 0x01, 0x01, (byte)key });
+ SendRequest(rq, 8, readHandler);
+ }
+
+ ///
+ /// Формирует пакет с запросом прибору
+ ///
+ ///
+ ///
+ private byte[] PackRequest(byte[] rqData)
+ {
+ List request = new List();
+
+ // Сетевой адрес
+ request.Add((byte)this.NetworkAddress);
+
+ // Пакет с запросом
+ request.AddRange(rqData);
+
+ ushort crc = ModBusCrc.Calc(request);
+
+ request.Add((byte)(crc & 0x00FF));
+ request.Add((byte)((crc & 0xFF00) >> 8));
+
+
+ return request.ToArray();
+ }
+
+
+ ///
+ /// Отправка запроса прибору
+ ///
+ ///
+ ///
+ ///
+ private void SendRequest(byte[] request, int responseLength, VktDataReadEventHandler readHandler)
+ {
+ CommandSettings cmd = new CommandSettings("", 1000, responseLength, 10);
+
+ this.handlers.AddLast(readHandler);
+
+ this.responseLength = responseLength;
+
+ this.remoteConsole.SendCommandAsync(request, cmd, 0, DataReadCallback, null);
+ }
+
+ private void DataReadCallback(Lers.AsyncOperation asyncOp)
+ {
+ try
+ {
+ // Завершаем операцию чтения данных
+ Lers.Networking.ExecuteRequestAsyncOperation execRequestAsyncOp
+ = (Lers.Networking.ExecuteRequestAsyncOperation)asyncOp;
+
+ execRequestAsyncOp.EndExecuteRequest();
+ }
+ catch (Exception e)
+ {
+ // При ошибке отправки данных отключаемся от устройства
+ LogError("Ошибка чтения данных. " + e.Message);
+ }
+ }
+
+ private void remoteConsole_DeviceDataReceived(object sender, DeviceDataEventArgs args)
+ {
+ // Проверим, что консоль подключена к прибору
+ if (!this.remoteConsole.IsConnected)
+ {
+ return;
+ }
+
+ // Получаем обработчик запроса
+ VktDataReadEventHandler currentHandler = this.handlers.First.Value;
+ this.handlers.RemoveFirst();
+
+ // Проверим длину считанного пакета
+ if (args.Response.Length < 5)
+ {
+ // Повторяем запрос
+ LogError("Неверная длина ответа прибора. Ожидалось не менее 5 байт, получено " + args.Response.Length);
+
+ CallRequestError();
+
+ // Отключаемся
+ try
+ {
+ this.remoteConsole.DisconnectAsync(null, null);
+ }
+ catch (Lers.PermissionDeniedException exc)
+ {
+ LogError("Ошибка отключения удалённого пульта. " + exc.Message);
+ }
+
+ return;
+ }
+
+ // Проверим контрольную сумму
+ ushort calcCs = ModBusCrc.Calc(args.Response, 0, args.Response.Length - 2);
+ ushort recvCrc = BitConverter.ToUInt16(args.Response, args.Response.Length - 2);
+
+ if (calcCs != recvCrc)
+ {
+ LogWarning("Не сходится контрольная сумма ответа");
+
+ // Повторяем запрос
+ SendRequest(args.Request, this.responseLength, currentHandler);
+
+ return;
+ }
+
+ // Проверим сетевой адрес
+ if (args.Response[0] != (byte)this.NetworkAddress)
+ {
+ LogWarning("В ответе указан неверный контрольный адрес");
+
+ // Повторяем запрос
+ SendRequest(args.Request, this.responseLength, currentHandler);
+
+ return;
+ }
+
+ // Возвращаем считанные прибором данные
+ if (currentHandler != null)
+ {
+ byte[] rspData = new byte[args.Response.Length - 5];
+ Array.Copy(args.Response, 3, rspData, 0, rspData.Length);
+ currentHandler(rspData);
+ }
+ }
+
+
+ ///
+ /// Объект для отправки запросов и считывания ответов от удалённого прибора
+ ///
+ private RemoteConsole remoteConsole = null;
+
+ ///
+ /// Длина ответа на запрос
+ ///
+ private int responseLength = 0;
+
+ ///
+ /// Список обработчиков ответов
+ ///
+ LinkedList handlers = new LinkedList();
+ }
+
+ class ModBusCrc
+ {
+ ///
+ /// Вычисляет контрольную сумму для переданного блока данных, согласно
+ /// спецификации протокола ModBus (Modicon Modbus Protocol Reference Guide)
+ ///
+ /// Для расчета контрольной суммы используется модифицированный CRC-16-IBM с полиномом 0xA001.
+ /// В отличие от стандартного алгоритма CRC-16-IBM, начальное значение устанавливается равным 0xFFFF
+ ///
+ /// Массив байт, по которому нужно посчитать CRC
+ /// Начальный индекс в массиве байт
+ /// Количество байт, начиная со start, используемых в расчете контрольной суммы
+ /// Значение контрольной суммы
+ public static ushort Calc(IList input, int start, int length)
+ {
+ int i, j;
+
+ if (length > input.Count)
+ throw new Exception(String.Format("При расчете контрольной суммы по блоку данных длиной {0} байт, указана длина {1} байт", input.Count, length));
+
+ // Для хранения CRC используем тип int, чтобы не заниматься приведением типов
+ // постоянно, а сделать это только при выходе
+ // При расчете CRC значение никогда не выйдет за границы 2-х младших байт (сдвигаем всегда вправо)
+ // поэтому при операциях сдвига, сдвиг знакового бита переменной crc не обрабатываем
+ int crc = 0xFFFF;
+
+ // обнуляем 2 старших байта
+ for (i = start; i < start + length; i++)
+ {
+ crc = (ushort)crc & 0xFF00 + (ushort)(crc & 0x00FF) ^ input[i];
+
+ for (j = 0; j < 8; j++)
+ {
+ if ((crc & 0x01) > 0)
+ {
+ // Сдвигаем вправо на 1 бит и XOR-им полиномом 0xA001
+ crc = (crc >> 1) ^ 0xA001;
+ }
+ else
+ {
+ // Сдвигаем вправо на 1 бит
+ crc = (crc >> 1);
+ }
+ }
+ }
+
+ // Возвращаем 2 младших байта
+ return (ushort)crc;
+ }
+
+ ///
+ /// Вычисляет контрольную сумму для переданного блока данных, согласно
+ /// спецификации протокола ModBus (Modicon Modbus Protocol Reference Guide)
+ ///
+ /// Для расчета контрольной суммы используется модифицированный CRC-16-IBM с полиномом 0xA001.
+ /// В отличие от стандартного алгоритма CRC-16-IBM, начальное значение устанавливается равным 0xFFFF
+ ///
+ /// Массив байт, по которому нужно посчитать CRC
+ /// Значение контрольной суммы
+ public static ushort Calc(IList input)
+ {
+ return ModBusCrc.Calc(input, 0, input.Count);
+ }
+ }
+}
\ No newline at end of file
diff --git a/VKT5_RemoteConsole/Vkt5ConsoleControl.Designer.cs b/VKT5_RemoteConsole/Vkt5ConsoleControl.Designer.cs
new file mode 100644
index 0000000..0e3548e
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5ConsoleControl.Designer.cs
@@ -0,0 +1,222 @@
+namespace Vkt5_RemoteConsole
+{
+ partial class Vkt5ConsoleControl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Vkt5ConsoleControl));
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.txtLine2 = new System.Windows.Forms.Label();
+ this.txtLine1 = new System.Windows.Forms.Label();
+ this.btnMenu = new System.Windows.Forms.Button();
+ this.btnBack = new System.Windows.Forms.Button();
+ this.btnTab = new System.Windows.Forms.Button();
+ this.btnLeft = new System.Windows.Forms.Button();
+ this.btnEnter = new System.Windows.Forms.Button();
+ this.btnDown = new System.Windows.Forms.Button();
+ this.btnUp = new System.Windows.Forms.Button();
+ this.btnRight = new System.Windows.Forms.Button();
+ this.refreshTimer = new System.Windows.Forms.Timer();
+ this.cursorTimer = new System.Windows.Forms.Timer();
+ this.panel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // panel1
+ //
+ this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(140)))), ((int)(((byte)(180)))), ((int)(((byte)(40)))));
+ this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.panel1.Controls.Add(this.txtLine2);
+ this.panel1.Controls.Add(this.txtLine1);
+ this.panel1.Location = new System.Drawing.Point(12, 14);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(318, 67);
+ this.panel1.TabIndex = 20;
+ //
+ // txtLine2
+ //
+ this.txtLine2.Font = new System.Drawing.Font("Lucida Console", 21.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
+ this.txtLine2.ForeColor = System.Drawing.Color.DimGray;
+ this.txtLine2.Location = new System.Drawing.Point(3, 35);
+ this.txtLine2.Name = "txtLine2";
+ this.txtLine2.Size = new System.Drawing.Size(310, 29);
+ this.txtLine2.TabIndex = 1;
+ this.txtLine2.Text = "подключения";
+ //
+ // txtLine1
+ //
+ this.txtLine1.Font = new System.Drawing.Font("Lucida Console", 21.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
+ this.txtLine1.ForeColor = System.Drawing.Color.DimGray;
+ this.txtLine1.Location = new System.Drawing.Point(3, 3);
+ this.txtLine1.Name = "txtLine1";
+ this.txtLine1.Size = new System.Drawing.Size(310, 29);
+ this.txtLine1.TabIndex = 0;
+ this.txtLine1.Text = "Нет";
+ //
+ // btnMenu
+ //
+ this.btnMenu.BackColor = System.Drawing.Color.Gray;
+ this.btnMenu.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnMenu.Image = ((System.Drawing.Image)(resources.GetObject("btnMenu.Image")));
+ this.btnMenu.Location = new System.Drawing.Point(222, 102);
+ this.btnMenu.Name = "btnMenu";
+ this.btnMenu.Size = new System.Drawing.Size(108, 64);
+ this.btnMenu.TabIndex = 18;
+ this.btnMenu.UseVisualStyleBackColor = false;
+ this.btnMenu.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnMenu_MouseDown);
+ this.btnMenu.MouseUp += new System.Windows.Forms.MouseEventHandler(this.btnMenu_MouseUp);
+ //
+ // btnBack
+ //
+ this.btnBack.BackColor = System.Drawing.Color.Gray;
+ this.btnBack.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnBack.Image = ((System.Drawing.Image)(resources.GetObject("btnBack.Image")));
+ this.btnBack.Location = new System.Drawing.Point(12, 102);
+ this.btnBack.Name = "btnBack";
+ this.btnBack.Size = new System.Drawing.Size(64, 64);
+ this.btnBack.TabIndex = 12;
+ this.btnBack.UseVisualStyleBackColor = false;
+ this.btnBack.Click += new System.EventHandler(this.btnBack_Click);
+ //
+ // btnTab
+ //
+ this.btnTab.BackColor = System.Drawing.Color.Gray;
+ this.btnTab.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnTab.Image = ((System.Drawing.Image)(resources.GetObject("btnTab.Image")));
+ this.btnTab.Location = new System.Drawing.Point(222, 172);
+ this.btnTab.Name = "btnTab";
+ this.btnTab.Size = new System.Drawing.Size(108, 64);
+ this.btnTab.TabIndex = 19;
+ this.btnTab.UseVisualStyleBackColor = false;
+ this.btnTab.Click += new System.EventHandler(this.btnTab_Click);
+ //
+ // btnLeft
+ //
+ this.btnLeft.BackColor = System.Drawing.Color.Gray;
+ this.btnLeft.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnLeft.Image = ((System.Drawing.Image)(resources.GetObject("btnLeft.Image")));
+ this.btnLeft.Location = new System.Drawing.Point(12, 172);
+ this.btnLeft.Name = "btnLeft";
+ this.btnLeft.Size = new System.Drawing.Size(64, 64);
+ this.btnLeft.TabIndex = 15;
+ this.btnLeft.UseVisualStyleBackColor = false;
+ this.btnLeft.Click += new System.EventHandler(this.btnLeft_Click);
+ //
+ // btnEnter
+ //
+ this.btnEnter.BackColor = System.Drawing.Color.Gray;
+ this.btnEnter.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnEnter.Image = ((System.Drawing.Image)(resources.GetObject("btnEnter.Image")));
+ this.btnEnter.Location = new System.Drawing.Point(152, 102);
+ this.btnEnter.Name = "btnEnter";
+ this.btnEnter.Size = new System.Drawing.Size(64, 64);
+ this.btnEnter.TabIndex = 14;
+ this.btnEnter.UseVisualStyleBackColor = false;
+ this.btnEnter.Click += new System.EventHandler(this.btnEnter_Click);
+ //
+ // btnDown
+ //
+ this.btnDown.BackColor = System.Drawing.Color.Gray;
+ this.btnDown.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnDown.Image = ((System.Drawing.Image)(resources.GetObject("btnDown.Image")));
+ this.btnDown.Location = new System.Drawing.Point(82, 172);
+ this.btnDown.Name = "btnDown";
+ this.btnDown.Size = new System.Drawing.Size(64, 64);
+ this.btnDown.TabIndex = 16;
+ this.btnDown.UseVisualStyleBackColor = false;
+ this.btnDown.Click += new System.EventHandler(this.btnDown_Click);
+ //
+ // btnUp
+ //
+ this.btnUp.BackColor = System.Drawing.Color.Gray;
+ this.btnUp.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnUp.Image = ((System.Drawing.Image)(resources.GetObject("btnUp.Image")));
+ this.btnUp.Location = new System.Drawing.Point(82, 102);
+ this.btnUp.Name = "btnUp";
+ this.btnUp.Size = new System.Drawing.Size(64, 64);
+ this.btnUp.TabIndex = 13;
+ this.btnUp.UseVisualStyleBackColor = false;
+ this.btnUp.Click += new System.EventHandler(this.btnUp_Click);
+ //
+ // btnRight
+ //
+ this.btnRight.BackColor = System.Drawing.Color.Gray;
+ this.btnRight.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
+ this.btnRight.Image = ((System.Drawing.Image)(resources.GetObject("btnRight.Image")));
+ this.btnRight.Location = new System.Drawing.Point(152, 172);
+ this.btnRight.Name = "btnRight";
+ this.btnRight.Size = new System.Drawing.Size(64, 64);
+ this.btnRight.TabIndex = 17;
+ this.btnRight.UseVisualStyleBackColor = false;
+ this.btnRight.Click += new System.EventHandler(this.btnRight_Click);
+ //
+ // refreshTimer
+ //
+ this.refreshTimer.Interval = 1000;
+ this.refreshTimer.Tick += new System.EventHandler(this.refreshTimer_Tick);
+ //
+ // cursorTimer
+ //
+ this.cursorTimer.Interval = 500;
+ this.cursorTimer.Tick += new System.EventHandler(this.cursorTimer_Tick);
+ //
+ // Vkt5ConsoleControl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.panel1);
+ this.Controls.Add(this.btnMenu);
+ this.Controls.Add(this.btnBack);
+ this.Controls.Add(this.btnTab);
+ this.Controls.Add(this.btnLeft);
+ this.Controls.Add(this.btnEnter);
+ this.Controls.Add(this.btnDown);
+ this.Controls.Add(this.btnUp);
+ this.Controls.Add(this.btnRight);
+ this.Name = "Vkt5ConsoleControl";
+ this.Size = new System.Drawing.Size(348, 257);
+ this.panel1.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Label txtLine2;
+ private System.Windows.Forms.Label txtLine1;
+ private System.Windows.Forms.Button btnMenu;
+ private System.Windows.Forms.Button btnBack;
+ private System.Windows.Forms.Button btnTab;
+ private System.Windows.Forms.Button btnLeft;
+ private System.Windows.Forms.Button btnEnter;
+ private System.Windows.Forms.Button btnDown;
+ private System.Windows.Forms.Button btnUp;
+ private System.Windows.Forms.Button btnRight;
+ private System.Windows.Forms.Timer refreshTimer;
+ private System.Windows.Forms.Timer cursorTimer;
+ }
+}
diff --git a/VKT5_RemoteConsole/Vkt5ConsoleControl.cs b/VKT5_RemoteConsole/Vkt5ConsoleControl.cs
new file mode 100644
index 0000000..efbaad5
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5ConsoleControl.cs
@@ -0,0 +1,382 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.Drawing.Text;
+using System.Runtime.InteropServices;
+using Lers;
+using Lers.Poll;
+
+namespace Vkt5_RemoteConsole
+{
+ ///
+ /// Делегат для события .
+ ///
+ public delegate void WriteLogEventHandler(Importance importance, string message);
+
+
+ ///
+ /// Контрол удалённого пульта ВКТ-5
+ ///
+ public partial class Vkt5ConsoleControl : UserControl
+ {
+ ///
+ /// Состояния контрола
+ ///
+ private enum State
+ {
+ /// Начальное состояния
+ None,
+
+ /// Отключены от прибора
+ Disconnected,
+
+ /// Режим ожидания команд
+ Ready,
+
+ /// Чтение буфера экрана
+ ReadingScreenBuffer,
+
+ /// Отправка кода клавиши
+ SendingKeyCode,
+
+ /// Ожидание обновления буфера экрана
+ WaitingScreenBuffer
+ }
+
+
+ #region События и методы для протоколирования
+
+ public event WriteLogEventHandler WriteLog;
+
+ private void LogMessage(string msg)
+ {
+ if (this.WriteLog != null)
+ {
+ this.WriteLog(Importance.Info, msg);
+ }
+ }
+
+ private void LogWarning(string msg)
+ {
+ if (this.WriteLog != null)
+ {
+ this.WriteLog(Importance.Warn, msg);
+ }
+ }
+
+ private void LogError(string msg)
+ {
+ if (this.WriteLog != null)
+ {
+ this.WriteLog(Importance.Error, msg);
+ }
+ }
+
+ #endregion
+
+
+ ///
+ /// Конструктор
+ ///
+ public Vkt5ConsoleControl()
+ {
+ InitializeComponent();
+
+ SetState(State.Disconnected);
+ }
+
+ ///
+ /// Инициализация контрола
+ ///
+ ///
+ ///
+ public void Initialize(RemoteConsole remoteConsole, int networkAddress)
+ {
+ this.vktConsole = new Vkt5Console(remoteConsole);
+ this.vktConsole.WriteLog += this.WriteLog;
+ this.vktConsole.RequestError += new EventHandler(vktConsole_RequestError);
+ this.vktConsole.NetworkAddress = networkAddress;
+ }
+
+ ///
+ /// Изменилось состояние подключения к удалённому устройству
+ ///
+ ///
+ public void ConnectionChanged(bool connected)
+ {
+ if (connected)
+ {
+ SetState(State.WaitingScreenBuffer);
+
+ this.vktConsole.Reset();
+
+ ReadScreenBuffer();
+ }
+ else
+ {
+ SetState(State.Disconnected);
+ }
+ }
+
+
+ #region Обработчики событий контролов
+
+ private void cursorTimer_Tick(object sender, EventArgs e)
+ {
+ this.displayCursor = !this.displayCursor;
+
+ RefreshCursor();
+ }
+
+ ///
+ /// Таймер обновления содержимого экрана
+ ///
+ ///
+ ///
+ private void refreshTimer_Tick(object sender, EventArgs e)
+ {
+ ReadScreenBuffer();
+ }
+
+ void vktConsole_RequestError(object sender, EventArgs e)
+ {
+ // Отменяем чтение
+ SetState(State.Ready);
+ }
+
+ private void btnUp_Click(object sender, EventArgs e)
+ {
+ SendKeyCode(Vkt5Key.Up);
+ }
+
+ private void btnDown_Click(object sender, EventArgs e)
+ {
+ SendKeyCode(Vkt5Key.Down);
+ }
+
+ private void btnTab_Click(object sender, EventArgs e)
+ {
+ SendKeyCode(Vkt5Key.Tab);
+ }
+
+ private void btnBack_Click(object sender, EventArgs e)
+ {
+ SendKeyCode(Vkt5Key.Back);
+ }
+
+ private void btnRight_Click(object sender, EventArgs e)
+ {
+ SendKeyCode(Vkt5Key.Right);
+ }
+
+ private void btnLeft_Click(object sender, EventArgs e)
+ {
+ SendKeyCode(Vkt5Key.Left);
+ }
+
+ private void btnEnter_Click(object sender, EventArgs e)
+ {
+ SendKeyCode(Vkt5Key.Enter);
+ }
+
+ private void btnMenu_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ if (!this.btnMenu.Enabled)
+ {
+ return;
+ }
+
+ this.isMenuBtnDown = true;
+ this.menuBtnPressTime = DateTime.Now;
+ }
+
+ private void btnMenu_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
+ {
+ if (!this.btnMenu.Enabled)
+ {
+ return;
+ }
+
+ if (this.isMenuBtnDown)
+ {
+ this.isMenuBtnDown = false;
+ DateTime now = DateTime.Now;
+
+ int totalMs = (int)(now - this.menuBtnPressTime).TotalMilliseconds;
+
+ if (totalMs >= 3000)
+ {
+ SendKeyCode(Vkt5Key.LongMenuPress);
+ }
+ else
+ {
+ SendKeyCode(Vkt5Key.Menu);
+ }
+ }
+ }
+
+ #endregion
+
+
+ private void ReadScreenBuffer()
+ {
+ if (this.state == State.Ready || this.state == State.WaitingScreenBuffer)
+ {
+ SetState(State.ReadingScreenBuffer);
+
+ this.vktConsole.ReadScreenBuffer(this.ReadScreenBufferCallback);
+ }
+ }
+
+
+ private void ReadScreenBufferCallback(byte[] data)
+ {
+ if (this.state != State.SendingKeyCode)
+ {
+ // Буфер экрана считан. Выставим состояние "Ready", если он пришёл не во время отправки кода клавиши.
+
+ SetState(State.Ready);
+ }
+
+ this.displayLine = Encoding.GetEncoding(866).GetString(data, 0, data.Length - 1);
+ this.cursorPos = data[data.Length - 1];
+
+ RefreshCursor();
+
+ if (!this.cursorTimer.Enabled)
+ {
+ this.cursorTimer.Start();
+ }
+
+ if (!this.refreshTimer.Enabled)
+ {
+ this.refreshTimer.Start();
+ }
+ }
+
+ private void SendKeyCode(Vkt5Key keyCode)
+ {
+ if (this.state == State.Disconnected || this.state == State.SendingKeyCode)
+ {
+ return;
+ }
+
+ SetState(State.SendingKeyCode);
+ this.vktConsole.SendKeyCode(keyCode, SendKeyCodeCallback);
+ }
+
+ private void SendKeyCodeCallback(byte[] data)
+ {
+ SetState(State.WaitingScreenBuffer);
+
+ ReadScreenBuffer();
+ }
+
+ ///
+ /// Устанавливает новое состояние контрола
+ ///
+ ///
+ private void SetState(State newState)
+ {
+ if (newState == this.state)
+ {
+ return;
+ }
+
+
+ switch (newState)
+ {
+ case State.Ready:
+ SetReady();
+ break;
+
+ case State.Disconnected:
+ SetDisconnected();
+ break;
+
+ case State.SendingKeyCode:
+ case State.WaitingScreenBuffer:
+ EnableButtons(false);
+ break;
+
+ case State.ReadingScreenBuffer:
+ break;
+ }
+
+
+ this.state = newState;
+ }
+
+ private void SetReady()
+ {
+ EnableButtons(true);
+ }
+
+ private void SetDisconnected()
+ {
+ this.cursorTimer.Stop();
+ this.displayLine = "";
+ this.cursorPos = 0;
+ }
+
+
+
+ private void RefreshCursor()
+ {
+ if (string.IsNullOrEmpty(this.displayLine))
+ {
+ return;
+ }
+
+ string cursorChar = "\u2588";
+
+ string showLine = this.displayLine;
+
+ if (this.displayCursor)
+ {
+ showLine = showLine.Remove(this.cursorPos, 1);
+ showLine = showLine.Insert(this.cursorPos, cursorChar);
+ }
+
+ this.txtLine1.Text = showLine.Substring(0, 16);
+ this.txtLine2.Text = showLine.Substring(16, 16);
+ }
+
+ private void EnableButtons(bool enable)
+ {
+ this.btnUp.Enabled = enable;
+ this.btnDown.Enabled = enable;
+ this.btnLeft.Enabled = enable;
+ this.btnRight.Enabled = enable;
+ this.btnEnter.Enabled = enable;
+ this.btnBack.Enabled = enable;
+ this.btnMenu.Enabled = enable;
+ this.btnTab.Enabled = enable;
+ }
+
+
+
+
+ ///
+ /// Объект для работы с подключенным ECL 300
+ ///
+ private Vkt5Console vktConsole = null;
+
+ ///
+ /// Текущее состояние контрола
+ ///
+ private State state = State.None;
+
+ private string displayLine = "";
+ private int cursorPos = 0;
+ private bool displayCursor = false;
+
+ private bool isMenuBtnDown = false;
+ private DateTime menuBtnPressTime = DateTime.MinValue;
+ }
+}
diff --git a/VKT5_RemoteConsole/Vkt5ConsoleControl.resx b/VKT5_RemoteConsole/Vkt5ConsoleControl.resx
new file mode 100644
index 0000000..0d08dd6
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5ConsoleControl.resx
@@ -0,0 +1,866 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+
+ 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
+ 3208vUqMAAAAAElFTkSuQmCC
+
+
+
+
+ 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
+ 8P9abW3/DWbMf1iOz3IqAAAAAElFTkSuQmCC
+
+
+
+
+ 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
+ SUVORK5CYII=
+
+
+
+
+ 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
+ SUVORK5CYII=
+
+
+
+
+ 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
+
+
+
+ 17, 17
+
+
+ 132, 16
+
+
\ No newline at end of file
diff --git a/VKT5_RemoteConsole/Vkt5RemoteConsoleForm.cs b/VKT5_RemoteConsole/Vkt5RemoteConsoleForm.cs
new file mode 100644
index 0000000..3969744
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5RemoteConsoleForm.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using Lers;
+using Lers.UI.Tabs;
+
+namespace Vkt5_RemoteConsole
+{
+ class Vkt5RemoteConsoleForm: RemoteConsoleForm
+ {
+ ///
+ /// Конструктор
+ ///
+ public Vkt5RemoteConsoleForm()
+ {
+ this.Load += new EventHandler(Vkt5RemoteConsoleForm_Load);
+
+ // Создаём контрол удалённого пульта и размещаем на пользовательской панели
+ this.vktConsoleControl = new Vkt5ConsoleControl();
+ this.vktConsoleControl.Parent = this.UserArea;
+ this.vktConsoleControl.Dock = System.Windows.Forms.DockStyle.Fill;
+
+ // Подписываемся на событие протоколирование контрола удалённого пульта.
+ // Каждый раз когда удалённый пульт будет протоколировать событие, будет вызываться этот метод.
+ this.vktConsoleControl.WriteLog += new WriteLogEventHandler(vktConsoleControl_WriteLog);
+ }
+
+
+ ///
+ /// Переопределяем инициализацию окна с удалённым пультом ВКТ-5
+ ///
+ ///
+ ///
+ public override void Initialize(RemoteConsoleFormParams parameters, Lers.LersServer server)
+ {
+ base.Initialize(parameters, server);
+
+ // Подписка на события подключения и отключения от удалённого устройства
+
+ this.RemoteConsole.Connected += new EventHandler(RemoteConsole_Connected);
+ this.RemoteConsole.Disconnected += new EventHandler(RemoteConsole_Disconnected);
+
+ int networkAddress = 0;
+ if (parameters.Device.PollSettings.Network != null)
+ {
+ Int32.TryParse(parameters.Device.NetworkAddress, out networkAddress);
+ }
+
+ // Инициализируем контрол с удалённым пультом
+ this.vktConsoleControl.Initialize(this.RemoteConsole, networkAddress);
+ }
+
+
+ void vktConsoleControl_WriteLog(Importance importance, string message)
+ {
+ this.AddLogRecord(importance, DateTime.Now, message);
+ }
+
+ void Vkt5RemoteConsoleForm_Load(object sender, EventArgs e)
+ {
+ this.vktConsoleControl.Enabled = false;
+ }
+
+ void RemoteConsole_Connected(object sender, EventArgs e)
+ {
+ this.vktConsoleControl.Enabled = true;
+ this.vktConsoleControl.ConnectionChanged(true);
+ }
+
+ void RemoteConsole_Disconnected(object sender, EventArgs e)
+ {
+ this.vktConsoleControl.Enabled = false;
+ this.vktConsoleControl.ConnectionChanged(false);
+ }
+
+
+ private Vkt5ConsoleControl vktConsoleControl = null;
+ }
+}
diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole.csproj b/VKT5_RemoteConsole/Vkt5_RemoteConsole.csproj
new file mode 100644
index 0000000..20eb7f3
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole.csproj
@@ -0,0 +1,127 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}
+ Library
+ Properties
+ Vkt5_RemoteConsole
+ Vkt5_RemoteConsole
+ v4.0
+ 512
+
+
+ true
+ full
+ false
+ C:\Program Files\LERS\Common\Plugins\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+
+
+
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+ False
+
+
+
+
+
+
+
+
+
+
+
+ UserControl
+
+
+ Vkt5ConsoleControl.cs
+
+
+ Form
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ Vkt5ConsoleControl.cs
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole.sln b/VKT5_RemoteConsole/Vkt5_RemoteConsole.sln
new file mode 100644
index 0000000..25e3d08
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vkt5_RemoteConsole", "Vkt5_RemoteConsole.csproj", "{5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|x64.ActiveCfg = Release|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|x86.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.csproj b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.csproj
new file mode 100644
index 0000000..8bdd364
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.csproj
@@ -0,0 +1,134 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}
+ Library
+ Properties
+ Vkt5_RemoteConsole
+ Vkt5_RemoteConsole
+ v4.0
+ 512
+
+
+ true
+ full
+ false
+ C:\Program Files\LERS\Common\Plugins\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+
+
+
+
+
+ False
+ ..\..\Framework\Lers.Plugins\bin\Debug\Lers.Plugins.dll
+ False
+
+
+ False
+ ..\..\Framework\Lers.Plugins.Attributes\bin\Debug\Lers.Plugins.Attributes.dll
+ False
+
+
+ False
+ ..\..\Framework\Lers.System\bin\Debug\Lers.System.dll
+ False
+
+
+ False
+ ..\..\Framework\Lers.UI\bin\Debug\Lers.UI.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+ UserControl
+
+
+ Vkt5ConsoleControl.cs
+
+
+ Form
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+ Vkt5ConsoleControl.cs
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.sln b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.sln
new file mode 100644
index 0000000..8f6701d
--- /dev/null
+++ b/VKT5_RemoteConsole/Vkt5_RemoteConsole_debug.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vkt5_RemoteConsole_debug", "Vkt5_RemoteConsole_debug.csproj", "{5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5622B98C-E274-4C99-BF9B-6FCC2E85EBD8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal