// DEPRECATED !!!

unit VspaCtrl;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Buttons, ComCtrls, VisVespA;

const
  VspaAlarms: array[0..23] of string = (
    #0+#$00#$04+#$00#$00+'Устройство не готово к работе',
    #0+#$00#$08+#$00#$08+'Авария',
    #0+#$00#$10+#$00#$10+'Ошибка ввода',
    #1+#$00#$01+#$00#$01+'Перегрузка по току. Нарушение в цепи заземления. Кз в нагрузке.',
    #1+#$00#$02+#$00#$02+'Перегрузка по напряжению',
    #1+#$00#$04+#$00#$04+'Перегрузка преобразователя',
    #1+#$00#$08+#$00#$08+'Перегрев теплоотвода',
    #1+#$00#$20+#$00#$20+'Нарушение основной цепи',
    #1+#$00#$80+#$00#$80+'Внешняя неисправность',
    #1+#$01#$00+#$01#$00+'Неисправность преобразователя',
    #1+#$02#$00+#$02#$00+'Перегрузка электродвигателя',
    #1+#$08#$00+#$08#$00+'Пропадание входного напряжения во время считывания состояния',
    #1+#$10#$00+#$10#$00+'Недостаточное напрежение',
    #1+#$20#$00+#$20#$00+'Обрыв фазы на входе или выходе',
    #1+#$40#$00+#$40#$00+'Неисправность в цепи торможения',
    #2+#$00#$01+#$00#$01+'Ошибка записи',
    #2+#$00#$08+#$00#$08+'Значение данных находится вне допустимых пределов',
    #2+#$00#$10+#$00#$10+'Неверное значение при регулировании',
    #3+#$00#$FF+#$00#$01+'Ошибка кода операции',
    #3+#$00#$FF+#$00#$02+'Ошибка номера регистра',
    #3+#$00#$FF+#$00#$03+'Ошибка размещения данных',
    #3+#$00#$FF+#$00#$21+'Ошибка установки данных',
    #3+#$00#$FF+#$00#$22+'Некорректный режим ввода',
    #4+#$00#$01+#$00#$01+'Нет связи с устройством'
    );

type
  TAlarmFlags = array of byte;

type
  TVspaCtrlFrame = class(TFrame)
    SostPanel: TPanel;
    NamePanel: TPanel;
    ButPanel: TPanel;
    AutoButton: TSpeedButton;
    Label4: TLabel;
    Panel2: TPanel;
    StartButton: TSpeedButton;
    StopButton: TSpeedButton;
    HandLabel: TLabel;
    StatList: TListView;
    Label1: TLabel;
    OpFreqPanel: TPanel;
    Label2: TLabel;
    OutFreqPanel: TPanel;
    Label3: TLabel;
    OutTokPanel: TPanel;
    btFreqStatus: TSpeedButton;
    FreqList: TListView;
    procedure AutoButtonClick(Sender: TObject);
    procedure StartButtonClick(Sender: TObject);
    procedure StopButtonClick(Sender: TObject);
    procedure StatListInfoTip(Sender: TObject; Item: TListItem;
      var InfoTip: String);
    procedure OpFreqPanelClick(Sender: TObject);
    procedure NamePanelClick(Sender: TObject);
    procedure btFreqStatusClick(Sender: TObject);
    procedure FreqListDblClick(Sender: TObject);
  private
    FMessageTag: string;

    FSost: integer;
    FControl: integer;
    FOpFreq: integer;
    FOutFreq: integer;
    FOutTok: integer;

    FTagEnable: integer;
    FTagErrorFlag: integer;
    FTagReg20: integer;
    FTagReg21: integer;
    FTagReg22: integer;
    FTagReg23: integer;
    FTagReg24: integer;
    FTagReg27: integer;
    FTagReg28: integer;
    FTagAnswer: integer;
    FTagOpFreqDef: integer;

    FAlarms: TAlarmFlags;
  public
    M: TVisVespA;
//    TagName: string;
//    TagPath: string;
//    DeviceName: string;

    procedure Init;
    procedure Process;
  end;

  procedure CheckVspaAlarms(A: TAlarmFlags; num,value: integer);
  procedure UpdateVspaAlarmList(list: TListView; A: TAlarmFlags);

implementation
uses
  MesConst, TagStorage, DevSetPanel, MesLogging, SetChannel, numbers, VspaSetPanel;

{$R *.DFM}

{ TVspaCtrlFrame }

procedure TVspaCtrlFrame.Init;
var
  s: string;
  i,k: integer;
