private void VirtualOneNode(int no, int type)//当前需要虚拟节点编号+节点类型+父亲节点 { // if (no == 0) return; int dr = 14; int de = 16; int tmpX, tmpY;//临时计算坐标用 NodeDescribePacket childNode = new NodeDescribePacket(); childNode = mainHome.nodeInfoArray[no]; //子节点 if (type == 0x01) { Point point2 = new Point(childNode.point.x, childNode.point.y); EndPoint.Add(point2); tmpX = (int)(200 * Math.Cos(childNode.point.angle)) + childNode.point.x; tmpY = (int)(200 * Math.Sin(childNode.point.angle)) + childNode.point.y; childNode.pictureBox.Location = new System.Drawing.Point(tmpX - dr, tmpY - dr); Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); childNode.point.x = tmpX; childNode.point.y = tmpY; } else { Point point2 = new Point(childNode.point.x, childNode.point.y); EndPoint.Add(point2); tmpX = (int)(100 * Math.Cos(childNode.point.angle)) + childNode.point.x; tmpY = (int)(100 * Math.Sin(childNode.point.angle)) + childNode.point.y; childNode.pictureBox.Location = new System.Drawing.Point(tmpX - de, tmpY - de); Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); childNode.point.x = tmpX; childNode.point.y = tmpY; } }
private void firstAddCoor() { //预先增加协调器 NodeDescribePacket newNode = new NodeDescribePacket(); newNode.name = "V000"; newNode.Mac = "0000000000000000"; newNode.NetAddr = 0; nodeMacIndexHash.Add(newNode.Mac, 0); nodeNameIndexHash.Add(newNode.name, 0); nodeAddrIndexHash.Add(newNode.NetAddr, 0); nodeInfoArray.Add(newNode); }
private void firstAddCoor() { //预先增加协调器 NodeDescribePacket newNode = new NodeDescribePacket(); newNode.name = "V000"; newNode.Mac = "0000000000000000"; newNode.NetAddr = 0; nodeMacIndexHash.Add(newNode.Mac, 0); nodeNameIndexHash.Add(newNode.name, 0); nodeAddrIndexHash.Add(newNode.NetAddr, 0); nodeInfoArray.Add(newNode); }
private void AddPictureBox(int no, int type, int x, int y, double r)//相对坐标 { NodeDescribePacket nodePacket = mainHome.nodeInfoArray[no];; if (type == 0x01) { nodePacket.point.x = x + 14; nodePacket.point.y = y + 14; nodePacket.point.angle = r; nodePacket.virtualPoint.x = x + 14 + Convert.ToInt32(60 * Math.Cos(nodePacket.point.angle)); nodePacket.virtualPoint.y = y + 14 + Convert.ToInt32(60 * Math.Sin(nodePacket.point.angle)); nodePacket.virtualPoint.angle = r; } else if (type == 0x02) { nodePacket.point.x = x + 16; nodePacket.point.y = y + 16; nodePacket.point.angle = r; nodePacket.virtualPoint.x = x + 16 + Convert.ToInt32(60 * Math.Cos(nodePacket.point.angle)); nodePacket.virtualPoint.y = y + 16 + Convert.ToInt32(60 * Math.Sin(nodePacket.point.angle)); nodePacket.virtualPoint.angle = r; } nodePacket.pictureBox.Location = new System.Drawing.Point(x, y); if (type == 0x00) { nodePacket.pictureBox.Name = "0" + ":" + no.ToString() + ":" + mainHome.nodeInfoArray[no].SensorNum.ToString();//这个用于节点的tooltip nodePacket.pictureBox.Image = global::AccleZigBee.Properties.Resources.Coor; nodePacket.pictureBox.Size = new System.Drawing.Size(60, 60); } else if (type == 0x01) { nodePacket.pictureBox.Name = "1" + ":" + no.ToString() + ":" + mainHome.nodeInfoArray[no].SensorNum.ToString(); nodePacket.pictureBox.Image = global::AccleZigBee.Properties.Resources.Router; nodePacket.pictureBox.Size = new System.Drawing.Size(28, 28); } else { nodePacket.pictureBox.Name = "2" + ":" + no.ToString() + ":" + mainHome.nodeInfoArray[no].SensorNum.ToString(); nodePacket.pictureBox.Image = global::AccleZigBee.Properties.Resources.End; nodePacket.pictureBox.Size = new System.Drawing.Size(32, 32); } nodePacket.pictureBox.Cursor = System.Windows.Forms.Cursors.Hand; nodePacket.pictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; // nodePacket.pictureBox.ContextMenuStrip = this.contextMenuStrip1;//右键菜单 // nodePacket.pictureBox.MouseEnter += new System.EventHandler(this.pictureBoxPhotoEnter);//进入后有tooltips this.panel1.Controls.Add(nodePacket.pictureBox); // Console.WriteLine("当前控件数目{0}",this.panel1.Controls.Count); }
//当前需要虚拟节点编号+节点类型+父亲节点 private void VirtualOneNode(int no, int type) { // if (no == 0) return; int dr = 14; int de = 16; int tmpX, tmpY;//临时计算坐标用 NodeDescribePacket childNode = new NodeDescribePacket(); childNode = mainHome.nodeInfoArray[no]; //子节点 if (type == 0x01) { Point point2 = new Point(childNode.point.x, childNode.point.y); EndPoint.Add(point2); tmpX = (int)(200 * Math.Cos(childNode.point.angle)) + childNode.point.x; tmpY = (int)(200 * Math.Sin(childNode.point.angle)) + childNode.point.y; childNode.pictureBox.Location = new System.Drawing.Point(tmpX - dr, tmpY - dr); Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); childNode.point.x = tmpX; childNode.point.y = tmpY; } else { Point point2 = new Point(childNode.point.x, childNode.point.y); EndPoint.Add(point2); tmpX = (int)(100 * Math.Cos(childNode.point.angle)) + childNode.point.x; tmpY = (int)(100 * Math.Sin(childNode.point.angle)) + childNode.point.y; childNode.pictureBox.Location = new System.Drawing.Point(tmpX - de, tmpY - de); Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); childNode.point.x = tmpX; childNode.point.y = tmpY; } }
private void StartUpdateNetPicture() { bool flag = false; int dc = 30, dr = 14, de = 16; // int w = 624, h = 375; int w = (this.panel1.Width == 0) ? 624 : (int)(this.panel1.Width / 2), h = (this.panel1.Height == 0) ? 375 : (int)(this.panel1.Height / 2); //获取拓扑页的中心 int tmpX, tmpY; //总的节点数 int totalNodeNum = mainHome.nodeInfoArray.Count; //this.label1.Text = "[ZigBee加速度网表控制中心] | 当前时间为[" + DateTime.Now.Date.ToShortDateString() + "] | 当前共[" + totalNodeNum.ToString() + "]个节点在线"; double angle = 0.0; //this.panel1.Controls.Clear();//清除 StartPoint.Clear(); EndPoint.Clear(); //清除后为下一次做准备 int i, j, k, index; NodeDescribePacket parentNode = new NodeDescribePacket(); //父亲节点 NodeDescribePacket virtualParentNode = new NodeDescribePacket(); //虚拟节点,虚拟作为父节点 NodeDescribePacket childNode = new NodeDescribePacket(); //子节点 #region 协调器的子节点处理 for (i = 0; i < totalNodeNum; ++i) //读取节点循环 { childNode = mainHome.nodeInfoArray[i]; for (j = 0; j < 8; j++) { childNode.used[j] = false; //每个节点之初都没有节点连接 childNode.virtualUsed[j] = false; //每个节点的虚拟位都没有占用 } if (i == 0) { if (childNode.NetAddr != 0x0000) { MessageBox.Show("未发现协调器,或者协调器数据格式错误,请断开连接重新启动"); return; } //更新协调器节点的位置 parentNode = mainHome.nodeInfoArray[0]; parentNode.point.x = w; parentNode.point.y = h; AddPictureBox(i, 0x00, w - dc, h - dc, 0); } else if (childNode.ParentAddr == 0x0000)//先处理协调器的子节点 { for (k = 0; k < level1Num; k++) { if (!parentNode.used[k]) //找到一个可以使用的点 { angle = Math.PI * level1Angle[k] / 180.0; parentNode.used[k] = true; parentNode.indexNo[k] = i; //储存 break; } }//for(k) if (k >= level1Num) //如果节点的儿子数太多,则进行调整构造 { flag = true; break; }//if(k >=R1) if (childNode.NodeName == 0x01) { tmpX = Convert.ToInt32(level1Router * Math.Cos(angle)) + w; tmpY = Convert.ToInt32(level1Router * Math.Sin(angle)) + h; AddPictureBox(i, 0x01, tmpX - dr, tmpY - dr, angle);//图片插入的坐标和画线坐标不同 Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); } else if (childNode.NodeName == 0x02) { tmpX = Convert.ToInt32(level1End * Math.Cos(angle)) + w; tmpY = Convert.ToInt32(level1End * Math.Sin(angle)) + h; AddPictureBox(i, 0x02, tmpX - de, tmpY - de, angle);//图片插入的坐标和画线坐标不同 Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); } Point point2 = new Point(w, h); EndPoint.Add(point2); } //else if (childNode.ParentAddr == 0x0000) } //End for "for (i = readedNodeNum; i <= totalNodeNum; ++i)" if (flag) //拓扑树派生虚拟节点,在虚拟节点上生长叶子 { j = 0; //j用于循环旋转编号 k = parentNode.indexNo[j];//k表示当前旋转编号对应的zigbee节点,parent在这里为协调器 virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 for (; i < totalNodeNum; ++i) { childNode = mainHome.nodeInfoArray[i]; //子节点 for (int jj = 0; jj < 8; ++jj) { childNode.used[jj] = false; //每个节点之初都没有节点连接 childNode.virtualUsed[jj] = false; } if (childNode.ParentAddr != 0x0000)//避免无用循环 continue; for (index = 0; index < 6; index++) { if (!virtualParentNode.virtualUsed[index]) //查看虚拟节点的虚拟点是否可用 { virtualParentNode.virtualUsed[index] = true; angle = Math.PI * virtualAngle[index] / 180.0; break; } } if (index >= 6) //当前虚拟点已经排满 { j++; if (j >= 8) { MessageBox.Show("协调器扩展叶子节点太多,当前节点网络拓扑丢弃,传感信息仍可用"); break; } k = parentNode.indexNo[j]; //k表示当前旋转编号对应的zigbee节点 virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 i--; //回退一次,处理当前节点 continue; }//if (indexer >= 8) if (childNode.ParentAddr == 0x0000)// { if (childNode.NodeName == 0x02)//终端 { int x = Convert.ToInt32(level2End * Math.Cos(angle)); int y = Convert.ToInt32(level2End * Math.Sin(angle));//新坐标 angle = virtualParentNode.point.angle;//用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y;//得到旧坐标 AddPictureBox(i, 0x02, xx - de, yy - de, virtualParentNode.point.angle + (Math.PI * level2Angle[index] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } else//路由节点 { int x = Convert.ToInt32(level2Router * Math.Cos(angle)); int y = Convert.ToInt32(level2Router * Math.Sin(angle));//新坐标 angle = virtualParentNode.point.angle;//用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y;//得到旧坐标 AddPictureBox(i, 0x01, xx - dr, yy - dr, virtualParentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } }//if (childNode.ParentAddr == 0x0000) }//for (; i < totalNodeNum; i++) }//if(flag),处理的是虚拟节点的叶子 flag = false; #endregion for (int p = 1; p < totalNodeNum; p++)//父亲 { parentNode = mainHome.nodeInfoArray[p]; if (parentNode.NodeName != 0x01)//只有路由器才有儿子 continue; for (i = p + 1; i < totalNodeNum; ++i)//儿子 { if (p == i) continue; childNode = mainHome.nodeInfoArray[i]; if (childNode.ParentAddr == parentNode.NetAddr)//找到子节点 { for (j = 0; j < level2Num; j++) { if (!parentNode.used[j]) { angle = Math.PI * level2Angle[j] / 180.0; parentNode.used[j] = true; parentNode.indexNo[j] = i; //储存 break; } } if (j >= level2Num) //节点太多,进行调整构造 { // MessageBox.Show("一个zigbee节点的儿子节点超已过7个"); flag = true; break; } if (childNode.NodeName == 0x02)//终端 { int x = Convert.ToInt32(level2End * Math.Cos(angle)); int y = Convert.ToInt32(level2End * Math.Sin(angle));//新坐标 angle = parentNode.point.angle; //用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + parentNode.point.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + parentNode.point.y;//得到旧坐标 AddPictureBox(i, 0x02, xx - de, yy - de, parentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(parentNode.point.x, parentNode.point.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } else//路由节点 { int x = Convert.ToInt32(level2Router * Math.Cos(angle)); int y = Convert.ToInt32(level2Router * Math.Sin(angle));//新坐标 angle = parentNode.point.angle;//用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + parentNode.point.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + parentNode.point.y;//得到旧坐标 AddPictureBox(i, 0x01, xx - dr, yy - dr, parentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(parentNode.point.x, parentNode.point.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } }//if (childNode.ParentAddr == parentNode.NetAddr) }//for (i = 1; i< totalNodeNum; ++i) // parentNode = (NodeDescribePacket)NodeDesList[p]; //------------------------------------------ if (flag) //拓扑树派生虚拟节点,在虚拟节点上生长叶子 { j = 0; //j用于循环旋转编号 k = parentNode.indexNo[j];//k表示当前旋转编号对应的zigbee节点,parent在这里为路由器 // Console.WriteLine("[{0},{1}]-----------",j,k); virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 for (; i < totalNodeNum; ++i) { if (p == i) continue; childNode = mainHome.nodeInfoArray[i]; //子节点 if (childNode.ParentAddr != parentNode.NetAddr)//避免无用循环 continue; for (index = 0; index < 6; index++) { if (!virtualParentNode.virtualUsed[index]) //查看虚拟节点的虚拟点是否可用 { virtualParentNode.virtualUsed[index] = true; angle = Math.PI * virtualAngle[index] / 180.0; break; } } if (index >= 6) //当前虚拟点已经排满 { j++; if (j >= 7) { MessageBox.Show("路由器扩展叶子节点太多,当前节点网络拓扑丢弃,传感信息仍可用"); break; } k = parentNode.indexNo[j]; //k表示当前旋转编号对应的zigbee节点 virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 i--; //回退一次,处理当前节点 continue; }//if (indexer >= 8) if (childNode.NodeName == 0x02)//终端 { int x = Convert.ToInt32(level2End * Math.Cos(angle)); int y = Convert.ToInt32(level2End * Math.Sin(angle));//新坐标 angle = virtualParentNode.point.angle;//用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y;//得到旧坐标 AddPictureBox(i, 0x02, xx - de, yy - de, virtualParentNode.point.angle + (Math.PI * level2Angle[index] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } else//路由节点 { int x = Convert.ToInt32(level2Router * Math.Cos(angle)); int y = Convert.ToInt32(level2Router * Math.Sin(angle));//新坐标 angle = virtualParentNode.point.angle;//用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y;//得到旧坐标 AddPictureBox(i, 0x01, xx - dr, yy - dr, virtualParentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } }//for (; i < totalNodeNum; i++) }//if(flag),处理的是虚拟节点的叶子 flag = false; //------------------------------------------ }//for (i = 1; i < totalNodeNum; i++) this.panel1.Refresh(); // Display(); }
//用于处理串口收到的所有数据 public void DataProcess() { if (0x00 == tmpBuf[2]) { #region 描述符 byte nodeType = tmpBuf[3]; ushort net = Convert.ToUInt16(tmpBuf[4] * 256 + tmpBuf[5]); string mac = Convert.ToString(tmpBuf[6], 16).PadLeft(2, '0') + Convert.ToString(tmpBuf[7], 16).PadLeft(2, '0') + Convert.ToString(tmpBuf[8], 16).PadLeft(2, '0') + Convert.ToString(tmpBuf[9], 16).PadLeft(2, '0') + Convert.ToString(tmpBuf[10], 16).PadLeft(2, '0') + Convert.ToString(tmpBuf[11], 16).PadLeft(2, '0') + Convert.ToString(tmpBuf[12], 16).PadLeft(2, '0') + Convert.ToString(tmpBuf[13], 16).PadLeft(2, '0'); mac = mac.ToUpper(); ushort parentAddr = Convert.ToUInt16(tmpBuf[14] * 256 + tmpBuf[15]); //获取节点名字 string name = readNameByMac(mac); if (name == null) { //MessageBox.Show("该节点没有入库,请检查Config目录下的IEEE.txt。添加信息后复位该节点"); // Console.WriteLine("name:{0},mac:{1}",name,mac); Notify notify = new Notify("该节点没有入库,请检查Config目录下的IEEE.txt。添加信息后复位该节点"); notify.ShowDialog(); return; } //因为协调器在软件启动时已经虚拟出来,所以真正节点上线后需要特殊处理 if (0x00 == nodeType) { if (coorIsOnline) return; # region 协调器 if (nodeMacIndexHash.ContainsKey("0000000000000000")) { nodeMacIndexHash.Remove("0000000000000000"); } if (!nodeMacIndexHash.ContainsKey(mac)) nodeMacIndexHash.Add(mac, 0); else nodeMacIndexHash[mac] = 0; if (name != "V000") { nodeNameIndexHash.Remove("V000"); if (!nodeNameIndexHash.ContainsKey(name)) nodeNameIndexHash.Add(name, 0); else nodeNameIndexHash[name] = 0; } if (net != 0x0000) { nodeAddrIndexHash.Remove(0); if (!nodeAddrIndexHash.ContainsKey(net)) nodeAddrIndexHash.Add(net, 0); else nodeAddrIndexHash[net] = 0; } nodeInfoArray[0].NodeName = nodeType; nodeInfoArray[0].Mac = mac; nodeInfoArray[0].NetAddr = net; nodeInfoArray[0].name = name; nodeInfoArray[0].ParentAddr = 0; this.Invoke((EventHandler)(delegate { //按钮的名字就是MAC地址 nodeInfoArray[0].nodeBtn.Name = mac; //按钮的文本就是通用名字 nodeInfoArray[0].nodeBtn.Text = name; //修改协调器的节点图标属性 nodeInfoArray[0].nodeBtn.Image = global::AccleZigBee.Properties.Resources.Coor; nodeInfoArray[0].nodeBtn.ToolTipText = mac; nodeInfoArray[0].nodeBtn.Size = new System.Drawing.Size(56, 56); // newNode.nodeBtn.Click += new System.EventHandler(this.toolStripSplitRouterClick); })); coorIsOnline = true; addStripBtn(mac); #endregion } else { if (!coorIsOnline) { this.Invoke((EventHandler)(delegate { //按钮的名字就是MAC地址 nodeInfoArray[0].nodeBtn.Name = "0000000000000000"; //按钮的文本就是通用名字 nodeInfoArray[0].nodeBtn.Text = "V000"; //修改协调器的节点图标属性 nodeInfoArray[0].nodeBtn.Image = global::AccleZigBee.Properties.Resources.Coor; nodeInfoArray[0].nodeBtn.ToolTipText = "0000000000000000"; nodeInfoArray[0].nodeBtn.Size = new System.Drawing.Size(56, 56); // newNode.nodeBtn.Click += new System.EventHandler(this.toolStripSplitRouterClick); })); coorIsOnline = true; } //节点第一次上线 if (!nodeMacIndexHash.ContainsKey(mac)) { NodeDescribePacket newNode = new NodeDescribePacket(); newNode.NodeName = nodeType; newNode.Mac = mac; newNode.NetAddr = net; newNode.name = name; newNode.ParentAddr = parentAddr; //按钮的名字就是MAC地址 newNode.nodeBtn.Name = mac; //按钮的文本就是通用名字 newNode.nodeBtn.Text = name; //终端节点处理 if (0x02 == nodeType) { #region 终端节点 //[2]读取标定系数 if (!ReadCalibrationCoefficient(newNode)) { // MessageBox.Show("没有找到config.txt标定文件,默认为各个系数为1"); Notify notify = new Notify("没有找到config.txt标定文件,默认为各个系数为1"); notify.ShowDialog(); } //设置终端节点的图标与大小 this.Invoke((EventHandler)(delegate { newNode.nodeBtn.Image = global::AccleZigBee.Properties.Resources.End; newNode.nodeBtn.ToolTipText = newNode.Mac; newNode.nodeBtn.Size = new System.Drawing.Size(32, 32); newNode.nodeBtn.Click += new System.EventHandler(this.toolStripSplitWaveClick); newNode.linkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkClicked); //设置linkLabel,为了防止与toolstripbtn同名,在后边加了空格 newNode.linkLabel.Name = newNode.Mac + " "; })); newNode.count = count; #endregion }//终端处理完毕 else if (0x01 == nodeType) { #region 路由器 //设置路由器节点的图标与大小 this.Invoke((EventHandler)(delegate { newNode.nodeBtn.Image = global::AccleZigBee.Properties.Resources.midRouter; newNode.nodeBtn.ToolTipText = newNode.Mac; newNode.nodeBtn.Size = new System.Drawing.Size(56, 56); newNode.nodeBtn.Click += new System.EventHandler(this.toolStripSplitRouterClick); })); if (!ReadPortWithName(newNode)) { // MessageBox.Show("未找到该开关节点的端口映射表,请重新配置"); Notify notify = new Notify("未找到该开关节点的端口映射表,请重新配置"); notify.ShowDialog(); return; } #endregion } nodeInfoArray.Add(newNode); if(!nodeMacIndexHash.ContainsKey(mac)) nodeMacIndexHash.Add(mac, nodeInfoArray.Count - 1); if (!nodeNameIndexHash.ContainsKey(name)) nodeNameIndexHash.Add(name, nodeInfoArray.Count - 1); else nodeNameIndexHash[name] = nodeInfoArray.Count - 1; //更新短地址映射的数组索引 if (nodeAddrIndexHash.ContainsKey(net)) nodeAddrIndexHash[net] = nodeInfoArray.Count - 1; else nodeAddrIndexHash.Add(net, nodeInfoArray.Count - 1); if (newNode.NodeName != 0x02) addStripBtn(newNode.Mac); this.toolStripStatusLabel3.Text = "节点数:" + nodeInfoArray.Count.ToString(); // Console.WriteLine("节点{0},的索引是{1}", mac, nodeInfoArray.Count - 1); }//如果是节点第一次上线 else { int index = nodeInfoArray.Count; try { index = nodeMacIndexHash[mac]; } catch (Exception) { return; } if (index >= nodeInfoArray.Count) { return; } try { if (net != nodeInfoArray[index].NetAddr) { int outIndex; if (nodeAddrIndexHash.TryGetValue(nodeInfoArray[index].NetAddr, out outIndex)) { nodeAddrIndexHash.Remove(nodeInfoArray[index].NetAddr); nodeAddrIndexHash.Add(net, index); } } }catch(Exception) { if (nodeAddrIndexHash.ContainsKey(net)) { nodeAddrIndexHash[net] = index; } else nodeAddrIndexHash.Add(net, index); } // Console.WriteLine("再次上线节点的MAC地址为{0},IP地址为{1}",mac, net); nodeInfoArray[index].NetAddr = net; nodeInfoArray[index].NodeName = nodeType; nodeInfoArray[index].Mac = mac; nodeInfoArray[index].name = name; nodeInfoArray[index].ParentAddr = parentAddr; //foreach(KeyValuePair<ushort,int>kvp in nodeAddrIndexHash) //{ //} this.Invoke((EventHandler)(delegate { //按钮的名字就是MAC地址 nodeInfoArray[index].nodeBtn.Name = mac; //按钮的文本就是通用名字 nodeInfoArray[index].nodeBtn.Text = name; nodeInfoArray[index].nodeBtn.ToolTipText = mac; })); if (0x01 == nodeType) { if (!ReadPortWithName(nodeInfoArray[index])) { //MessageBox.Show("未找到该开关节点的端口映射表,请重新配置"); Notify notify = new Notify("未找到该开关节点的端口映射表,请重新配置"); notify.ShowDialog(); return; } } else { nodeInfoArray[index].avg = 0; nodeInfoArray[index].count = count; nodeInfoArray[index].sum = 0; nodeInfoArray[index].dataSaveCount = 1; nodeInfoArray[index].head = 0; nodeInfoArray[index].tail = 0; nodeInfoArray[index].flag = false; nodeInfoArray[index].packetCount = 0; //nodeInfoArray[index].packetCount = 0; if (!ReadCalibrationCoefficient(nodeInfoArray[index])) { //MessageBox.Show("没有找到config.txt标定文件,默认为各个系数为1"); Notify notify = new Notify("没有找到config.txt标定文件,默认为各个系数为1"); notify.ShowDialog(); } } } } #endregion }//if (0x00 == tmpBuf[2]) else if (0x01 == tmpBuf[2]) { #region 数据处理 int k = 6; double data3; int index = -1; # if false try { index = nodeAddrIndexHash[Convert.ToUInt16(tmpBuf[3] * 256 + tmpBuf[4])]; //增加该节点收到包的计数 ++nodeInfoArray[index].packetCount; nodeDataUsed = nodeInfoArray[index]; // Console.WriteLine("收到MAC地址{0}的数据,他的IP地址是{1},索引是{2}",nodeDataUsed.Mac,tmp,index); } catch (Exception) { int tmp = Convert.ToUInt16(tmpBuf[3] * 256 + tmpBuf[4]); Console.WriteLine("错误的匹配,当前IP为{0}",tmp); if (!error) { //MessageBox.Show("收到未知节点的数据,请检查端口映射是否添加正确,设备是否入库"); Notify notify = new Notify("没收到未知节点的数据,请检查端口映射是否添加正确,设备是否入库"); notify.ShowDialog(); LogError(tmpBuf.ToString()+" "+index.ToString()+" "); error = true; } return; } #else if (nodeAddrIndexHash.TryGetValue(Convert.ToUInt16(tmpBuf[3] * 256 + tmpBuf[4]), out index)) { //增加该节点收到包的计数 ++nodeInfoArray[index].packetCount; nodeDataUsed = nodeInfoArray[index]; } else { //int tmp = Convert.ToUInt16(tmpBuf[3] * 256 + tmpBuf[4]);/////////////////////// if (!error)//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ { //MessageBox.Show("收到未知节点的数据,请检查端口映射是否添加正确,设备是否入库"); Notify notify = new Notify("没收到未知节点的数据,请检查端口映射是否添加正确,设备是否入库"); notify.ShowDialog(); // Console.WriteLine("数据异常:地址:{0},{1},{2}",tmp,tmpBuf[3],tmpBuf[4]); // LogError(tmpBuf.ToString() + " " + index.ToString() + " "); error = true; } return; } #endif //开始处理数据 if (0x20 == tmpBuf[k]) { Int32 tmpData; tmpBuf[k + 1] ^= 0x80; if ((tmpBuf[k + 1] & 0x80) != 0) //负数 tmpData = (65536 * tmpBuf[k + 1] + 256 * tmpBuf[k + 2] + tmpBuf[k + 3]) - 16777216; else tmpData = 65536 * tmpBuf[k + 1] + 256 * tmpBuf[k + 2] + tmpBuf[k + 3]; data3 = Convert.ToDouble(tmpData) / accleAccuracy; //将数据放到循环队列 nodeDataUsed.inptData(data3); //元素数据 if (nodeDataUsed.packetCount == UInt32.MaxValue) nodeDataUsed.packetCount = 2; //节点收到第一次数据,才建立文件.系统将excel行的创建与文件的创建延迟到了这里 if (nodeDataUsed.packetCount == 1) { //当前需要写的行号 nodeInfoArray[index].line = nodeDataUsed.line = ++ecxelLine; /***这里一定要先创建myDataPath,因为creatMyDataText中会对角度文件进行处理**/ //创建原始数据文件 nodeDataUsed.myDataPath = nodeInfoArray[index].myDataPath = creatMyDataText(nodeDataUsed.name); // Console.WriteLine("名字是446----{0}",nodeDataUsed.name); Thread.Sleep(500); //创建excel行+++++++++++++++++++++++++++++++++++++++++++++ nodeDataUsed.path = nodeInfoArray[index].path = creatDataTxt(nodeDataUsed.name); Thread.Sleep(500); using (StreamWriter sw = File.AppendText(nodeDataUsed.myDataPath)) { sw.WriteLine(data3.ToString()); sw.Close(); } } //为了减少数据量,每4个数据才记录一次 if ((nodeDataUsed.packetCount & 1) == 0) { //偶数折半后还是偶数,则表示为4的倍数 if (((nodeDataUsed.packetCount >> 4) & 1) == 0) { using (StreamWriter sw = File.AppendText(nodeDataUsed.myDataPath)) { sw.WriteLine(data3.ToString()); sw.Close(); } } } if (filter) { //如果未满30组数据 if (nodeDataUsed.flag == false) { //小于26个数的均值 data3 = nodeDataUsed.sum / (nodeDataUsed.tail - nodeDataUsed.head); } else { // data3 = nodeDataUsed.sum / 26; //等于26个值得均值 data3 = nodeDataUsed.sum * 0.03846; } } //如果选择了标定 if (modify) { double tmpdata3 = data3; double retdata3 = nodeDataUsed.config[4]; retdata3 += nodeDataUsed.config[3] * tmpdata3; tmpdata3 *= data3; retdata3 += nodeDataUsed.config[2] * tmpdata3; tmpdata3 *= data3; retdata3 += nodeDataUsed.config[1] * tmpdata3; tmpdata3 *= data3; retdata3 += nodeDataUsed.config[0] * tmpdata3; data3 = retdata3; //标定后计算完成 } //是否更新label实时显示数据 if (nodeDataUsed.dataLabel.Visible) { this.Invoke((EventHandler)(delegate { nodeDataUsed.dataLabel.Text = Math.Round(data3, 4).ToString(); })); } //更新波形显示 //如果当前收到的数据的索引是打开的索引 if ((index == openingEndIndnex) && this.userControl11.Visible) { this.Invoke((EventHandler)(delegate { update(index); })); } //检查数据超时保存时间到 if (nodeDataUsed.count > count) { if (4294967290 - nodeDataUsed.count + count < saveTime) { nodeDataUsed.avg = data3; return; } } else { if (count - nodeDataUsed.count < saveTime) { nodeDataUsed.avg = data3; return; } } //求均值 data3 = (data3 + nodeDataUsed.avg) * 0.5; //保存该节点的均值 nodeDataUsed.avg = data3; if (nodeDataUsed.dataSaveCount == 1) { //注释原因:以前为增加数据到记事本,现在导入到excel #if false using (StreamReader sr = new StreamReader(nodeDataUsed.path)) { tmpAngleString = sr.ReadLine(); sr.Close(); } using (StreamWriter sw = new StreamWriter(nodeDataUsed.path, false)) { sw.WriteLine(tmpAngleString); sw.WriteLine(data3.ToString()); sw.Close(); } #endif try { //防止excel在换文件时,导致数据错乱 if (nodeDataUsed.line <= ecxelLine) { excel.AddData<string>(nodeDataUsed.line, 4, nodeDataUsed.avg.ToString()); excel.SaveData(); } } catch (Exception) { Notify notify = new Notify("请关闭data.xls,在软件中使用转存后打开data_copy.xls,软件稍后需要使用data.xls"); notify.ShowDialog(); try { excel.RealeseResource(); initExcel(excelName+".xls"); excel.AddData<string>(nodeDataUsed.line, 4, nodeDataUsed.avg.ToString()); excel.SaveData(); } catch (Exception) { } } ++nodeDataUsed.dataSaveCount; } else if (nodeDataUsed.dataSaveCount >= 50) nodeDataUsed.dataSaveCount = 1; else ++nodeDataUsed.dataSaveCount; #if false Console.WriteLine("{0}",nodeDataUsed.dataSaveCount); using (FileStream stream2 = File.Open(nodeDataUsed.path, FileMode.OpenOrCreate, FileAccess.Write)) { stream2.Seek(0, SeekOrigin.Begin); stream2.SetLength(0); stream2.Close(); using (StreamWriter sw = File.AppendText(nodeDataUsed.path)) { sw.WriteLine(data3.ToString()); sw.Close(); } } #endif }//if (0x20 == tmpBuf[k])加速度数据处理完毕 #endregion }//数据处理完毕 else if (0x03 == tmpBuf[2]) { #region 控制状态返回 int index = nodeAddrIndexHash[Convert.ToUInt16(tmpBuf[3] * 256 + tmpBuf[4])]; nodeAck = nodeInfoArray[index]; //更新开关状态 nodeInfoArray[index].onFlag = Convert.ToUInt16(tmpBuf[5] * 256 + tmpBuf[6]); if(index == openingRouterIndex) { uptateCheckBox(index); } #endregion } else if (0x04 == tmpBuf[2]) { #region 有空隙时间 Monitor.Enter(this.ls); if (SendPacket.Count != 0) { //发送数据,并返回ACK值 ACK = SendPacket.First.Value.doTask(); this.toolStripStatusLabel2.Text = "当前正在尝试发送编号为"+ACK.ToString()+"的控制命令"; } else { //this.toolStripStatusLabel2.Text = "正确收到ACK编号" + ACK.ToString() + "/当前共" + SendPacket.Count.ToString() + "个命令在排队"; ; serialPort.Write(noDataAck, 0, 9); } Monitor.Exit(this.ls); #endregion } else if (0x07 == tmpBuf[2]) { #region ACK返回 if (tmpBuf[3] == ACK) { // Console.WriteLine("队首元素发出后ACK收到,当前正在排队的命令共{0}", SendPacket.Count); if (SendPacket.Count != 0) { if (SendPacket.Count != 0) SendPacket.RemoveFirst(); this.toolStripStatusLabel2.Text = "正确收到ACK编号" + ACK.ToString() + "/当前共" + SendPacket.Count.ToString() + "个命令在排队"; } } else { if(SendPacket.Count!=0) SendPacket.RemoveLast(); Notify notify = new Notify("ACK返回错误,设备间同步出错,正在重新协调同步"); notify.ShowDialog(); //MessageBox.Show("ACK返回错误,设备间同步出错"); } #endregion } }
private bool ReadPortWithName(NodeDescribePacket newNode) { string tpath = System.AppDomain.CurrentDomain.BaseDirectory + @"\Config\" + newNode.name + @".txt"; if (!File.Exists(tpath)) { //MessageBox.Show("Config目录下的VXXX.txt未找到该网关节点的端口映射表,请在软件中配置端口映射并复位该网关节点即可"); return false; } else { //读取端口映射值 using (StreamReader sr = new StreamReader(tpath)) { string line; if ((line = sr.ReadLine()) != null) { string[] split = line.Split(new Char[] { ';' }); int num = split.Length; for (int j = 0; j < num; ++j) { //通过名字来获取MAC地址 //如果某个端口没有设备则设置成null line = split[j].Trim(); if (line.Length != 0) { //port用于存放每个端口连接的加速度节点的硬件地址 newNode.port[j] = readMacByName(line); //设置未被选中,但是已经使能,也即是该端口可以使用 newNode.portChecked[j] = 0x00; } else { //设置该端口,不能被使用 newNode.portChecked[j] = 0x02; newNode.port[j] = null; } // Console.WriteLine("当前{0}端口配置{1}", j, newNode.port[j]); } sr.Close(); } }//using return true; } }
private bool ReadCalibrationCoefficient(NodeDescribePacket newNode) { string tpath = System.AppDomain.CurrentDomain.BaseDirectory + @"\config.txt"; if (!File.Exists(tpath)) { return false; } else { using (StreamReader sr = new StreamReader(tpath)) { string line; while ((line = sr.ReadLine()) != null) { if (line == newNode.Mac) { line = sr.ReadLine(); string[] split = line.Split(new Char[] { ';' }); newNode.config[0] = System.Convert.ToDouble(split[0]); newNode.config[1] = System.Convert.ToDouble(split[1]); newNode.config[2] = System.Convert.ToDouble(split[2]); newNode.config[3] = System.Convert.ToDouble(split[3]); newNode.config[4] = System.Convert.ToDouble(split[4]); sr.Close(); break; } }//while }//using return true; } }
private void initial() { //检查必须文件是否存在 checkFile(); //3个object为同步变量,用于串口模块并发 lm = new object(); lo = new object(); ls = new object(); //气泡提示 tips = new ToolTip(); //滤波标志 filter = true; //标定标志 modify = true; //记录日志标志 logData = true; //周期发送开闭标志,多点周期的标志 cycleFlag = false; //记录是否是第一次多点周期循环,因为第一次总是需要让设备处于打开状态 isFirstCycleFlag = false; //循环发送标志 ringFlag = false; oneFlag = false; //manuallyFlag = false; //软件启动后,界面上显示的灰色图标的标记,第一次使用后变失效 noDataWithGrayPic = false; //记录打开的加速度节点 (终端)编号,用于波形显示 openingEndIndnex = 0; //记录打开的网关(路由器)节点便后,用于显示他的儿子节点 openingRouterIndex = 0; //count用于该系统的心跳,每一秒触发一次,也作为整个系统的软件时钟,所有时间都是从count中获取 count = 0; error = false; isSameAngle = false; sameAngle = 0; coorIsOnline = false; //默认的超过该时间才保存日志 saveTime = 5 * 60; //用于给zigbee协调器发送没有数据上传,可以上传一些控制请求信息 noDataAck = new byte[9]; //3个hash表,用于快速根据短地址,长地址来定位节点描述符的索引 nodeMacIndexHash = new Dictionary <string, int>(); nodeAddrIndexHash = new Dictionary <ushort, int>(); nodeNameIndexHash = new Dictionary <string, int>(); //待发送给zigbee网络的控制帧队列,所有的控制命令都需要先在这里排队等待空闲间隙 SendPacket = new LinkedList <CtlPacket>(); nodeInfoArray = new List <NodeDescribePacket>(); nodeDataUsed = new NodeDescribePacket(); nodeAck = new NodeDescribePacket(); //启动多线程并发串口模块 // StartSerialPort(); //首先增加协调器节点的信息,防止丢失协调器信息后,其他节点上线后找不到父节点 firstAddCoor(); //初始化该帧 initNoDataAck(); //用于下面线程同步用 resumeEvent = new ManualResetEvent(false); //建立循环发送线程,并且建立好后,线程阻塞等待用户控制 sendThread = new Thread(sendMsgToZigbee); sendThread.Start(); //启动软件系统的心跳 // timerOut.Enabled = true; timerOut.Interval = 1000; //Thread.Sleep(500); // timerOut.Start(); try { initExcel(excelName + ".xls"); } catch (Exception) { } }
private void initial() { //检查必须文件是否存在 checkFile(); //3个object为同步变量,用于串口模块并发 lm = new object(); lo = new object(); ls = new object(); //气泡提示 tips = new ToolTip(); //滤波标志 filter = true; //标定标志 modify = true; //记录日志标志 logData = true; //周期发送开闭标志,多点周期的标志 cycleFlag = false; //记录是否是第一次多点周期循环,因为第一次总是需要让设备处于打开状态 isFirstCycleFlag = false; //循环发送标志 ringFlag = false; oneFlag = false; //manuallyFlag = false; //软件启动后,界面上显示的灰色图标的标记,第一次使用后变失效 noDataWithGrayPic = false; //记录打开的加速度节点 (终端)编号,用于波形显示 openingEndIndnex = 0; //记录打开的网关(路由器)节点便后,用于显示他的儿子节点 openingRouterIndex = 0; //count用于该系统的心跳,每一秒触发一次,也作为整个系统的软件时钟,所有时间都是从count中获取 count = 0; error = false; isSameAngle = false; sameAngle = 0; coorIsOnline = false; //默认的超过该时间才保存日志 saveTime = 5 * 60 ; //用于给zigbee协调器发送没有数据上传,可以上传一些控制请求信息 noDataAck = new byte[9]; //3个hash表,用于快速根据短地址,长地址来定位节点描述符的索引 nodeMacIndexHash = new Dictionary<string, int>(); nodeAddrIndexHash = new Dictionary<ushort, int>(); nodeNameIndexHash = new Dictionary<string, int>(); //待发送给zigbee网络的控制帧队列,所有的控制命令都需要先在这里排队等待空闲间隙 SendPacket = new LinkedList<CtlPacket>(); nodeInfoArray = new List<NodeDescribePacket>(); nodeDataUsed = new NodeDescribePacket(); nodeAck = new NodeDescribePacket(); //启动多线程并发串口模块 // StartSerialPort(); //首先增加协调器节点的信息,防止丢失协调器信息后,其他节点上线后找不到父节点 firstAddCoor(); //初始化该帧 initNoDataAck(); //用于下面线程同步用 resumeEvent = new ManualResetEvent(false); //建立循环发送线程,并且建立好后,线程阻塞等待用户控制 sendThread = new Thread(sendMsgToZigbee); sendThread.Start(); //启动软件系统的心跳 // timerOut.Enabled = true; timerOut.Interval = 1000; //Thread.Sleep(500); // timerOut.Start(); try { initExcel(excelName + ".xls"); } catch (Exception) { } }
private float level2Router = 150; //第2层路由器 private void StartUpdateNetPicture() { bool flag = false; int dc = 30, dr = 14, de = 16; // int w = 624, h = 375; int w = (this.panel1.Width == 0) ? 624 : (int)(this.panel1.Width / 2), h = (this.panel1.Height == 0) ? 375 : (int)(this.panel1.Height / 2); //获取拓扑页的中心 int tmpX, tmpY; //总的节点数 int totalNodeNum = mainHome.nodeInfoArray.Count; //this.label1.Text = "[ZigBee加速度网表控制中心] | 当前时间为[" + DateTime.Now.Date.ToShortDateString() + "] | 当前共[" + totalNodeNum.ToString() + "]个节点在线"; double angle = 0.0; //this.panel1.Controls.Clear();//清除 StartPoint.Clear(); EndPoint.Clear(); //清除后为下一次做准备 int i, j, k, index; NodeDescribePacket parentNode = new NodeDescribePacket(); //父亲节点 NodeDescribePacket virtualParentNode = new NodeDescribePacket(); //虚拟节点,虚拟作为父节点 NodeDescribePacket childNode = new NodeDescribePacket(); //子节点 #region 协调器的子节点处理 for (i = 0; i < totalNodeNum; ++i) //读取节点循环 { childNode = mainHome.nodeInfoArray[i]; for (j = 0; j < 8; j++) { childNode.used[j] = false; //每个节点之初都没有节点连接 childNode.virtualUsed[j] = false; //每个节点的虚拟位都没有占用 } if (i == 0) { if (childNode.NetAddr != 0x0000) { MessageBox.Show("未发现协调器,或者协调器数据格式错误,请断开连接重新启动"); return; } //更新协调器节点的位置 parentNode = mainHome.nodeInfoArray[0]; parentNode.point.x = w; parentNode.point.y = h; AddPictureBox(i, 0x00, w - dc, h - dc, 0); } else if (childNode.ParentAddr == 0x0000)//先处理协调器的子节点 { for (k = 0; k < level1Num; k++) { if (!parentNode.used[k]) //找到一个可以使用的点 { angle = Math.PI * level1Angle[k] / 180.0; parentNode.used[k] = true; parentNode.indexNo[k] = i; //储存 break; } }//for(k) if (k >= level1Num) //如果节点的儿子数太多,则进行调整构造 { flag = true; break; }//if(k >=R1) if (childNode.NodeName == 0x01) { tmpX = Convert.ToInt32(level1Router * Math.Cos(angle)) + w; tmpY = Convert.ToInt32(level1Router * Math.Sin(angle)) + h; AddPictureBox(i, 0x01, tmpX - dr, tmpY - dr, angle);//图片插入的坐标和画线坐标不同 Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); } else if (childNode.NodeName == 0x02) { tmpX = Convert.ToInt32(level1End * Math.Cos(angle)) + w; tmpY = Convert.ToInt32(level1End * Math.Sin(angle)) + h; AddPictureBox(i, 0x02, tmpX - de, tmpY - de, angle);//图片插入的坐标和画线坐标不同 Point point1 = new Point(tmpX, tmpY); StartPoint.Add(point1); } Point point2 = new Point(w, h); EndPoint.Add(point2); } //else if (childNode.ParentAddr == 0x0000) } //End for "for (i = readedNodeNum; i <= totalNodeNum; ++i)" if (flag) //拓扑树派生虚拟节点,在虚拟节点上生长叶子 { j = 0; //j用于循环旋转编号 k = parentNode.indexNo[j]; //k表示当前旋转编号对应的zigbee节点,parent在这里为协调器 virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 for (; i < totalNodeNum; ++i) { childNode = mainHome.nodeInfoArray[i]; //子节点 for (int jj = 0; jj < 8; ++jj) { childNode.used[jj] = false; //每个节点之初都没有节点连接 childNode.virtualUsed[jj] = false; } if (childNode.ParentAddr != 0x0000)//避免无用循环 { continue; } for (index = 0; index < 6; index++) { if (!virtualParentNode.virtualUsed[index]) //查看虚拟节点的虚拟点是否可用 { virtualParentNode.virtualUsed[index] = true; angle = Math.PI * virtualAngle[index] / 180.0; break; } } if (index >= 6) //当前虚拟点已经排满 { j++; if (j >= 8) { MessageBox.Show("协调器扩展叶子节点太多,当前节点网络拓扑丢弃,传感信息仍可用"); break; } k = parentNode.indexNo[j]; //k表示当前旋转编号对应的zigbee节点 virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 i--; //回退一次,处理当前节点 continue; }//if (indexer >= 8) if (childNode.ParentAddr == 0x0000) // { if (childNode.NodeName == 0x02) //终端 { int x = Convert.ToInt32(level2End * Math.Cos(angle)); int y = Convert.ToInt32(level2End * Math.Sin(angle)); //新坐标 angle = virtualParentNode.point.angle; //用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y; //得到旧坐标 AddPictureBox(i, 0x02, xx - de, yy - de, virtualParentNode.point.angle + (Math.PI * level2Angle[index] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } else//路由节点 { int x = Convert.ToInt32(level2Router * Math.Cos(angle)); int y = Convert.ToInt32(level2Router * Math.Sin(angle)); //新坐标 angle = virtualParentNode.point.angle; //用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y; //得到旧坐标 AddPictureBox(i, 0x01, xx - dr, yy - dr, virtualParentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } } //if (childNode.ParentAddr == 0x0000) } //for (; i < totalNodeNum; i++) } //if(flag),处理的是虚拟节点的叶子 flag = false; #endregion for (int p = 1; p < totalNodeNum; p++)//父亲 { parentNode = mainHome.nodeInfoArray[p]; if (parentNode.NodeName != 0x01)//只有路由器才有儿子 { continue; } for (i = p + 1; i < totalNodeNum; ++i)//儿子 { if (p == i) { continue; } childNode = mainHome.nodeInfoArray[i]; if (childNode.ParentAddr == parentNode.NetAddr)//找到子节点 { for (j = 0; j < level2Num; j++) { if (!parentNode.used[j]) { angle = Math.PI * level2Angle[j] / 180.0; parentNode.used[j] = true; parentNode.indexNo[j] = i; //储存 break; } } if (j >= level2Num) //节点太多,进行调整构造 { // MessageBox.Show("一个zigbee节点的儿子节点超已过7个"); flag = true; break; } if (childNode.NodeName == 0x02)//终端 { int x = Convert.ToInt32(level2End * Math.Cos(angle)); int y = Convert.ToInt32(level2End * Math.Sin(angle)); //新坐标 angle = parentNode.point.angle; //用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + parentNode.point.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + parentNode.point.y; //得到旧坐标 AddPictureBox(i, 0x02, xx - de, yy - de, parentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(parentNode.point.x, parentNode.point.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } else//路由节点 { int x = Convert.ToInt32(level2Router * Math.Cos(angle)); int y = Convert.ToInt32(level2Router * Math.Sin(angle)); //新坐标 angle = parentNode.point.angle; //用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + parentNode.point.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + parentNode.point.y; //得到旧坐标 AddPictureBox(i, 0x01, xx - dr, yy - dr, parentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(parentNode.point.x, parentNode.point.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } } //if (childNode.ParentAddr == parentNode.NetAddr) } //for (i = 1; i< totalNodeNum; ++i) // parentNode = (NodeDescribePacket)NodeDesList[p]; //------------------------------------------ if (flag) //拓扑树派生虚拟节点,在虚拟节点上生长叶子 { j = 0; //j用于循环旋转编号 k = parentNode.indexNo[j]; //k表示当前旋转编号对应的zigbee节点,parent在这里为路由器 // Console.WriteLine("[{0},{1}]-----------",j,k); virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 for (; i < totalNodeNum; ++i) { if (p == i) { continue; } childNode = mainHome.nodeInfoArray[i]; //子节点 if (childNode.ParentAddr != parentNode.NetAddr) //避免无用循环 { continue; } for (index = 0; index < 6; index++) { if (!virtualParentNode.virtualUsed[index]) //查看虚拟节点的虚拟点是否可用 { virtualParentNode.virtualUsed[index] = true; angle = Math.PI * virtualAngle[index] / 180.0; break; } } if (index >= 6) //当前虚拟点已经排满 { j++; if (j >= 7) { MessageBox.Show("路由器扩展叶子节点太多,当前节点网络拓扑丢弃,传感信息仍可用"); break; } k = parentNode.indexNo[j]; //k表示当前旋转编号对应的zigbee节点 virtualParentNode = mainHome.nodeInfoArray[k]; VirtualOneNode(k, virtualParentNode.NodeName); //构造虚拟节点 i--; //回退一次,处理当前节点 continue; }//if (indexer >= 8) if (childNode.NodeName == 0x02)//终端 { int x = Convert.ToInt32(level2End * Math.Cos(angle)); int y = Convert.ToInt32(level2End * Math.Sin(angle)); //新坐标 angle = virtualParentNode.point.angle; //用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y; //得到旧坐标 AddPictureBox(i, 0x02, xx - de, yy - de, virtualParentNode.point.angle + (Math.PI * level2Angle[index] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } else//路由节点 { int x = Convert.ToInt32(level2Router * Math.Cos(angle)); int y = Convert.ToInt32(level2Router * Math.Sin(angle)); //新坐标 angle = virtualParentNode.point.angle; //用来计算老坐标 int xx = Convert.ToInt32(x * Math.Cos(angle) - y * Math.Sin(angle)) + virtualParentNode.virtualPoint.x; int yy = Convert.ToInt32(x * Math.Sin(angle) + y * Math.Cos(angle)) + virtualParentNode.virtualPoint.y; //得到旧坐标 AddPictureBox(i, 0x01, xx - dr, yy - dr, virtualParentNode.point.angle + (Math.PI * level2Angle[j] / 180.0)); Point point1 = new Point(xx, yy); Point point2 = new Point(virtualParentNode.virtualPoint.x, virtualParentNode.virtualPoint.y); StartPoint.Add(point1); EndPoint.Add(point2); continue; } } //for (; i < totalNodeNum; i++) } //if(flag),处理的是虚拟节点的叶子 flag = false; //------------------------------------------ }//for (i = 1; i < totalNodeNum; i++) this.panel1.Refresh(); // Display(); }