123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950 |
- using Newtonsoft.Json;
- using Newtonsoft.Json.Linq;
- using RestSharp;
- using S7.Net;
- using System.Drawing.Imaging;
- using System.Runtime.InteropServices;
- using System.Threading.Channels;
- using System.Windows.Forms;
- using static xicheji.CHCNetSDK;
- namespace xicheji
- {
- public partial class MainForm : Form
- {
- private readonly Config config;
- private static DateTime logDate = DateTime.Now;
- private static StreamWriter logWriter;
- private DateTime lastReceiveTime = DateTime.MinValue;
- private byte[]? currentDataBlock;
- private Plc? plc = null;
- private bool m_bInitSDK = false;
- private bool m_bRecord = false;
- private uint iLastErr = 0;
- private int m_lUserID = -1;
- private int m_lRealHandle = -1;
- private string str1;
- private string str2;
- private int i = 0;
- private int m_lTree = 0;
- private string str;
- private long iSelIndex = 0;
- private uint dwAChanTotalNum = 0;
- private uint dwDChanTotalNum = 0;
- private int m_lPort = -1;
- private IntPtr m_ptrRealHandle;
- private int[] iIPDevID = new int[96];
- private int[] iChannelNum = new int[96];
- private CHCNetSDK.REALDATACALLBACK RealData = null;
- public CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo;
- public CHCNetSDK.NET_DVR_IPPARACFG_V40 m_struIpParaCfgV40;
- public CHCNetSDK.NET_DVR_STREAM_MODE m_struStreamMode;
- public CHCNetSDK.NET_DVR_IPCHANINFO m_struChanInfo;
- public CHCNetSDK.NET_DVR_PU_STREAM_URL m_struStreamURL;
- public CHCNetSDK.NET_DVR_IPCHANINFO_V40 m_struChanInfoV40;
- private PlayCtrl.DECCBFUN m_fDisplayFun = null;
- public delegate void MyDebugInfo(string str);
- private readonly List<WashRecord> washRecords = new();
- private string lastCarNo = string.Empty;
- private IFreeSql db;
- public MainForm()
- {
- InitializeComponent();
- config = ConfigHelper.GetConfig();
- logWriter = new StreamWriter(DateTime.Now.ToString("yyyy_MM_dd") + ".log");
- db = new FreeSql.FreeSqlBuilder()
- .UseAutoSyncStructure(true)
- .UseConnectionString(FreeSql.DataType.Sqlite, config.DBString)
- .Build();
- }
- private void MainForm_Load(object sender, EventArgs e)
- {
- try
- {
- m_bInitSDK = CHCNetSDK.NET_DVR_Init();
- if (m_bInitSDK == false)
- {
- MessageBox.Show("NET_DVR_Init error!");
- return;
- }
- else
- {
- //保存SDK日志 To save the SDK log
- CHCNetSDK.NET_DVR_SetLogToFile(3, Path.Combine(Directory.GetCurrentDirectory(), "log"), true);
- for (int i = 0; i < 64; i++)
- {
- iIPDevID[i] = -1;
- iChannelNum[i] = -1;
- }
- }
- dataGridView1.AutoGenerateColumns = false;
- dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
- #region 测试代码: 表格数据
- washRecords.Add(new WashRecord()
- {
- DeviceId = "asdf",
- 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,
- });
- #endregion
- 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 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 (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 { }
- }
- public static void Log(object message)
- {
- if (message == null) return;
- if (DateTime.Now.Date != logDate.Date)
- {
- logDate = DateTime.Now;
- logWriter = new StreamWriter(DateTime.Now.ToString("yyyy_MM_dd") + ".log");
- }
- logWriter.WriteLine(DateTime.Now.ToString("HH:mm:ss:fff> ") + " " + message);
- logWriter.Flush();
- }
- #region 读PLC数据
- 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 receivePLCTimer_Tick(object sender, EventArgs e)
- {
- try
- {
- if (plc == null || !plc.IsConnected)
- {
- receivePLCTimer.Enabled = false;
- return;
- }
- ReadPLCData();
- }
- catch (Exception ex)
- {
- receivePLCTimer.Enabled = false;
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- private void ReadPLCData()
- {
- currentDataBlock = plc!.ReadBytes(DataType.DataBlock, 1, 0, 100);
- var time = DateTime.Now; //临时代码, 先跳过下面日期报错的
- //var time = new DateTime(
- // DateTime.Now.Year,
- // ReadPLCInt("当前月"),
- // ReadPLCInt("当前日"),
- // ReadPLCInt("当前时"),
- // ReadPLCInt("当前分"),
- // ReadPLCInt("当前秒"));
- var macAddress = ReadMacAddress();
- Log("macAddress: " + macAddress);
- if (string.IsNullOrEmpty(config.PLCMacAddress))
- {
- //第一次配置为空时,更新一下mac地址
- config.PLCMacAddress = macAddress;
- }
- //if (config.PLCMacAddress != macAddress)
- //{
- // //以后还不匹配就提示
- // MessageBox.Show("PLC设备Mac地址不匹配,请确认!");
- // return;
- //}
- if (time <= lastReceiveTime)
- {
- //已经读过这个时间的了
- return;
- }
- db.Insert(new PLCRecord() { Data = currentDataBlock }).ExecuteAffrows();
- lastReceiveTime = time;
- ReadError();
- ReadStatus();
- lblWashCount.Text = ReadPLCString("洗车次数");
- lblTotalWater.Text = ReadPLCString("累计用水量");
- lblTotalElectricity.Text = ReadPLCString("累计用电量");
- //.Text = ReadPLCStringValue("当前流量");
- lblCurrentElectricity.Text = ReadPLCString("当前功率");
- lblCurrentWaterP.Text = ReadPLCString("当前压力");
- var myCrc = CRCCheck(currentDataBlock);
- var readCrc = ReadPLCInt("CRC");
- if (myCrc != readCrc)
- {
- //receivePLCTimer.Enabled = false;
- //MessageBox.Show("CRC不匹配!");
- //return;
- }
- if (ReadPLCInt("最后一次洗车开始月") != 0)
- {
- if (string.IsNullOrEmpty(lastCarNo))
- {
- receivePLCTimer.Enabled = false;
- MessageBox.Show("未检测到车牌信息,请检查是否识别正常");
- return;
- }
- //洗车完成后才有数据的
- var washStartTime = new DateTime(
- DateTime.Now.Year,
- ReadPLCInt("最后一次洗车开始月"),
- ReadPLCInt("最后一次洗车开始日"),
- ReadPLCInt("最后一次洗车开始时"),
- ReadPLCInt("最后一次洗车开始分"),
- ReadPLCInt("最后一次洗车开始秒"));
- var washEndTime = new DateTime(
- DateTime.Now.Year,
- ReadPLCInt("最后一次洗车结束月"),
- ReadPLCInt("最后一次洗车结束日"),
- ReadPLCInt("最后一次洗车结束时"),
- ReadPLCInt("最后一次洗车结束分"),
- ReadPLCInt("最后一次洗车结束秒"));
- var washRecord = new WashRecord()
- {
- DeviceId = macAddress,
- CarNum = lastCarNo,
- StartTime = washStartTime,
- EndTime = washEndTime,
- DryTime = ReadPLCInt("最后一次洗车风干时长"),
- TotalElectricity = ReadPLCInt("最后一次洗车用电"),
- TotalWater = ReadPLCInt("最后一次洗车用水"),
- WashTime = ReadPLCInt("最后一次洗车总时长"),
- WaterPressure = ReadPLCInt("最后一次洗车水压"),
- };
- washRecords.Add(washRecord);
- db.Insert(washRecord).ExecuteAffrows();
- //洗车完成后重置车牌信息
- lastCarNo = string.Empty;
- }
- }
- private static readonly ushort[] crcTable = new ushort[256] {
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
- 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
- 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
- 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
- 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
- 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
- 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
- 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
- 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
- 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
- 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
- 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
- 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
- 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
- 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
- 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
- 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
- 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
- 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
- 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
- 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
- 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
- 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
- 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
- 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
- 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
- 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
- };
- private static ushort CRCCheck(byte[] data)
- {
- ushort crc = 0xFFFF;
- foreach (byte b in data)
- {
- byte tableIndex = (byte)(((crc >> 8) ^ b) & 0xFF);
- crc = (ushort)((crc << 8) ^ crcTable[tableIndex]);
- }
- return crc;
- }
- private string ReadMacAddress()
- {
- var mac1 = ReadPLCInt("MAC1");
- var mac2 = ReadPLCInt("MAC2");
- var mac3 = ReadPLCInt("MAC3");
- var mac4 = ReadPLCInt("MAC4");
- var mac5 = ReadPLCInt("MAC5");
- var mac6 = ReadPLCInt("MAC6");
- return $"{ConvertMacItem(mac1)}:{ConvertMacItem(mac2)}:{ConvertMacItem(mac3)}:{ConvertMacItem(mac4)}:{ConvertMacItem(mac5)}:{ConvertMacItem(mac6)}";
- }
- private string ConvertMacItem(int value)
- {
- return value.ToString("X").PadLeft(2, '0');
- }
- 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 || currentDataBlock == null)
- return string.Empty;
- ParsePLCKey(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}".TrimEnd();
- }
- else if (varType == VarType.Word)
- {
- var value = S7.Net.Types.Word.FromByteArray(currentDataBlock.Take(new Range(address, address + 2)).ToArray());
- return $"{value} {variable.Desc}".TrimEnd();
- }
- else if (varType == VarType.Byte)
- {
- var value = S7.Net.Types.Byte.FromByteArray(currentDataBlock.Take(new Range(address, address + 1)).ToArray());
- return $"{value} {variable.Desc}".TrimEnd();
- }
- return string.Empty;
- }
- private int ReadPLCInt(string name)
- {
- var variable = ConfigHelper.FindVariable(name);
- if (variable == null || currentDataBlock == null)
- return 0;
- ParsePLCKey(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;
- }
- else if (varType == VarType.Byte)
- {
- var value = S7.Net.Types.Byte.FromByteArray(currentDataBlock.Take(new Range(address, address + 1)).ToArray());
- return value;
- }
- return 0;
- }
- private bool ReadPLCBool(string name)
- {
- var variable = ConfigHelper.FindVariable(name);
- if (variable == null || currentDataBlock == null)
- return false;
- ParsePLCKey(variable.Key, out _, out _, out _, out var address, out var bitNumber);
- var value = S7.Net.Types.Boolean.GetValue(currentDataBlock[address], bitNumber);
- return value;
- }
- private static void ParsePLCKey(string plcKey, out DataType dataType, out int dbNumber, out VarType varType, out int address, out int bitNumber)
- {
- bitNumber = -1;
- dbNumber = 0;
- switch (plcKey.Substring(0, 2))
- {
- case "DB":
- string[] strings = plcKey.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(plcKey.Substring(2));
- varType = VarType.Byte;
- return;
- case "IW":
- case "EW":
- // Input word
- dataType = DataType.Input;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.Word;
- return;
- case "ID":
- case "ED":
- // Input double-word
- dataType = DataType.Input;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.DWord;
- return;
- case "QB":
- case "AB":
- case "OB":
- // Output byte
- dataType = DataType.Output;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.Byte;
- return;
- case "QW":
- case "AW":
- case "OW":
- // Output word
- dataType = DataType.Output;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.Word;
- return;
- case "QD":
- case "AD":
- case "OD":
- // Output double-word
- dataType = DataType.Output;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.DWord;
- return;
- case "MB":
- // Memory byte
- dataType = DataType.Memory;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.Byte;
- return;
- case "MW":
- // Memory word
- dataType = DataType.Memory;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.Word;
- return;
- case "MD":
- // Memory double-word
- dataType = DataType.Memory;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(2));
- varType = VarType.DWord;
- return;
- default:
- switch (plcKey.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(plcKey.Substring(1));
- varType = VarType.Timer;
- return;
- case "Z":
- case "C":
- // Counter
- dataType = DataType.Counter;
- dbNumber = 0;
- address = int.Parse(plcKey.Substring(1));
- varType = VarType.Counter;
- return;
- default:
- throw new InvalidAddressException(string.Format("{0} is not a valid address", plcKey.Substring(0, 1)));
- }
- string txt2 = plcKey.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;
- }
- }
- #endregion
- #region 上传到洗车平台
- private async void uploadTimer_Tick(object sender, EventArgs e)
- {
- try
- {
- await UploadPlatform();
- }
- catch (Exception ex)
- {
- uploadTimer.Enabled = false;
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- private async Task UploadPlatform()
- {
- var restClient = new RestClient(config.Server);
- var request = new RestRequest("cyft/common/carWashRecord", Method.Post);
- // 测试代码
- WashRecord washRecord = new WashRecord();
- var jsonBody = new
- {
- deviceId = washRecord.DeviceId, //洗车机器mac地址
- carNo = washRecord.CarNum, //车牌号码
- beginTime = washRecord.StartTime.ToString("yyyy-MM-dd HH:mm:ss"), //洗车开始时间
- endTime = washRecord.EndTime.ToString("yyyy-MM-dd HH:mm:ss"), //洗车结束时间
- washTime = washRecord.WashTime, //洗车时长(s)
- widnowsDefender = washRecord.TotalWater, //用水量(t)
- waterPressure = washRecord.WaterPressure, //压力(MPa)
- picBase64 = ImageToBase64(pbCamera.Image, ImageFormat.Jpeg), //洗车图片base64
- };
- request.AddParameter("application/json", JsonConvert.SerializeObject(jsonBody), ParameterType.RequestBody);
- var response = await restClient.ExecuteAsync(request);
- if (response == null) return;
- }
- #endregion
- #region 摄像头
- private void btnConnectCamera_Click(object sender, EventArgs e)
- {
- try
- {
- ConnectCamera();
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- private void ConnectCamera()
- {
- try
- {
- cboCameraChannel.DisplayMember = "Display";
- cboCameraChannel.ValueMember = "Value";
- cboCameraChannel.Items.Clear();
- //登录设备 Login the device
- m_lUserID = CHCNetSDK.NET_DVR_Login_V30(config.CameraIP, int.Parse(config.CameraPort),
- config.CameraUserName, config.CameraPassword, ref DeviceInfo);
- if (m_lUserID < 0)
- {
- var iLastErr = CHCNetSDK.NET_DVR_GetLastError();
- var errMsg = "NET_DVR_Login_V30 failed, error code= " + iLastErr; //登录失败,输出错误号 Failed to login and output the error code
- MessageBox.Show(errMsg);
- return;
- }
- else
- {
- //登录成功
- Log("NET_DVR_Login_V30 succ!");
- dwAChanTotalNum = (uint)DeviceInfo.byChanNum;
- dwDChanTotalNum = (uint)DeviceInfo.byIPChanNum + 256 * (uint)DeviceInfo.byHighDChanNum;
- if (dwDChanTotalNum > 0)
- {
- InfoIPChannel();
- }
- else
- {
- for (var i = 0; i < dwAChanTotalNum; i++)
- {
- ListAnalogChannel(i + 1, 1);
- iChannelNum[i] = i + (int)DeviceInfo.byStartChan;
- }
- //comboBoxView.SelectedItem = 1;
- // MessageBox.Show("This device has no IP channel!");
- }
- }
- if (cboCameraChannel.Items.Count > 0 && cboCameraChannel.SelectedIndex == -1)
- {
- cboCameraChannel.SelectedIndex = 0;
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- public void InfoIPChannel()
- {
- uint dwSize = (uint)Marshal.SizeOf(m_struIpParaCfgV40);
- IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal((Int32)dwSize);
- Marshal.StructureToPtr(m_struIpParaCfgV40, ptrIpParaCfgV40, false);
- uint dwReturn = 0;
- int iGroupNo = 0; //该Demo仅获取第一组64个通道,如果设备IP通道大于64路,需要按组号0~i多次调用NET_DVR_GET_IPPARACFG_V40获取
- if (!CHCNetSDK.NET_DVR_GetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_IPPARACFG_V40, iGroupNo, ptrIpParaCfgV40, dwSize, ref dwReturn))
- {
- iLastErr = CHCNetSDK.NET_DVR_GetLastError();
- str = "NET_DVR_GET_IPPARACFG_V40 failed, error code= " + iLastErr;
- //获取IP资源配置信息失败,输出错误号 Failed to get configuration of IP channels and output the error code
- Log(str);
- }
- else
- {
- Log("NET_DVR_GET_IPPARACFG_V40 succ!");
- m_struIpParaCfgV40 = (CHCNetSDK.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40, typeof(CHCNetSDK.NET_DVR_IPPARACFG_V40));
- for (var i = 0; i < dwAChanTotalNum; i++)
- {
- ListAnalogChannel(i + 1, m_struIpParaCfgV40.byAnalogChanEnable[i]);
- iChannelNum[i] = i + (int)DeviceInfo.byStartChan;
- }
- byte byStreamType = 0;
- uint iDChanNum = 64;
- if (dwDChanTotalNum < 64)
- {
- iDChanNum = dwDChanTotalNum; //如果设备IP通道小于64路,按实际路数获取
- }
- for (var i = 0; i < iDChanNum; i++)
- {
- iChannelNum[i + dwAChanTotalNum] = i + (int)m_struIpParaCfgV40.dwStartDChan;
- byStreamType = m_struIpParaCfgV40.struStreamMode[i].byGetStreamType;
- dwSize = (uint)Marshal.SizeOf(m_struIpParaCfgV40.struStreamMode[i].uGetStream);
- switch (byStreamType)
- {
- //目前NVR仅支持直接从设备取流 NVR supports only the mode: get stream from device directly
- case 0:
- IntPtr ptrChanInfo = Marshal.AllocHGlobal((Int32)dwSize);
- Marshal.StructureToPtr(m_struIpParaCfgV40.struStreamMode[i].uGetStream, ptrChanInfo, false);
- m_struChanInfo = (CHCNetSDK.NET_DVR_IPCHANINFO)Marshal.PtrToStructure(ptrChanInfo, typeof(CHCNetSDK.NET_DVR_IPCHANINFO));
- //列出IP通道 List the IP channel
- ListIPChannel(i + 1, m_struChanInfo.byEnable, m_struChanInfo.byIPID);
- iIPDevID[i] = m_struChanInfo.byIPID + m_struChanInfo.byIPIDHigh * 256 - iGroupNo * 64 - 1;
- Marshal.FreeHGlobal(ptrChanInfo);
- break;
- case 4:
- IntPtr ptrStreamURL = Marshal.AllocHGlobal((Int32)dwSize);
- Marshal.StructureToPtr(m_struIpParaCfgV40.struStreamMode[i].uGetStream, ptrStreamURL, false);
- m_struStreamURL = (CHCNetSDK.NET_DVR_PU_STREAM_URL)Marshal.PtrToStructure(ptrStreamURL, typeof(CHCNetSDK.NET_DVR_PU_STREAM_URL));
- //列出IP通道 List the IP channel
- ListIPChannel(i + 1, m_struStreamURL.byEnable, m_struStreamURL.wIPID);
- iIPDevID[i] = m_struStreamURL.wIPID - iGroupNo * 64 - 1;
- Marshal.FreeHGlobal(ptrStreamURL);
- break;
- case 6:
- IntPtr ptrChanInfoV40 = Marshal.AllocHGlobal((Int32)dwSize);
- Marshal.StructureToPtr(m_struIpParaCfgV40.struStreamMode[i].uGetStream, ptrChanInfoV40, false);
- m_struChanInfoV40 = (CHCNetSDK.NET_DVR_IPCHANINFO_V40)Marshal.PtrToStructure(ptrChanInfoV40, typeof(CHCNetSDK.NET_DVR_IPCHANINFO_V40));
- //列出IP通道 List the IP channel
- ListIPChannel(i + 1, m_struChanInfoV40.byEnable, m_struChanInfoV40.wIPID);
- iIPDevID[i] = m_struChanInfoV40.wIPID - iGroupNo * 64 - 1;
- Marshal.FreeHGlobal(ptrChanInfoV40);
- break;
- default:
- break;
- }
- }
- }
- Marshal.FreeHGlobal(ptrIpParaCfgV40);
- }
- public void ListIPChannel(int iChanNo, byte byOnline, int byIPID)
- {
- str1 = String.Format("通道 {0}", iChanNo);
- m_lTree++;
- if (byIPID == 0)
- {
- str2 = "空闲"; //通道空闲,没有添加前端设备 the channel is idle
- }
- else
- {
- if (byOnline == 0)
- {
- str2 = "离线"; //通道不在线 the channel is off-line
- }
- else
- str2 = "在线"; //通道在线 The channel is on-line
- }
- cboCameraChannel.Items.Add(new
- {
- Display = $"{str1}: {str2}",
- Value = iChanNo,
- });
- }
- public void ListAnalogChannel(int iChanNo, byte byEnable)
- {
- str1 = String.Format("通道 {0}", iChanNo);
- m_lTree++;
- if (byEnable == 0)
- {
- str2 = "禁用"; //通道已被禁用 This channel has been disabled
- }
- else
- {
- str2 = "启用"; //通道处于启用状态 This channel has been enabled
- }
- cboCameraChannel.Items.Add(new
- {
- Display = $"{str1}: {str2}",
- Value = iChanNo,
- });
- }
- private void cboCameraChannel_SelectedIndexChanged(object sender, EventArgs e)
- {
- try
- {
- //停止预览 Stop live view
- if (!CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle))
- {
- iLastErr = CHCNetSDK.NET_DVR_GetLastError();
- str = "NET_DVR_StopRealPlay failed, error code= " + iLastErr;
- Log(str);
- }
- Log("NET_DVR_StopRealPlay succ!");
- m_lRealHandle = -1;
- pbCamera.Invalidate();//刷新窗口 refresh the window
- iSelIndex = cboCameraChannel.SelectedIndex;
- //hikApi?.PlaybackService.StartPlayBack(channelNumber, pbCamera.Handle);
- CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();
- lpPreviewInfo.hPlayWnd = pbCamera.Handle;//预览窗口 live view window
- lpPreviewInfo.lChannel = iChannelNum[(int)iSelIndex];//预览的设备通道 the device channel number
- lpPreviewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推
- lpPreviewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
- lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流
- lpPreviewInfo.dwDisplayBufNum = 15; //播放库显示缓冲区最大帧数
- IntPtr pUser = IntPtr.Zero;//用户数据 user data
- //打开预览 Start live view
- m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser);
- if (m_lRealHandle < 0)
- {
- iLastErr = CHCNetSDK.NET_DVR_GetLastError();
- str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号 failed to start live view, and output the error code.
- Log(str);
- pbCamera.Invalidate();//刷新窗口 refresh the window
- return;
- }
- else
- {
- //预览成功
- Log("NET_DVR_RealPlay_V40 succ!");
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message + ex.StackTrace);
- }
- }
- #endregion
- #region 服务接口回调->更新汽车信息
- #endregion
- #region Image <-> Base64
- public static Image Base64ToImage(string base64String)
- {
- byte[] imageBytes = Convert.FromBase64String(base64String);
- using var ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
- ms.Write(imageBytes, 0, imageBytes.Length);
- Image image = Image.FromStream(ms, true);
- return image;
- }
- public static string ImageToBase64(Image image, ImageFormat format)
- {
- if (image == null) return string.Empty;
- using var memoryStream = new MemoryStream();
- image.Save(memoryStream, format);
- var imageBytes = memoryStream.ToArray();
- return Convert.ToBase64String(imageBytes);
- }
- #endregion
- }
- }
|