begin
  NamePanel.Caption := M.DeviceName;

  FMessageTag := M.DeviceName;

  s := M.TagPath + '.VSPA_' + M.TagName + '_Enable';
  FTagEnable := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_ErrorFlag';
  FTagErrorFlag := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Reg20';
  FTagReg20 := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Reg21';
  FTagReg21 := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Reg22';
  FTagReg22 := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Reg23';
  FTagReg23 := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Reg24';
  FTagReg24 := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Reg27';
  FTagReg27 := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Reg28';
  FTagReg28 := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_Answer';
  FTagAnswer := GetTagIndex(s);

  s := M.TagPath + '.VSPA_' + M.TagName + '_OpFreqDef';
  FTagOpFreqDef := GetTagIndex(s);

  // Список частот
  btFreqStatus.Caption := 'Обороты';
  FreqList.Left := 400;
  FreqList.Items.Clear;
  for i:=1 to 10 do begin
    s := format('%s.VSPA_%s_OpFreq%.2d', [M.TagPath, M.TagName, i]);
    k := GetTagIndex(s);
    if k>=0 then with FreqList.Items.Add do begin
      Caption := 'Уровень ' + IntToStr(i);
      Subitems.Add('');
      Subitems.Add(s);
      Data := pointer(k);
    end;
  end;
  if FreqList.Items.Count > 1 then begin
    with FreqList.Items[0] do Caption := Caption + ' (внизу)';
    with FreqList.Items[FreqList.Items.Count-1] do Caption := Caption + ' (вверху)';
  end;


  FSost := -1;
  FControl := -1;
  FOpFreq := -1;
  FOutFreq := -1;
  FOutTok := -1;

  StatList.Items.Clear;
  SetLength(FAlarms, length(VspaAlarms));
  for i:=0 to length(FAlarms)-1 do FAlarms[i] := 0;

  Process;
end;

procedure TVspaCtrlFrame.Process;
var
  value, venab, vreg20, vreg21, vreg22, vreg23, vreg24, vreg27, vreg28, verr, vansw, i: integer;
  s: string;
begin

  venab   := GetTagValue( FTagEnable );
  vreg20  := GetTagValue( FTagReg20 );
  vreg21  := GetTagValue( FTagReg21 );
  vreg22  := GetTagValue( FTagReg22 );
  vreg23  := GetTagValue( FTagReg23 );
  vreg24  := GetTagValue( FTagReg24 );
  vreg27  := GetTagValue( FTagReg27 );
  vreg28  := GetTagValue( FTagReg28 );
  verr    := GetTagValue( FTagErrorFlag );
//  vopfreq := GetTagValue( FTagOpFreqDef );
  vansw   := GetTagValue( FTagAnswer );


  value := (vreg20 and 3);
  if FSost <> value then begin
    case value of
      0: SostPanel.Caption := 'Отключено';
      1: SostPanel.Caption := 'Работает';
      2: SostPanel.Caption := 'Отключено (реверс)';
      3: SostPanel.Caption := 'Работает (реверс)';
    end;
    FSost := value;
  end;

  value := (venab and 7);
  if FControl <> value then begin
    if (value and 3) = 1 then begin
      AutoButton.Down := true;
      AutoButton.Font.Style := [fsBold];
    end else begin
      AutoButton.Down := false;
      AutoButton.Font.Style := [];
    end;

    if value=7 then begin
      StartButton.Down := true;
      StartButton.Font.Style := [fsBold];
    end else begin
      StartButton.Down := false;
      StartButton.Font.Style := [];
    end;

    if value=3 then begin
      StopButton.Down := true;
      StopButton.Font.Style := [fsBold];
    end else begin
      StopButton.Down := false;
      StopButton.Font.Style := [];
    end;

    FControl := value;
  end;

  value := vreg23;
  if value <> FOpFreq then begin
    OpFreqPanel.Caption := format('%.1f', [value/10]);
    FOpFreq := value;
  end;

  value := vreg24;
  if value <> FOutFreq then begin
    OutFreqPanel.Caption := format('%.1f', [value/10]);
    FOutFreq := value;
  end;

  value := vreg27;
  if value <> FOutTok then begin
    OutTokPanel.Caption := format('%.1f', [value/10]);
    FOutTok := value;
  end;

  value := (vreg28 and $02);
  if (value=0) xor (ButPanel.Enabled) then begin
    ButPanel.Enabled := not ButPanel.Enabled;
    AutoButton.Enabled := ButPanel.Enabled;
    StartButton.Enabled := ButPanel.Enabled;
    StopButton.Enabled := ButPanel.Enabled;
    if ButPanel.Enabled then begin
      HandLabel.Font.Color := clGray;
      HandLabel.Caption := 'Ручное управление';
    end else begin
      HandLabel.Font.Color := clRed;
      HandLabel.Caption := 'Местное управление';
    end;
  end;

  if not ButPanel.Enabled then HandLabel.Visible := not HandLabel.Visible;

//  if FreqList.Visible then begin
    for i:=0 to FreqList.Items.Count-1 do begin
      value := GetTagValue(integer(FreqList.Items[i].Data)) div 10;
      s := IntToStr(value);
      if not(s = FreqList.Items[i].SubItems[0]) then
        FreqList.Items[i].SubItems[0] := s;
    end;
//  end else begin
    CheckVspaAlarms(FAlarms, 0, vreg20);
    CheckVspaAlarms(FAlarms, 1, vreg21);
    CheckVspaAlarms(FAlarms, 2, vreg22);
    CheckVspaAlarms(FAlarms, 3, vansw);
    CheckVspaAlarms(FAlarms, 4, verr);

    UpdateVspaAlarmList(StatList, FAlarms);
