// DEPRECATED !!!

unit DltaCtrl;

interface

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

const
  DltaAlarms: array[0..18] of string = (
    #0+#$00#$FF+#$00#$01+'Перегрузка по току',
    #0+#$00#$FF+#$00#$03+'Перегрев',
    #0+#$00#$FF+#$00#$04+'Перегрузка',
    #0+#$00#$FF+#$00#$05+'Перегрузка двигателя',
    #0+#$00#$FF+#$00#$06+'Внешняя неисправность',
    #0+#$00#$FF+#$00#$07+'Неисправность ЦПУ',
    #0+#$00#$FF+#$00#$08+'Неисправность ЦПУ или в аналоговой цепи',
    #0+#$00#$FF+#$00#$09+'Неисправность аппаратной защиты',
    #0+#$00#$FF+#$00#$0A+'ocA',
    #0+#$00#$FF+#$00#$0B+'ocD',
    #0+#$00#$FF+#$00#$0C+'ocN',
    #0+#$00#$FF+#$00#$0D+'Неисправность заземления',
    #0+#$00#$FF+#$00#$0E+'Низкое напряжение',
    #0+#$00#$FF+#$00#$0F+'Зарезервировано',
    #0+#$00#$FF+#$00#$10+'Неисправность ЦПУ 1',
    #0+#$00#$FF+#$00#$11+'База блокирована',
    #0+#$00#$FF+#$00#$12+'Перегрузка',
    #0+#$00#$FF+#$00#$13+'Неисправность системы автоматического ускорения/торможения',
    #0+#$00#$FF+#$00#$14+'Защита ПО активирована'
    );

type
  TAlarmFlags = array of byte;

type
  TDltaCtrlFrame = 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;
    Label5: TLabel;
    NetAddressPanel: TPanel;
    btReset: TSpeedButton;
    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);
    procedure btResetClick(Sender: TObject);
  private
    FSost: integer;
    FControl: integer;
    FOpFreq: integer;
    FOutFreq: integer;
    FOutTok: integer;
    FNetAddress: integer;

    FTagEnable: integer;
    FTagErrorFlag: integer;
    FTagReg2100: integer;
    FTagReg2101: integer;
    FTagReg2102: integer;
    FTagReg2103: integer;
    FTagReg2104: integer;
    FTagNetAddress: integer;
    FTagOpFreqDef: integer;

    FAlarms: TAlarmFlags;
    FMessageTagName: string;
  public
    M: TVisDlta;

    procedure Init;
    procedure Process;
  end;

  procedure CheckDltaAlarms(A: TAlarmFlags; num,value: integer);
  procedure UpdateDltaAlarmList(list: TListView; A: TAlarmFlags);

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

{$R *.DFM}

