123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- using Google.Protobuf;
- using Message;
- using parkMonitor.LOG;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace parkspace_manager
- {
- public partial class FormParkSpaceStatus : Form
- {
- public static int s_spacesInRow = 18;
- public static int s_floors = 13;
- public static int s_rows = 1;
- public static bool s_isClosing;
- private static object s_map_update_lock;
- private static object s_parkspace_force_update_queue_lock;
- private static object s_parkspace_status_lock;
- /// <summary>
- /// 车位id与车位信息映射
- /// </summary>
- private Dictionary<int, Parkspace_info> m_idPssMap;
- /// <summary>
- /// 强制更新反馈消息队列,用于处理同时收到多个反馈消息的情况
- /// </summary>
- private Queue<Parkspace_force_update_response_msg> m_parkspace_force_update_response_queue;
- /// <summary>
- /// 当前所有车位状态,由界面更新线程主动更新
- /// </summary>
- Parkspace_allocation_data_msg m_parkspace_status;
- Thread m_update_display_thread;
- public FormParkSpaceStatus()
- {
- m_parkspace_status = new Parkspace_allocation_data_msg();
- s_map_update_lock = new object();
- s_parkspace_force_update_queue_lock = new object();
- s_parkspace_status_lock = new object();
- m_parkspace_force_update_response_queue = new Queue<Parkspace_force_update_response_msg>();
- m_idPssMap = new Dictionary<int, Parkspace_info>();
- s_isClosing = false;
- InitializeComponent();
- Communicator.Instance.Init();
- Communicator.Instance.Bind("tcp://192.168.2.154:12333");
- Communicator.Instance.Connect("tcp://192.168.2.127:30008");
- Communicator.Instance.Connect("tcp://192.168.2.127:30000");
- Communicator.Instance.SetParkspaceForceUpdateResponseDelegate(ParkspaceForceUpdateResponseCallback);
- // 库位显示
- m_update_display_thread = new Thread(new ThreadStart(UpdateParkingSpaceView));
- m_update_display_thread.Start();
- }
- public void Uninit()
- {
- s_isClosing = true;
- Communicator.Instance.Uninit();
- //if(m_update_display_thread!=null)
- //{
- // m_update_display_thread.Join();
- //}
- }
- /// <summary>
- /// 接收到强制更新车位反馈消息回调
- /// </summary>
- /// <param name="response"></param>
- void ParkspaceForceUpdateResponseCallback(Parkspace_force_update_response_msg response)
- {
- lock (s_parkspace_force_update_queue_lock)
- {
- if (m_parkspace_force_update_response_queue != null)
- {
- m_parkspace_force_update_response_queue.Enqueue(response);
- }
- }
- }
- /// <summary>
- /// 更新立体停车位显示
- /// </summary>
- private void UpdateParkingSpaceView()
- {
- while (!s_isClosing)
- {
- bool needUpdate = false;
- List<Parkspace_info> psList = null;
- Thread.Sleep(1000);
- bool get_status_result = Communicator.Instance.Get_parkspace_status(ref m_parkspace_status);
- lock (s_parkspace_status_lock)
- {
- if (get_status_result && (m_parkspace_status == null || m_parkspace_status.ParkspaceInfoEx == null))
- {
- get_status_result = false;
- }
- }
- if (!get_status_result)
- {
- lock (s_map_update_lock)
- {
- m_idPssMap.Clear();
- }
- continue;
- }
- else
- {
- lock (s_parkspace_status_lock)
- {
- psList = m_parkspace_status.ParkspaceInfoEx.ToList();
- }
- }
- if (psList == null || psList.Count <= 0)
- {
- Thread.Sleep(1000);
- continue;
- }
- //更新映射表
- try
- {
- lock (s_map_update_lock)
- {
- if (m_idPssMap.Count != psList.Count)
- {
- m_idPssMap.Clear();
- for (int i = 0; i < psList.Count; i++)
- {
- m_idPssMap.Add(psList[i].ParkingspaceIndexId, psList[i]);
- }
- }
- else
- {
- for (int i = 0; i < psList.Count; i++)
- {
- m_idPssMap[psList[i].ParkingspaceIndexId] = psList[i];
- }
- }
- }
- }
- catch (Exception e) { Console.WriteLine(e.StackTrace); /*Log.WriteLog(LogType.process, LogFile.WARNING, "实时更新所有库位异常");*/ }
- Action action = () =>
- {
- int blockSize = s_spacesInRow * s_floors * s_rows;
- int offset = (s_rows + 1 - ((blockSize / s_spacesInRow) % s_rows)) * s_spacesInRow;
- //创建控件
- if (ParkingSpaceMonitorPanel != null && ParkingSpaceMonitorPanel.Controls.Count == 0 || needUpdate)
- {
- TableLayoutPanel tlp = new TableLayoutPanel();
- tlp.Name = "tlp_ParkingSpace";
- tlp.ColumnCount = s_rows;
- tlp.RowCount = 1;
- tlp.Dock = DockStyle.Fill;
- tlp.AutoScroll = true;
- tlp.BackColor = SystemColors.GradientActiveCaption;
- for (int i = 0; i < s_rows; i++)
- {
- TableLayoutPanel temp = new TableLayoutPanel();
- temp.Name = "tlp_ParkingSpaceSection" + (i + 1).ToString();
- temp.RowCount = s_floors;
- temp.ColumnCount = s_spacesInRow;
- temp.Dock = DockStyle.Fill;
- temp.AutoSize = true;
- temp.BackColor = SystemColors.GradientActiveCaption;
- temp.Margin = new Padding(1, 2, 1, 2);
- for (int j = Math.Max(psList.Count, blockSize) - 1; j >= 0; j--)
- {
- Button btn = new Button();
- btn.Anchor = (AnchorStyles.Top | AnchorStyles.Left);
- btn.AutoSize = true;
- btn.Location = new Point(5, 5);
- btn.Margin = new Padding(1, 2, 1, 2);
- btn.Padding = new Padding(5);
- btn.Name = "lb_parkingSpace" + j;
- btn.TextAlign = ContentAlignment.MiddleCenter;
- btn.MouseClick += new MouseEventHandler(Btnvalue_Click);
- btn.MouseHover += new EventHandler(Btnvalue_Mouse_Hover);
- if (((j + offset) / s_spacesInRow) % s_rows == i)
- {
- if (j > psList.Count - 1)
- {
- btn.Text = "#####";
- temp.Controls.Add(btn);
- btn.BackColor = GetPSColor(Parkspace_status.EParkspaceError);
- }
- else
- {
- try
- {
- btn.Text = "车位" + psList[j].ParkingspaceIndexId;
- btn.BackColor = GetPSColor(psList[j].ParkingspaceStatus);
- temp.Controls.Add(btn);
- }
- catch { Log.WriteLog(LogType.process, LogFile.WARNING, "实时更新单一库位异常"); }
- }
- }
- }
- tlp.Controls.Add(temp);
- //tlpList.Add(temp);
- }
- ParkingSpaceMonitorPanel.Controls.Clear();
- ParkingSpaceMonitorPanel.Controls.Add(tlp);
- needUpdate = false;
- }
- //更新控件
- else
- {
- Control.ControlCollection psCC = ParkingSpaceMonitorPanel.Controls;
- foreach (Control segment in psCC)
- {
- Control.ControlCollection segmentCC = segment.Controls;
- //Console.WriteLine("seg::"+segmentCC.Count);
- foreach (Control spaces in segmentCC)
- {
- Control.ControlCollection spaceCC = spaces.Controls;
- //Console.WriteLine("spaces::"+spaceCC.Count);
- foreach (Control space in spaceCC)
- {
- if (space.GetType() == typeof(Button))
- {
- int index = -1;
- bool result = int.TryParse(space.Text.Substring(2), out index);
- lock (s_map_update_lock)
- {
- //Console.WriteLine("text is :" + space.Text+", index:"+index);
- if (m_idPssMap.ContainsKey(index))
- {
- //Console.WriteLine("index:" + index+", status:"+ idPssMap[index].spaceStatus);
- space.BackColor = GetPSColor(m_idPssMap[index].ParkingspaceStatus);
- }
- else if (result)
- {
- needUpdate = true;
- //Console.WriteLine("need update:"+index);
- break;
- }
- }
- }
- }
- }
- if (needUpdate)
- {
- break;
- }
- }
- }
- };
- if (this != null && this.IsHandleCreated)
- {
- this.Invoke(action);
- }
- }
- }
- /// <summary>
- /// 按钮点击事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Btnvalue_Click(object sender, MouseEventArgs e)
- {
- Button btn = (Button)sender;
- //实例化窗口,选择待修改状态
- FormStatusSelect formStatusSelect = new FormStatusSelect(btn);
- formStatusSelect.Location = Control.MousePosition;
- formStatusSelect.StartPosition = FormStartPosition.Manual;
- formStatusSelect.SetCallback(ForceUpdateStatusCallback);
- formStatusSelect.ShowDialog();
- }
- private void Btnvalue_Mouse_Hover(object sender, EventArgs e)
- {
- Button btn = (Button)sender;
- // 创建the ToolTip
- ToolTip toolTip_parkspace_info = new ToolTip();
- // 设置显示样式
- toolTip_parkspace_info.AutoPopDelay = 20000;//提示信息的可见时间
- toolTip_parkspace_info.InitialDelay = 500;//事件触发多久后出现提示
- toolTip_parkspace_info.ReshowDelay = 1000;//指针从一个控件移向另一个控件时,经过多久才会显示下一个提示框
- toolTip_parkspace_info.ShowAlways = false;//是否显示提示框
- // 获取车位信息,处理后显示
- int parkspaceID = GetParkspaceIdFromButton(btn);
- Parkspace_info space_info = null;
- lock (s_parkspace_status_lock)
- {
- if (parkspaceID <= 0 || m_parkspace_status == null || m_parkspace_status.ParkspaceInfoEx == null)
- return;
- for (int i = 0; i < m_parkspace_status.ParkspaceInfoEx.Count; i++)
- {
- if (m_parkspace_status.ParkspaceInfoEx[i].ParkingspaceIndexId == parkspaceID)
- {
- space_info = m_parkspace_status.ParkspaceInfoEx[i];
- break;
- }
- }
- }
- if (space_info == null)
- return;
- // 设置伴随的对象
- toolTip_parkspace_info.SetToolTip(btn, space_info.ToString().Replace(",", "\n"));//设置提示按钮和提示内容
- }
- /// <summary>
- /// 定义用于发送修改请求,以及修改button状态的回调函数
- /// </summary>
- /// <param name="status"></param>
- private void ForceUpdateStatusCallback(Parkspace_status status, Button btn)
- {
- int parkspaceID = GetParkspaceIdFromButton(btn);
- lock(s_parkspace_status_lock)
- {
- if (parkspaceID <= 0 || m_parkspace_status == null || m_parkspace_status.ParkspaceInfoEx == null)
- return;
- }
- SendAndReceive(status, parkspaceID);
- }
- /// <summary>
- /// 发送后接收对应反馈消息
- /// </summary>
- private void SendAndReceive(Parkspace_status status, int parkspaceID)
- {
- // 遍历强制更新反馈队列,清除对应车位已存在的反馈消息,即将非对应车位的消息放回队列
- lock (s_parkspace_force_update_queue_lock)
- {
- for (int i = 0; i < m_parkspace_force_update_response_queue.Count; i++)
- {
- Parkspace_force_update_response_msg response = m_parkspace_force_update_response_queue.Dequeue();
- if (response.ManualParkspaceInfoEx != null && response.ManualParkspaceInfoEx.Count > 0 && response.ManualParkspaceInfoEx[0].ParkingspaceIndexId != parkspaceID)
- {
- m_parkspace_force_update_response_queue.Enqueue(response);
- }
- }
- }
- // 发送强制更新请求
- Parkspace_info space_info = null;
- lock (s_parkspace_status_lock)
- {
- //用于清除所有车位状态的特殊指令
- if (parkspaceID == 9999)
- {
- space_info = new Parkspace_info();
- if (m_parkspace_status.ParkspaceInfoEx.Count() > 0)
- {
- space_info = m_parkspace_status.ParkspaceInfoEx[0];
- }
- space_info.ParkingspaceIndexId = 9999;
- }
- else
- {
- for (int i = 0; i < m_parkspace_status.ParkspaceInfoEx.Count; i++)
- {
- if (m_parkspace_status.ParkspaceInfoEx[i].ParkingspaceIndexId == parkspaceID)
- {
- space_info = m_parkspace_status.ParkspaceInfoEx[i];
- break;
- }
- }
- }
- }
- DateTime startTime = DateTime.Now;
- string commandKey = startTime.ToString("yyyy-MM-dd_HH:mm:ss:ffff");
- try
- {
- space_info.ParkingspaceStatus = status;
- Parkspace_force_update_request_msg parkspace_force_update_request_msg = new Parkspace_force_update_request_msg();
- Base_info base_Info = new Base_info();
- base_Info.MsgType = Message_type.EParkspaceForceUpdateRequestMsg;
- base_Info.TimeoutMs = 2000;
- base_Info.Sender = Message.Communicator.EParkspace;
- base_Info.Receiver = Message.Communicator.EParkspace;
- parkspace_force_update_request_msg.BaseInfo = base_Info;
- parkspace_force_update_request_msg.CommandKey = commandKey;
- parkspace_force_update_request_msg.ManualParkspaceInfoEx.Add(space_info);
- Communicator.Instance.Send_msg(parkspace_force_update_request_msg.ToByteString());
- }
- catch (Exception ex) { Console.WriteLine(ex.StackTrace); }
- // 遍历强制更新反馈队列,寻找对应反馈消息
- bool get_result = false;
- while ((DateTime.Now - startTime).TotalMilliseconds < Communicator.Instance.m_timeout_milli)
- {
- lock (s_parkspace_force_update_queue_lock)
- {
- for (int i = 0; i < m_parkspace_force_update_response_queue.Count; i++)
- {
- Parkspace_force_update_response_msg response = m_parkspace_force_update_response_queue.Dequeue();
- if (response.ManualParkspaceInfoEx != null && response.ManualParkspaceInfoEx.Count > 0 && response.CommandKey == commandKey && response.ManualParkspaceInfoEx[0].ParkingspaceIndexId== parkspaceID)
- {
- get_result = true;
- if (response.ErrorManager != null)
- {
- if (response.ErrorManager.ErrorCode != 0)
- {
- //btn.BackColor = GetPSColor(status);
- Console.WriteLine("force update failed, code: " + response.ErrorManager.ErrorCode + ", description: " + response.ErrorManager.ErrorDescription);
- }
- }
- break;
- }
- else
- {
- m_parkspace_force_update_response_queue.Enqueue(response);
- }
- }
- }
- if (get_result)
- break;
- Thread.Sleep(50);
- }
- if (!get_result && space_info != null)
- {
- MessageBox.Show("force update get response timeout: " + space_info.ToString());
- }
- }
- /// <summary>
- /// 通过按钮信息截取车位id,失败返回-1
- /// </summary>
- /// <param name="btn"></param>
- /// <returns></returns>
- private int GetParkspaceIdFromButton(Button btn)
- {
- if (btn == null || btn.Text.Length < 3)
- return -1;
- int parkspaceID = -1;
- bool parse_result = int.TryParse(btn.Text.Substring(2), out parkspaceID);
- if (parse_result)
- {
- return parkspaceID;
- }
- else
- {
- return -1;
- }
- }
- /// <summary>
- /// 获取状态对应颜色
- /// </summary>
- /// <param name="status"></param>
- /// <returns></returns>
- private Color GetPSColor(Parkspace_status status)
- {
- switch (status)
- {
- case Parkspace_status.EParkspaceEmpty: return Color.White;
- case Parkspace_status.EParkspaceOccupied: return Color.Yellow;
- case Parkspace_status.EParkspaceReserved: return Color.SkyBlue;
- case Parkspace_status.EParkspaceLocked: return Color.LightGreen;
- case Parkspace_status.EParkspaceError: return Color.Red;
- default: return Color.Violet;
- }
- }
- private void FormParkSpaceStatus_FormClosing(object sender, FormClosingEventArgs e)
- {
- e.Cancel = true;
- this.Visible = false;
- }
- private void FormParkSpaceStatus_FormClosed(object sender, FormClosedEventArgs e)
- {
- try
- {
- if (m_update_display_thread != null)
- {
- m_update_display_thread.Abort();
- }
- }
- catch { Console.WriteLine("线程退出"); }
- //s_isClosing = true;
- ////if (m_update_display_thread != null)
- ////{
- //// m_update_display_thread.Join();
- ////}
- //Communicator.Instance.Uninit();
- }
- /// <summary>
- /// 一键清除所有号牌,车位全部设置空闲,调试用
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btn_clear_Click(object sender, EventArgs e)
- {
- SendAndReceive(Parkspace_status.EParkspaceEmpty, 9999);
- }
- }
- }
|