123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- using Hik.Api;
- using Newtonsoft.Json.Linq;
- using S7.Net;
- using System.Threading.Channels;
- using System.Windows.Forms;
- namespace xicheji
- {
- public partial class MainForm : Form
- {
- private readonly Config config;
- private readonly List<WashRecord> washRecords = new();
- private DateTime lastReceiveTime = DateTime.MinValue;
- private byte[] currentDataBlock;
- private Plc? plc = null;
- private HikApi? hikApi = null;
- public MainForm()
- {
- InitializeComponent();
- config = ConfigHelper.GetConfig();
- }
- private void MainForm_Load(object sender, EventArgs e)
- {
- try
- {
- //测试数据
- washRecords.Add(new WashRecord()
- {
- CarNum = "京123456",
- StartTime = new DateTime(2024, 6, 1, 12, 00, 00),
- EndTime = new DateTime(2024, 6, 1, 12, 30, 00),
- WashTime = 15,
- DryTime = 15,
- TotalElectricity = 10,
- TotalWater = 2,
- WaterPressure = 6,
- });
- dataGridView1.DataSource = washRecords;
- ConnectPLC();
- //ConnectCamera();
- receivePLCTimer.Interval = config.PLCReceiveInterval * 1000;
- receivePLCTimer.Enabled = true;
- uploadTimer.Enabled = true;
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- private void btnConnectCamera_Click(object sender, EventArgs e)
- {
- try
- {
- ConnectCamera();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- private void nowTimer_Tick(object sender, EventArgs e)
- {
- try
- {
- var now = DateTime.Now;
- lblTime.Text = $"{now.Month}月 {now.Day}日 {now.Hour}:{now:mm}:{now:ss}";
- }
- catch { }
- }
- private void receivePLCTimer_Tick(object sender, EventArgs e)
- {
- try
- {
- if (plc == null || !plc.IsConnected)
- {
- receivePLCTimer.Enabled = false;
- return;
- }
- ReadPLCData();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- private void ReadPLCData()
- {
- currentDataBlock = plc!.ReadBytes(DataType.DataBlock, 1, 0, 100);
- var time = new DateTime(
- DateTime.Now.Year,
- ReadPLCInt("当前月"),
- ReadPLCInt("当前日"),
- ReadPLCInt("当前时"),
- ReadPLCInt("当前分"),
- ReadPLCInt("当前秒"));
- if (time <= lastReceiveTime)
- {
- //已经读过这个时间的了
- return;
- }
- lastReceiveTime = time;
- ReadError();
- ReadStatus();
- lblWashCount.Text = ReadPLCString("洗车次数");
- lblTotalWater.Text = ReadPLCString("累计用水量");
- lblTotalElectricity.Text = ReadPLCString("累计用电量");
- //.Text = ReadPLCStringValue("当前流量");
- lblCurrentElectricity.Text = ReadPLCString("当前功率");
- lblCurrentWaterP.Text = ReadPLCString("当前压力");
- }
- private void ReadStatus()
- {
- lblStatus.Text = string.Empty;
- var statuses = new List<string>() {
- "洗车中", "清洗中", "沥水中",
- "出车中", "风干中"};
- foreach (var status in statuses)
- {
- if (ReadPLCBool(status))
- {
- lblStatus.Text = status;
- break;
- }
- }
- }
- private void ReadError()
- {
- lblError.Text = string.Empty;
- var errors = new List<string>() {
- "急停", "冲洗泵故障", "反洗泵故障",
- "清淤泵故障", "伴热故障", "风刀故障" };
- foreach (var error in errors)
- {
- if (ReadPLCBool(error))
- {
- lblError.Text = error;
- break;
- }
- }
- }
- private string ReadPLCString(string name)
- {
- var variable = ConfigHelper.FindVariable(name);
- if (variable == null)
- return string.Empty;
- Parse(variable.Key, out _, out _, out var varType, out var address, out var bitNumber);
- if (varType == VarType.DWord)
- {
- var value = S7.Net.Types.DWord.FromByteArray(currentDataBlock.Take(new Range(address, address + 4)).ToArray());
- return $"{value} {variable.Desc}";
- }
- else if (varType == VarType.Word)
- {
- var value = S7.Net.Types.Word.FromByteArray(currentDataBlock.Take(new Range(address, address + 2)).ToArray());
- return $"{value} {variable.Desc}";
- }
- return string.Empty;
- }
- private int ReadPLCInt(string name)
- {
- var variable = ConfigHelper.FindVariable(name);
- if (variable == null)
- return 0;
- Parse(variable.Key, out var dataType, out var dbNumber, out var varType, out var address, out var bitNumber);
- if (varType == VarType.DWord)
- {
- var value = S7.Net.Types.DWord.FromByteArray(currentDataBlock.Take(new Range(address, address + 4)).ToArray());
- return (int)value;
- }
- else if (varType == VarType.Word)
- {
- var value = S7.Net.Types.Word.FromByteArray(currentDataBlock.Take(new Range(address, address + 2)).ToArray());
- return value;
- }
- return 0;
- }
- private bool ReadPLCBool(string name)
- {
- var variable = ConfigHelper.FindVariable(name);
- if (variable == null)
- return false;
- Parse(variable.Key, out _, out _, out _, out var address, out var bitNumber);
- var value = S7.Net.Types.Boolean.GetValue(currentDataBlock[address], bitNumber);
- return value;
- }
- private void uploadTimer_Tick(object sender, EventArgs e)
- {
- }
- private void btnSetting_Click(object sender, EventArgs e)
- {
- try
- {
- var settingForm = new SettingForm();
- if (settingForm.ShowDialog() == DialogResult.OK)
- {
- ConnectPLC();
- ConnectCamera();
- receivePLCTimer.Enabled = true;
- uploadTimer.Enabled = true;
- }
- }
- catch { }
- }
- private void ConnectPLC()
- {
- plc = new Plc(config.PLCType, config.PLCIP, int.Parse(config.PLCPort), 0, 1);
- plc.Open();
- if (!plc.IsConnected)
- {
- MessageBox.Show("PLC连接失败!");
- return;
- }
- }
- private void ConnectCamera()
- {
- try
- {
- hikApi = HikApi.Login(config.CameraIP, int.Parse(config.CameraPort),
- config.CameraUserName, config.CameraPassword) as HikApi;
- if (hikApi == null || !hikApi.Connected)
- {
- MessageBox.Show("摄像头连接失败!");
- return;
- }
- hikApi.PlaybackService.StartPlayBack(hikApi.DefaultIpChannel, pictureBox1.Handle);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- public void UpdateCarInfo(DateTime now)
- {
- this.Invoke(() =>
- {
- this.Text = now.ToString();
- });
- }
- public static void Parse(string input, out DataType dataType, out int dbNumber, out VarType varType, out int address, out int bitNumber)
- {
- bitNumber = -1;
- dbNumber = 0;
- switch (input.Substring(0, 2))
- {
- case "DB":
- string[] strings = input.Split(new char[] { '.' });
- if (strings.Length < 2)
- throw new InvalidAddressException("To few periods for DB address");
- dataType = DataType.DataBlock;
- dbNumber = int.Parse(strings[0].Substring(2));
- address = int.Parse(strings[1].Substring(3));
- string dbType = strings[1].Substring(0, 3);
- switch (dbType)
- {
- case "DBB":
- varType = VarType.Byte;
- return;
- case "DBW":
- varType = VarType.Word;
- return;
- case "DBD":
- varType = VarType.DWord;
- return;
- case "DBX":
- bitNumber = int.Parse(strings[2]);
- if (bitNumber > 7)
- throw new InvalidAddressException("Bit can only be 0-7");
- varType = VarType.Bit;
- return;
- default:
- throw new InvalidAddressException();
- }
- case "IB":
- case "EB":
- // Input byte
- dataType = DataType.Input;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.Byte;
- return;
- case "IW":
- case "EW":
- // Input word
- dataType = DataType.Input;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.Word;
- return;
- case "ID":
- case "ED":
- // Input double-word
- dataType = DataType.Input;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.DWord;
- return;
- case "QB":
- case "AB":
- case "OB":
- // Output byte
- dataType = DataType.Output;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.Byte;
- return;
- case "QW":
- case "AW":
- case "OW":
- // Output word
- dataType = DataType.Output;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.Word;
- return;
- case "QD":
- case "AD":
- case "OD":
- // Output double-word
- dataType = DataType.Output;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.DWord;
- return;
- case "MB":
- // Memory byte
- dataType = DataType.Memory;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.Byte;
- return;
- case "MW":
- // Memory word
- dataType = DataType.Memory;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.Word;
- return;
- case "MD":
- // Memory double-word
- dataType = DataType.Memory;
- dbNumber = 0;
- address = int.Parse(input.Substring(2));
- varType = VarType.DWord;
- return;
- default:
- switch (input.Substring(0, 1))
- {
- case "E":
- case "I":
- // Input
- dataType = DataType.Input;
- varType = VarType.Bit;
- break;
- case "Q":
- case "A":
- case "O":
- // Output
- dataType = DataType.Output;
- varType = VarType.Bit;
- break;
- case "M":
- // Memory
- dataType = DataType.Memory;
- varType = VarType.Bit;
- break;
- case "T":
- // Timer
- dataType = DataType.Timer;
- dbNumber = 0;
- address = int.Parse(input.Substring(1));
- varType = VarType.Timer;
- return;
- case "Z":
- case "C":
- // Counter
- dataType = DataType.Counter;
- dbNumber = 0;
- address = int.Parse(input.Substring(1));
- varType = VarType.Counter;
- return;
- default:
- throw new InvalidAddressException(string.Format("{0} is not a valid address", input.Substring(0, 1)));
- }
- string txt2 = input.Substring(1);
- if (txt2.IndexOf(".") == -1)
- throw new InvalidAddressException("To few periods for DB address");
- address = int.Parse(txt2.Substring(0, txt2.IndexOf(".")));
- bitNumber = int.Parse(txt2.Substring(txt2.IndexOf(".") + 1));
- if (bitNumber > 7)
- throw new InvalidAddressException("Bit can only be 0-7");
- return;
- }
- }
- }
- }
|