{ TDltaCtrlFrame }

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

  stag := M.TagPath + '.DLTA_' + M.TagName;

  s := stag + '_Enable';
  FTagEnable := GetTagIndex(s);

  s := stag + '_ErrorFlag';
  FTagErrorFlag := GetTagIndex(s);

  s := stag + '_Reg2100';
  FTagReg2100 := GetTagIndex(s);

  s := stag + '_Reg2101';
  FTagReg2101 := GetTagIndex(s);

  s := stag + '_Reg2102';
  FTagReg2102 := GetTagIndex(s);

  s := stag + '_Reg2103';
  FTagReg2103 := GetTagIndex(s);

  s := stag + '_Reg2104';
  FTagReg2104 := GetTagIndex(s);

  s := stag + '_NetAddress';
  FTagNetAddress := GetTagIndex(s);

  s := stag + '_OpFreqDef';
  FTagOpFreqDef := GetTagIndex(s);


  // Список частот
  btFreqStatus.Caption := 'Обороты';
  FreqList.Left := 400;
  FreqList.Items.Clear;
  for i:=1 to 10 do begin
    s := format('%s.DLTA_%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;
  FNetAddress := -1;

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

  Process;
end;

procedure TDltaCtrlFrame.Process;
var
  value,venable,vreg2101,vreg2102,vreg2103,vreg2104,vregNetAddress, i: integer;
  s: string;
begin

  venable   := GetTagValue( FTagEnable );
//  vreg2100  := GetTagValue( FTagReg2100 );
  vreg2101  := GetTagValue( FTagReg2101 );
  vreg2102  := GetTagValue( FTagReg2102 );
  vreg2103  := GetTagValue( FTagReg2103 );
  vreg2104  := GetTagValue( FTagReg2104 );
  vregNetAddress  := GetTagValue( FTagNetAddress );

  if GetTagValue( FTagErrorFlag )>0 then begin
    SostPanel.Caption := 'Нет связи';
    FSost := -1;
  end else begin
    value := (vreg2101 and $1000);
    if FSost <> value then begin
      case value of
            0: SostPanel.Caption := 'Отключено';
        $1000: SostPanel.Caption := 'Работает';
      end;
      FSost := value;
    end;
  end;  

  value := (venable 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 := vreg2102;
  if value <> FOpFreq then begin
    OpFreqPanel.Caption := format('%.2f', [value/100]);
    FOpFreq := value;
  end;

  value := vreg2103;
  if value <> FOutFreq then begin
    if value > $8000 then
      OutFreqPanel.Caption := format('-%.2f', [($10000 - value)/100])
    else
      OutFreqPanel.Caption := format('%.2f', [value/100]);
    FOutFreq := value;
  end;

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

  value := vregNetAddress;
  if value <> FNetAddress then begin
    NetAddressPanel.Caption := inttostr(value);
    FNetAddress := value;
  end;


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

    for i:=0 to FreqList.Items.Count-1 do begin
      value := GetTagValue(integer(FreqList.Items[i].Data)) div 100;
      s := IntToStr(value);
      if not(s = FreqList.Items[i].SubItems[0]) then
        FreqList.Items[i].SubItems[0] := s;
    end;

    CheckDltaAlarms(FAlarms, 0, GetTagValue( FTagReg2100 ));
    UpdateDltaAlarmList(StatList, FAlarms);
end;


procedure UpdateDltaAlarmList(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(DltaAlarms[i], 6, 128);
        Data := pointer(i);
      end;
    end;

end;


procedure CheckDltaAlarms(A: TAlarmFlags; num,value: integer);
var
  i,n,m,v: integer;
  s: string;
begin
  for i:=0 to length(A)-1 do begin
    s := DltaAlarms[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 TDltaCtrlFrame.AutoButtonClick(Sender: TObject);
begin
  SaveMessageText(mcMode_text, FMessageTagName, 'Автомат', mcMode_bc, mcMode_fc);
  SetTagValue( FTagEnable, (GetTagValue(FTagEnable) or 1) and $FD);
end;

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

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

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

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

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

    val(s,r,i);
    r := r*100;
    v := trunc(r);
    SaveMessageText(mcParam_text, FMessageTagName, 'F=' + s, mcParam_bc, mcParam_fc);
    SetTagValue( FTagOpFreqDef, v);
  end;

end;

procedure TDltaCtrlFrame.NamePanelClick(Sender: TObject);
//var
//  DltaSetPanelForm: TDltaSetPanelForm;
begin
//  DltaSetPanelForm := TDltaSetPanelForm.Create(self);
//  DltaSetPanelForm.M := M;
//  DltaSetPanelForm.ShowModal;
//  DltaSetPanelForm.Free;
end;


procedure TDltaCtrlFrame.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 TDltaCtrlFrame.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);
      SaveMessageText(mcParam_text, FMessageTagName, 'Fур' +
          inttostr(FreqList.Selected.Index+1) + '=' + IntToStr(v), mcParam_bc, mcParam_fc);
      SetTagValue(integer(FreqList.Selected.Data), $10000 + v*100);
  end;
end;

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

  SaveMessageText(mcMode_text, FMessageTagName, 'Сброс аварии', mcMode_bc, mcMode_fc);
  SetTagValue( FTagEnable, (GetTagValue(FTagEnable) or 8));
end;

end.