//  end;


end;

procedure UpdateVspaAlarmList(list: TListView; A: TAlarmFlags);
var
  i, j: integer;
  flag: boolean;
begin
  i := 0;
  while i<list.Items.Count do with list.Items[i] do
    if A[integer(Data)] = 0 then Delete else inc(i);

  for i:=0 to length(A)-1 do
    if A[i]>0 then begin
      flag := true;
      for j:=0 to list.Items.Count-1 do
        if integer(list.Items[j].Data) = i then begin
          flag := false;
          break;
        end;

      if flag then with list.Items.Add do begin
        Caption := copy(VspaAlarms[i], 6, 128);
        Data := pointer(i);
      end;
    end;

end;


procedure CheckVspaAlarms(A: TAlarmFlags; num,value: integer);
var
  i,n,m,v: integer;
  s: string;
begin
  for i:=0 to length(A)-1 do begin
    s := VspaAlarms[i];
    n := ord(s[1]);

    if n = num then begin
      m := ord(s[2])*256 + ord(s[3]);
      v := ord(s[4])*256 + ord(s[5]);
      
      if (value and m) = v then
        A[i] := 1
      else
        A[i] := 0;
    end;
  end;
end;


//============================================================================
// Кнопка авто/руч
//============================================================================
procedure TVspaCtrlFrame.AutoButtonClick(Sender: TObject);
begin
  SaveMessageText(mcMode_text, FMessageTag, 'Автомат', mcMode_bc, mcMode_fc);
  SetTagValue( FTagEnable, (GetTagValue(FTagEnable) or 1) and $FD);
end;

procedure TVspaCtrlFrame.StartButtonClick(Sender: TObject);
begin
  if MessageDlg('ВНИМАНИЕ! Вы подтверждаете запуск машины?',
      mtConfirmation, [mbYes, mbNo], 0) <> mrYes then begin
    FControl := -1;
    exit;
  end;

  SaveMessageText(mcMode_text, FMessageTag, 'Ручное - старт', mcMode_bc, mcMode_fc);
  SetTagValue( FTagEnable, (GetTagValue(FTagEnable) or 6));
end;

procedure TVspaCtrlFrame.StopButtonClick(Sender: TObject);
begin
  SaveMessageText(mcMode_text, FMessageTag, 'Ручное - стоп', mcMode_bc, mcMode_fc);
  SetTagValue( FTagEnable, (GetTagValue(FTagEnable) or 2) and $FB);
end;

procedure TVspaCtrlFrame.StatListInfoTip(Sender: TObject; Item: TListItem;
  var InfoTip: String);
begin
  InfoTip := item.Caption;
end;

procedure TVspaCtrlFrame.OpFreqPanelClick(Sender: TObject);
var
  s: string;
  v,i: integer;
begin
  s := IntToStr(GetTagValue(FTagOpFreqDef) div 10);
  if InputQuery('Установка опорной частоты для режима РУЧ',
      'Введите значение от 0 до ' + IntToStr(M.OpFreqMax)+ ', Гц', s) then begin

    val(s,v,i);
    if (v>=0) and (v<=M.OpFreqMax) then begin
      SaveMessageText(mcParam_Text, FMessageTag, 'F=' + IntToStr(v), mcParam_bc, mcParam_fc);
      SetTagValue( FTagOpFreqDef, v*10);
    end else
      MessageDlg('Значение вне допустимых пределов.', mtError, [mbOK], 0);
  end;

end;

procedure TVspaCtrlFrame.NamePanelClick(Sender: TObject);
var
  VspaSetPanelForm: TVspaSetPanelForm;
begin
  VspaSetPanelForm := TVspaSetPanelForm.Create(self);
  VspaSetPanelForm.M := M;
  VspaSetPanelForm.ShowModal;
  VspaSetPanelForm.Free;
end;


procedure TVspaCtrlFrame.btFreqStatusClick(Sender: TObject);
begin
  if btFreqStatus.Caption = 'Статус' then begin
    btFreqStatus.Caption := 'Обороты';
    FreqList.Left := 400
  end else begin
    btFreqStatus.Caption := 'Статус';
    FreqList.Left := 8;
  end;
end;

procedure TVspaCtrlFrame.FreqListDblClick(Sender: TObject);
var
  v,i: integer;
  tname,s: string;
begin
  if FreqList.Selected=nil then exit;

//  CheckEditMode;
//  if not EditMode_On then exit;

  s := FreqList.Selected.SubItems[0];
  tname := FreqList.Selected.SubItems[1];
  if InputQuery('Установка значения', 'Частота для "' +
      FreqList.Selected.Caption + '"', s) then begin

    val(s, v, i);
    if v > M.OpFreqMax then
      ShowMessage('Частота не должна превышать ' + inttostr(M.OpFreqMax))
    else begin
      SaveMessageText(mcParam_text, FMessageTag, 'Fур' +
          inttostr(FreqList.Selected.Index+1) + '=' + IntToStr(v), mcParam_bc, mcParam_fc);
      SetTagValue(integer(FreqList.Selected.Data), $10000 + v*10);
    end;
  end;
end;

end.
