⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devreader.pas

📁 通过USB接口通信 实现USB UPS电源的自动开关机
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit DevReader;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons, JvHidControllerClass, ExtCtrls, ComCtrls, Mask, inifiles;

type
  TPlaybackResult = (pbIgnore, pbSuccess, pbFail);
  TUPSSTATE = packed record
    InputPower: string; //输入电压
    OutputPower: string; //输出电压
    PowerLoad: string; //负载
    Tmprt: string; //温度
  end;

  TReport = packed record
    ReportID: Byte;
    Bytes: array[0..63] of Byte;
  end;

  TMainForm = class(TForm)
    HistoryListBox: TListBox;
    HidCtl: TJvHidDeviceController;
    OpenDateTimePicker: TDateTimePicker;
    CloseDateTimePicker: TDateTimePicker;
    Label3: TLabel;
    Label4: TLabel;
    Timer1: TTimer;
    Button1: TButton;
    Button2: TButton;
    DevListBox: TListBox;
    Label1: TLabel;
    Button3: TButton;
    Timer2: TTimer;
    procedure FormActivate(Sender: TObject);
    procedure HidCtlDeviceChange(Sender: TObject);
    function HidCtlEnumerate(HidDev: TJvHidDevice;
      const Idx: Integer): Boolean;
    procedure HidCtlDeviceDataError(HidDev: TJvHidDevice; Error: Cardinal);
    procedure HidCtlRemoval(HidDev: TJvHidDevice);
    procedure DevListBoxClick(Sender: TObject);
    procedure InfoBtnClick(Sender: TObject);
    procedure ClearBtnClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  public
    Activated: Boolean;
    CurrentDevice: TJvHidDevice;

    Readdata, tmpReadData: string;
    UPSSTATE: TUPSSTATE;

    function DeviceName(HidDev: TJvHidDevice): string;
    procedure ShowRead(HidDev: TJvHidDevice; ReportID: Byte; const Data: Pointer; Size: Word);
    procedure AddToHistory(Str: string);

    function SendCommand(const Senddata: array of Byte): boolean;
    function UpsvListBox: boolean;
    function WinExitInNT(iFlags: integer): boolean;
    function SetPrivilege(sPrivilegeName: string; bEnabled: boolean): boolean;
    procedure Delay(waittime: integer);
    procedure InsertLogfile(log_str: string); //记录关机日志
    procedure MinMin(var Msg: TWMSYSCOMMAND); message WM_SYSCOMMAND;
  end;

var
  MainForm: TMainForm;

implementation

uses
  Math,
  Info;

{$R *.dfm}

procedure TMainForm.FormActivate(Sender: TObject);
var
  I, J: Integer;
  Dev: TJvHidDevice;
begin
  if not Activated then
  begin
    Activated := True;
    DevListBoxClick(Self);
  end;
end;


procedure TMainForm.HidCtlDeviceChange(Sender: TObject);
var
  Dev: TJvHidDevice;
  I, N: Integer;
begin
  for I := 0 to DevListBox.Items.Count - 1 do
  begin
    Dev := TJvHidDevice(DevListBox.Items.Objects[I]);
    Dev.Free;
  end;
  DevListBox.Items.Clear;

  while HidCtl.CheckOut(Dev) do
  begin
    N := DevListBox.Items.Add(DeviceName(Dev));
    Dev.NumInputBuffers := 128;
    Dev.NumOverlappedBuffers := 128;
    DevListBox.Items.Objects[N] := Dev;
  end;
end;

function TMainForm.DeviceName(HidDev: TJvHidDevice): string;
begin
  if HidDev.ProductName <> '' then
    Result := HidDev.ProductName
  else
    Result := Format('Device VID=%.4x PID=%.4x',
      [HidDev.Attributes.VendorID, HidDev.Attributes.ProductID]);
  if HidDev.SerialNumber <> '' then
    Result := Result + Format(' (Serial=%s)', [HidDev.SerialNumber]);
end;

function TMainForm.HidCtlEnumerate(HidDev: TJvHidDevice; const Idx: Integer): Boolean;
var
  N: Integer;
  Dev: TJvHidDevice;
begin
  N := DevListBox.Items.Add(DeviceName(HidDev));
  HidCtl.CheckOutByIndex(Dev, Idx);
  Dev.NumInputBuffers := 128;
  Dev.NumOverlappedBuffers := 128;
  DevListBox.Items.Objects[N] := Dev;
  Result := True;
end;

procedure TMainForm.DevListBoxClick(Sender: TObject);
var
  I: Integer;
  Dev: TJvHidDevice;
begin
  // stop reader thread
  if Assigned(CurrentDevice) then
    CurrentDevice.OnData := nil;
  CurrentDevice := nil;
  if (DevListBox.Items.Count > 0) and (DevListBox.ItemIndex >= 0) then begin
    Dev := TJvHidDevice(DevListBox.Items.Objects[DevListBox.ItemIndex]);
    Dev.OnData := ShowRead;
    CurrentDevice := Dev;
    AddToHistory('设备名称:' + DeviceName(CurrentDevice));
  end;
end;

procedure TMainForm.AddToHistory(Str: string);
var
  N: Integer;
begin
  HistoryListBox.Canvas.Font := HistoryListBox.Font;
  N := HistoryListBox.Canvas.TextWidth(Str) + 16;
  if HistoryListBox.ScrollWidth < N then
    HistoryListBox.ScrollWidth := N;
  HistoryListBox.ItemIndex := HistoryListBox.Items.Add(Str);
  HistoryListBox.ClearSelection;
end;

procedure TMainForm.ShowRead(HidDev: TJvHidDevice; ReportID: Byte;
  const Data: Pointer; Size: Word);
var
  I, j: Integer;
  Str, tmp: string;
  Hexstr: Byte;
begin
  str := '';
  for I := 0 to Size - 1 do begin
    Str := Format('%.2x', [Cardinal(PChar(Data)[I])]);
    tmpReadData := tmpReadData + Str + ' ';
    ReadData := ReadData + Str;
    if Str = '0D' then begin
      AddToHistory('读数据:' + tmpReadData);
      for j := 1 to (Length(ReadData) div 2) do begin
        Hexstr := StrToInt('$' + Copy(ReadData, j * 2 - 1, 2));
        if Hexstr <> $28 then tmp := tmp + Chr(Hexstr);
      end;
      AddToHistory(tmp);
      UPSSTATE.InputPower := Copy(tmp, 1, pos(' ', tmp) - 1);
      Delete(tmp, 1, pos(' ', tmp));
      Delete(tmp, 1, pos(' ', tmp));

      UPSSTATE.OutputPower := Copy(tmp, 1, pos(' ', tmp) - 1);
      Delete(tmp, 1, pos(' ', tmp));

      UPSSTATE.PowerLoad := Copy(tmp, 1, pos(' ', tmp) - 1);
      Delete(tmp, 1, pos(' ', tmp));

      Delete(tmp, 1, pos(' ', tmp));
      Delete(tmp, 1, pos(' ', tmp));
      UPSSTATE.Tmprt := Copy(tmp, 1, pos(' ', tmp) - 1);

      AddToHistory('输入电压:' + UPSSTATE.InputPower);
      AddToHistory('输出电压:' + UPSSTATE.OutputPower);
      AddToHistory('    负载:' + format('%d', [StrToint(UPSSTATE.PowerLoad)]) + '%');
      AddToHistory('    温度:' + UPSSTATE.Tmprt);
    end;
  end;

end;

procedure TMainForm.HidCtlDeviceDataError(HidDev: TJvHidDevice; Error: Cardinal);
begin
  AddToHistory(Format('READ ERROR: %s (%x)', [SysErrorMessage(Error), Error]));
end;

procedure TMainForm.HidCtlRemoval(HidDev: TJvHidDevice);
begin
  AddToHistory('Removal of ' + DeviceName(HidDev));
end;

procedure TMainForm.InfoBtnClick(Sender: TObject);
begin
  if (DevListBox.Items.Count > 0) and (DevListBox.ItemIndex >= 0) then
    with TInfoForm.Create(Self) do
    begin
      Dev := TJvHidDevice(DevListBox.Items.Objects[DevListBox.ItemIndex]);
      ShowModal;
      Free;
    end;
end;

procedure TMainForm.ClearBtnClick(Sender: TObject);
begin
  HistoryListBox.Items.Clear;
  HistoryListBox.ScrollWidth := 0;
end;

function TMainForm.SendCommand(const Senddata: array of Byte): boolean;
var
  I: Integer;
  Buf: array[0..64] of Byte;
  Written: Cardinal;
  ToWrite: Cardinal;
  Str: string;
  Err: DWORD;
begin
  if Assigned(CurrentDevice) then
  begin
    for i := 0 to 64 do Buf[i] := $00;
    ToWrite := CurrentDevice.Caps.OutputReportByteLength;
    for i := 0 to ToWrite - 1 do
      Buf[I + 1] := Senddata[i];

    if not CurrentDevice.WriteFile(Buf, ToWrite, Written) then
    begin
      Err := GetLastError;
      AddToHistory(Format('WRITE ERROR: %s (%x)', [SysErrorMessage(Err), Err]));
    end
    else
    begin
      Str := Format('写数据: %.2x  ', [Buf[0]]);
      for I := 1 to Written - 1 do
        Str := Str + Format('%.2x ', [Buf[I]]);
      AddToHistory(formatdatetime('yyyy-mm-dd hh:mm:ss', now) + '  State>>' +  #13 + Str);
    end;
  end;
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
  winexec('.\osk.exe', 0);
end;

function TMainForm.UpsvListBox: boolean;
var
  I: Integer;
  Dev: TJvHidDevice;
  UpsName: string;
begin
  try
    Result := false;
    if Assigned(CurrentDevice) then CurrentDevice.OnData := nil;
    CurrentDevice := nil;
    if (DevListBox.Items.Count > 0) then begin
      for i := 0 to DevListBox.Items.Count - 1 do begin
        UpsName := trim(DevListBox.Items.Strings[i]);
        if pos('USB to Serial', UpsName) > 0 then begin
          Dev := TJvHidDevice(DevListBox.Items.Objects[i]);
          Dev.OnData := ShowRead;
          CurrentDevice := Dev;
          AddToHistory('UPS设备名称:' + DeviceName(CurrentDevice));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -