diff --git a/Document/FAQ.doc b/Document/FAQ.doc index ae8806a..72e92d7 100644 Binary files a/Document/FAQ.doc and b/Document/FAQ.doc differ diff --git a/SCADA/Database/mysql.sql b/SCADA/Database/mysql.sql index 504c9e0..98ce37f 100644 --- a/SCADA/Database/mysql.sql +++ b/SCADA/Database/mysql.sql @@ -1,410 +1,392 @@ -/* -SQLyog Enterprise Trial - MySQL GUI v7.11 -MySQL - 5.7.20-log : Database - scada -********************************************************************* -*/ - -/*!40101 SET NAMES utf8 */; - -/*!40101 SET SQL_MODE=''*/; - -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; - -CREATE DATABASE /*!32312 IF NOT EXISTS*/`scada` /*!40100 DEFAULT CHARACTER SET utf8 */; - -USE `scada`; - -/*Table structure for table `dictionary` */ - -DROP TABLE IF EXISTS `dictionary`; - -CREATE TABLE `dictionary` ( - `DictType` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', - `Code` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', - `Description` varchar(50) COLLATE latin1_german1_ci DEFAULT '' -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `dictionary` */ - -/*Table structure for table `log_alarm` */ - -DROP TABLE IF EXISTS `log_alarm`; - -CREATE TABLE `log_alarm` ( - `StartTime` datetime DEFAULT NULL, - `Source` varchar(50) COLLATE latin1_german1_ci DEFAULT '', - `ConditionID` int(11) DEFAULT '0', - `AlarmText` varchar(128) COLLATE latin1_german1_ci DEFAULT '', - `AlarmValue` text COLLATE latin1_german1_ci, - `Duration` int(11) DEFAULT '0', - `Severity` int(11) DEFAULT '0', - `SubAlarmType` int(11) DEFAULT '0' -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `log_alarm` */ - -/*Table structure for table `log_event` */ - -DROP TABLE IF EXISTS `log_event`; - -CREATE TABLE `log_event` ( - `EventType` int(11) DEFAULT NULL, - `Severity` int(11) DEFAULT NULL, - `IsAcked` bit(1) DEFAULT NULL, - `ActiveTime` datetime DEFAULT NULL, - `Source` varchar(50) DEFAULT NULL, - `Comment` varchar(50) DEFAULT NULL, - `SQLCounter` int(11) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`SQLCounter`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - -/*Data for the table `log_event` */ - -/*Table structure for table `log_hdata` */ - -DROP TABLE IF EXISTS `log_hdata`; - -CREATE TABLE `log_hdata` ( - `ID` int(11) NOT NULL DEFAULT '0', - `TimeStamp` datetime NOT NULL, - `Value` text COLLATE latin1_german1_ci -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `log_hdata` */ - -/*Table structure for table `membership` */ - -DROP TABLE IF EXISTS `membership`; - -CREATE TABLE `membership` ( - `ID` int(11) NOT NULL AUTO_INCREMENT, - `UserName` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', - `Password` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', - `Role` int(11) NOT NULL DEFAULT '0', - `Email` varchar(50) COLLATE latin1_german1_ci DEFAULT '', - `Phone` varchar(50) COLLATE latin1_german1_ci DEFAULT '', - PRIMARY KEY (`ID`) -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `membership` */ - -insert into `membership`(`ID`,`UserName`,`Password`,`Role`,`Email`,`Phone`) values (1,'admin','c4ca4238a0b923820dcc509a6f75849b',4,NULL,NULL),(2,'op','c4ca4238a0b923820dcc509a6f75849b',1,NULL,NULL),(3,'everyone','c4ca4238a0b923820dcc509a6f75849b',1,NULL,NULL); - -/*Table structure for table `meta_condition` */ - -DROP TABLE IF EXISTS `meta_condition`; - -CREATE TABLE `meta_condition` ( - `TypeID` int(11) NOT NULL AUTO_INCREMENT, - `Source` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', - `AlarmType` int(11) NOT NULL DEFAULT '0', - `EventType` tinyint(4) NOT NULL DEFAULT '0', - `ConditionType` tinyint(4) NOT NULL DEFAULT '0', - `Para` text COLLATE latin1_german1_ci, - `IsEnabled` tinyint(4) NOT NULL DEFAULT '1', - `DeadBand` text COLLATE latin1_german1_ci, - `Delay` int(11) NOT NULL DEFAULT '0', - `Comment` varchar(50) COLLATE latin1_german1_ci DEFAULT '', - PRIMARY KEY (`TypeID`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `meta_condition` */ - -/*Table structure for table `meta_driver` */ - -DROP TABLE IF EXISTS `meta_driver`; - -CREATE TABLE `meta_driver` ( - `DriverID` int(11) NOT NULL DEFAULT '0', - `DriverType` int(11) NOT NULL DEFAULT '0', - `DriverName` varchar(64) COLLATE latin1_german1_ci NOT NULL DEFAULT '', - `TimeOut` int(11) NOT NULL DEFAULT '0', - `Server` varchar(128) COLLATE latin1_german1_ci DEFAULT '', - `Spare1` varchar(50) COLLATE latin1_german1_ci DEFAULT '', - `Spare2` varchar(50) COLLATE latin1_german1_ci DEFAULT '' -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `meta_driver` */ - -insert into `meta_driver`(`DriverID`,`DriverType`,`DriverName`,`TimeOut`,`Server`,`Spare1`,`Spare2`) values (1,3,'S1',1000,'127.0.0.1','{6E6170F0-FF2D-11D2-8087-00105AA8F840}','9600'),(2,5,'Modbus',1000,'127.0.0.1','','2'); - -/*Table structure for table `meta_group` */ - -DROP TABLE IF EXISTS `meta_group`; - -CREATE TABLE `meta_group` ( - `GroupID` int(11) NOT NULL DEFAULT '0', - `DriverID` int(11) DEFAULT '0', - `GroupName` varchar(20) COLLATE latin1_german1_ci DEFAULT '', - `UpdateRate` int(11) DEFAULT '0', - `DeadBand` text COLLATE latin1_german1_ci, - `IsActive` tinyint(4) NOT NULL DEFAULT '1' -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `meta_group` */ - -insert into `meta_group`(`GroupID`,`DriverID`,`GroupName`,`UpdateRate`,`DeadBand`,`IsActive`) values (20001,1,'Receiving1',300,'0',0),(20002,1,'Receiving2',0,'0',0),(20003,2,'test',1000,'0',1); - -/*Table structure for table `meta_scale` */ - -DROP TABLE IF EXISTS `meta_scale`; - -CREATE TABLE `meta_scale` ( - `ScaleID` int(11) NOT NULL DEFAULT '0', - `ScaleType` tinyint(4) NOT NULL DEFAULT '0', - `EUHi` text COLLATE latin1_german1_ci, - `EULo` text COLLATE latin1_german1_ci, - `RawHi` text COLLATE latin1_german1_ci, - `RawLo` text COLLATE latin1_german1_ci -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `meta_scale` */ - -/*Table structure for table `meta_subcondition` */ - -DROP TABLE IF EXISTS `meta_subcondition`; - -CREATE TABLE `meta_subcondition` ( - `ConditionID` int(11) NOT NULL DEFAULT '0', - `SubAlarmType` int(11) NOT NULL DEFAULT '0', - `Threshold` text COLLATE latin1_german1_ci, - `Severity` tinyint(4) NOT NULL DEFAULT '0', - `Message` varchar(250) COLLATE latin1_german1_ci DEFAULT '', - `IsEnable` tinyint(4) NOT NULL DEFAULT '1' -) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; - -/*Data for the table `meta_subcondition` */ - -/*Table structure for table `meta_tag` */ - -DROP TABLE IF EXISTS `meta_tag`; - -CREATE TABLE `meta_tag` ( - `TagID` smallint(5) NOT NULL AUTO_INCREMENT, - `TagName` varchar(512) NOT NULL, - `DataType` tinyint(3) unsigned NOT NULL, - `DataSize` smallint(5) NOT NULL DEFAULT '0', - `Address` varchar(64) NOT NULL, - `GroupID` smallint(5) NOT NULL DEFAULT '0', - `IsActive` bit(1) NOT NULL, - `Archive` bit(1) NOT NULL, - `DefaultValue` blob, - `Description` varchar(128) DEFAULT NULL, - `Maximum` float(24,2) NOT NULL DEFAULT '0.00', - `Minimum` float(24,2) NOT NULL DEFAULT '0.00', - `Cycle` int(10) NOT NULL DEFAULT '0', - `RowVersion` blob NOT NULL, - UNIQUE KEY `TagID` (`TagID`) -) ENGINE=InnoDB AUTO_INCREMENT=159 DEFAULT CHARSET=utf8; - -/*Data for the table `meta_tag` */ - -insert into `meta_tag`(`TagID`,`TagName`,`DataType`,`DataSize`,`Address`,`GroupID`,`IsActive`,`Archive`,`DefaultValue`,`Description`,`Maximum`,`Minimum`,`Cycle`,`RowVersion`) values (2,'Receiving1_AlmAck',1,1,'Channel4.Receiving1.K0008.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0划'),(3,'Receiving1_888',1,1,'Channel4.Receiving1.K0006.14',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0化'),(4,'Receiving1_Conveyor3_Running',1,1,'Channel4.Receiving1.K0006.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0话'),(5,'Receiving1_Conveyor4_Alarm',1,1,'Channel4.Receiving1.K0001.04',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0槐'),(6,'Receiving1_Conveyor4_Running',1,1,'Channel4.Receiving1.K0001.03',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0徊'),(7,'Receiving1_Conveyor5_Alarm',1,1,'Channel4.Receiving1.K0008.00',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0怀'),(8,'Receiving1_Conveyor5_Running',1,1,'Channel4.Receiving1.K0007.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0淮'),(9,'Receiving1_Conveyor6_Alarm',1,1,'Channel4.Receiving1.K0008.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0坏'),(10,'Receiving1_Conveyor6_Running',1,1,'Channel4.Receiving1.K0005.14',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0欢'),(11,'Receiving1_Conveyor7_Alarm',1,1,'Channel4.Receiving1.K0006.13',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0环'),(12,'Receiving1_Conveyor7_Running',1,1,'Channel4.Receiving1.K0006.12',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0桓'),(13,'Receiving1_Conveyor8_Running',1,1,'Channel4.Receiving1.K0001.12',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0还'),(14,'Receiving1_Conveyor9_Alarm',1,1,'Channel4.Receiving1.K0001.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0缓'),(15,'Receiving1_Conveyor9_Running',1,1,'Channel4.Receiving1.K0001.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0换'),(16,'Receiving1_DF01SQH_Alarm',1,1,'Channel4.Receiving1.K0002.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0患'),(17,'Receiving1_DF01SQL_Alarm',1,1,'Channel4.Receiving1.K0003.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0唤'),(18,'Receiving1_DF02SQH_Alarm',1,1,'Channel4.Receiving1.K0002.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0痪'),(19,'Receiving1_DF02SQL_Alarm',1,1,'Channel4.Receiving1.K0003.03',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0豢'),(20,'Receiving1_DF03SQH_Alarm',1,1,'Channel4.Receiving1.K0002.04',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0焕'),(21,'Receiving1_DF03SQL_Alarm',1,1,'Channel4.Receiving1.K0003.04',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0涣'),(22,'Receiving1_DF04SQH_Alarm',1,1,'Channel4.Receiving1.K0002.03',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0宦'),(23,'Receiving1_DF04SQL_Alarm',1,1,'Channel4.Receiving1.K0003.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0幻'),(24,'Receiving1_DF05SQH_Alarm',1,1,'Channel4.Receiving1.K0002.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0荒'),(25,'Receiving1_DF05SQL_Alarm',1,1,'Channel4.Receiving1.K0003.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0慌'),(26,'Receiving1_DF06SQL_Alarm',1,1,'Channel4.Receiving1.K0002.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0黄'),(27,'Receiving1_F01SQH_Alarm',1,1,'Channel4.Receiving1.K0007.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0磺'),(28,'Receiving1_F02SQH_Alarm',1,1,'Channel4.Receiving1.K0007.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0蝗'),(29,'Receiving1_F03SQH_Alarm',1,1,'Channel4.Receiving1.K0007.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0簧'),(30,'Receiving1_F04SQH_Alarm',1,1,'Channel4.Receiving1.K0007.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0皇'),(31,'Receiving1_F05SQH_Alarm',1,1,'Channel4.Receiving1.K0007.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0凰'),(32,'Receiving1_F06SQH_Alarm',1,1,'Channel4.Receiving1.K0007.03',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0惶'),(33,'Receiving1_Fan1_Alarm',1,1,'Channel4.Receiving1.K0008.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0煌'),(34,'Receiving1_Fan1_Running',1,1,'Channel4.Receiving1.K0008.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0晃'),(35,'Receiving1_Fan2_Running',1,1,'Channel4.Receiving1.K0008.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0幌'),(36,'Receiving1_Fan3_Running',1,1,'Channel4.Receiving1.K0001.13',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0恍'),(37,'Receiving1_FourWays_Left',1,1,'Channel4.Receiving1.K0006.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0谎'),(38,'Receiving1_FourWays_MID',1,1,'Channel4.Receiving1.K0006.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0灰'),(39,'Receiving1_FourWays_Right',1,1,'Channel4.Receiving1.K0006.15',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0挥'),(40,'Receiving1_Gate1_Ols',1,1,'Channel4.Receiving1.K0000.01',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0辉'),(41,'Receiving1_Gate10_Alarm',1,1,'Channel4.Receiving1.K0003.11',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0徽'),(42,'Receiving1_Gate10_Cls',1,1,'Channel4.Receiving1.K0004.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0恢'),(43,'Receiving1_Gate10_Ols',1,1,'Channel4.Receiving1.K0004.00',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0蛔'),(44,'Receiving1_Gate11_Alarm',1,1,'Channel4.Receiving1.K0005.04',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0回'),(45,'Receiving1_Gate11_Cls',1,1,'Channel4.Receiving1.K0001.00',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0毁'),(46,'Receiving1_Gate11_Ols',1,1,'Channel4.Receiving1.K0005.03',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0悔'),(47,'Receiving1_Gate12_Alarm',1,1,'Channel4.Receiving1.K0005.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0慧'),(48,'Receiving1_Gate12_Cls',1,1,'Channel4.Receiving1.K0001.01',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0卉'),(49,'Receiving1_Gate12_Ols',1,1,'Channel4.Receiving1.K0005.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0惠'),(50,'Receiving1_Gate13_Alarm',1,1,'Channel4.Receiving1.K0005.01',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0晦'),(51,'Receiving1_Gate13_Cls',1,1,'Channel4.Receiving1.K0001.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0贿'),(52,'Receiving1_Gate13_Ols',1,1,'Channel4.Receiving1.K0005.00',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0秽'),(53,'Receiving1_Gate14_Alarm',1,1,'Channel4.Receiving1.K0005.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0会'),(54,'Receiving1_Gate14_Cls',1,1,'Channel4.Receiving1.K0000.15',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0烩'),(55,'Receiving1_Gate14_Ols',1,1,'Channel4.Receiving1.K0005.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0汇'),(56,'Receiving1_Gate15_Alarm',1,1,'Channel4.Receiving1.K0005.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0讳'),(57,'Receiving1_Gate15_Cls',1,1,'Channel4.Receiving1.K0000.14',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0诲'),(58,'Receiving1_Gate15_Ols',1,1,'Channel4.Receiving1.K0005.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0绘'),(59,'Receiving1_Gate16_Ols',1,1,'Channel4.Receiving1.K0000.11',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0荤'),(60,'Receiving1_Gate17_Ols',1,1,'Channel4.Receiving1.K0000.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0昏'),(61,'Receiving1_Gate18_Ols',1,1,'Channel4.Receiving1.K0000.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0婚'),(62,'Receiving1_Gate19_Ols',1,1,'Channel4.Receiving1.K0000.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0魂'),(63,'Receiving1_Gate20_Ols',1,1,'Channel4.Receiving1.K0000.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0浑'),(64,'Receiving1_Gate21_Ols',1,1,'Channel4.Receiving1.K0000.01',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0混'),(65,'Receiving1_Gate3_Alarm',1,1,'Channel4.Receiving1.K0005.12',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0豁'),(66,'Receiving1_Gate3_Cls',1,1,'Channel4.Receiving1.K0000.12',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0活'),(67,'Receiving1_Gate3_Ols',1,1,'Channel4.Receiving1.K0005.11',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0伙'),(68,'Receiving1_Gate4_Alarm',1,1,'Channel4.Receiving1.K0005.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0火'),(69,'Receiving1_Gate4_Cls',1,1,'Channel4.Receiving1.K0000.13',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0获'),(70,'Receiving1_Gate4_Ols',1,1,'Channel4.Receiving1.K0005.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0或'),(71,'Receiving1_Gate5_Alarm',1,1,'Channel4.Receiving1.K0003.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0惑'),(72,'Receiving1_Gate5_Cls',1,1,'Channel4.Receiving1.K0004.01',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0霍'),(73,'Receiving1_Gate5_Ols',1,1,'Channel4.Receiving1.K0000.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0货'),(74,'Receiving1_Gate6_Alarm',1,1,'Channel4.Receiving1.K0003.08',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0祸'),(75,'Receiving1_Gate6_Cls',1,1,'Channel4.Receiving1.K0004.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0击'),(76,'Receiving1_Gate6_Ols',1,1,'Channel4.Receiving1.K0000.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0圾'),(77,'Receiving1_Gate7_Alarm',1,1,'Channel4.Receiving1.K0003.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0基'),(78,'Receiving1_Gate7_Cls',1,1,'Channel4.Receiving1.K0004.04',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0机'),(79,'Receiving1_Gate7_Ols',1,1,'Channel4.Receiving1.K0000.04',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0畸'),(80,'Receiving1_Gate8_Alarm',1,1,'Channel4.Receiving1.K0003.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0稽'),(81,'Receiving1_Gate8_Cls',1,1,'Channel4.Receiving1.K0004.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0积'),(82,'Receiving1_Gate8_Ols',1,1,'Channel4.Receiving1.K0000.03',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0箕'),(83,'Receiving1_Gate9_Alarm',1,1,'Channel4.Receiving1.K0003.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(84,'Receiving1_Gate9_Cls',1,1,'Channel4.Receiving1.K0004.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(85,'Receiving1_Gate9_Ols',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(86,'Receiving1_Gate9_Ols4',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(87,'Receiving1_Gate9_Ols5',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(88,'Receiving1_Gate9_Ols6',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(89,'Receiving1_Gate9_Ols7',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(90,'Receiving1_Gate9_Ols8',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(91,'Receiving1_Gate9_Ols9',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(92,'Receiving1_leg1alm',1,1,'Channel4.Receiving1.K0010.00',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0 '),(93,'Receiving1_LegMotor1_Overload',8,4,'Channel4.Receiving1.R0016',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糪n'),(94,'Receiving1_LegMotor1_Running',1,1,'Channel4.Receiving1.K0006.01',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0 '),(95,'Receiving1_LegMotor2_Overload',8,4,'Channel4.Receiving1.R0024',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0 '),(96,'Receiving1_LegMotor2_Running',1,1,'Channel4.Receiving1.K0005.15',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糪r'),(97,'Receiving1_Legmotor2Speed_Speed',8,4,'Channel4.Receiving1.R0028',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(98,'Receiving1_LegMotor3_Overload',8,4,'Channel4.Receiving1.R0044',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(99,'Receiving1_LegMotor3_Running',1,1,'Channel4.Receiving1.K0006.00',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(100,'Receiving1_Legmotor3Curr_Digi',8,4,'Channel4.Receiving1.R0036',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(101,'Receiving1_Legmotor3Speed_Speed',8,4,'Channel4.Receiving1.R0048',20001,'','',NULL,'鎻愬崌鏈烘祴閫',0.00,0.00,0,'\0\0\0\0\0'),(102,'Receiving1_LegMotor4_Overload',8,4,'Channel4.Receiving1.R0004',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(103,'Receiving1_LegMotor4_Running',1,1,'Channel4.Receiving1.K0001.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(104,'Receiving1_Legmotor4Curr_Digi',8,4,'Channel4.Receiving1.R0000',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(105,'Receiving1_LocalRemote',1,1,'Channel4.Receiving1.K0008.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(106,'Receiving1_MagicRoll1_Alarm',1,1,'Channel4.Receiving1.K0007.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(107,'Receiving1_MagicRoll1_Running',1,1,'Channel4.Receiving1.K0006.11',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(108,'Receiving1_MagicRoll2_Alarm',1,1,'Channel4.Receiving1.K0007.01',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(109,'Receiving1_MagicRoll2_Running',1,1,'Channel4.Receiving1.K0006.06',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糪Z'),(110,'Receiving1_MagicRoll3_Alarm',1,1,'Channel4.Receiving1.K0007.00',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(111,'Receiving1_MagicRoll3_Running',1,1,'Channel4.Receiving1.K0006.04',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(112,'Receiving1_MagicRoll4_Alarm',1,1,'Channel4.Receiving1.K0001.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(113,'Receiving1_MagicRoll4_Running',1,1,'Channel4.Receiving1.K0001.09',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(114,'Receiving1_Sifter1_Running',1,1,'Channel4.Receiving1.K0006.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0'),(115,'Receiving1_Sifter2_Running',1,1,'Channel4.Receiving1.K0006.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0 '),(116,'Receiving1_Sifter3_Alarm',1,1,'Channel4.Receiving1.K0001.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0!'),(117,'Receiving1_Sifter3_Running',1,1,'Channel4.Receiving1.K0001.10',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糪"'),(118,'Receiving1_ThreeWays1_Left',1,1,'Channel4.Receiving1.K0001.07',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0#'),(119,'Receiving1_ThreeWays1_Right',1,1,'Channel4.Receiving1.K0001.05',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0$'),(120,'Receiving1_ThreeWays2_Left',1,1,'Channel4.Receiving1.K0006.03',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0%'),(121,'Receiving1_ThreeWays2_Right',1,1,'Channel4.Receiving1.K0006.02',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0&'),(122,'Receiving2_LegCUR102_Digi',8,4,'Channel4.Receiving1.R0020',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糪''),(123,'Receiving2_LegCUR106_Digi',8,4,'Channel4.Receiving1.R0012',20001,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0('),(124,'Receiving1_Conveyor1_Alarm',1,1,'Channel4.Receiving2.K0002.11',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0)'),(125,'Receiving1_Conveyor1_Running',1,1,'Channel4.Receiving2.K0002.10',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0*'),(126,'Receiving1_Conveyor2_Alarm',1,1,'Channel4.Receiving2.K0002.09',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0+'),(127,'Receiving1_Conveyor2_Running',1,1,'Channel4.Receiving2.K0002.04',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0,'),(128,'Receiving1_Gate1_Alarm',1,1,'Channel4.Receiving2.K0001.14',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0-'),(129,'Receiving1_Gate1_Cls',1,1,'Channel4.Receiving2.K0001.13',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0.'),(130,'Receiving1_Gate1_Ols',1,1,'Channel4.Receiving2.K0001.11',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0/'),(131,'Receiving1_Gate2_Alarm',1,1,'Channel4.Receiving2.K0001.08',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\00'),(132,'Receiving1_Gate2_Cls',1,1,'Channel4.Receiving2.K0001.09',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\01'),(133,'Receiving1_Gate2_Ols',1,1,'Channel4.Receiving2.K0001.10',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\02'),(134,'Receiving2_Airport1_Alarm',1,1,'Channel4.Receiving2.K0002.08',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\03'),(135,'Receiving2_Airport1_Running',1,1,'Channel4.Receiving2.K0001.05',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\04'),(136,'Receiving2_Airport2_Alarm',1,1,'Channel4.Receiving2.K0001.00',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\05'),(137,'Receiving2_Airport2_Running',1,1,'Channel4.Receiving2.K0001.01',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\06'),(138,'Receiving2_AlmAck',1,1,'Channel4.Receiving2.K0002.02',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\07'),(139,'Receiving2_Converyor1_Running',1,1,'Channel4.Receiving2.K0001.15',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\08'),(140,'Receiving2_Converyor2_Alarm',1,1,'Channel4.Receiving2.K0002.12',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\09'),(141,'Receiving2_Converyor2_Running',1,1,'Channel4.Receiving2.K0002.13',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0:'),(142,'Receiving2_Fan1_Alarm',1,1,'Channel4.Receiving2.K0001.02',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0;'),(143,'Receiving2_Fan1_Running',1,1,'Channel4.Receiving2.K0001.03',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0<'),(144,'Receiving2_Gate1_Alarm',1,1,'Channel4.Receiving2.K0001.04',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0='),(145,'Receiving2_Gate1_Cls',1,1,'Channel4.Receiving2.K0001.06',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0>'),(146,'Receiving2_Gate1_Ols',1,1,'Channel4.Receiving2.K0001.07',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0?'),(147,'Receiving2_Gate2_Ols',1,1,'Channel4.Receiving2.K0002.05',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0粿'),(148,'Receiving2_LegMotor1_Overload',8,4,'Channel4.Receiving2.R0008',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糀'),(149,'Receiving2_Legmotor1Speed_Speed',8,4,'Channel4.Receiving2.R0012',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糂'),(150,'Receiving2_LegMotor2_Overload',8,4,'Channel4.Receiving2.R0000',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糃'),(151,'Receiving2_LegMotor2_Running',1,1,'Channel4.Receiving2.K0002.01',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糄'),(152,'Receiving2_Legmotor2Speed_Speed',8,4,'Channel4.Receiving2.R0004',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糆'),(153,'Receiving2_LocalRemote',1,1,'Channel4.Receiving2.K0002.03',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糉'),(154,'Receiving2_MagicRoll1_Alarm',1,1,'Channel4.Receiving2.K0002.14',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糋'),(155,'Receiving2_MagicRoll1_Running',1,1,'Channel4.Receiving2.K0002.00',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糎'),(156,'Receiving2_Sifter1_Alarm',1,1,'Channel4.Receiving2.K0002.15',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糏'),(157,'Receiving2_Sifter1_Running',1,1,'Channel4.Receiving2.K0002.07',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糐'),(158,'Receiving2_Sifter1_Running8',1,1,'Channel4.Receiving2.K0002.07',20002,'','\0',NULL,NULL,0.00,0.00,0,'\0\0\0\0\0糑'); - -/*Table structure for table `registermodule` */ - -DROP TABLE IF EXISTS `registermodule`; - -CREATE TABLE `registermodule` ( - `DriverID` int(10) NOT NULL AUTO_INCREMENT, - `AssemblyName` varchar(255) DEFAULT NULL, - `ClassName` varchar(50) DEFAULT NULL, - `ClassFullName` varchar(128) DEFAULT NULL, - `Description` varchar(50) DEFAULT NULL, - UNIQUE KEY `DriverID` (`DriverID`) -) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; - -/*Data for the table `registermodule` */ - -insert into `registermodule`(`DriverID`,`AssemblyName`,`ClassName`,`ClassFullName`,`Description`) values (4,'E:\\SCADA\\dll\\OPCDriver.dll','OPCReader','OPCDriver.OPCReader','OPC鍗忚'),(5,'E:\\SCADA\\dll\\FileDriver.dll','DataBaseReader','FileDriver.DataBaseReader','SQL 鏁版嵁搴'),(6,'E:\\SCADA\\dll\\FileDriver.dll','TagDriver','FileDriver.TagDriver','鏍囩鐩存帴璇诲啓'),(8,'E:\\SCADA\\dll\\ModbusDriver.dll','ModbusRTUReader','ModbusDriver.ModbusRTUReader','Modbus RTU鍗忚'),(9,'E:\\SCADA\\dll\\ModbusDriver.dll','ModbusTCPReader','ModbusDriver.ModbusTCPReader','Modbus Tcp鍗忚'),(10,'E:\\SCADA\\dll\\SiemensPLCDriver.dll','SiemensTCPReader','SiemensPLCDriver.SiemensTCPReader','S7 浠ュお缃戝崗璁'); - -/* Procedure structure for procedure `AddEventLog` */ - -/*!50003 DROP PROCEDURE IF EXISTS `AddEventLog` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `AddEventLog`(IN pStartTime DATETIME, - IN pSource NVARCHAR(50) , - IN pComment NVARCHAR(50)) -BEGIN -IF pComment<>IFNULL((SELECT Comment FROM LOG_EVENT WHERE EVENTTYPE=2 AND Source=Source ORDER BY SQLCOUNTER DESC LIMIT 1),'') THEN - INSERT INTO LOG_EVENT(EVENTTYPE,SEVERITY,ACTIVETIME,SOURCE,COMMENT) VALUES(2,0,pStartTime,pSource,pComment); -END IF; - -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `GetAlarm` */ - -/*!50003 DROP PROCEDURE IF EXISTS `GetAlarm` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `GetAlarm`(IN pStartTime DATETIME, - IN pEndTime DATETIME ) -BEGIN -SELECT StartTime,AlarmText,AlarmValue,SubAlarmType,Severity,ConditionID,Source,Duration FROM LOG_ALARM WHERE StartTime BETWEEN pStartTime AND pEndTime ORDER BY StartTime; - -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `GetEventTime` */ - -/*!50003 DROP PROCEDURE IF EXISTS `GetEventTime` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `GetEventTime`(IN pEVENTTYPE int, - IN pSOURCE nvarchar(50), - IN pCOMMENT nvarchar(50), - OUT pSTARTTIME DATETIME, - OUT pENDTIME DATETIME) -BEGIN -DECLARE _ID INT DEFAULT 0; - -SELECT SQLCOUNTER,ACTIVETIME INTO _ID,pSTARTTIME FROM LOG_EVENT WHERE EVENTTYPE=pEVENTTYPE AND SOURCE=pSOURCE AND COMMENT=pCOMMENT ORDER BY ACTIVETIME DESC LIMIT 1; - -SET @sql = CONCAT('SELECT ACTIVETIME INTO ', pENDTIME, ' FROM LOG_EVENT WHERE EVENTTYPE = "', - pEVENTTYPE, '" AND SOURCE = "', pSOURCE, '" AND SQLCOUNTER> ',_ID,' ORDER BY ACTIVETIME DESC LIMIT 1'); - PREPARE stmt FROM @sql; - EXECUTE stmt; - DEALLOCATE PREPARE stmt; -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `InitServer` */ - -/*!50003 DROP PROCEDURE IF EXISTS `InitServer` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `InitServer`(IN pTYPE int) -BEGIN - - IF pTYPE<>1 THEN - SELECT M.DRIVERID,DRIVERNAME,SERVER,TIMEOUT,R.AssemblyName,R.ClassFullName,Spare1,Spare2 FROM META_DRIVER M INNER JOIN RegisterModule R ON M.DRIVERTYPE=R.DriverID; - END IF; - - SELECT COUNT(*) FROM META_TAG; - - SELECT TAGID,GROUPID,RTRIM(TAGNAME),ADDRESS,DATATYPE,DATASIZE,ARCHIVE,MAXIMUM,MINIMUM,CYCLE FROM META_TAG WHERE ISACTIVE=1; - - IF pTYPE<>1 THEN - SELECT DRIVERID,GROUPNAME,GROUPID,UPDATERATE,DEADBAND,ISACTIVE FROM META_GROUP ; - END IF; - - IF pTYPE=0 THEN - SELECT SOURCE FROM META_Condition WHERE EVENTTYPE=2; - END IF; - - IF pTYPE<>2 THEN - SELECT TYPEID,SOURCE,ALARMTYPE,A.ISENABLED,CONDITIONTYPE,PARA,IFNULL(COMMENT,''),DEADBAND,DELAY,SUBALARMTYPE,Threshold,SEVERITY, - IFNULL(MESSAGE,''),B.ISENABLE FROM META_Condition a LEFT OUTER JOIN META_SUBCONDITION b ON a.TypeID=b.ConditionID WHERE EVENTTYPE<>2; - END IF; - - -- LEFT OUTER JOIN META_TAG c ON a.SOURCEID=c.TAGID - SELECT SCALEID,SCALETYPE,EUHI,EULO,RAWHI,RAWLO FROM META_SCALE; - -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `ReadALL` */ - -/*!50003 DROP PROCEDURE IF EXISTS `ReadALL` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `ReadALL`(IN pGroupID SMALLINT) -BEGIN - -SELECT COUNT(*) FROM META_TAG WHERE GROUPID=pGroupID AND IsActive=1; -SELECT TAGID,DATATYPE,IFNULL(DEFAULTVALUE,0) FROM META_TAG WHERE IsActive=1 AND GROUPID=pGroupID ORDER BY TAGID; - -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `ReadHData` */ - -/*!50003 DROP PROCEDURE IF EXISTS `ReadHData` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `ReadHData`(IN pStartTime DATETIME, - IN pEndTime DATETIME, - IN pID INT) -BEGIN - - IF pID IS NULL THEN - SELECT ID,TIMESTAMP,VALUE,M.DATATYPE FROM LOG_HDATA L INNER JOIN META_TAG M ON L.ID=M.TAGID WHERE TIMESTAMP BETWEEN pStartTime AND pEndTime ORDER BY ID,TIMESTAMP; - ELSE - SELECT TIMESTAMP,VALUE,M.DATATYPE FROM LOG_HDATA L INNER JOIN META_TAG M ON L.ID=M.TAGID WHERE ID=pID AND TIMESTAMP BETWEEN pStartTime AND pEndTime ORDER BY TIMESTAMP; - -- select ID,TIMESTAMP,VALUE from HDADATA WHERE TIMESTAMP BETWEEN @StartTime AND @EndTime order by TIMESTAMP - END IF; - -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `ReadValueByID` */ - -/*!50003 DROP PROCEDURE IF EXISTS `ReadValueByID` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `ReadValueByID`(IN pID SMALLINT, - IN pDATATYPE TinyInt) -BEGIN - - -- 寰呭畬鍠 --- IF @DATATYPE=1 --- SELECT CAST(DEFAULTVALUE AS BIT) FROM META_TAG WHERE TAGID=@ID --- ELSE IF @DATATYPE=3 --- SELECT CAST(DEFAULTVALUE AS TINYINT) FROM META_TAG WHERE TAGID=@ID --- ELSE IF @DATATYPE=4 --- SELECT CAST(DEFAULTVALUE AS SMALLINT) FROM META_TAG WHERE TAGID=@ID --- ELSE IF @DATATYPE=7 --- SELECT CAST(DEFAULTVALUE AS INT) FROM META_TAG WHERE TAGID=@ID --- ELSE IF @DATATYPE=8 --- SELECT CAST(DEFAULTVALUE AS REAL) FROM META_TAG WHERE TAGID=@ID --- ELSE IF @DATATYPE=11 --- SELECT CAST(DEFAULTVALUE AS VARCHAR) FROM META_TAG WHERE TAGID=@ID - -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `UpdateValueByID` */ - -/*!50003 DROP PROCEDURE IF EXISTS `UpdateValueByID` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `UpdateValueByID`(IN pID SMALLINT, - IN pValue varchar(50)) -BEGIN - - UPDATE META_TAG SET DEFAULTVALUE=pValue WHERE TAGID=pID; - -END */$$ -DELIMITER ; - -/* Procedure structure for procedure `WriteHData` */ - -/*!50003 DROP PROCEDURE IF EXISTS `WriteHData` */; - -DELIMITER $$ - -/*!50003 CREATE DEFINER=`root`@`localhost` PROCEDURE `WriteHData`(IN pDATE DATETIME) -BEGIN - - -- DELETE FROM LOG_HDATA FROM LOG_HDATA L INNER JOIN META_TAG T ON T.TAGID=L.ID WHERE T.DATATYPE=11 - -- SELECT COUNT(*),COUNT(DISTINCT ID) FROM LOG_HDATA WHERE DATEDIFF(DAY,@DATE,TIMESTAMP)=0; - -- SELECT H.ID,T.DATATYPE,C FROM( SELECT ID,COUNT(*)C FROM LOG_HDATA WHERE DATEDIFF(DAY,@DATE,TIMESTAMP)=0 GROUP BY ID)H INNER JOIN META_TAG T ON H.ID=T.TAGID ORDER BY ID --WITH ROLLUP - -- SELECT TIMESTAMP,VALUE FROM LOG_HDATA WHERE DATEDIFF(DAY,@DATE,TIMESTAMP)=0 ORDER BY ID,TIMESTAMP - - -- DELETE FROM LOG_HDATA WHERE DATEDIFF(DAY,@DATE,TIMESTAMP)=0; -END */$$ -DELIMITER ; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `dictionary` ( + `DictType` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', + `Code` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', + `Description` varchar(50) COLLATE latin1_german1_ci DEFAULT '' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `log_alarm` ( + `StartTime` datetime DEFAULT NULL, + `Source` varchar(50) COLLATE latin1_german1_ci DEFAULT '', + `ConditionID` int(11) DEFAULT '0', + `AlarmText` varchar(128) COLLATE latin1_german1_ci DEFAULT '', + `AlarmValue` float DEFAULT NULL, + `Duration` int(11) DEFAULT '0', + `Severity` int(11) DEFAULT '0', + `SubAlarmType` int(11) DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `log_event` ( + `EventType` int(11) DEFAULT NULL, + `Severity` int(11) DEFAULT NULL, + `IsAcked` bit(1) DEFAULT NULL, + `ActiveTime` datetime DEFAULT NULL, + `Source` varchar(50) DEFAULT NULL, + `Comment` varchar(50) DEFAULT NULL, + `SQLCounter` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`SQLCounter`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `log_hdata` ( + `ID` int(11) NOT NULL DEFAULT '0', + `TimeStamp` datetime NOT NULL, + `Value` float NOT NULL DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `membership` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `UserName` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', + `Password` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', + `Role` int(11) NOT NULL DEFAULT '0', + `Email` varchar(50) COLLATE latin1_german1_ci DEFAULT '', + `Phone` varchar(50) COLLATE latin1_german1_ci DEFAULT '', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `membership` VALUES (1,'admin','c4ca4238a0b923820dcc509a6f75849b',4,NULL,NULL),(2,'op','c4ca4238a0b923820dcc509a6f75849b',1,NULL,NULL),(3,'everyone','c4ca4238a0b923820dcc509a6f75849b',1,NULL,NULL); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `meta_condition` ( + `TypeID` int(11) NOT NULL AUTO_INCREMENT, + `Source` varchar(50) COLLATE latin1_german1_ci NOT NULL DEFAULT '', + `AlarmType` int(11) NOT NULL DEFAULT '0', + `EventType` tinyint(4) NOT NULL DEFAULT '0', + `ConditionType` tinyint(4) NOT NULL DEFAULT '0', + `Para` float NOT NULL DEFAULT '0', + `IsEnabled` tinyint(4) NOT NULL DEFAULT '1', + `DeadBand` float NOT NULL DEFAULT '0', + `Delay` int(11) NOT NULL DEFAULT '0', + `Comment` varchar(50) COLLATE latin1_german1_ci DEFAULT '', + PRIMARY KEY (`TypeID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `meta_driver` ( + `DriverID` int(11) NOT NULL DEFAULT '0', + `DriverType` int(11) NOT NULL DEFAULT '0', + `DriverName` varchar(64) COLLATE latin1_german1_ci NOT NULL DEFAULT '', + `TimeOut` int(11) NOT NULL DEFAULT '0', + `Server` varchar(128) COLLATE latin1_german1_ci DEFAULT '', + `Spare1` varchar(50) COLLATE latin1_german1_ci DEFAULT '', + `Spare2` varchar(50) COLLATE latin1_german1_ci DEFAULT '' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `meta_driver` VALUES (1,3,'S1',1000,'127.0.0.1','{6E6170F0-FF2D-11D2-8087-00105AA8F840}','9600'),(2,5,'Modbus',1000,'127.0.0.1','','2'); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `meta_group` ( + `GroupID` int(11) NOT NULL DEFAULT '0', + `DriverID` int(11) DEFAULT '0', + `GroupName` varchar(20) COLLATE latin1_german1_ci DEFAULT '', + `UpdateRate` int(11) DEFAULT '0', + `DeadBand` float DEFAULT NULL, + `IsActive` bit(1) NOT NULL DEFAULT b'1' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `meta_group` VALUES (20001,1,'Receiving1',300,0,''),(20002,1,'Receiving2',0,0,''),(20003,2,'test',1000,0,''); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `meta_scale` ( + `ScaleID` int(11) NOT NULL DEFAULT '0', + `ScaleType` tinyint(4) NOT NULL DEFAULT '0', + `EUHi` float NOT NULL DEFAULT '0', + `EULo` float NOT NULL DEFAULT '0', + `RawHi` float NOT NULL DEFAULT '0', + `RawLo` float NOT NULL DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `meta_subcondition` ( + `ConditionID` int(11) NOT NULL DEFAULT '0', + `SubAlarmType` int(11) NOT NULL DEFAULT '0', + `Threshold` float NOT NULL DEFAULT '0', + `Severity` tinyint(4) NOT NULL DEFAULT '0', + `Message` varchar(250) COLLATE latin1_german1_ci DEFAULT '', + `IsEnable` bit(1) NOT NULL DEFAULT b'1' +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `meta_tag` ( + `TagID` smallint(5) NOT NULL AUTO_INCREMENT, + `TagName` varchar(512) NOT NULL, + `DataType` tinyint(3) unsigned NOT NULL, + `DataSize` smallint(5) NOT NULL DEFAULT '0', + `Address` varchar(64) NOT NULL, + `GroupID` smallint(5) NOT NULL DEFAULT '0', + `IsActive` bit(1) NOT NULL, + `Archive` bit(1) NOT NULL, + `DefaultValue` blob, + `Description` varchar(128) DEFAULT NULL, + `Maximum` float(24,2) NOT NULL DEFAULT '0.00', + `Minimum` float(24,2) NOT NULL DEFAULT '0.00', + `Cycle` int(10) NOT NULL DEFAULT '0', + `RowVersion` timestamp NULL DEFAULT NULL, + UNIQUE KEY `TagID` (`TagID`) +) ENGINE=InnoDB AUTO_INCREMENT=159 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `meta_tag` VALUES (2,'Receiving1_AlmAck',1,1,'Channel4.Receiving1.K0008.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(3,'Receiving1_888',1,1,'Channel4.Receiving1.K0006.14',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(4,'Receiving1_Conveyor3_Running',1,1,'Channel4.Receiving1.K0006.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(5,'Receiving1_Conveyor4_Alarm',1,1,'Channel4.Receiving1.K0001.04',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(6,'Receiving1_Conveyor4_Running',1,1,'Channel4.Receiving1.K0001.03',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(7,'Receiving1_Conveyor5_Alarm',1,1,'Channel4.Receiving1.K0008.00',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(8,'Receiving1_Conveyor5_Running',1,1,'Channel4.Receiving1.K0007.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(9,'Receiving1_Conveyor6_Alarm',1,1,'Channel4.Receiving1.K0008.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(10,'Receiving1_Conveyor6_Running',1,1,'Channel4.Receiving1.K0005.14',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(11,'Receiving1_Conveyor7_Alarm',1,1,'Channel4.Receiving1.K0006.13',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(12,'Receiving1_Conveyor7_Running',1,1,'Channel4.Receiving1.K0006.12',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(13,'Receiving1_Conveyor8_Running',1,1,'Channel4.Receiving1.K0001.12',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(14,'Receiving1_Conveyor9_Alarm',1,1,'Channel4.Receiving1.K0001.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(15,'Receiving1_Conveyor9_Running',1,1,'Channel4.Receiving1.K0001.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(16,'Receiving1_DF01SQH_Alarm',1,1,'Channel4.Receiving1.K0002.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(17,'Receiving1_DF01SQL_Alarm',1,1,'Channel4.Receiving1.K0003.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(18,'Receiving1_DF02SQH_Alarm',1,1,'Channel4.Receiving1.K0002.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(19,'Receiving1_DF02SQL_Alarm',1,1,'Channel4.Receiving1.K0003.03',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(20,'Receiving1_DF03SQH_Alarm',1,1,'Channel4.Receiving1.K0002.04',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(21,'Receiving1_DF03SQL_Alarm',1,1,'Channel4.Receiving1.K0003.04',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(22,'Receiving1_DF04SQH_Alarm',1,1,'Channel4.Receiving1.K0002.03',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(23,'Receiving1_DF04SQL_Alarm',1,1,'Channel4.Receiving1.K0003.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(24,'Receiving1_DF05SQH_Alarm',1,1,'Channel4.Receiving1.K0002.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(25,'Receiving1_DF05SQL_Alarm',1,1,'Channel4.Receiving1.K0003.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(26,'Receiving1_DF06SQL_Alarm',1,1,'Channel4.Receiving1.K0002.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(27,'Receiving1_F01SQH_Alarm',1,1,'Channel4.Receiving1.K0007.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(28,'Receiving1_F02SQH_Alarm',1,1,'Channel4.Receiving1.K0007.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(29,'Receiving1_F03SQH_Alarm',1,1,'Channel4.Receiving1.K0007.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(30,'Receiving1_F04SQH_Alarm',1,1,'Channel4.Receiving1.K0007.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(31,'Receiving1_F05SQH_Alarm',1,1,'Channel4.Receiving1.K0007.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(32,'Receiving1_F06SQH_Alarm',1,1,'Channel4.Receiving1.K0007.03',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(33,'Receiving1_Fan1_Alarm',1,1,'Channel4.Receiving1.K0008.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(34,'Receiving1_Fan1_Running',1,1,'Channel4.Receiving1.K0008.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(35,'Receiving1_Fan2_Running',1,1,'Channel4.Receiving1.K0008.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(36,'Receiving1_Fan3_Running',1,1,'Channel4.Receiving1.K0001.13',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(37,'Receiving1_FourWays_Left',1,1,'Channel4.Receiving1.K0006.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(38,'Receiving1_FourWays_MID',1,1,'Channel4.Receiving1.K0006.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(39,'Receiving1_FourWays_Right',1,1,'Channel4.Receiving1.K0006.15',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(40,'Receiving1_Gate1_Ols',1,1,'Channel4.Receiving1.K0000.01',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(41,'Receiving1_Gate10_Alarm',1,1,'Channel4.Receiving1.K0003.11',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(42,'Receiving1_Gate10_Cls',1,1,'Channel4.Receiving1.K0004.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(43,'Receiving1_Gate10_Ols',1,1,'Channel4.Receiving1.K0004.00',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(44,'Receiving1_Gate11_Alarm',1,1,'Channel4.Receiving1.K0005.04',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(45,'Receiving1_Gate11_Cls',1,1,'Channel4.Receiving1.K0001.00',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(46,'Receiving1_Gate11_Ols',1,1,'Channel4.Receiving1.K0005.03',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(47,'Receiving1_Gate12_Alarm',1,1,'Channel4.Receiving1.K0005.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(48,'Receiving1_Gate12_Cls',1,1,'Channel4.Receiving1.K0001.01',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(49,'Receiving1_Gate12_Ols',1,1,'Channel4.Receiving1.K0005.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(50,'Receiving1_Gate13_Alarm',1,1,'Channel4.Receiving1.K0005.01',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(51,'Receiving1_Gate13_Cls',1,1,'Channel4.Receiving1.K0001.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(52,'Receiving1_Gate13_Ols',1,1,'Channel4.Receiving1.K0005.00',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(53,'Receiving1_Gate14_Alarm',1,1,'Channel4.Receiving1.K0005.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(54,'Receiving1_Gate14_Cls',1,1,'Channel4.Receiving1.K0000.15',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(55,'Receiving1_Gate14_Ols',1,1,'Channel4.Receiving1.K0005.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(56,'Receiving1_Gate15_Alarm',1,1,'Channel4.Receiving1.K0005.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(57,'Receiving1_Gate15_Cls',1,1,'Channel4.Receiving1.K0000.14',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(58,'Receiving1_Gate15_Ols',1,1,'Channel4.Receiving1.K0005.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(59,'Receiving1_Gate16_Ols',1,1,'Channel4.Receiving1.K0000.11',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(60,'Receiving1_Gate17_Ols',1,1,'Channel4.Receiving1.K0000.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(61,'Receiving1_Gate18_Ols',1,1,'Channel4.Receiving1.K0000.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(62,'Receiving1_Gate19_Ols',1,1,'Channel4.Receiving1.K0000.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(63,'Receiving1_Gate20_Ols',1,1,'Channel4.Receiving1.K0000.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(64,'Receiving1_Gate21_Ols',1,1,'Channel4.Receiving1.K0000.01',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(65,'Receiving1_Gate3_Alarm',1,1,'Channel4.Receiving1.K0005.12',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(66,'Receiving1_Gate3_Cls',1,1,'Channel4.Receiving1.K0000.12',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(67,'Receiving1_Gate3_Ols',1,1,'Channel4.Receiving1.K0005.11',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(68,'Receiving1_Gate4_Alarm',1,1,'Channel4.Receiving1.K0005.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(69,'Receiving1_Gate4_Cls',1,1,'Channel4.Receiving1.K0000.13',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(70,'Receiving1_Gate4_Ols',1,1,'Channel4.Receiving1.K0005.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(71,'Receiving1_Gate5_Alarm',1,1,'Channel4.Receiving1.K0003.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(72,'Receiving1_Gate5_Cls',1,1,'Channel4.Receiving1.K0004.01',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(73,'Receiving1_Gate5_Ols',1,1,'Channel4.Receiving1.K0000.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(74,'Receiving1_Gate6_Alarm',1,1,'Channel4.Receiving1.K0003.08',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(75,'Receiving1_Gate6_Cls',1,1,'Channel4.Receiving1.K0004.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(76,'Receiving1_Gate6_Ols',1,1,'Channel4.Receiving1.K0000.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(77,'Receiving1_Gate7_Alarm',1,1,'Channel4.Receiving1.K0003.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(78,'Receiving1_Gate7_Cls',1,1,'Channel4.Receiving1.K0004.04',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(79,'Receiving1_Gate7_Ols',1,1,'Channel4.Receiving1.K0000.04',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(80,'Receiving1_Gate8_Alarm',1,1,'Channel4.Receiving1.K0003.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(81,'Receiving1_Gate8_Cls',1,1,'Channel4.Receiving1.K0004.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(82,'Receiving1_Gate8_Ols',1,1,'Channel4.Receiving1.K0000.03',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(83,'Receiving1_Gate9_Alarm',1,1,'Channel4.Receiving1.K0003.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(84,'Receiving1_Gate9_Cls',1,1,'Channel4.Receiving1.K0004.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(85,'Receiving1_Gate9_Ols',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(86,'Receiving1_Gate9_Ols4',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(87,'Receiving1_Gate9_Ols5',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(88,'Receiving1_Gate9_Ols6',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(89,'Receiving1_Gate9_Ols7',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(90,'Receiving1_Gate9_Ols8',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(91,'Receiving1_Gate9_Ols9',1,1,'Channel4.Receiving1.K0000.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(92,'Receiving1_leg1alm',1,1,'Channel4.Receiving1.K0010.00',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(93,'Receiving1_LegMotor1_Overload',8,4,'Channel4.Receiving1.R0016',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(94,'Receiving1_LegMotor1_Running',1,1,'Channel4.Receiving1.K0006.01',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(95,'Receiving1_LegMotor2_Overload',8,4,'Channel4.Receiving1.R0024',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(96,'Receiving1_LegMotor2_Running',1,1,'Channel4.Receiving1.K0005.15',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(97,'Receiving1_Legmotor2Speed_Speed',8,4,'Channel4.Receiving1.R0028',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(98,'Receiving1_LegMotor3_Overload',8,4,'Channel4.Receiving1.R0044',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(99,'Receiving1_LegMotor3_Running',1,1,'Channel4.Receiving1.K0006.00',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(100,'Receiving1_Legmotor3Curr_Digi',8,4,'Channel4.Receiving1.R0036',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(101,'Receiving1_Legmotor3Speed_Speed',8,4,'Channel4.Receiving1.R0048',20001,'','',NULL,'鎻愬崌鏈烘祴閫',0.00,0.00,0,NULL),(102,'Receiving1_LegMotor4_Overload',8,4,'Channel4.Receiving1.R0004',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(103,'Receiving1_LegMotor4_Running',1,1,'Channel4.Receiving1.K0001.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(104,'Receiving1_Legmotor4Curr_Digi',8,4,'Channel4.Receiving1.R0000',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(105,'Receiving1_LocalRemote',1,1,'Channel4.Receiving1.K0008.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(106,'Receiving1_MagicRoll1_Alarm',1,1,'Channel4.Receiving1.K0007.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(107,'Receiving1_MagicRoll1_Running',1,1,'Channel4.Receiving1.K0006.11',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(108,'Receiving1_MagicRoll2_Alarm',1,1,'Channel4.Receiving1.K0007.01',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(109,'Receiving1_MagicRoll2_Running',1,1,'Channel4.Receiving1.K0006.06',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(110,'Receiving1_MagicRoll3_Alarm',1,1,'Channel4.Receiving1.K0007.00',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(111,'Receiving1_MagicRoll3_Running',1,1,'Channel4.Receiving1.K0006.04',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(112,'Receiving1_MagicRoll4_Alarm',1,1,'Channel4.Receiving1.K0001.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(113,'Receiving1_MagicRoll4_Running',1,1,'Channel4.Receiving1.K0001.09',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(114,'Receiving1_Sifter1_Running',1,1,'Channel4.Receiving1.K0006.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(115,'Receiving1_Sifter2_Running',1,1,'Channel4.Receiving1.K0006.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(116,'Receiving1_Sifter3_Alarm',1,1,'Channel4.Receiving1.K0001.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(117,'Receiving1_Sifter3_Running',1,1,'Channel4.Receiving1.K0001.10',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(118,'Receiving1_ThreeWays1_Left',1,1,'Channel4.Receiving1.K0001.07',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(119,'Receiving1_ThreeWays1_Right',1,1,'Channel4.Receiving1.K0001.05',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(120,'Receiving1_ThreeWays2_Left',1,1,'Channel4.Receiving1.K0006.03',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(121,'Receiving1_ThreeWays2_Right',1,1,'Channel4.Receiving1.K0006.02',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(122,'Receiving2_LegCUR102_Digi',8,4,'Channel4.Receiving1.R0020',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(123,'Receiving2_LegCUR106_Digi',8,4,'Channel4.Receiving1.R0012',20001,'','\0',NULL,NULL,0.00,0.00,0,NULL),(124,'Receiving1_Conveyor1_Alarm',1,1,'Channel4.Receiving2.K0002.11',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(125,'Receiving1_Conveyor1_Running',1,1,'Channel4.Receiving2.K0002.10',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(126,'Receiving1_Conveyor2_Alarm',1,1,'Channel4.Receiving2.K0002.09',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(127,'Receiving1_Conveyor2_Running',1,1,'Channel4.Receiving2.K0002.04',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(128,'Receiving1_Gate1_Alarm',1,1,'Channel4.Receiving2.K0001.14',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(129,'Receiving1_Gate1_Cls',1,1,'Channel4.Receiving2.K0001.13',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(130,'Receiving1_Gate1_Ols',1,1,'Channel4.Receiving2.K0001.11',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(131,'Receiving1_Gate2_Alarm',1,1,'Channel4.Receiving2.K0001.08',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(132,'Receiving1_Gate2_Cls',1,1,'Channel4.Receiving2.K0001.09',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(133,'Receiving1_Gate2_Ols',1,1,'Channel4.Receiving2.K0001.10',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(134,'Receiving2_Airport1_Alarm',1,1,'Channel4.Receiving2.K0002.08',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(135,'Receiving2_Airport1_Running',1,1,'Channel4.Receiving2.K0001.05',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(136,'Receiving2_Airport2_Alarm',1,1,'Channel4.Receiving2.K0001.00',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(137,'Receiving2_Airport2_Running',1,1,'Channel4.Receiving2.K0001.01',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(138,'Receiving2_AlmAck',1,1,'Channel4.Receiving2.K0002.02',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(139,'Receiving2_Converyor1_Running',1,1,'Channel4.Receiving2.K0001.15',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(140,'Receiving2_Converyor2_Alarm',1,1,'Channel4.Receiving2.K0002.12',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(141,'Receiving2_Converyor2_Running',1,1,'Channel4.Receiving2.K0002.13',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(142,'Receiving2_Fan1_Alarm',1,1,'Channel4.Receiving2.K0001.02',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(143,'Receiving2_Fan1_Running',1,1,'Channel4.Receiving2.K0001.03',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(144,'Receiving2_Gate1_Alarm',1,1,'Channel4.Receiving2.K0001.04',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(145,'Receiving2_Gate1_Cls',1,1,'Channel4.Receiving2.K0001.06',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(146,'Receiving2_Gate1_Ols',1,1,'Channel4.Receiving2.K0001.07',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(147,'Receiving2_Gate2_Ols',1,1,'Channel4.Receiving2.K0002.05',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(148,'Receiving2_LegMotor1_Overload',8,4,'Channel4.Receiving2.R0008',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(149,'Receiving2_Legmotor1Speed_Speed',8,4,'Channel4.Receiving2.R0012',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(150,'Receiving2_LegMotor2_Overload',8,4,'Channel4.Receiving2.R0000',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(151,'Receiving2_LegMotor2_Running',1,1,'Channel4.Receiving2.K0002.01',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(152,'Receiving2_Legmotor2Speed_Speed',8,4,'Channel4.Receiving2.R0004',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(153,'Receiving2_LocalRemote',1,1,'Channel4.Receiving2.K0002.03',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(154,'Receiving2_MagicRoll1_Alarm',1,1,'Channel4.Receiving2.K0002.14',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(155,'Receiving2_MagicRoll1_Running',1,1,'Channel4.Receiving2.K0002.00',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(156,'Receiving2_Sifter1_Alarm',1,1,'Channel4.Receiving2.K0002.15',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(157,'Receiving2_Sifter1_Running',1,1,'Channel4.Receiving2.K0002.07',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL),(158,'Receiving2_Sifter1_Running8',1,1,'Channel4.Receiving2.K0002.07',20002,'','\0',NULL,NULL,0.00,0.00,0,NULL); +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `registermodule` ( + `DriverID` int(10) NOT NULL AUTO_INCREMENT, + `AssemblyName` varchar(255) DEFAULT NULL, + `ClassName` varchar(50) DEFAULT NULL, + `ClassFullName` varchar(128) DEFAULT NULL, + `Description` varchar(50) DEFAULT NULL, + UNIQUE KEY `DriverID` (`DriverID`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; +INSERT INTO `registermodule` VALUES (4,'E:\\SCADA\\dll\\OPCDriver.dll','OPCReader','OPCDriver.OPCReader','OPC鍗忚'),(5,'E:\\SCADA\\dll\\FileDriver.dll','DataBaseReader','FileDriver.DataBaseReader','SQL 鏁版嵁搴'),(6,'E:\\SCADA\\dll\\FileDriver.dll','TagDriver','FileDriver.TagDriver','鏍囩鐩存帴璇诲啓'),(8,'E:\\SCADA\\dll\\ModbusDriver.dll','ModbusRTUReader','ModbusDriver.ModbusRTUReader','Modbus RTU鍗忚'),(9,'E:\\SCADA\\dll\\ModbusDriver.dll','ModbusTCPReader','ModbusDriver.ModbusTCPReader','Modbus Tcp鍗忚'),(10,'E:\\SCADA\\dll\\SiemensPLCDriver.dll','SiemensTCPReader','SiemensPLCDriver.SiemensTCPReader','S7 浠ュお缃戝崗璁'); +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `AddEventLog`(IN pStartTime DATETIME, + IN pSource NVARCHAR(50) , + IN pComment NVARCHAR(50)) +BEGIN +IF pComment<>IFNULL((SELECT Comment FROM LOG_EVENT WHERE EVENTTYPE=2 AND Source=Source ORDER BY SQLCOUNTER DESC LIMIT 1),'') THEN + INSERT INTO LOG_EVENT(EVENTTYPE,SEVERITY,ACTIVETIME,SOURCE,COMMENT) VALUES(2,0,pStartTime,pSource,pComment); +END IF; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `GetAlarm`(IN pStartTime DATETIME, + IN pEndTime DATETIME ) +BEGIN +SELECT StartTime,AlarmText,AlarmValue,SubAlarmType,Severity,ConditionID,Source,Duration FROM LOG_ALARM WHERE StartTime BETWEEN pStartTime AND pEndTime ORDER BY StartTime; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `GetEventTime`(IN pEVENTTYPE int, + IN pSOURCE nvarchar(50), + IN pCOMMENT nvarchar(50), + OUT pSTARTTIME DATETIME, + OUT pENDTIME DATETIME) +BEGIN +DECLARE _ID INT DEFAULT 0; + +SELECT SQLCOUNTER,ACTIVETIME INTO _ID,pSTARTTIME FROM LOG_EVENT WHERE EVENTTYPE=pEVENTTYPE AND SOURCE=pSOURCE AND COMMENT=pCOMMENT ORDER BY ACTIVETIME DESC LIMIT 1; + +SET @sql = CONCAT('SELECT ACTIVETIME INTO ', pENDTIME, ' FROM LOG_EVENT WHERE EVENTTYPE = "', + pEVENTTYPE, '" AND SOURCE = "', pSOURCE, '" AND SQLCOUNTER> ',_ID,' ORDER BY ACTIVETIME DESC LIMIT 1'); + PREPARE stmt FROM @sql; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `InitServer`(IN pTYPE int) +BEGIN + + IF pTYPE<>1 THEN + SELECT M.DRIVERID,DRIVERNAME,SERVER,TIMEOUT,R.AssemblyName,R.ClassFullName,Spare1,Spare2 FROM META_DRIVER M INNER JOIN RegisterModule R ON M.DRIVERTYPE=R.DriverID; + END IF; + + SELECT COUNT(*) FROM META_TAG; + + SELECT TAGID,GROUPID,RTRIM(TAGNAME),ADDRESS,DATATYPE,DATASIZE,ARCHIVE,MAXIMUM,MINIMUM,CYCLE FROM META_TAG WHERE ISACTIVE=1; + + IF pTYPE<>1 THEN + SELECT DRIVERID,GROUPNAME,GROUPID,UPDATERATE,DEADBAND,ISACTIVE FROM META_GROUP ; + END IF; + + IF pTYPE=0 THEN + SELECT SOURCE FROM META_Condition WHERE EVENTTYPE=2; + END IF; + + IF pTYPE<>2 THEN + SELECT TYPEID,SOURCE,ALARMTYPE,A.ISENABLED,CONDITIONTYPE,PARA,IFNULL(COMMENT,''),DEADBAND,DELAY,SUBALARMTYPE,Threshold,SEVERITY, + IFNULL(MESSAGE,''),B.ISENABLE FROM META_Condition a LEFT OUTER JOIN META_SUBCONDITION b ON a.TypeID=b.ConditionID WHERE EVENTTYPE<>2; + END IF; + + + SELECT SCALEID,SCALETYPE,EUHI,EULO,RAWHI,RAWLO FROM META_SCALE; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `ReadALL`(IN pGroupID SMALLINT) +BEGIN + +SELECT COUNT(*) FROM META_TAG WHERE GROUPID=pGroupID AND IsActive=1; +SELECT TAGID,DATATYPE,IFNULL(DEFAULTVALUE,0) FROM META_TAG WHERE IsActive=1 AND GROUPID=pGroupID ORDER BY TAGID; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `ReadHData`(IN pStartTime DATETIME, + IN pEndTime DATETIME, + IN pID INT) +BEGIN + + IF pID IS NULL THEN + SELECT ID,TIMESTAMP,VALUE,M.DATATYPE FROM LOG_HDATA L INNER JOIN META_TAG M ON L.ID=M.TAGID WHERE TIMESTAMP BETWEEN pStartTime AND pEndTime ORDER BY ID,TIMESTAMP; + ELSE + SELECT TIMESTAMP,VALUE,M.DATATYPE FROM LOG_HDATA L INNER JOIN META_TAG M ON L.ID=M.TAGID WHERE ID=pID AND TIMESTAMP BETWEEN pStartTime AND pEndTime ORDER BY TIMESTAMP; + + END IF; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `ReadValueByID`(IN pID SMALLINT, + IN pDATATYPE TinyInt) +BEGIN + + + + + + + + + + + + + + + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `UpdateValueByID`(IN pID SMALLINT, + IN pValue varchar(50)) +BEGIN + + UPDATE META_TAG SET DEFAULTVALUE=pValue WHERE TAGID=pID; + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8 */ ; +/*!50003 SET character_set_results = utf8 */ ; +/*!50003 SET collation_connection = utf8_general_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO' */ ; +DELIMITER ;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `WriteHData`(IN pDATE DATETIME) +BEGIN + + + + + + + +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; diff --git a/SCADA/Program/CoreApp/DataService/.vs/DataService/v15/Server/sqlite3/db.lock b/SCADA/Program/CoreApp/DataService/.vs/DataService/v15/Server/sqlite3/db.lock new file mode 100644 index 0000000..e69de29 diff --git a/SCADA/Program/CoreApp/DataService/.vs/DataService/v15/Server/sqlite3/storage.ide b/SCADA/Program/CoreApp/DataService/.vs/DataService/v15/Server/sqlite3/storage.ide new file mode 100644 index 0000000..ddff1c1 Binary files /dev/null and b/SCADA/Program/CoreApp/DataService/.vs/DataService/v15/Server/sqlite3/storage.ide differ diff --git a/SCADA/Program/CoreApp/DataService/ClientDriver/ClientDriver.cs b/SCADA/Program/CoreApp/DataService/ClientDriver/ClientDriver.cs new file mode 100644 index 0000000..f80f146 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/ClientDriver/ClientDriver.cs @@ -0,0 +1,1129 @@ +锘縰sing System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using DataService; + +namespace ClientDriver +{ + [Description("瀹㈡埛绔┍鍔")] + public class ClientReader : IDriver//瀹㈡埛绔瓨鍦ㄥTLV鏁版嵁鐨勫瓧鑺傚簭杞崲闂锛岄渶娴嬭瘯 + { + short _id; + public short ID + { + get + { + return _id; + } + } + + private int _timeout = 0; + public int TimeOut + { + get { return _timeout; } + set { _timeout = value; } + } + + string _name; + public string Name + { + get + { + return _name; + } + } + + string _ip; + public string ServerName + { + get { return _ip; } + set { _ip = value; } + } + + internal Socket tcpSend; + internal Socket tcpRecive; + + public bool IsClosed + { + get + { + //return tcpASynCl.Poll(-1, SelectMode.SelectRead); + return tcpSend == null || tcpRecive == null || !tcpSend.Connected || !tcpRecive.Connected; + } + } + + List _grps = new List(1); + public IEnumerable Groups + { + get { return _grps; } + } + + IDataServer _server; + public IDataServer Parent + { + get { return _server; } + } + + public ClientReader(IDataServer server, short id, string name, string ip, int timeout) + { + _id = id; + _server = server; + _ip = ip; + _name = name; + _timeout = timeout; + Connect(); + } + + public bool Connect() + { + int port = 6543; + lock (this) + { + try + { + if (tcpRecive != null) + { + tcpRecive.Dispose(); + } + if (tcpSend != null) + { + tcpSend.Dispose(); + } + tcpRecive = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + tcpRecive.Connect(_ip, port); + tcpRecive.SendTimeout = _timeout; + tcpRecive.ReceiveTimeout = -1; + + tcpSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + tcpSend.Connect(_ip, port); + tcpSend.SendTimeout = _timeout; + tcpSend.ReceiveTimeout = _timeout; + return true; + } + catch (SocketException error) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(error.Message)); + return false; + } + } + } + + public IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false) + { + ClientGroup grp = new ClientGroup(id, name, updateRate, active, this); + _grps.Add(grp); + return grp; + } + + public bool RemoveGroup(IGroup grp) + { + grp.IsActive = false; + return _grps.Remove(grp); + } + + public event ShutdownRequestEventHandler OnClose; + + public void Dispose() + { + foreach (IGroup grp in _grps) + { + grp.Dispose(); + } + _grps.Clear(); + try + { + if (tcpRecive != null) + { + if (tcpRecive.Connected) + tcpRecive.Shutdown(SocketShutdown.Both); + tcpRecive.Dispose(); + } + if (tcpSend != null) + { + if (tcpSend.Connected) + tcpSend.Shutdown(SocketShutdown.Both); + tcpSend.Dispose(); + } + } + catch (SocketException err) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(err.Message)); + } + } + } + + public class ClientGroup : IGroup + { + bool _active = false; + public bool IsActive + { + get + { + return _active; + } + set + { + _active = value; + if (value) + { + if (_plcReader != null && _plcReader.tcpSend != null) + { + this._tcpRecive = _plcReader.tcpRecive; + this._tcpSend = _plcReader.tcpSend; + try + { + _addr = (_tcpSend.RemoteEndPoint as IPEndPoint).Address; + } + catch { } + Thread workItem = new Thread(new ThreadStart(ReciveData)); + workItem.Priority = ThreadPriority.Highest; + workItem.Start(); + if (_updateRate > 0) + ThreadPool.QueueUserWorkItem(new WaitCallback(this.OnUpdate)); + else + Init(); + } + } + } + } + + protected short _id; + public short ID + { + get + { + return _id; + } + } + + protected int _updateRate; + public int UpdateRate + { + get + { + return _updateRate; + } + set + { + _updateRate = value; + } + } + + protected DeviceAddress _start; + public DeviceAddress Start + { + get + { + return _start; + } + } + + protected string _name; + public string Name + { + get + { + return _name; + } + set + { + _name = value; + } + } + + protected float _deadband; + public float DeadBand + { + get + { + return _deadband; + } + set + { + _deadband = value; + } + } + + protected ClientReader _plcReader; + public IDriver Parent + { + get + { + return _plcReader; + } + } + + protected Dictionary _items; + public IEnumerable Items + { + get { return _items.Values; } + } + + IDataServer _server; + public IDataServer Server + { + get + { + return _server; + } + } + + Socket _tcpSend, _tcpRecive; + byte[] tcpBuffer; + + IPAddress _addr; + public IPAddress RemoteAddress + { + get { return _addr; } + } + + public ClientGroup(short id, string name, int updateRate, bool active, ClientReader plcReader) + { + this._id = id; + this._name = name; + this._updateRate = updateRate; + this._active = active; + this._plcReader = plcReader; + this._server = plcReader.Parent; + tcpBuffer = new byte[8192]; + } + + object sendasync = new object(); + private byte[] ReadSingleData(DeviceAddress address, DataSource source = DataSource.Cache) + { + if (_tcpSend == null) return null; + short ID = (short)address.Start; + byte type = (byte)address.VarType; + byte len = (byte)(address.DataSize); + byte[] idbits = BitConverter.GetBytes(ID); + byte[] write_data = new byte[6] { FCTCOMMAND.fctHead, FCTCOMMAND.fctReadSingle, + source == DataSource.Cache?(byte)0:(byte)1, idbits[0], idbits[1] ,len}; + byte[] data = new byte[len]; + SocketError error; + lock (sendasync) + { + _tcpSend.Send(write_data, 0, 6, SocketFlags.None, out error); + int result = _tcpSend.Receive(tcpBuffer, 0, data.Length + 5, SocketFlags.None, out error); + } + Array.Copy(tcpBuffer, 5, data, 0, data.Length); + if (error == SocketError.Success) + return data; + else + { + return null; + } + } + + private int WriteSingleData(DeviceAddress address, byte[] value) + { + if (_tcpSend == null) return -1; + short ID = (short)address.Start; + byte type = (byte)address.VarType; + byte[] idbits = BitConverter.GetBytes(ID); + byte[] write_data = new byte[6] { FCTCOMMAND.fctHead, FCTCOMMAND.fctWriteSingle, 1, idbits[0], idbits[1], (byte)(value.Length) }; + byte[] data = new byte[6 + value.Length]; + write_data.CopyTo(data, 0); + value.CopyTo(data, 6); + SocketError error; + lock (sendasync) + { + _tcpSend.Send(data, 0, data.Length, SocketFlags.None, out error); + _tcpSend.Receive(tcpBuffer, 0, 2, SocketFlags.None, out error); + } + if (error == SocketError.Success) + return tcpBuffer[1];//鍙湪姝ゅ杩斿洖涓涓敊璇彿 + else + { + return (int)error; + } + } + + public void Init() + { + if (_items != null && _tcpSend != null) + { + int len = 0; + List tags = new List(); + foreach (var tag in _items.Values) + { + len += (3 + tag.Address.DataSize); + if (len >= tcpBuffer.Length - 10) + { + len = 0; + BatchRead(DataSource.Cache, true, tags.ToArray()); + tags.Clear(); + } + tags.Add(tag); + } + BatchRead(DataSource.Cache, true, tags.ToArray()); + } + } + + private void ReciveData() + { + if (!_active || _plcReader.tcpRecive == null) return; + List historys = null; + byte[] bytes = new byte[ushort.MaxValue]; + byte[] temp = new byte[_tcpRecive.ReceiveBufferSize]; + Storage value = Storage.Empty; + int result = 0; + int start = 0; + SocketError error; + do + { + if (!_tcpRecive.Connected) return; + result = _tcpRecive.Receive(bytes, 0, bytes.Length, SocketFlags.None, out error); + if (error == SocketError.Success) + { + if (DataChange != null) + historys = new List(); + //DateTime time = DateTime.Now;//褰撳墠鏃堕棿鎴 + if (start != 0 && temp[0] == FCTCOMMAND.fctHead) + { + int j = 3; + if (start < 0) + { + Array.Copy(bytes, 0, temp, -start, 5 + start); + } + short tc = BitConverter.ToInt16(temp, j);//鎬诲瓧鑺傛暟 + if (start < 0) + start += tc; + Array.Copy(bytes, 0, temp, tc - start, start); + j += 2; + while (j < tc) + { + short id = BitConverter.ToInt16(temp, j);//鏍囩ID銆佹暟鎹暱搴︺佹暟鎹硷紙T,L,V) + j += 2; + byte length = temp[j++]; + ITag tag; + if (_items.TryGetValue(id, out tag)) + { + //鏁版嵁绫诲瀷 + switch (tag.Address.VarType) + { + case DataType.BOOL: + value.Boolean = BitConverter.ToBoolean(temp, j); + break; + case DataType.BYTE: + value.Byte = temp[j]; + break; + case DataType.WORD: + case DataType.SHORT: + value.Int16 = BitConverter.ToInt16(temp, j);//闇娴嬭瘯 + break; + case DataType.INT: + value.Int32 = BitConverter.ToInt32(temp, j);//闇娴嬭瘯 + break; + case DataType.FLOAT: + value.Single = BitConverter.ToSingle(temp, j); + break; + case DataType.STR: + StringTag strTag = tag as StringTag; + if (strTag != null) + { + strTag.String = Encoding.ASCII.GetString(temp, j, length).Trim((char)0); + } + break; + default: + break; + } + j += length; + DateTime time = DateTime.FromFileTime(BitConverter.ToInt64(temp, j)); + j += 8; + tag.Update(value, time, QUALITIES.QUALITY_GOOD); + if (historys != null) + historys.Add(new HistoryData(id, QUALITIES.QUALITY_GOOD, value, time)); + } + else + j += length + 8; + } + } + byte head = bytes[start]; + int count = start; + while (head == FCTCOMMAND.fctHead && result > count) + { + if (count + 5 > bytes.Length) + { + start = count - bytes.Length; + Array.Copy(bytes, count, temp, 0, -start); + break; + } + int j = count + 3; + short tc = BitConverter.ToInt16(bytes, j);//鎬绘爣绛炬暟 + count += tc; + if (count >= bytes.Length) + { + start = count - bytes.Length; + Array.Copy(bytes, count - tc, temp, 0, tc - start); + break; + } + else start = 0; + j += 2; + while (j < count) + { + short id = BitConverter.ToInt16(bytes, j);//鏍囩ID銆佹暟鎹暱搴︺佹暟鎹硷紙T,L,V) + j += 2; + byte length = bytes[j++]; + ITag tag; + if (_items.TryGetValue(id, out tag)) + { + //鏁版嵁绫诲瀷 + switch (tag.Address.VarType) + { + case DataType.BOOL: + value.Boolean = BitConverter.ToBoolean(bytes, j); + break; + case DataType.BYTE: + value.Byte = bytes[j]; + break; + case DataType.WORD: + case DataType.SHORT: + value.Int16 = BitConverter.ToInt16(bytes, j);//闇娴嬭瘯 + break; + case DataType.INT: + value.Int32 = BitConverter.ToInt32(bytes, j);//闇娴嬭瘯 + break; + case DataType.FLOAT: + value.Single = BitConverter.ToSingle(bytes, j); + break; + case DataType.STR: + StringTag strTag = tag as StringTag; + if (strTag != null) + { + strTag.String = Encoding.ASCII.GetString(bytes, j, length).Trim((char)0); + } + break; + default: + break; + } + j += length; + DateTime time = DateTime.FromFileTime(BitConverter.ToInt64(bytes, j)); + j += 8; + tag.Update(value, time, QUALITIES.QUALITY_GOOD); + if (historys != null) + historys.Add(new HistoryData(id, QUALITIES.QUALITY_GOOD, value, time)); + } + else + j += length + 8; + } + head = bytes[count]; + } + if (DataChange != null && historys.Count > 0) + DataChange(this, new DataChangeEventArgs(1, historys)); + + } + else if (error == SocketError.ConnectionReset || error == SocketError.Interrupted + || error == SocketError.HostDown || error == SocketError.NetworkDown || error == SocketError.Shutdown) + { + _tcpRecive.Dispose(); + _active = false; + return; + } + } + while (result > 0); + } + + public void OnUpdate(object stateInfo) + { + while (true) + { + Thread.Sleep(_updateRate); + lock (this) + { + if (!_active) + { + return; + } + Init(); + } + } + } + + public bool AddItems(IList items) + { + int count = items.Count; + if (_items == null) _items = new Dictionary(count); + lock (_server.SyncRoot) + { + for (int i = 0; i < count; i++) + { + ITag dataItem = null; + TagMetaData meta = items[i]; + DeviceAddress addr = new DeviceAddress(0, 0, 0, meta.ID, meta.Size, 0, meta.DataType); + switch (meta.DataType) + { + case DataType.BOOL: + dataItem = new BoolTag(meta.ID, addr, this); + break; + case DataType.BYTE: + dataItem = new ByteTag(meta.ID, addr, this); + break; + case DataType.WORD: + case DataType.SHORT: + dataItem = new ShortTag(meta.ID, addr, this); + break; + case DataType.TIME: + case DataType.INT: + dataItem = new IntTag(meta.ID, addr, this); + break; + case DataType.FLOAT: + dataItem = new FloatTag(meta.ID, addr, this); + break; + case DataType.STR: + dataItem = new StringTag(meta.ID, addr, this); + break; + default: + dataItem = new BoolTag(meta.ID, addr, this); + break; + } + _items.Add(meta.ID, dataItem); + _server.AddItemIndex(meta.Name, dataItem); + } + } + //Init(); + return true; + } + + public bool AddTags(IEnumerable tags) + { + if (_items == null) + { + _items = new Dictionary(); + } + foreach (ITag tag in tags) + { + if (tag != null) + { + _items.Add(tag.ID, tag); + } + } + //Init(); + return true; + } + + public bool RemoveItems(params ITag[] items) + { + foreach (var item in items) + { + _server.RemoveItemIndex(item.GetTagName()); + _items.Remove(item.ID); + } + return true; + } + + public bool SetActiveState(bool active, params short[] items) + { + return true; + } + + public ITag FindItemByAddress(DeviceAddress addr) + { + ITag tag; + if (_items.TryGetValue((short)addr.Start, out tag)) + return tag; + return _server[(short)addr.Start]; + } + + public HistoryData[] BatchRead(DataSource source, bool isSync, params ITag[] itemArray) + { + if (itemArray.Length == 0 || _tcpSend == null || !_tcpSend.Connected) return null; + short len = (short)itemArray.Length; + byte[] bt = new byte[2]; + byte[] data = new byte[5 + len * 2]; + int j = 0; + data[j++] = FCTCOMMAND.fctHead; + data[j++] = FCTCOMMAND.fctReadMultiple; + data[j++] = source == DataSource.Cache ? (byte)0 : (byte)1; + bt = BitConverter.GetBytes(len); + data[j++] = bt[0]; + data[j++] = bt[1]; + for (int i = 0; i < len; i++) + { + bt = BitConverter.GetBytes(itemArray[i].ID); + data[j++] = bt[0]; + data[j++] = bt[1]; + } + SocketError error; + lock (sendasync) + { + _tcpSend.Send(data, 0, data.Length, SocketFlags.None, out error); + int result = _tcpSend.Receive(tcpBuffer, 0, tcpBuffer.Length, SocketFlags.None, out error); + } + //锛侊紒锛侊紒姝ゅ鐨勫崗璁簲娉ㄦ剰锛屽鎵归噺璇诲叆鐨勬暟鎹噺瓒呰繃缂撳瓨锛屽繀椤诲垎鎵瑰悎骞讹紱鍦ㄥ崗璁ご搴斿姞鍏ユ诲瓧鑺傛暟锛屼互鍜宺esult姣旇緝鏄惁闇瑕佸惊鐜鍏ャ + j = 5; + if (error == SocketError.Success) + { + DateTime time = DateTime.Now; + HistoryData[] values = new HistoryData[len]; + for (int i = 0; i < len; i++) + { + short id = BitConverter.ToInt16(tcpBuffer, j); + j += 2; + ITag tag = _server[id]; + byte length = tcpBuffer[j++]; + if (tag != null && length > 0) + { + switch (tag.Address.VarType) + { + case DataType.BOOL: + values[i].Value.Boolean = BitConverter.ToBoolean(tcpBuffer, j); + break; + case DataType.BYTE: + values[i].Value.Byte = tcpBuffer[j]; + break; + case DataType.WORD: + case DataType.SHORT: + values[i].Value.Int16 = BitConverter.ToInt16(tcpBuffer, j); + break; + case DataType.INT: + values[i].Value.Int32 = BitConverter.ToInt32(tcpBuffer, j); + break; + case DataType.FLOAT: + values[i].Value.Single = BitConverter.ToSingle(tcpBuffer, j); + break; + case DataType.STR: + StringTag strTag = tag as StringTag; + if (strTag != null) + { + strTag.String = Encoding.ASCII.GetString(tcpBuffer, j, length).Trim(); + } + break; + } + if (values[i].Value != tag.Value) + tag.Update(values[i].Value, time, QUALITIES.QUALITY_GOOD); + } + j += length; + } + return values; + } + else + return null; + } + + public int BatchWrite(SortedDictionary items, bool isSync = true) + { + if (_tcpSend == null || !_tcpSend.Connected) return -1; + List list = new List(new byte[] { FCTCOMMAND.fctHead, FCTCOMMAND.fctWriteMultiple }); + list.AddRange(BitConverter.GetBytes((short)items.Count)); + foreach (var item in items) + { + ITag tag = item.Key; + list.AddRange(BitConverter.GetBytes(tag.ID)); + var addr = tag.Address; + if (addr.VarType != DataType.STR) + list.Add((byte)(addr.DataSize));//姝ゅ瀛樼枒 + switch (addr.VarType) + { + case DataType.BOOL: + list.Add(Convert.ToBoolean(item.Value) ? (byte)1 : (byte)0); + break; + case DataType.BYTE: + list.Add(Convert.ToByte(item.Value)); + break; + case DataType.WORD: + case DataType.SHORT: + list.AddRange(BitConverter.GetBytes(Convert.ToInt16(item.Value))); + break; + case DataType.INT: + list.AddRange(BitConverter.GetBytes(Convert.ToInt32(item.Value))); + break; + case DataType.FLOAT: + list.AddRange(BitConverter.GetBytes(Convert.ToSingle(item.Value))); + break; + case DataType.STR: + var bts = Encoding.ASCII.GetBytes(Convert.ToString(item.Value)); + list.Add((byte)bts.Length); + list.AddRange(bts); + break; + } + } + SocketError error; + lock (sendasync) + { + _tcpSend.Send(list.ToArray(), 0, list.Count, SocketFlags.None, out error); + _tcpSend.Receive(tcpBuffer, 0, 2, SocketFlags.None, out error); + } + if (error == SocketError.Success) + return tcpBuffer[1]; + else + { + return (int)error; + } + } + + public IEnumerable SendHdaRequest(DateTime start, DateTime end) + { + if (_tcpSend == null || !_tcpSend.Connected) yield break; + byte[] hdaReq = new byte[18]; + hdaReq[0] = FCTCOMMAND.fctHead; + hdaReq[1] = FCTCOMMAND.fctHdaRequest; + byte[] startbuffer = BitConverter.GetBytes(start.ToFileTime()); + startbuffer.CopyTo(hdaReq, 2); + byte[] endbuffer = BitConverter.GetBytes(end.ToFileTime()); + endbuffer.CopyTo(hdaReq, 10); + SocketError error; + HistoryData data = HistoryData.Empty; + short tempid = short.MinValue; + byte[] temp = new byte[14]; + ITag tag = null; + int index = 0; + int size = 0; + int result = 0; + short id = 0; + lock (sendasync) + { + _tcpSend.Send(hdaReq); + do + { + result = _tcpSend.Receive(tcpBuffer, 0, tcpBuffer.Length, SocketFlags.None, out error); + if (error == SocketError.ConnectionReset || error == SocketError.Interrupted || error == SocketError.HostDown || error == SocketError.NetworkDown || error == SocketError.Shutdown) + { + _tcpSend.Dispose(); + yield break; + } + if (index != 0) + { + Array.Copy(tcpBuffer, 0, temp, 14 - index, index); + id = BitConverter.ToInt16(temp, 0); + tempid = id; + tag = _server[id]; + if (tag == null) yield break; + data.ID = id; + size = tag.Address.DataSize; + index -= (4 - size); + switch (tag.Address.VarType) + { + case DataType.BOOL: + data.Value.Boolean = BitConverter.ToBoolean(temp, 2); + break; + case DataType.BYTE: + data.Value.Byte = tcpBuffer[index]; + break; + case DataType.WORD: + case DataType.SHORT: + data.Value.Int16 = BitConverter.ToInt16(temp, 2); + break; + case DataType.TIME: + case DataType.INT: + data.Value.Int32 = BitConverter.ToInt32(temp, 2); + break; + case DataType.FLOAT: + data.Value.Single = BitConverter.ToSingle(temp, 2); + break; + } + long fileTime = BitConverter.ToInt64(temp, 2 + size); + if (fileTime == -1) yield break; + data.TimeStamp = DateTime.FromFileTime(fileTime); + yield return data; + } + while (result >= index + 2) + { + id = BitConverter.ToInt16(tcpBuffer, index); + if (tempid != id) + { + tempid = id; + tag = _server[id]; + if (tag == null) yield break; + size = tag.Address.DataSize; + } + if (index + 10 + size > result) + break; + data.ID = id; + index += 2; + switch (tag.Address.VarType) + { + case DataType.BOOL: + data.Value.Boolean = BitConverter.ToBoolean(tcpBuffer, index); + break; + case DataType.BYTE: + data.Value.Byte = tcpBuffer[index]; + break; + case DataType.WORD: + case DataType.SHORT: + data.Value.Int16 = BitConverter.ToInt16(tcpBuffer, index); + break; + case DataType.TIME: + case DataType.INT: + data.Value.Int32 = BitConverter.ToInt32(tcpBuffer, index); + break; + case DataType.FLOAT: + data.Value.Single = BitConverter.ToSingle(tcpBuffer, index); + break; + } + index += size; + long fileTime = BitConverter.ToInt64(tcpBuffer, index); + if (fileTime == -1) yield break; + data.TimeStamp = DateTime.FromFileTime(fileTime); + index += 8; + yield return data; + } + if (index == result) + index = 0; + else + { + Array.Copy(tcpBuffer, index, temp, 0, result - index); + index += 14 - result; + } + } while (result > 0); + } + yield break; + } + + public IEnumerable SendHdaRequest(DateTime start, DateTime end, short id) + { + if (_tcpSend == null || !_tcpSend.Connected) yield break; + ITag tag = _server[id]; + if (tag == null) yield break; + byte[] hdaReq = new byte[20]; + hdaReq[0] = FCTCOMMAND.fctHead; + hdaReq[1] = FCTCOMMAND.fctHdaIdRequest; + byte[] startbuffer = BitConverter.GetBytes(start.ToFileTime()); + startbuffer.CopyTo(hdaReq, 2); + byte[] endbuffer = BitConverter.GetBytes(end.ToFileTime()); + endbuffer.CopyTo(hdaReq, 10); + byte[] idbuffer = BitConverter.GetBytes(id); + idbuffer.CopyTo(hdaReq, 18); + SocketError error; + int index = 0; + HistoryData data = HistoryData.Empty; + data.ID = id; + int result = 0; + lock (sendasync) + { + _tcpSend.Send(hdaReq); + switch (tag.Address.VarType) + { + case DataType.FLOAT: + do + { + result = _tcpSend.Receive(tcpBuffer, 0, tcpBuffer.Length, SocketFlags.None, out error); + if (error == SocketError.ConnectionReset || error == SocketError.Interrupted || error == SocketError.HostDown || error == SocketError.NetworkDown || error == SocketError.Shutdown) + { + _tcpSend.Dispose(); + yield break; + } + while (index + 12 <= result) + { + data.Value.Single = BitConverter.ToSingle(tcpBuffer, index);//鏈潵鍙冭檻閲忕▼杞崲鍜屽叾浠栨暟鎹被鍨 + index += 4; + long fileTime = BitConverter.ToInt64(tcpBuffer, index); + if (fileTime == -1) yield break; + data.TimeStamp = DateTime.FromFileTime(fileTime); + index += 8; + yield return data; + } + if (index == result) + index = 0; + else + index += 12 - result;//涓㈠純涓涓 + } while (result > 0); + break; + case DataType.INT: + do + { + result = _tcpSend.Receive(tcpBuffer, 0, tcpBuffer.Length, SocketFlags.None, out error); + if (error == SocketError.ConnectionReset || error == SocketError.Interrupted || error == SocketError.HostDown || error == SocketError.NetworkDown || error == SocketError.Shutdown) + { + _tcpSend.Dispose(); + yield break; + } + while (index + 12 <= result) + { + data.Value.Int32 = BitConverter.ToInt32(tcpBuffer, index);//鏈潵鍙冭檻閲忕▼杞崲鍜屽叾浠栨暟鎹被鍨 + index += 4; + long fileTime = BitConverter.ToInt64(tcpBuffer, index); + if (fileTime == -1) yield break; + data.TimeStamp = DateTime.FromFileTime(fileTime); + index += 8; + yield return data; + } + if (index == result) + index = 0; + else + index += 12 - result;//涓㈠純涓涓 + } while (result > 0); + break; + case DataType.BOOL://甯冨皵閲忎竴涓兘涓嶈兘灏 + { + byte[] temp = new byte[9]; + do + { + result = _tcpSend.Receive(tcpBuffer, 0, tcpBuffer.Length, SocketFlags.None, out error); + if (error == SocketError.ConnectionReset || error == SocketError.Interrupted || error == SocketError.HostDown || error == SocketError.NetworkDown || error == SocketError.Shutdown) + { + _tcpSend.Dispose(); + yield break; + } + if (index != 0) + { + Array.Copy(tcpBuffer, 0, temp, 9 - index, index); + data.Value.Boolean = BitConverter.ToBoolean(temp, 0); + long fileTime = BitConverter.ToInt64(temp, 1); + if (fileTime == -1) yield break; + data.TimeStamp = DateTime.FromFileTime(fileTime); + yield return data; + } + while (index + 9 <= result) + { + data.Value.Boolean = BitConverter.ToBoolean(tcpBuffer, index); + index += 1; + long fileTime = BitConverter.ToInt64(tcpBuffer, index); + if (fileTime == -1) yield break; + data.TimeStamp = DateTime.FromFileTime(fileTime); + index += 8; + yield return data; + } + if (index == result) + index = 0; + else + { + Array.Copy(tcpBuffer, index, temp, 0, result - index); + index += 9 - result; + } + } while (result > 0); + } + break; + } + } + } + + public int SendResetRequest() + { + if (_tcpSend != null && _tcpSend.Connected) + { + var ipaddr = (_tcpSend.LocalEndPoint as IPEndPoint).Address; + byte[] resetReq = new byte[6]; + resetReq[0] = FCTCOMMAND.fctHead; + resetReq[1] = FCTCOMMAND.fctReset; + ipaddr.GetAddressBytes().CopyTo(resetReq, 2); + lock (sendasync) + { + return _tcpSend.Send(resetReq); + } + } + return -1; + } + + public int SendAlarmRequest(DateTime? start, DateTime? end) + { + if (_tcpSend != null && _tcpSend.Connected) + { + byte[] alarmReq = new byte[18]; + alarmReq[0] = FCTCOMMAND.fctHead; + alarmReq[1] = FCTCOMMAND.fctAlarmRequest; + if (start.HasValue) + { + byte[] startbuffer = BitConverter.GetBytes(start.Value.ToFileTime()); + startbuffer.CopyTo(alarmReq, 2); + } + if (end.HasValue) + { + byte[] endbuffer = BitConverter.GetBytes(end.Value.ToFileTime()); + endbuffer.CopyTo(alarmReq, 10); + } + SocketError error; + lock (sendasync) + { + _tcpSend.Send(alarmReq); + _tcpSend.Receive(tcpBuffer, 0, 2, SocketFlags.None, out error); + } + return (int)error; + } + return -1; + } + + public ItemData ReadInt32(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt32(data, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt16(data, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(data[0], 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadFloat(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + if (data == null) + return new ItemData(0.0f, 0, QUALITIES.QUALITY_BAD); + else + { + int value = BitConverter.ToInt32(data, 0); + return new ItemData(*(((float*)&value)), 0, QUALITIES.QUALITY_GOOD); + } + } + + public ItemData ReadBool(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(false, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToBoolean(data, address.Bit), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(string.Empty, 0, QUALITIES.QUALITY_BAD) : + new ItemData(Encoding.ASCII.GetString(data, 0, Math.Min((int)address.DataSize, 254)).Trim((char)0), 0, QUALITIES.QUALITY_GOOD); + } + + public int WriteInt32(DeviceAddress address, int value) + { + return WriteSingleData(address, BitConverter.GetBytes(value)); + } + + public int WriteInt16(DeviceAddress address, short value) + { + return WriteSingleData(address, BitConverter.GetBytes(value)); + } + + public int WriteFloat(DeviceAddress address, float value) + { + return WriteSingleData(address, BitConverter.GetBytes(value)); + } + + public int WriteString(DeviceAddress address, string value) + { + return WriteSingleData(address, Encoding.ASCII.GetBytes(value)); + } + + public int WriteBit(DeviceAddress address, bool value) + { + return WriteSingleData(address, new byte[] { (byte)(value ? 1 : 0) }); + } + + public int WriteBits(DeviceAddress address, byte value) + { + return WriteSingleData(address, new byte[] { value }); + } + + public event DataChangeEventHandler DataChange; + + public void Dispose() + { + if (_items != null) + { + _items.Clear(); + } + _items = null; + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/ClientDriver/ClientDriver.csproj b/SCADA/Program/CoreApp/DataService/ClientDriver/ClientDriver.csproj new file mode 100644 index 0000000..45f8072 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/ClientDriver/ClientDriver.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp2.0 + + + + true + + + + + + + diff --git a/SCADA/Program/CoreApp/DataService/DataHelper/DataHelper.cs b/SCADA/Program/CoreApp/DataService/DataHelper/DataHelper.cs new file mode 100644 index 0000000..cd9ba9f --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataHelper/DataHelper.cs @@ -0,0 +1,198 @@ +锘縰sing Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Debug; +using MySql.Data.MySqlClient; +using System; +using System.Data; +using System.Data.Common; +using System.IO; +using System.Net; +using System.Text; + +namespace DatabaseLib +{ + public static class DataHelper + { + static string m_ConnStr = @"Data Source=.\SQLEXPRESS;Initial Catalog=SharpSCADA;Integrated Security=True"; + static string m_Path = @"D:\HDA"; + static string m_host = Environment.MachineName; + static string m_type = "MSSQL"; + //鏁版嵁搴撳伐鍘傛帴鍙 + const string CFGPATH = @"C:\DataConfig\host.cfg"; + const string INIPATH = @"C:\DataConfig\host.ini"; + const string DATALOGSOURCE = "Data Operations"; + const string DATALOGNAME = "Data Log"; + const int STRINGMAX = 255; + + static ILogger Log; + #region GetInstance + private static IDataFactory _ins; + + public static IDataFactory Instance + { + get + { + return _ins; + } + } + + public static string HostName + { + get { return m_host; } + } + + public static string ConnectString + { + get { return m_ConnStr; } + } + + public static string HdaPath + { + get { return m_Path; } + } + #endregion + /// + /// 鏁版嵁搴撳伐鍘傛瀯閫犲嚱鏁 + /// + /// 鏁版嵁搴撴灇涓 + static DataHelper() + { + var loggerFactory = new LoggerFactory(); + Func filter = (category, level) => true; + loggerFactory.AddProvider(new DebugLoggerProvider(filter)); + Log = loggerFactory.CreateLogger(DATALOGSOURCE); + try + { + if (File.Exists(INIPATH)) + { + var builder = new ConfigurationBuilder(); + var ibuild = builder.AddIniFile(INIPATH); + var root = ibuild.Build(); + var host = root.GetSection("HOST"); + m_host = host.GetSection("SERVER").Value; + var db = root.GetSection("DATABASE"); + m_ConnStr = db.GetSection("CONNSTRING").Value; + m_Path = db.GetSection("ARCHIVE").Value; + m_type = db.GetSection("TYPE").Value; + } + else if (File.Exists(CFGPATH)) + { + using (StreamReader objReader = new StreamReader(CFGPATH)) + { + m_host = objReader.ReadLine(); + m_ConnStr = objReader.ReadLine(); + m_Path = objReader.ReadLine(); + } + } + IPAddress addr; + if (string.IsNullOrEmpty(m_host) || !IPAddress.TryParse(m_host, out addr)) + { + m_host = Environment.MachineName; + } + _ins = new MysqlFactory(); + } + catch (Exception e) + { + AddErrorLog(e); + } + } + + public static DbParameter CreateParam(string paramName, SqlDbType dbType, object objValue, int size = 0, ParameterDirection direction = ParameterDirection.Input) + { + return _ins.CreateParam(paramName, dbType, objValue, size, direction); + } + + public static string DataTableToCsv(DataTable table) + { + //浠ュ崐瑙掗楀彿锛堝嵆,锛変綔鍒嗛殧绗︼紝鍒椾负绌轰篃瑕佽〃杈惧叾瀛樺湪銆 + //鍒楀唴瀹瑰瀛樺湪鍗婅閫楀彿锛堝嵆,锛夊垯鐢ㄥ崐瑙掑紩鍙凤紙鍗""锛夊皢璇ュ瓧娈靛煎寘鍚捣鏉ャ + //鍒楀唴瀹瑰瀛樺湪鍗婅寮曞彿锛堝嵆"锛夊垯搴旀浛鎹㈡垚鍗婅鍙屽紩鍙凤紙""锛夎浆涔夛紝骞剁敤鍗婅寮曞彿锛堝嵆""锛夊皢璇ュ瓧娈靛煎寘鍚捣鏉ャ + StringBuilder sb = new StringBuilder(); + DataColumn colum; + foreach (DataRow row in table.Rows) + { + for (int i = 0; i < table.Columns.Count; i++) + { + colum = table.Columns[i]; + if (i != 0) sb.Append(","); + var txt = row[colum] == null ? "" : row[colum].ToString(); + if (colum.DataType == typeof(string) && txt.Contains(",")) + { + sb.Append("\"" + txt.Replace("\"", "\"\"") + "\""); + } + else sb.Append(txt); + } + sb.AppendLine(); + } + return sb.ToString(); + } + + public static string ReaderToCsv(IDataReader reader) + { + StringBuilder sb = new StringBuilder(); + var colcount = reader.FieldCount; + while (reader.Read()) + { + for (int i = 0; i < colcount; i++) + { + if (i != 0) sb.Append(","); + var txt = reader[i] == null ? "" : reader[i].ToString(); + if (txt.Contains(",")) + { + sb.Append("\"" + txt.Replace("\"", "\"\"") + "\""); + } + else sb.Append(txt); + } + sb.AppendLine(); + } + return sb.ToString(); + } + + public static void AddErrorLog(Exception e) + { + string err = ""; + Exception exp = e; + while (exp != null) + { + err += string.Format("\n {0}", exp.Message); + exp = exp.InnerException; + } + err += string.Format("\n {0}", e.StackTrace); + Log.LogError(err); + } + + public static string GetNullableString(this DbDataReader reader, int index) + { + return reader.GetString(index); + } + + public static DateTime? GetNullableTime(this DbDataReader reader, int index) + { + return reader.GetDateTime(index); + } + + public static int GetTimeTick(this DbDataReader reader, int index) + { + var datetime = reader.GetDateTime(index); + var value = datetime.Subtract(new DateTime(1900, 1, 1)); + long num2 = value.Ticks - value.Days * 864000000000; + if (num2 < 0) + num2 += 864000000000; + int num3 = (int)(num2 / 10000.0 * 0.3 + 0.5); + if (num3 > 300 * 60 * 60 * 24 - 1) + num3 = 0; + return num3; + } + + public static object GetSqlValue(this DbDataReader reader, int index) + { + var mq = reader as MySqlDataReader; + if (mq != null) + { + return mq.GetValue(index); + } + return ""; + } + } + +} \ No newline at end of file diff --git a/SCADA/Program/CoreApp/DataService/DataHelper/DataHelper.csproj b/SCADA/Program/CoreApp/DataService/DataHelper/DataHelper.csproj new file mode 100644 index 0000000..085e74a --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataHelper/DataHelper.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp2.0 + + + + true + + + + + + + + + + + + + + diff --git a/SCADA/Program/CoreApp/DataService/DataHelper/HDAIOHelper.cs b/SCADA/Program/CoreApp/DataService/DataHelper/HDAIOHelper.cs new file mode 100644 index 0000000..c2a3903 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataHelper/HDAIOHelper.cs @@ -0,0 +1,927 @@ +锘縰sing DataService; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlTypes; +using System.IO; +using System.IO.MemoryMappedFiles; +using System.Runtime.InteropServices; +using System.Text; + +namespace DatabaseLib +{ + public class HDAIOHelper + { + static int[] dataLen = new int[] { 5, 5, 5, 5, 6, 6, 8, 8, 8, 8, 8, 8 }; + + static string m_Path = @"D:\HDA"; + + static HDAIOHelper() + { + m_Path = DataHelper.HdaPath; + } + + public static bool FindFile(DateTime date) + { + if (Directory.Exists(m_Path)) + { + return File.Exists(string.Concat(m_Path, "\\", date.Year.ToString(), "-", date.Month.ToString(), ".bin")); + } + return false; + } + + public static bool CreateFile(int year, int month) + { + string path = string.Concat(m_Path, "\\", year.ToString(), "-", month.ToString(), ".bin"); + try + { + if (Directory.Exists(m_Path)) + { + if (File.Exists(path)) + { + return true; + } + } + else + { + Directory.CreateDirectory(m_Path); + } + using (var stream = File.Create(path, 0x100)) + { + stream.Write(new byte[0x100], 0, 0x100); + return true; + } + } + catch (Exception err) + { + DataHelper.AddErrorLog(err); + return false; + } + } + + public static bool GetRangeFromDatabase(short? ID, ref DateTime start, ref DateTime end) + { + using (var reader = DataHelper.Instance.ExecuteReader("SELECT MIN(TIMESTAMP),MAX(TIMESTAMP) FROM LOG_HDATA" + (ID.HasValue ? " WHERE ID=" + ID.Value : ""))) + { + if (reader != null) + { + while (reader.Read()) + { + if (!reader.IsDBNull(0)) + start = reader.GetDateTime(0); + if (!reader.IsDBNull(1)) + end = reader.GetDateTime(1); + return true; + } + } + } + //start = end = DateTime.MinValue; + return false; + } + + public static void BackUpFile(DateTime date) + { + lock (typeof(HDAIOHelper)) + { + if (WriteToFile(date.AddDays(-1)) == 0) + { + DataHelper.Instance.ExecuteNonQuery(string.Format("DELETE FROM LOG_HDATA WHERE [TIMESTAMP]<='{0}';", date.ToShortDateString())); + } + } + } + + public static int WriteToFile(DateTime date)//姣忓ぉ鍑屾櫒鍐欏叆鏄ㄥぉ鐨勬暟鎹埌鏂囦欢锛屽彲浠ヨ冭檻鐢ㄦ湇鍔℃垨璁″垝浠诲姟;鏁版嵁搴撳彧淇濈暀褰撳ぉ鐨勮褰曪紱璋冨害绋嬪簭璐熻矗鍒犻櫎杩囨湡璁板綍;鍘嗗彶鏁版嵁搴旀敮鎸佸悎骞 + { + int year = date.Year; int month = date.Month; int day = date.Day; + string path = string.Concat(m_Path, "\\", year.ToString(), "-", month.ToString(), ".bin"); + if (CreateFile(year, month))//濡傝鏈堟枃浠朵笉瀛樺湪锛屽垯鍒涘缓锛涘惁鍒欏啓鍏 + { + using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + stream.Seek(day * 8, SeekOrigin.Begin);//鍏堣鍏ョ储寮曞尯锛屽畾浣嶅埌璇ユ棩鏈熺殑鎸囬拡 + byte[] bits = new byte[8]; + stream.Read(bits, 0, 8);//濡傛灉璇ヤ綅缃寚閽堜负>0鐨勬鏁帮紝璇存槑璇ュ尯鍩熷凡鏈夋暟鎹 + if (BitConverter.ToInt64(bits, 0) > 0) return -1; + } + using (var dataReader = DataHelper.Instance.ExecuteProcedureReader("WRITEHDATA", DataHelper.CreateParam("@DATE", SqlDbType.DateTime, date))) + { + if (dataReader == null) return -10; + else + { + dataReader.Read(); + int cont = dataReader.GetInt32(0);//璇诲叆鏍囩鏁伴噺 + if (cont == 0) return -2; + string path2 = path + ".temp"; + try + { + File.Copy(path, path2, true);//鍏堟妸鍘熸枃浠跺叏閮ㄥ鍒跺埌涓存椂鏂囦欢 + //Stopwatch sw = Stopwatch.StartNew(); + using (FileStream stream = File.Open(path2, FileMode.Open)) + { + //w.Seek(8 + day * 8, SeekOrigin.Begin); + //w.Seek(0x100, SeekOrigin.Begin); + long start = stream.Seek(0, SeekOrigin.End);//瀹氫綅鍒版枃浠舵湯灏 + long end = 0; + using (BinaryWriter w = new BinaryWriter(stream)) + { + w.Write(new SqlDateTime(date).DayTicks);//鍐欏叆鏃ユ湡 + w.Write(cont);///鍐欏叆鏍囩鏁伴噺 + int count = dataReader.GetInt32(1); + w.Write(count); + HDataFormat[] list = new HDataFormat[count]; + if (dataReader.NextResult()) + { + int p = 0; + int x = 0; + while (dataReader.Read())//鍐欏叆鏍囩鍏冩暟鎹 + { + short id = dataReader.GetInt16(0);//ID鍙 + byte type = dataReader.GetByte(1);//鏁版嵁绫诲瀷 + int cn = dataReader.GetInt32(2);//鏍囩涓暟 + //list[x].ID = id; + list[x].Type = (DataType)type; + list[x].Count = cn; + //list[x].Offset = p; + w.Write(id); + w.Write(type); + w.Write(cn); + w.Write(p); + p += cn * dataLen[type]; + x++; + } + if (dataReader.NextResult()) + { + for (int i = 0; i < list.Length; i++) + { + int len = list[i].Count; + for (int j = 0; j < len; j++) + { + if (dataReader.Read()) + { + w.Write(dataReader.GetTimeTick(0)); + switch (list[i].Type) + { + case DataType.BOOL: + w.Write(dataReader.GetFloat(1) > 0); + break; + case DataType.BYTE: + w.Write((byte)dataReader.GetFloat(1)); + break; + case DataType.WORD: + case DataType.SHORT: + w.Write((short)dataReader.GetFloat(1)); + break; + case DataType.INT: + w.Write((int)dataReader.GetFloat(1)); + break; + case DataType.FLOAT: + w.Write(dataReader.GetFloat(1)); + break; + } + } + } + } + + } + } + end = stream.Position;//鏂囦欢鐨勭粨灏撅紝鎬婚暱搴 + w.Seek((day - 1) * 8, SeekOrigin.Begin);//瀹氫綅鍒扮储寮曞尯 + w.Write(start);//鍐欏叆褰撴棩鎸囬拡 + w.Write(end);//鍐欏叆涓嬩竴鏃ユ寚閽 + //w.Close(); + } + } + File.Copy(path2, path, true); + } + catch (Exception err) + { + DataHelper.AddErrorLog(err); + return -3; + } + finally + { + if (File.Exists(path2)) + File.Delete(path2); + } + //dataReader.Close(); + return 0; + /*鍐欏叆澶辫触锛屽垯灏嗗浠芥枃浠惰繕鍘燂紱鏁版嵁搴撲笉鍋氬垹闄ゅ姩浣滐紝淇濈暀璁板綍锛屾鏃ユ湇鍔℃鏌ユ暟鎹枃浠舵槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯鍚堝苟鍐欏叆 + 鍙湪鏈嶅姟鍐呭缓XML鏂囦欢淇濆瓨澶辫触璁板綍鐨勬棩鏈熷垪琛紝浠ヤ究杩樺師锛涚敤File.Mov锛涘畾鏃堕棿闅斻佸紑濮嬫椂闂翠篃鍙疿ML瀹氫箟銆 + 鍏堝浠戒簩杩涘埗褰掓。搴擄紝鍐嶅姞杞芥暟鎹簱鏁版嵁锛屽啓鍏ユ枃浠讹紱濡傛垚鍔燂紝鍒犻櫎鏁版嵁搴撳綋鏃ヨ褰曞苟鍒犻櫎澶囦唤鏂囦欢 + sw.Stop(); + * if (sw.ElapsedTicks > 0) { } + */ + } + } + } + return -10; + } + + public static IEnumerable LoadFromFile(DateTime start, DateTime end, bool sdt = false) + { + //Stopwatch sw = Stopwatch.StartNew(); + //鏂囦欢鐨勭粍缁囨牸寮忥細澶存枃浠讹細31锛宭n涓洪棿闅旀棩鏈燂紝position涓烘寚鍚戞棩鏈熸鐨勬寚閽堬紝sizes涓烘棩鏈熸鐨勯暱搴︺ + //姣忔棩鐨勬姮澶达細鎸塈D娆″簭锛屽寘鍚瘡涓猅AG鐨勬暟閲忥紝arr涓烘瘡涓棩鏈熸墍鏈夌殑鏍囩銆佹瘡鏍囩鏁伴噺銆佹暟鎹被鍨嬨佷綅缃寚閽堛 + //鎸夋椂闂存帓搴忥紝姣忎釜鏍囩鐨勫笺佹椂闂存埑銆 + string path = string.Concat(m_Path, "\\", start.Year.ToString(), "-", start.Month.ToString(), sdt ? ".sdt" : ".bin"); + if (!File.Exists(path)) yield break; + int day1 = start.Day; + int startTicks = new SqlDateTime(start).TimeTicks; + int endTicks = new SqlDateTime(end).TimeTicks; + int ln = end.Day - day1 + 1; + using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + BinaryReader reader = new BinaryReader(stream); + long[] positions = new long[ln + 1]; + long[] sizes = new long[ln]; + stream.Seek((day1 - 1) * 8, SeekOrigin.Begin); + positions[0] = reader.ReadInt64(); + for (int i = 0; i < ln; i++) + { + positions[i + 1] = reader.ReadInt64(); + sizes[i] = positions[i + 1] - positions[i];//姣忎竴澶╂暟鎹殑闀垮害 + } + //reader.Close(); + HistoryData data = HistoryData.Empty; + using (MemoryMappedFile mapp = MemoryMappedFile.CreateFromFile(stream, Guid.NewGuid().ToString(), 0, MemoryMappedFileAccess.Read, + HandleInheritability.Inheritable, false)) + { + for (int k = 0; k < ln; k++) + { + if (positions[k] < 0x100 || sizes[k] <= 0 || positions[k] + sizes[k] > stream.Length) + continue; + using (MemoryMappedViewAccessor acc = mapp.CreateViewAccessor(positions[k], sizes[k], MemoryMappedFileAccess.Read)) + { + long pos = 0; + int day = acc.ReadInt32(pos); + pos += 8; + int count = acc.ReadInt32(pos); + pos += 4; + HDataFormat[] arr = new HDataFormat[count]; + for (int i = 0; i < count; i++) + { + arr[i].ID = acc.ReadInt16(pos); + pos += 2; + arr[i].Type = (DataType)acc.ReadByte(pos); + pos++; + arr[i].Count = acc.ReadInt32(pos);//4涓瓧鑺傛槸棰勭暀 + pos += 8; + } + long tempos = pos; + for (int i = 0; i < count; i++) + { + int con = arr[i].Count; + int j = 0; + pos = tempos + acc.ReadInt32(i * 11 + 19); + long pf = pos; + DataType type = arr[i].Type; + int len = dataLen[(int)type]; + if (k == 0) //鍒ゆ柇鏄惁涓鸿捣濮嬫棩鏈熸垨缁撴潫鏃ユ湡 + { + int ind = BinarySearchTime(acc, pf, con, len, startTicks); + if (ind < 0) ind = ~ind; + j += ind; + pos += ind * len; + } + if (k == ln - 1) + { + int index = BinarySearchTime(acc, pf, con, len, endTicks); + con = index >= 0 ? index : ~index; + } + while (j++ < con) + { + data.ID = arr[i].ID; + data.TimeStamp = new SqlDateTime(day, acc.ReadInt32(pos)).Value; + pos += 4; + switch (type) + { + case DataType.BOOL: + data.Value.Boolean = acc.ReadBoolean(pos); + pos++; + break; + case DataType.BYTE: + data.Value.Byte = acc.ReadByte(pos); + pos++; + break; + case DataType.WORD: + case DataType.SHORT: + data.Value.Int16 = acc.ReadInt16(pos); + pos += 2; + break; + case DataType.INT: + data.Value.Int32 = acc.ReadInt32(pos); + pos += 4; + break; + case DataType.FLOAT: + data.Value.Single = acc.ReadSingle(pos); + pos += 4; + break; + } + yield return data; + } + } + } + } + } + } + yield break; + } + + public static IEnumerable LoadFromFile(DateTime start, DateTime end, short ID, bool sdt = false) + { + string path = string.Concat(m_Path, "\\", start.Year.ToString(), "-", start.Month.ToString(), sdt ? ".sdt" : ".bin");//bin-sdt + if (!File.Exists(path)) yield break; + int day1 = start.Day; + int startTicks = new SqlDateTime(start).TimeTicks;//寮濮嬫棩鏈熼儴鍒嗙殑4浣嶆暟鎹 + int endTicks = new SqlDateTime(end).TimeTicks; + int ln = end.Day - day1 + 1;//鏃ユ湡澶╂暟 + using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + long filelen = stream.Length;//鏂囦欢闀垮害 + BinaryReader reader = new BinaryReader(stream); + long[] positions = new long[ln];//姣忔棩鏁版嵁鎸囬拡锛堟寚鍚戠涓鏉℃暟鎹紝鍖呮嫭褰撴棩鏁版嵁绱㈠紩鍖猴級 + stream.Seek((day1 - 1) * 8, SeekOrigin.Begin);///鎵惧埌瀵瑰簲鐨勫紑濮嬫棩鏈熺储寮曚綅缃 + + for (int i = 0; i < ln; i++) + { + positions[i] = reader.ReadInt64();//璇诲叆鏃堕棿娈靛唴姣忔棩鏁版嵁闀垮害鍊 + } + long[] sizes = new long[ln]; + for (int i = 0; i < ln; i++) + { + if (positions[i] >= filelen) break;//濡傛灉璇诲叆闀垮害瓒呰繃鏂囦欢澶у皬鍒欓鍑 + stream.Seek(positions[i] + 8, SeekOrigin.Begin);//瀹氫綅鏂囦欢鎸囬拡鍒板綋鏃ユ暟鎹紑澶 + sizes[i] = reader.ReadInt32();//sizes涓哄綋鏃ヨ鏍囩鏁 + } + //reader.Close(); + HistoryData data = HistoryData.Empty; + //stream.Read(new byte[] + using (MemoryMappedFile mapp = MemoryMappedFile.CreateFromFile(stream, Guid.NewGuid().ToString(), filelen, MemoryMappedFileAccess.Read, + HandleInheritability.Inheritable, false)) + { + for (int k = 0; k < ln; k++)//鍏堣鍏ュ綋鏃ョ储寮曞尯 + { + if (positions[k] < 0x100 || sizes[k] <= 0 || positions[k] + sizes[k] > filelen) + continue; + //if (sizes[k] == 0) continue; + long pos = 0; + int count = 0; + int day = 0; + int len = 0; + DataType type = DataType.NONE; + using (MemoryMappedViewAccessor acc1 = mapp.CreateViewAccessor(positions[k], 12 + sizes[k] * 11, MemoryMappedFileAccess.Read))//12鏄ご鐨勯暱搴︼紝11鏄竴涓牸寮忓瓧娈电殑闀垮害 + { + day = acc1.ReadInt32(0);//褰撴棩鏃ユ湡閮ㄥ垎 + int index = BinarySearch(acc1, (int)sizes[k], ID);//鎵惧埌褰撳ぉ 鎸囧畾鏍囩鐨勮褰曠储寮 + if (index >= 0) + index = index * 11 + 12;//濡傛壘鍒帮紝鍒欏畾浣嶅埌褰撴棩鏁版嵁鐨勫厓鏁版嵁锛堢浉瀵逛綅绉伙級 + //sw.Stop(); + else continue; + byte tp = acc1.ReadByte(index + 2);//璇诲叆鏁版嵁绫诲瀷 + type = (DataType)tp; + len = dataLen[tp];//4锛6锛8鍒嗗埆涓哄瓨鍌ㄧ殑鏍囩闀垮害锛屽叾涓4瀛楄妭鏄椂闂存埑 + count = acc1.ReadInt32(index + 3);//璇诲叆鏁伴噺 + pos = positions[k] + 12 + sizes[k] * 11 + acc1.ReadInt32(index + 7);//鎸囬拡鎸囧悜褰撴棩褰撳墠鏍囩绗竴鏉¤褰 + } + using (MemoryMappedViewAccessor acc2 = mapp.CreateViewAccessor(pos, count * len, MemoryMappedFileAccess.Read))//閲嶆柊浠庡ご瀹氫綅鏂囦欢鎸囬拡鍒版暟鎹尯 + { + pos = 0; + int j = 0; + if (k == 0)//鍒ゆ柇鏄惁涓鸿捣濮嬫棩鏈熸垨缁撴潫鏃ユ湡 + { + int ind = BinarySearchTime(acc2, 0, count, len, startTicks);//鏍规嵁鏃堕棿鎺掑簭鏂瑰紡浜屽垎娉曟煡鎵惧綋鏃ュ綋鍓嶆椂闂磋妭鐐圭殑鏁版嵁锛屽涓虹涓鏃 + if (ind < 0) ind = ~ind; + j += ind; + pos += ind * len; + } + if (k == ln - 1) + { + int ind = BinarySearchTime(acc2, 0, count, len, endTicks);//濡傛灉涓烘渶鍚庝竴鏃ョ殑鏁版嵁锛屽垯鎸夌粨鏉熸椂闂村畾浣 + count = ind >= 0 ? ind : ~ind; + } + while (j++ < count) + { + data.ID = ID; + data.TimeStamp = new SqlDateTime(day, acc2.ReadInt32(pos)).Value;//鏃ユ湡鍦ㄥ墠(4浣嶏級 + pos += 4;//鏁版嵁鍖轰篃鏄4浣 + switch (type) + { + case DataType.BOOL: + data.Value.Boolean = acc2.ReadBoolean(pos); + pos++; + break; + case DataType.BYTE: + data.Value.Byte = acc2.ReadByte(pos); + pos++; + break; + case DataType.WORD: + case DataType.SHORT: + data.Value.Int16 = acc2.ReadInt16(pos); + pos += 2; + break; + case DataType.INT: + data.Value.Int32 = acc2.ReadInt32(pos); + pos += 4; + break; + case DataType.FLOAT: + data.Value.Single = acc2.ReadSingle(pos); + pos += 4; + break; + } + yield return data; + } + } + } + } + reader.Close(); + } + yield break; + } + + public static IEnumerable LoadFromDatabase(DateTime start, DateTime end, short? ID = null) + { + using (var dataReader = DataHelper.Instance.ExecuteProcedureReader("READHDATA", + DataHelper.CreateParam("@STARTTIME", SqlDbType.DateTime, start), + DataHelper.CreateParam("@ENDTIME", SqlDbType.DateTime, end), + DataHelper.CreateParam("@ID", SqlDbType.Int, (object)ID ?? DBNull.Value))) + { + if (dataReader == null) yield break; + HistoryData data = HistoryData.Empty; + int itime = ID.HasValue ? 0 : 1; + int ivalue = ID.HasValue ? 1 : 2; + int itype = ID.HasValue ? 2 : 3; + while (dataReader.Read()) + { + data.ID = ID.HasValue ? ID.Value : dataReader.GetInt16(0); + data.TimeStamp = dataReader.GetDateTime(itime); + switch ((DataType)dataReader.GetByte(itype)) + { + case DataType.BOOL: + data.Value.Boolean = dataReader.GetFloat(ivalue) > 0 ? true : false; + break; + case DataType.BYTE: + data.Value.Byte = Convert.ToByte(dataReader.GetFloat(ivalue)); + break; + case DataType.WORD: + case DataType.SHORT: + data.Value.Int16 = Convert.ToInt16(dataReader.GetFloat(ivalue)); + break; + case DataType.INT: + data.Value.Int32 = Convert.ToInt32(dataReader.GetFloat(ivalue)); + break; + case DataType.FLOAT: + data.Value.Single = dataReader.GetFloat(ivalue); + break; + } + yield return data; + } + } + yield break; + } + + public static IEnumerable LoadFromDatabaseAtTime(short? ID, params DateTime[] timeStamps) + { + StringBuilder sql = new StringBuilder("SELECT "); + if (ID == null) sql.Append("ID,"); + sql.Append(" [TIMESTAMP],[VALUE],M.DATATYPE FROM LOG_HDATA L INNER JOIN META_TAG M ON L.ID=M.TAGID WHERE"); + if (ID != null) sql.Append(" ID=").Append(ID.Value).Append(" AND "); + sql.Append(" [TIMESTAMP] IN("); + for (int i = 0; i < timeStamps.Length; i++) + { + sql.Append("'").Append(timeStamps[i]).Append("',"); + } + using (var dataReader = DataHelper.Instance.ExecuteReader(sql.Append("1)").ToString())) + { + if (dataReader == null) yield break; + HistoryData data = HistoryData.Empty; + int itime = ID == null ? 0 : 1; + int ivalue = ID == null ? 1 : 2; + int itype = ID == null ? 2 : 3; + while (dataReader.Read()) + { + data.ID = ID == null ? dataReader.GetInt16(0) : ID.Value; + data.TimeStamp = dataReader.GetDateTime(itime); + switch ((DataType)dataReader.GetByte(itype)) + { + case DataType.BOOL: + data.Value.Boolean = dataReader.GetFloat(ivalue) > 0 ? true : false; + break; + case DataType.BYTE: + data.Value.Byte = Convert.ToByte(dataReader.GetFloat(ivalue)); + break; + case DataType.WORD: + case DataType.SHORT: + data.Value.Int16 = Convert.ToInt16(dataReader.GetFloat(ivalue)); + break; + case DataType.INT: + data.Value.Int32 = Convert.ToInt32(dataReader.GetFloat(ivalue)); + break; + case DataType.FLOAT: + data.Value.Single = dataReader.GetFloat(ivalue); + break; + } + yield return data; + } + } + yield break; + } + + private static int BinarySearch(MemoryMappedViewAccessor acc, int length, short value) + { + int i = 0; + int num2 = length - 1; + while (i <= num2) + { + int num3 = i + ((num2 - i) >> 1); + int num4 = acc.ReadInt16(12 + num3 * 11).CompareTo(value); + if (num4 == 0) + { + return num3; + } + if (num4 < 0) + { + i = num3 + 1; + } + else + { + num2 = num3 - 1; + } + } + return -1; + } + + private static int BinarySearchTime(MemoryMappedViewAccessor acc, long offset, int count, int len, int ticks) + { + int i = 0; + int num2 = count - 1; + while (i <= num2) + { + int num3 = i + ((num2 - i) >> 1); + int num4 = acc.ReadInt32(offset + num3 * len).CompareTo(ticks); + if (num4 == 0) + { + return num3; + } + if (num4 < 0) + { + i = num3 + 1; + } + else + { + num2 = num3 - 1; + } + } + return ~i; + } + + public static void SDTCompression(int year, int month, float E = 0.7f) + { + //Stopwatch sw = Stopwatch.StartNew(); + string path = string.Concat(m_Path, "\\", year.ToString(), "-", month.ToString()); + using (FileStream stream = File.Open(path + ".bin", FileMode.Open, FileAccess.Read, FileShare.Read)) + { + using (FileStream outstream = File.Create(path + ".sdt")) + { + outstream.Write(new byte[0x100], 0, 0x100); + BinaryWriter w = new BinaryWriter(outstream); + using (MemoryMappedFile mapp = MemoryMappedFile.CreateFromFile(stream, "map1", stream.Length, + MemoryMappedFileAccess.ReadWrite, HandleInheritability.Inheritable, false)) + { + int days = DateTime.DaysInMonth(year, month); + long[] ps = new long[days + 1]; + long[] ps1 = new long[days + 1]; + long[] sizes = new long[days]; + MemoryMappedViewAccessor acc1 = mapp.CreateViewAccessor(0, 8 * days); + long begin = 0; + ps[0] = acc1.ReadInt64(begin); + for (int i = 0; i < days; i++) + { + begin += 8; + ps[i + 1] = (i == days - 1 ? stream.Length : acc1.ReadInt64(begin)); + sizes[i] = ps[i + 1] - ps[i]; + } + acc1.Dispose(); + for (int i = 0; i < days; i++) + { + if (ps[i] < 0x100 || sizes[i] <= 0) + continue; + using (MemoryMappedViewAccessor acc = mapp.CreateViewAccessor(ps[i], sizes[i])) + { + ps1[i] = outstream.Position; + int len = acc.ReadInt32(8); + int len1 = len * 11 + 12; + HDataFormat[] list = new HDataFormat[len]; + w.Write(acc.ReadInt32(0)); + w.Write(acc.ReadInt32(4)); + w.Write(len); + outstream.Write(new byte[len1 - 12], 0, len1 - 12); + long pos = 12; + int off = 0; + for (int j = 0; j < len; j++) + { + short id; byte type; int count; int offset; + id = acc.ReadInt16(pos); + type = acc.ReadByte(pos + 2); + count = acc.ReadInt32(pos + 3); + offset = acc.ReadInt32(pos + 7); + list[j].ID = id; + list[j].Type = (DataType)type; + list[j].Offset = off;//姝ゅ鍙噰鍙栦笁娆″埌浜旀鎶芥牱寰楀埌E鍜孴LM + if (count < 3) + { + long pos2 = len1 + offset; + for (int m = 0; m < count; m++) + { + w.Write(acc.ReadInt32(pos2)); + pos2 += 4; + w.Write(acc.ReadSingle(pos2)); + pos2 += 4; + } + continue; + } + else + { + switch (list[j].Type) + { + case DataType.FLOAT: + { + int crt = 0; int net = 0; + float crv = 0; float nev = 0; + int maxt = 0; int mint = maxt; int sumt = 0; + float minv = 0; float maxv = minv; float sumv = 0; + int old_time = 0; int time = 0; + float mem = 0; float old_mem = 0; + long pp = len1 + offset; + long pos2 = pp + 16; + for (int c = 0; c < 9; c++) + { + crt = acc.ReadInt32(pp); + pp += 4; + crv = acc.ReadSingle(pp); + pp += 4; + if (c > 0) + { + float cv = crv - nev; + int ct = crt - net; + if (c == 1) + { + time = crt; + mem = crv; + maxt = mint = ct; + minv = maxv = cv; + } + else + { + if (cv > maxv) + maxv = cv; + if (cv < minv) + minv = cv; + if (ct > maxt) + maxt = ct; + if (ct < mint) + mint = ct; + } + sumv += cv; + sumt += ct; + } + else + { + old_mem = crv; + old_time = crt; + } + nev = crv; + net = crt; + } + int TLM = (sumt - maxt - mint) / 2; + float E1 = E * (sumv - maxv - minv) / 6; + int sum = 1; + //old_time = now_time = new_time = 0; + float timespan; + w.Write(old_time); + w.Write(old_mem); + float k1, k2, k; + timespan = time - old_time; + k = (mem - old_mem) / timespan; + k1 = k + (E1 / timespan); + k2 = 2 * k - k1; + for (int m = 2; m < count; m++) + { + if (timespan >= TLM || k < k2 || k > k1) + { + ++sum; + w.Write(old_time); + w.Write(old_mem); + k1 = k + (E1 / timespan); + k2 = 2 * k - k1; + } + old_time = time; + old_mem = mem; + time = acc.ReadInt32(pos2); + pos2 += 4; + mem = acc.ReadSingle(pos2); + pos2 += 4; + timespan = time - old_time; + k = (mem - old_mem) / timespan; + } + list[j].Count = sum; + off += sum * 8; + } + break; + case DataType.WORD: + case DataType.SHORT: + { + int crt = 0; int net = 0; + short crv = 0; short nev = 0; + int maxt = 0; int mint = maxt; int sumt = 0; + int minv = 0; int maxv = minv; int sumv = 0; + int old_time = 0; int time = 0; + short mem = 0; short old_mem = 0; + long pp = len1 + offset; + long pos2 = pp + 12; + for (int c = 0; c < 9; c++) + { + crt = acc.ReadInt32(pp); + pp += 4; + crv = acc.ReadInt16(pp); + pp += 2; + if (c > 0) + { + int cv = crv - nev; + int ct = crt - net; + if (c == 1) + { + time = crt; + maxt = mint = ct; + mem = crv; + minv = maxv = cv; + } + else + { + if (cv > maxv) + maxv = cv; + if (cv < minv) + minv = cv; + if (ct > maxt) + maxt = ct; + if (ct < mint) + mint = ct; + } + sumv += cv; + sumt += ct; + } + else + { + old_mem = crv; + old_time = crt; + } + nev = crv; + net = crt; + } + int TLM = (sumt - maxt - mint) / 2; + float E1 = E * (sumv - maxv - minv) / 6; + int sum = 1; + float timespan; + w.Write(old_time); + w.Write(old_mem); + float k1, k2, k; + timespan = time - old_time; + k = (mem - old_mem) / timespan; + k1 = k + (E1 / timespan); + k2 = 2 * k - k1; + for (int m = 2; m < count; m++) + { + if (timespan >= TLM || k < k2 || k > k1) + { + ++sum; + w.Write(old_time); + w.Write(old_mem); + k1 = k + (E1 / timespan); + k2 = 2 * k - k1; + } + old_time = time; + old_mem = mem; + time = acc.ReadInt32(pos2); + pos2 += 4; + mem = acc.ReadInt16(pos2); + pos2 += 2; + timespan = time - old_time; + k = (mem - old_mem) / timespan; + } + + list[j].Count = sum; + off += sum * 8; + } + break; + default: + { + byte[] buffer = new byte[count * dataLen[type]]; + stream.Seek(ps[i] + len1 + offset, SeekOrigin.Begin); + stream.Read(buffer, 0, buffer.Length); + outstream.Write(buffer, 0, buffer.Length); + list[j].Count = count; + off += buffer.Length; + } + break; + } + pos += 11; + } + } + outstream.Seek(ps1[i] + 12, SeekOrigin.Begin); + for (int j = 0; j < len; j++) + { + w.Write(list[j].ID); + w.Write((byte)list[j].Type); + w.Write(list[j].Count); + w.Write(list[j].Offset); + } + ps1[i + 1] = outstream.Seek(0, SeekOrigin.End); + } + + } + outstream.Seek(0, SeekOrigin.Begin); + for (int i = 0; i < days + 1; i++) + { + w.Write(ps1[i]); + } + } + } + } + } + + //閬嶅巻涓や釜鏂囦欢澶逛笅鎵鏈夊巻鍙茶褰曟枃浠讹紱濡傛棩鏈熸棤閲嶅锛屽垯澶嶅埗婧愯矾寰勪笅鏂囦欢鍒扮洰鏍囪矾寰勶紱鍚﹀垯鍚堝苟鍒颁竴涓枃浠 + public static unsafe bool Merge(string sourcePath, string targetPath) + { + return true; + } + + public static unsafe ushort ToFloat16(float f) + { + uint* i = (uint*)&f; + uint sign = (*i >> 31) & 0x1; + uint exponent = ((*i >> 23) & 0xff) - 0x7f; + uint mantissa = (*i) & 0x7fffff; + + exponent += 0x7; + uint ret = ((sign & 0x1) << 15); + ret |= ((exponent & 0xf) << 11); + ret |= ((mantissa >> 13) & 0x7ff); + return (ushort)ret; + } + + public static unsafe float ToFloat32(ushort f) + { + ushort* i = (ushort*)&f; + int sign = (*i >> 15) & 0x1; + int exponent = ((*i >> 11) & 0xf) - 0x7; + int mantissa = (*i) & 0x7ff; + + exponent += 0x7f; + int ret = ((sign & 0x1) << 31); + ret |= (exponent & 0xff) << 23; + ret |= (mantissa << 13) & 0x7fffff; + return *((float*)&ret); + } + + + public static float[] Interpolation(float[] dataIn, int n) + { + float[] dataOut = new float[n]; + int lenIn = dataIn.Length; + float[] divOut = new float[n]; + for (int i = 1; i < n; i++) + { + divOut[i] = divOut[i - 1] + lenIn / (float)n; + } + int k = 0; + for (int i = k; i < n; i++) + { + for (int j = 0; j < lenIn - 1; j++) + { + if (divOut[i] >= j && divOut[i] < j + 1) + { + dataOut[i] = (dataIn[j + 1] - dataIn[j]) * (divOut[i] - j) + dataIn[j]; + k = i; + } + } + } + return dataOut; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal struct HDataFormat + { + public short ID; + public DataType Type; + public int Count; + public int Offset; + + public HDataFormat(short id, DataType type, int count, int offset) + { + ID = id; + Type = type; + Count = count; + Offset = offset; + } + } +} \ No newline at end of file diff --git a/SCADA/Program/CoreApp/DataService/DataHelper/IDataFactory.cs b/SCADA/Program/CoreApp/DataService/DataHelper/IDataFactory.cs new file mode 100644 index 0000000..66260b9 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataHelper/IDataFactory.cs @@ -0,0 +1,32 @@ +锘縰sing System.Data; +using System.Data.Common; + +namespace DatabaseLib +{ + public interface IDataFactory + { + bool BulkCopy(IDataReader reader, string tableName, string command = null); + void CallException(string message); + bool ConnectionTest(); + DbParameter CreateParam(string paramName, SqlDbType dbType, object objValue, int size = 0, ParameterDirection direction = ParameterDirection.Input); + DataRow ExecuteDataRowProcedure(string ProName, params DbParameter[] ParaName); + DataRowView ExecuteDataRowViewProcedure(string ProName, params DbParameter[] ParaName); + DataSet ExecuteDataset(string SQL); + DataSet ExecuteDataset(string[] SQLs, string[] TableNames); + DataSet ExecuteDataset(string SQL, string TableName); + DataSet ExecuteDataSetProcedure(string ProName, params DbParameter[] ParaName); + DataSet ExecuteDataSetProcedure(string ProName, ref int returnValue, params DbParameter[] ParaName); + DataTable ExecuteDataTable(string SQL); + DataTable ExecuteDataTableProcedure(string ProName, params DbParameter[] ParaName); + DataTable ExecuteDataTableProcedure(string ProName, ref int returnValue, DbParameter[] ParaName); + int ExecuteNonQuery(string[] SQLs); + int ExecuteNonQuery(string SQL); + int ExecuteNonQuery(string[] SQLs, object[][] Pars); + DbDataReader ExecuteProcedureReader(string sSQL, params DbParameter[] ParaName); + DbDataReader ExecuteReader(string sSQL); + object ExecuteScalar(string sSQL); + bool ExecuteStoredProcedure(string ProName); + int ExecuteStoredProcedure(string ProName, params DbParameter[] ParaName); + void FillDataSet(ref DataSet ds, string SQL, string TableName); + } +} \ No newline at end of file diff --git a/SCADA/Program/CoreApp/DataService/DataHelper/MysqlFactory.cs b/SCADA/Program/CoreApp/DataService/DataHelper/MysqlFactory.cs new file mode 100644 index 0000000..45cb93e --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataHelper/MysqlFactory.cs @@ -0,0 +1,778 @@ +锘縰sing MySql.Data.MySqlClient; +using System; +using System.Data; +using System.Data.Common; +using System.IO; + +namespace DatabaseLib +{ + public class MysqlFactory : IDataFactory + { + public void CallException(string message) + { + DataHelper.AddErrorLog(new Exception(message)); + } + + public bool ConnectionTest() + { + //鍒涘缓杩炴帴瀵硅薄 + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + //myMySqlConnection.ConnectionTimeout = 1;//璁剧疆杩炴帴瓒呮椂鐨勬椂闂 + try + { + //Open DataBase + //鎵撳紑鏁版嵁搴 + m_Conn.Open(); + if (m_Conn.State == ConnectionState.Open) + { + return true; + } + } + catch (Exception e) + { + CallException(e.Message); + } + } + //myMySqlConnection is a MySqlConnection object + return false; + } + + public MySqlDbType ConvertType(SqlDbType dbType) + { + switch (dbType) + { + case SqlDbType.BigInt: + return MySqlDbType.Int64; + case SqlDbType.Binary: + return MySqlDbType.Binary; + case SqlDbType.Bit: + return MySqlDbType.Bit; + case SqlDbType.Date: + return MySqlDbType.Date; + case SqlDbType.SmallDateTime: + case SqlDbType.DateTime2: + case SqlDbType.DateTime: + return MySqlDbType.DateTime; + case SqlDbType.DateTimeOffset: + return MySqlDbType.Time; + case SqlDbType.Decimal: + return MySqlDbType.Decimal; + case SqlDbType.Float: + return MySqlDbType.Double; + case SqlDbType.Image: + return MySqlDbType.Binary; + case SqlDbType.Int: + return MySqlDbType.Int32; + case SqlDbType.Money: + return MySqlDbType.Float; + case SqlDbType.NText: + case SqlDbType.Text: + return MySqlDbType.Text; + case SqlDbType.Real: + return MySqlDbType.Float; + case SqlDbType.SmallInt: + return MySqlDbType.Int16; + case SqlDbType.Structured: + return MySqlDbType.Set; + case SqlDbType.Time: + return MySqlDbType.Time; + case SqlDbType.Timestamp: + return MySqlDbType.Timestamp; + case SqlDbType.TinyInt: + return MySqlDbType.Byte; + case SqlDbType.VarBinary: + return MySqlDbType.VarBinary; + case SqlDbType.Char: + case SqlDbType.NVarChar: + case SqlDbType.VarChar: + return MySqlDbType.VarChar; + default: + return MySqlDbType.VarChar; + } + } + + public DbParameter CreateParam(string paramName, SqlDbType dbType, object objValue, int size = 0, ParameterDirection direction = ParameterDirection.Input) + { + if (string.IsNullOrEmpty(paramName)) return null; + if (paramName[0] == '@') paramName = 'p' + paramName.TrimStart('@'); + MySqlParameter parameter = new MySqlParameter(paramName, ConvertType(dbType)); + if (size > 0) parameter.Size = size; + if (objValue == null) + { + if (direction == ParameterDirection.Output) + { + parameter.Direction = direction; + return parameter; + } + parameter.IsNullable = true; + parameter.Value = DBNull.Value; + return parameter; + } + parameter.Value = objValue; + return parameter; + } + #region ExecuteDataset //鎵ц鏌ヨ璇彞锛岃繑鍥炰竴涓褰曢泦 + + /// + /// 杩斿洖璁板綍闆 + /// + /// 鐢ㄤ簬杩斿洖璁板綍闆嗙殑SQL璇彞 + /// 璁板綍闆 + public DataSet ExecuteDataset(string SQL) + { + DataSet ds = new DataSet(); + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + MySqlCommand cmd = new MySqlCommand(SQL, m_Conn); + da.SelectCommand = cmd; + da.Fill(ds); + } + catch (Exception e) + { + CallException(SQL + " " + e.Message); + } + } + return ds; + } + + + /// + /// 杩斿洖璁板綍闆 + /// + /// 鐢ㄤ簬杩斿洖璁板綍闆嗙殑SQL璇彞 + /// 鏄犲皠琛ㄥ悕 + /// 璁板綍闆 + public DataSet ExecuteDataset(string SQL, string TableName) + { + DataSet ds = new DataSet(); + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + MySqlCommand cmd = new MySqlCommand(SQL, m_Conn); + da.SelectCommand = cmd; + da.Fill(ds, TableName); + } + catch (Exception e) + { + CallException(SQL + " " + e.Message); + } + } + return ds; + } + + /// + /// 杩斿洖鍖呭惈澶氫釜琛ㄧ殑璁板綍闆 + /// + /// 鐢ㄤ簬杩斿洖璁板綍闆嗙殑SQL璇彞 + /// 鏄犲皠琛ㄥ悕 + /// 璁板綍闆 + + public DataSet ExecuteDataset(string[] SQLs, string[] TableNames) + { + DataSet ds = new DataSet(); + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + for (int i = 0; i < SQLs.Length; i++) + { + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + MySqlCommand cmd = new MySqlCommand(SQLs[i], m_Conn); + da.SelectCommand = cmd; + da.Fill(ds, TableNames[i]); + } + } + catch (Exception e) + { + CallException(SQLs + " " + e.Message); + } + } + return ds; + } + + #endregion ExecuteDataset + + /// + /// 杩斿洖琛 + /// + /// 鐢ㄤ簬杩斿洖璁板綍闆嗙殑SQL璇彞 + /// 璁板綍闆 + public DataTable ExecuteDataTable(string SQL) + { + DataTable dt = new DataTable(); + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + MySqlCommand cmd = new MySqlCommand(SQL, m_Conn); + da.SelectCommand = cmd; + da.Fill(dt); + } + catch (Exception e) + { + CallException(SQL + " " + e.Message); + } + } + return dt; + } + + #region ExecuteNonQuery //鎵ц闈炴煡璇㈣鍙 + + /// + /// 鎵ц涓鏉NSERT銆乁PDATE銆丏ELETE璇彞 + /// + /// T-SQL璇彞 + /// 杩斿洖褰卞搷鐨勮鏁 + public int ExecuteNonQuery(string SQL) + { + int res = -1; + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + MySqlTransaction sqlT = null; MySqlBulkLoader loader = new MySqlBulkLoader(m_Conn); + //loader.Columns + try + { + using (MySqlCommand cmd = new MySqlCommand(SQL, m_Conn)) + { + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + cmd.Connection = m_Conn; + sqlT = m_Conn.BeginTransaction(); + cmd.Transaction = sqlT; + res = cmd.ExecuteNonQuery(); + sqlT.Commit(); + } + } + catch (Exception e) + { + if (sqlT != null) + sqlT.Rollback(); + CallException(SQL + " " + e.Message); + return -1; + } + return res; + } + } + + /// + /// 鎵ц涓缁処NSERT銆乁PDATE銆丏ELETE璇彞 + /// + /// T-SQL璇彞 + /// 杩斿洖褰卞搷鐨勮鏁 + public int ExecuteNonQuery(string[] SQLs) + { + int res = -1; + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + MySqlTransaction sqlT = null; + MySqlCommand cmd = new MySqlCommand(); + try + { + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + cmd.Connection = m_Conn; + sqlT = m_Conn.BeginTransaction(); + cmd.Transaction = sqlT; + for (int i = 0; i < SQLs.Length; i++) + { + cmd.CommandText = SQLs[i]; + res = cmd.ExecuteNonQuery(); + } + sqlT.Commit(); + } + catch (Exception e) + { + if (sqlT != null) + sqlT.Rollback(); + CallException(SQLs + " " + e.Message); + res = -1; + } + return res; + } + } + + /// + /// 鎵ц涓缁処NSERT銆乁PDATE銆丏ELETE璇彞 + /// + /// T-SQL璇彞 + /// 鎵ц鍙傛暟 + /// 杩斿洖褰卞搷鐨勮鏁 + public int ExecuteNonQuery(string[] SQLs, object[][] Pars) + { + int res = -1; + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + MySqlTransaction sqlT = null; + MySqlCommand cmd = new MySqlCommand(); + try + { + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + cmd.Connection = m_Conn; + sqlT = m_Conn.BeginTransaction(); + cmd.Transaction = sqlT; + for (int i = 0; i < SQLs.Length; i++) + { + cmd.CommandText = SQLs[i]; + cmd.Parameters.Clear(); + for (int j = 0; j < Pars[i].Length; j++) + { + cmd.Parameters.AddWithValue("@p" + j.ToString(), Pars[i][j]); + } + res = cmd.ExecuteNonQuery(); + } + sqlT.Commit(); + } + catch (Exception e) + { + if (sqlT != null) + sqlT.Rollback(); + CallException(SQLs + " " + e.Message); + res = -1; + } + return res; + } + } + + #endregion ExecuteNonQuery + + #region FillDataSet //濉厖涓涓褰曢泦 + + /// + /// 鐢ㄦ寚瀹氱殑SQL璇彞鏉ュ~鍏呬竴涓褰曢泦 + /// + /// 璁板綍闆 + /// SELECT璇彞 + /// 鏄犲皠琛ㄥ悕 + public void FillDataSet(ref DataSet ds, string SQL, string TableName) + { + try + { + MySqlConnection m_Conn; + m_Conn = new MySqlConnection(DataHelper.ConnectString); + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + MySqlCommand cmd = new MySqlCommand(SQL, m_Conn); + da.SelectCommand = cmd; + da.Fill(ds, TableName); + } + catch (Exception e) + { + CallException(SQL + " " + e.Message); + } + } + + #endregion FillDataSet + + #region + // + /// 杩斿洖涓涓狹ySqlDataReader + /// + public DbDataReader ExecuteReader(string sSQL) + { + MySqlConnection connection = new MySqlConnection(DataHelper.ConnectString); + MySqlCommand command = new MySqlCommand(sSQL, connection); + if (connection.State == ConnectionState.Closed) + connection.Open(); + return command.ExecuteReader(CommandBehavior.CloseConnection); + } + + + public DbDataReader ExecuteProcedureReader(string sSQL, params DbParameter[] ParaName) + { + MySqlConnection connection = new MySqlConnection(DataHelper.ConnectString); + MySqlCommand command = new MySqlCommand(sSQL, connection); + command.CommandType = CommandType.StoredProcedure; + if (ParaName != null) + { + command.Parameters.AddRange(ParaName); + } + try + { + if (connection.State == ConnectionState.Closed) + connection.Open(); + return command.ExecuteReader(CommandBehavior.CloseConnection); + } + catch (Exception e) + { + CallException(sSQL + " " + e.Message); + return null; + } + } + #endregion + + #region ExecuteScalar //鎵ц鏌ヨ锛屽苟杩斿洖鏌ヨ鎵杩斿洖鐨勭粨鏋滈泦涓涓琛岀殑绗竴鍒 + + /// + /// 鎵ц鏌ヨ锛屽苟杩斿洖鏌ヨ鎵杩斿洖鐨勭粨鏋滈泦涓涓琛岀殑绗竴鍒 + /// + /// SQL璇彞 + /// + public object ExecuteScalar(string sSQL) + { + MySqlTransaction sqlT = null; + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + MySqlCommand cmd = new MySqlCommand(sSQL, m_Conn); + try + { + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + sqlT = m_Conn.BeginTransaction(); + cmd.Transaction = sqlT; + var res = cmd.ExecuteScalar(); + sqlT.Commit(); + if (res == DBNull.Value) res = null; + return res; + } + catch (Exception e) + { + if (sqlT != null) + sqlT.Rollback(); + CallException(sSQL + " " + e.Message); + return null; + } + } + } + + #endregion ExecuteScalar + + #region ExecuteStoredProcedure //鎵ц涓涓瓨鍌ㄨ繃绋 + + /// + /// 鎵ц涓涓甫鍙傛暟鐨勫瓨鍌ㄨ繃绋 + /// + /// 瀛樺偍杩囩▼鍚 + /// 鍙傛暟鍚嶇О + /// 鍙傛暟鏂瑰悜锛孖nput鍙傛暟鏄緭鍏ュ弬鏁 InputOutput鍙傛暟鏃㈣兘杈撳叆锛屼篃鑳借緭鍑 Output鍙傛暟鏄緭鍑哄弬鏁 ReturnValue鍙傛暟瀛樺偍杩囩▼杩斿洖鍊笺 + /// 鍙傛暟瀵硅薄鏁扮粍 + /// 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse + public int ExecuteStoredProcedure(string ProName, params DbParameter[] ParaName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn) + { + CommandType = CommandType.StoredProcedure + }; + if (ParaName != null) + { + cmd.Parameters.AddRange(ParaName); + } + MySqlParameter param = new MySqlParameter(); + cmd.Parameters.Add(param); + param.Direction = ParameterDirection.ReturnValue; + if (m_Conn.State == ConnectionState.Closed) + { + m_Conn.Open(); + } + cmd.ExecuteNonQuery(); + return (int)param.Value; + } + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return -1; + } + } + } + + /// + /// 鎵ц涓涓病鏈夊弬鏁板拰杩斿洖鍊肩殑瀛樺偍杩囩▼锛堥粯璁ゅ弬鏁扮被鍨嬶級 + /// + /// 瀛樺偍杩囩▼鍚 + /// 鍙傛暟瀵硅薄鏁扮粍 + /// 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse + public bool ExecuteStoredProcedure(string ProName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn); + cmd.CommandType = CommandType.StoredProcedure; + cmd.ExecuteNonQuery(); + return true; + } + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return false; + } + } + } + + /// + /// 鎵ц涓涓甫鍙傛暟鐨勫瓨鍌ㄨ繃绋嬶紝骞惰繑鍥炴暟鎹泦 + /// + /// 瀛樺偍杩囩▼鍚 + /// 鍙傛暟鍚嶇О + /// 鍙傛暟瀵硅薄鏁扮粍 + /// 鎵ц杩囩▼涓繑鍥炵殑鏁版嵁闆 + /// 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse + public DataSet ExecuteDataSetProcedure(string ProName, ref int returnValue, params DbParameter[] ParaName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + DataSet ds = new DataSet(); + try + { + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn); + cmd.CommandType = CommandType.StoredProcedure; + if (ParaName != null) + { + cmd.Parameters.AddRange(ParaName); + } + MySqlParameter param = new MySqlParameter { Direction = ParameterDirection.ReturnValue }; + cmd.Parameters.Add(param); + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + da.SelectCommand = cmd; + da.Fill(ds); + returnValue = (int)param.Value; + return ds; + } + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return null; + } + } + } + + public DataSet ExecuteDataSetProcedure(string ProName, params DbParameter[] ParaName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + DataSet ds = new DataSet(); + try + { + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn); + cmd.CommandType = CommandType.StoredProcedure; + if (ParaName != null) + { + cmd.Parameters.AddRange(ParaName); + } + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + da.SelectCommand = cmd; + da.Fill(ds); + return ds; + } + + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return null; + } + } + } + + /// + /// 鎵ц涓涓甫鍙傛暟鐨勫瓨鍌ㄨ繃绋嬶紝骞惰繑鍥炴暟鎹泦 + /// + /// 瀛樺偍杩囩▼鍚 + /// 鍙傛暟鍚嶇О + /// 鍙傛暟瀵硅薄鏁扮粍 + /// 鎵ц杩囩▼涓繑鍥炵殑鏁版嵁闆 + /// 鎴愬姛杩斿洖true锛屽け璐ヨ繑鍥瀎alse + /// + public DataTable ExecuteDataTableProcedure(string ProName, params DbParameter[] ParaName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + DataTable ds = new DataTable(); + try + { + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn); + cmd.CommandType = CommandType.StoredProcedure; + if (ParaName != null) + { + cmd.Parameters.AddRange(ParaName); + } + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + da.SelectCommand = cmd; + da.Fill(ds); + return ds; + } + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return null; + } + } + } + + public DataTable ExecuteDataTableProcedure(string ProName, ref int returnValue, DbParameter[] ParaName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + DataTable ds = new DataTable(); + try + { + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn); + cmd.CommandType = CommandType.StoredProcedure; + if (ParaName != null) + { + cmd.Parameters.AddRange(ParaName); + } + MySqlParameter param = new MySqlParameter { Direction = ParameterDirection.ReturnValue }; + cmd.Parameters.Add(param); + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + da.SelectCommand = cmd; + da.Fill(ds); + returnValue = (int)param.Value; + return ds; + } + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return null; + } + } + } + + /// + /// 鎵ц涓涓甫鍙傛暟鐨勫瓨鍌ㄨ繃绋,鍚屾椂杈撳嚭涓琛 + /// + /// 瀛樺偍杩囩▼鍚 + /// 鍙傛暟鍚嶇О + /// 鍙傛暟瀵硅薄鏁扮粍 + /// 杩斿洖鏁存暟 + public DataRow ExecuteDataRowProcedure(string ProName, params DbParameter[] ParaName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn); + cmd.CommandType = CommandType.StoredProcedure; + if (ParaName != null) + { + cmd.Parameters.AddRange(ParaName); + } + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + DataTable table = new DataTable(); + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + da.SelectCommand = cmd; + da.Fill(table); + if (table.Rows.Count > 0) + return table.Rows[0]; + else + return table.NewRow(); + } + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return null; + } + } + } + + /// + /// 鎵ц涓涓甫鍙傛暟鐨勫瓨鍌ㄨ繃绋,鍚屾椂杈撳嚭涓琛 + /// + /// 瀛樺偍杩囩▼鍚 + /// 鍙傛暟鍚嶇О + /// 鍙傛暟瀵硅薄鏁扮粍 + /// 杩斿洖鏁存暟 + public DataRowView ExecuteDataRowViewProcedure(string ProName, params DbParameter[] ParaName) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + try + { + MySqlCommand cmd = new MySqlCommand(ProName, m_Conn); + cmd.CommandType = CommandType.StoredProcedure; + if (ParaName != null) + { + cmd.Parameters.AddRange(ParaName); + } + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + DataTable table = new DataTable(); + var da = MySqlClientFactory.Instance.CreateDataAdapter(); + da.SelectCommand = cmd; + da.Fill(table); + if (table.Rows.Count > 0) + return table.DefaultView[0]; + else + return table.DefaultView.AddNew(); + } + catch (Exception e) + { + CallException(ProName + " " + e.Message); + return null; + } + } + } + + public bool BulkCopy(IDataReader reader, string tableName, string command = null) + { + using (MySqlConnection m_Conn = new MySqlConnection(DataHelper.ConnectString)) + { + MySqlTransaction sqlT = null; + try + { + if (m_Conn.State == ConnectionState.Closed) + m_Conn.Open(); + sqlT = m_Conn.BeginTransaction(); + if (!string.IsNullOrEmpty(command)) + { + MySqlCommand cmd = new MySqlCommand(command, m_Conn); + cmd.Transaction = sqlT; + cmd.ExecuteNonQuery(); + } + string tmpPath = Path.GetTempFileName(); + string csv = DataHelper.ReaderToCsv(reader); + File.WriteAllText(tmpPath, csv); + MySqlBulkLoader copy = new MySqlBulkLoader(m_Conn) + { + FieldTerminator = ",", + FieldQuotationCharacter = '"', + EscapeCharacter = '"', + LineTerminator = "\r\n", + FileName = tmpPath, + NumberOfLinesToSkip = 0, + TableName = tableName, + }; + //copy.BatchSize = _capacity; + copy.Load();//濡傛灉鍐欏叆澶辫触锛岃冭檻涓嶈兘鏃犻檺澧炲姞绾跨▼鏁 + //Clear(); + sqlT.Commit(); + m_Conn.Close(); + File.Delete(tmpPath); + return true; + } + catch (Exception e) + { + if (sqlT != null) + sqlT.Rollback(); + m_Conn.Close(); + DataHelper.AddErrorLog(e); + return false; + } + } + } + + + #endregion ExecuteStoredProcedure + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService.sln b/SCADA/Program/CoreApp/DataService/DataService.sln new file mode 100644 index 0000000..f950486 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService.sln @@ -0,0 +1,71 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2005 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataService", "DataService\DataService.csproj", "{46BF803C-F153-4222-8FFC-9AC957F34EA5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GateWay", "GateWay\GateWay.csproj", "{99BEC8C4-2684-4BFD-897A-2340B6963120}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataHelper", "DataHelper\DataHelper.csproj", "{EE99C592-F4F2-4152-94CC-564ABA066C20}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModbusDriver", "ModbusDriver\ModbusDriver.csproj", "{79CDC563-AA30-48CA-8913-32454EDE76FA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClientDriver", "ClientDriver\ClientDriver.csproj", "{3D10E811-46FE-4EE7-A268-8B50C3B2D08F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Debug|x86.ActiveCfg = Debug|Any CPU + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Debug|x86.Build.0 = Debug|Any CPU + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Release|Any CPU.Build.0 = Release|Any CPU + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Release|x86.ActiveCfg = Release|Any CPU + {46BF803C-F153-4222-8FFC-9AC957F34EA5}.Release|x86.Build.0 = Release|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Debug|x86.ActiveCfg = Debug|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Debug|x86.Build.0 = Debug|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Release|Any CPU.Build.0 = Release|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Release|x86.ActiveCfg = Release|Any CPU + {99BEC8C4-2684-4BFD-897A-2340B6963120}.Release|x86.Build.0 = Release|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Debug|x86.ActiveCfg = Debug|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Debug|x86.Build.0 = Debug|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Release|Any CPU.Build.0 = Release|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Release|x86.ActiveCfg = Release|Any CPU + {EE99C592-F4F2-4152-94CC-564ABA066C20}.Release|x86.Build.0 = Release|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Debug|x86.ActiveCfg = Debug|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Debug|x86.Build.0 = Debug|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Release|Any CPU.Build.0 = Release|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Release|x86.ActiveCfg = Release|Any CPU + {79CDC563-AA30-48CA-8913-32454EDE76FA}.Release|x86.Build.0 = Release|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Debug|x86.Build.0 = Debug|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Release|Any CPU.Build.0 = Release|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Release|x86.ActiveCfg = Release|Any CPU + {3D10E811-46FE-4EE7-A268-8B50C3B2D08F}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {06245D70-C147-4613-91E1-E3990B520C63} + EndGlobalSection +EndGlobal diff --git a/SCADA/Program/CoreApp/DataService/DataService/Alarm.cs b/SCADA/Program/CoreApp/DataService/DataService/Alarm.cs new file mode 100644 index 0000000..523fadc --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/Alarm.cs @@ -0,0 +1,223 @@ +锘縰sing System; +using System.ComponentModel; + +namespace DataService +{ + + public class AlarmItem : IComparable, INotifyPropertyChanged + { + int _condiId; + + Severity _severity; + SubAlarmType _alarmType; + DateTime _startTime; + TimeSpan _duration; + object _alarmValue; + string _alarmText; + string _source; + + public SubAlarmType SubAlarmType + { + get + { + return _alarmType; + } + set + { + _alarmType = value; + } + } + + public Severity Severity + { + get + { + return _severity; + } + set + { + _severity = value; + } + } + + public DateTime StartTime + { + get + { + return _startTime; + } + set + { + _startTime = value; + } + } + + public int ConditionId + { + get + { + return _condiId; + } + set + { + _condiId = value; + } + } + + public TimeSpan Duration + { + get + { + //return _endTime-_startTime; + return _duration; + } + set + { + _duration = value; + OnPropertyChanged("Duration"); + } + } + + public object AlarmValue + { + get + { + return _alarmValue; + } + set + { + _alarmValue = value; + } + } + + public string AlarmText + { + get + { + return _alarmText; + } + set + { + _alarmText = value; + } + } + + public string Source + { + get + { + return _source; + } + set + { + _source = value; + } + } + + public AlarmItem(DateTime time, string alarmText, object alarmValue, SubAlarmType type, Severity severity, int condId, string source) + { + this._startTime = time; + this._alarmType = type; + this._alarmText = alarmText; + this._alarmValue = alarmValue; + this._severity = severity; + this._condiId = condId; + this._source = source; + } + + public AlarmItem() + { + this._startTime = DateTime.Now; + this._alarmType = SubAlarmType.None; + this._alarmText = string.Empty; + this._severity = Severity.Normal; + this._condiId = -1; + this._source = string.Empty; + } + + #region IComparable Members + + public int CompareTo(AlarmItem other) + { + return this._startTime.CompareTo(other._startTime); + } + + #endregion + + public event PropertyChangedEventHandler PropertyChanged; + + private void OnPropertyChanged(string propertyName) + { + if (this.PropertyChanged != null) + { + + this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + + } + + [Flags] + public enum AlarmType + { + None = 0, + Level = 1, + Dev = 2, + Dsc = 4, + ROC = 8, + Quality = 16, + Complex = 32, + WordDsc = 64 + } + + [Flags] + public enum SubAlarmType + { + None = 0, + LoLo = 1, + Low = 2, + High = 4, + HiHi = 8, + MajDev = 16, + MinDev = 32, + Dsc = 64, + + BadPV = 128, + MajROC = 256, + MinROC = 512 + } + + public enum Severity + { + Error = 7, + High = 6, + MediumHigh = 5, + Medium = 4, + MediumLow = 3, + Low = 2, + Information = 1, + Normal = 0 + } + + [Flags] + public enum ConditionState : byte + { + Acked = 4, + Actived = 2, + Enabled = 1 + } + + public enum EventType : byte + { + Simple = 1, + TraceEvent = 2, + ConditionEvent = 4, + } + + public enum ConditionType : byte + { + Absolute = 0, + Percent = 1 + } + +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/CacheReader.cs b/SCADA/Program/CoreApp/DataService/DataService/CacheReader.cs new file mode 100644 index 0000000..ac64220 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/CacheReader.cs @@ -0,0 +1,910 @@ +锘縰sing System; +using System.Net; +using System.Runtime.InteropServices; +using System.Text; + +namespace DataService +{ + public sealed class ByteCacheReader : ICache + { + byte[] _cache; + public Array Cache { get { return _cache; } } + + public int ByteCount + { + get { return 1; } + } + + int _size; + public int Size + { + get { return _size; } + set { _size = value; this._cache = new byte[_size]; } + } + + public ByteCacheReader() { } + + public ByteCacheReader(int size) + { + this.Size = size; + } + + public int GetOffset(DeviceAddress start, DeviceAddress end) + { + return start.Area == end.Area && start.DBNumber == end.DBNumber ? start.Start - end.Start : ushort.MaxValue; + } + + public ItemData ReadInt32(DeviceAddress address) + { + return new ItemData(BitConverter.ToInt32(_cache, address.CacheIndex), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadBit(DeviceAddress address) + { + return new ItemData((_cache[address.CacheIndex] & (1 << address.Bit)) != 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + return new ItemData(BitConverter.ToInt16(_cache, address.CacheIndex), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + return new ItemData(_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size = 0xFF) + { + return new ItemData(Encoding.ASCII.GetString(_cache, address.CacheIndex, size), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadFloat(DeviceAddress address) + { + return new ItemData(BitConverter.ToSingle(_cache, address.CacheIndex), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBit(DeviceAddress address, bool bit) + { + _cache[address.CacheIndex] |= (byte)(1 << address.Bit); + return 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + _cache[address.CacheIndex] = bits; + return 0; + } + + public unsafe int WriteInt16(DeviceAddress address, short value) + { + fixed (byte* p1 = _cache) + { + Marshal.WriteInt16((IntPtr)(p1 + address.CacheIndex), value); + } + return 0; + } + + public unsafe int WriteInt32(DeviceAddress address, int value) + { + fixed (byte* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), value); + } + return 0; + } + + public unsafe int WriteFloat(DeviceAddress address, float value) + { + fixed (byte* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), *(int*)&value); + } + return 0; + } + + public int WriteString(DeviceAddress address, string str) + { + byte[] b = Encoding.ASCII.GetBytes(str); + int index = address.CacheIndex; + Array.Copy(_cache, index, b, 0, b.Length); + return 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + byte[] bytes = new byte[size]; + Array.Copy(_cache, address.CacheIndex, bytes, 0, size); + return bytes; + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + if (bit != null && bit.Length > 0) + { + Array.Copy(bit, 0, _cache, address.CacheIndex, bit.Length); + return 0; + } + return -1; + } + } + + public sealed class NetByteCacheReader : ICache + { + byte[] _cache; + public Array Cache { get { return _cache; } } + + public int ByteCount + { + get { return 1; } + } + + int _size; + public int Size + { + get { return _size; } + set { _size = value; this._cache = new byte[_size]; } + } + + public NetByteCacheReader() { } + + public NetByteCacheReader(int size) + { + this.Size = size; + } + + public int GetOffset(DeviceAddress start, DeviceAddress end) + { + return start.Area == end.Area && start.DBNumber == end.DBNumber ? start.Start - end.Start : ushort.MaxValue; + } + + public ItemData ReadInt32(DeviceAddress address) + { + return new ItemData(Utility.NetToInt32(_cache, address.CacheIndex), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadBit(DeviceAddress address) + { + return new ItemData((_cache[address.CacheIndex] & (1 << address.Bit)) != 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + return new ItemData(Utility.NetToInt16(_cache, address.CacheIndex), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + return new ItemData(_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size = 0xFF) + { + return new ItemData(Utility.ConvertToString(_cache, address.CacheIndex, size), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadFloat(DeviceAddress address) + { + return new ItemData(Utility.NetToSingle(_cache, address.CacheIndex), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBit(DeviceAddress address, bool bit) + { + _cache[address.CacheIndex] |= (byte)(1 << address.Bit); + return 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + _cache[address.CacheIndex] = bits; + return 0; + } + + public unsafe int WriteInt16(DeviceAddress address, short value) + { + fixed (byte* p1 = _cache) + { + Marshal.WriteInt16((IntPtr)(p1 + address.CacheIndex), IPAddress.HostToNetworkOrder(value)); + } + return 0; + } + + public unsafe int WriteInt32(DeviceAddress address, int value) + { + fixed (byte* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), IPAddress.HostToNetworkOrder(value)); + } + return 0; + } + + public unsafe int WriteFloat(DeviceAddress address, float value) + { + fixed (byte* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), IPAddress.HostToNetworkOrder(*(int*)(&value))); + } + return 0; + } + + public int WriteString(DeviceAddress address, string str) + { + byte[] b = Encoding.ASCII.GetBytes(str); + int index = address.CacheIndex; + Array.Copy(_cache, index, b, 0, b.Length); + return 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + byte[] bytes = new byte[size]; + Array.Copy(_cache, address.CacheIndex, bytes, 0, size); + return bytes; + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + if (bit != null && bit.Length > 0) + { + Array.Copy(bit, 0, _cache, address.CacheIndex, bit.Length); + return 0; + } + return -1; + } + + } + + public sealed class ShortCacheReader : ICache + { + short[] _cache; + public Array Cache + { + get + { + return _cache; + } + } + + public int ByteCount + { + get { return 2; } + } + + int _size; + public int Size + { + get + { + return _size; + } + set + { + _size = value; + this._cache = new short[_size]; + } + } + + public ShortCacheReader() + { + } + + public ShortCacheReader(int size) + { + this.Size = size; + } + + public int GetOffset(DeviceAddress start, DeviceAddress end) + { + return start.Area == end.Area && start.DBNumber == end.DBNumber ? start.Start - end.Start : ushort.MaxValue; + } + + public ItemData ReadInt32(DeviceAddress address) + { + int startIndex = address.CacheIndex; + int result; + if (startIndex == _cache.Length - 1) + { + result = _cache[startIndex]; + } + else + { + result = (_cache[startIndex + 1] << 16) | ((ushort)_cache[startIndex]); + } + return new ItemData(result, 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadBit(DeviceAddress address) + { + return new ItemData((_cache[address.CacheIndex] & (1 << address.Bit)) != 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + return new ItemData(_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + return new ItemData((byte)_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size) + { + byte[] buffer = new byte[size]; + Buffer.BlockCopy(_cache, 2 * address.CacheIndex, buffer, 0, size); + return new ItemData(Encoding.ASCII.GetString(buffer).Trim(), 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadFloat(DeviceAddress address) + { + int startIndex = address.CacheIndex; + int result; + if (startIndex == _cache.Length - 1) + { + result = _cache[startIndex]; + } + else + { + result = (_cache[startIndex] << 16) | ((ushort)_cache[startIndex + 1]); + } + return new ItemData(*(((float*)&result)), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBit(DeviceAddress address, bool bit) + { + _cache[address.CacheIndex] |= (short)(1 << address.Bit); + return 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + _cache[address.CacheIndex] = bits; + return 0; + } + + public unsafe int WriteInt16(DeviceAddress address, short value) + { + _cache[address.CacheIndex] = value; + return 0; + } + + public unsafe int WriteInt32(DeviceAddress address, int value) + { + fixed (short* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), value); + } + return 0; + } + + public unsafe int WriteFloat(DeviceAddress address, float value) + { + fixed (short* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), *(int*)&value); + } + return 0; + } + + public int WriteString(DeviceAddress address, string str) + { + byte[] b = Encoding.ASCII.GetBytes(str); + int index = address.CacheIndex; + Buffer.BlockCopy(_cache, index, b, 0, b.Length); + return 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + byte[] bytes = new byte[2 * size]; + Buffer.BlockCopy(_cache, address.CacheIndex, bytes, 0, bytes.Length); + return bytes; + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + if (bit != null && bit.Length > 0) + { + Buffer.BlockCopy(bit, 0, _cache, address.CacheIndex, bit.Length); + return 0; + } + return -1; + } + } + + public sealed class NetShortCacheReader : ICache + { + short[] _cache; + public Array Cache + { + get + { + return _cache; + } + } + + public int ByteCount + { + get { return 2; } + } + + int _size; + public int Size + { + get + { + return _size; + } + set + { + _size = value; + this._cache = new short[_size]; + } + } + + public NetShortCacheReader() + { + } + + public NetShortCacheReader(int size) + { + this.Size = size; + } + + public int GetOffset(DeviceAddress start, DeviceAddress end) + { + return start.Area == end.Area && start.DBNumber == end.DBNumber ? start.Start - end.Start : ushort.MaxValue; + } + + public ItemData ReadInt32(DeviceAddress address) + { + int startIndex = address.CacheIndex; + int result; + if (startIndex == _cache.Length - 1) + { + result = _cache[startIndex]; + } + else + { + result = (IPAddress.HostToNetworkOrder(_cache[startIndex]) << 16) | ((ushort)IPAddress.HostToNetworkOrder(_cache[startIndex + 1])); + } + return new ItemData(result, 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadBit(DeviceAddress address) + { + return new ItemData((_cache[address.CacheIndex] & (1 << address.Bit.BitSwap())) != 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + return new ItemData(IPAddress.HostToNetworkOrder(_cache[address.CacheIndex]), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + return new ItemData((byte)IPAddress.HostToNetworkOrder(_cache[address.CacheIndex]), 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadString(DeviceAddress address, ushort size) + { + short[] sarray = new short[size / 2]; + int index = address.CacheIndex; + for (int i = 0; i < sarray.Length; i++) + { + sarray[i] = IPAddress.HostToNetworkOrder(_cache[index + i]); + } + byte[] buffer = new byte[size]; + Buffer.BlockCopy(sarray, 0, buffer, 0, size); + return new ItemData(Encoding.ASCII.GetString(buffer).Trim(), 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadFloat(DeviceAddress address) + { + int startIndex = address.CacheIndex; + int result; + if (startIndex == _cache.Length - 1) + { + result = _cache[startIndex]; + } + else + { + result = (IPAddress.HostToNetworkOrder(_cache[startIndex]) << 16) | ((ushort)IPAddress.HostToNetworkOrder(_cache[startIndex + 1])); + } + return new ItemData(*(((float*)&result)), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBit(DeviceAddress address, bool bit) + { + _cache[address.CacheIndex] |= (short)(1 << address.Bit.BitSwap()); + return 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + _cache[address.CacheIndex] = bits; + return 0; + } + + public unsafe int WriteInt16(DeviceAddress address, short value) + { + _cache[address.CacheIndex] = value; + return 0; + } + + public unsafe int WriteInt32(DeviceAddress address, int value) + { + fixed (short* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), IPAddress.HostToNetworkOrder(value)); + } + return 0; + } + + public unsafe int WriteFloat(DeviceAddress address, float value) + { + fixed (short* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), IPAddress.HostToNetworkOrder(*(int*)&value)); + } + return 0; + } + + public int WriteString(DeviceAddress address, string str) + { + byte[] b = Encoding.ASCII.GetBytes(str); + int index = address.CacheIndex; + Buffer.BlockCopy(_cache, index, b, 0, b.Length); + return 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + byte[] bytes = new byte[2 * size]; + Buffer.BlockCopy(_cache, address.CacheIndex, bytes, 0, bytes.Length); + return bytes; + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + if (bit != null && bit.Length > 0) + { + Buffer.BlockCopy(bit, 0, _cache, address.CacheIndex, bit.Length); + return 0; + } + return -1; + } + } + + public sealed class IntCacheReader : ICache + { + int[] _cache; + + public Array Cache + { + get + { + return _cache; + } + } + + public int ByteCount + { + get { return 4; } + } + + int _size; + public int Size + { + get + { + return _size; + } + set + { + _size = value; + this._cache = new int[_size]; + } + } + + public IntCacheReader() + { + } + + public IntCacheReader(int size) + { + this.Size = size; + } + + public int GetOffset(DeviceAddress start, DeviceAddress end) + { + return start.Area == end.Area && start.DBNumber == end.DBNumber ? start.Start - end.Start : ushort.MaxValue; + } + + public ItemData ReadInt32(DeviceAddress address) + { + + return new ItemData(_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadBit(DeviceAddress address) + { + return new ItemData((_cache[address.CacheIndex] & (1 << address.Bit)) != 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + return new ItemData((short)(_cache[address.CacheIndex]), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + return new ItemData((byte)_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size) + { + byte[] buffer = new byte[size]; + Buffer.BlockCopy(_cache, 4 * address.CacheIndex, buffer, 0, size); + return new ItemData(Encoding.ASCII.GetString(buffer).Trim(), 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadFloat(DeviceAddress address) + { + int result = _cache[address.CacheIndex]; + return new ItemData(*(((float*)&result)), 0, QUALITIES.QUALITY_GOOD);//寮哄埗灏4瀛楄妭杞崲涓烘诞鐐规牸寮 + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBit(DeviceAddress address, bool bit) + { + _cache[address.CacheIndex] |= (1 << address.Bit); + return 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + _cache[address.CacheIndex] = bits; + return 0; + } + + public unsafe int WriteInt16(DeviceAddress address, short value) + { + _cache[address.CacheIndex] = value; + return 0; + } + + public unsafe int WriteInt32(DeviceAddress address, int value) + { + _cache[address.CacheIndex] = value; + return 0; + } + + public unsafe int WriteFloat(DeviceAddress address, float value) + { + fixed (int* p1 = _cache) + { + Marshal.WriteInt32((IntPtr)(p1 + address.CacheIndex), *(int*)&value); + } + return 0; + } + + public int WriteString(DeviceAddress address, string str) + { + byte[] b = Encoding.ASCII.GetBytes(str); + int index = address.CacheIndex; + Buffer.BlockCopy(_cache, index, b, 0, b.Length); + return 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + byte[] bytes = new byte[4 * size]; + Buffer.BlockCopy(_cache, address.CacheIndex, bytes, 0, bytes.Length); + return bytes; + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + if (bit != null && bit.Length > 0) + { + Buffer.BlockCopy(bit, 0, _cache, address.CacheIndex, bit.Length); + return 0; + } + return -1; + } + } + + public sealed class FloatCacheReader : ICache + { + float[] _cache; + + public Array Cache + { + get + { + return _cache; + } + } + + public int ByteCount + { + get { return 4; } + } + + int _size; + public int Size + { + get + { + return _size; + } + set + { + _size = value; + this._cache = new float[_size]; + } + } + + public FloatCacheReader() + { + } + + public FloatCacheReader(int size) + { + this.Size = size; + } + + public int GetOffset(DeviceAddress start, DeviceAddress end) + { + return start.Area == end.Area && start.DBNumber == end.DBNumber ? start.Start - end.Start : ushort.MaxValue; + } + + public ItemData ReadInt32(DeviceAddress address) + { + + return new ItemData((int)_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadBit(DeviceAddress address) + { + return new ItemData(((int)_cache[address.CacheIndex] & (1 << address.Bit)) != 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + return new ItemData((short)(_cache[address.CacheIndex]), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + return new ItemData((byte)_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size) + { + byte[] buffer = new byte[size]; + Buffer.BlockCopy(_cache, 4 * address.CacheIndex, buffer, 0, size); + return new ItemData(Encoding.ASCII.GetString(buffer).Trim(), 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadFloat(DeviceAddress address) + { + return new ItemData(_cache[address.CacheIndex], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBit(DeviceAddress address, bool bit) + { + _cache[address.CacheIndex] = (int)_cache[address.CacheIndex] | (1 << address.Bit); + return 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + _cache[address.CacheIndex] = bits; + return 0; + } + + public unsafe int WriteInt16(DeviceAddress address, short value) + { + _cache[address.CacheIndex] = value; + return 0; + } + + public unsafe int WriteInt32(DeviceAddress address, int value) + { + _cache[address.CacheIndex] = value; + return 0; + } + + public unsafe int WriteFloat(DeviceAddress address, float value) + { + _cache[address.CacheIndex] = value; + return 0; + } + + public int WriteString(DeviceAddress address, string str) + { + byte[] b = Encoding.ASCII.GetBytes(str); + int index = address.CacheIndex; + Buffer.BlockCopy(_cache, index, b, 0, b.Length); + return 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + byte[] bytes = new byte[4 * size]; + Buffer.BlockCopy(_cache, address.CacheIndex, bytes, 0, bytes.Length); + return bytes; + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + if (bit != null && bit.Length > 0) + { + Buffer.BlockCopy(bit, 0, _cache, address.CacheIndex, bit.Length); + return 0; + } + return -1; + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/ClientReader.cs b/SCADA/Program/CoreApp/DataService/DataService/ClientReader.cs new file mode 100644 index 0000000..1b1c7bb --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/ClientReader.cs @@ -0,0 +1,607 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Net; +using System.Text; +using System.Threading; + +namespace DataService +{ + public class ClientReader : IDevice + { + string _ip; + public string ServerName + { + get { return _ip; } + } + + internal Socket tcpSynCl; + internal Socket tcpASynCl; + + public bool IsClosed + { + get + { + //return tcpASynCl.Poll(-1, SelectMode.SelectRead); + return !tcpSynCl.Connected || !tcpASynCl.Connected; + } + } + + private ushort _timeout = 0; + public int TimeOut + { + get { return _timeout; } + } + + + List _grps = new List(1); + public IEnumerable Groups + { + get { return _grps; } + } + + IDataServer _server; + public IDataServer Parent + { + get { return _server; } + } + + public ClientReader(IDataServer server, string ip) + { + _server = server; + _ip = ip; + } + + public bool Connect() + { + try + { + int port = 1000; + IPAddress ip = IPAddress.Parse(_ip); + tcpASynCl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + tcpASynCl.Connect(new IPEndPoint(ip, port)); + tcpASynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, _timeout); + tcpASynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, _timeout); + + tcpSynCl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + tcpSynCl.Connect(new IPEndPoint(ip, port)); + tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, _timeout); + tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, _timeout); + return true; + } + catch (SocketException error) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(error.Message)); + return false; + } + } + + public IGroup AddGroup(string name, ushort id, int updateRate, int timeOut = 0, float deadBand = 0f, bool active = false) + { + ClientGroup grp = new ClientGroup(id, name, updateRate, active, this); + _grps.Add(grp); + return grp; + } + + public int RemoveAllGroup() + { + foreach (IGroup grp in _grps) + { + grp.Dispose(); + } + _grps.Clear(); + return 1; + } + + public event ShutdownRequestEventHandler OnClose; + + public void Dispose() + { + if (tcpSynCl != null) + { + if (tcpSynCl.Connected) + { + try + { + tcpASynCl.Shutdown(SocketShutdown.Both); + tcpSynCl.Shutdown(SocketShutdown.Both); + } + catch { } + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs("SHUTDOWN")); + tcpSynCl.Close(); + tcpASynCl.Close(); + } + tcpSynCl = null; + tcpASynCl = null; + } + RemoveAllGroup(); + } + } + + public class ClientGroup : IGroup + { + public const byte fctHead = 0xAB; + public const byte fctReadSingle = 1; + public const byte fctReadMultiple = 2; + public const byte fctWriteSingle = 5; + public const byte fctWriteMultiple = 15; + + bool _active = false; + public bool IsActive + { + get + { + return _active; + } + set + { + _active = value; + if (value) + { + ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(ReciveData), _tcpASynCl); + } + } + } + + protected ushort _id; + public ushort ID + { + get + { + return _id; + } + } + + protected int _updateRate; + public int UpdateRate + { + get + { + return _updateRate; + } + set + { + _updateRate = value; + } + } + + protected DeviceAddress _start; + public DeviceAddress Start + { + get + { + return _start; + } + } + + public int Size + { + get + { + return _items == null ? 0 : _items.Length; + } + } + + protected string _name; + public string Name + { + get + { + return _name; + } + } + + protected float _deadband; + public float DeadBand + { + get + { + return _deadband; + } + set + { + _deadband = value; + } + } + + protected ClientReader _plcReader; + public IDevice Parent + { + get + { + return _plcReader; + } + } + + protected ITag[] _items; + public IEnumerable Items + { + get { return _items; } + } + + IDataServer _server; + Socket _tcpSynCl, _tcpASynCl; + + byte[] tcpSynClBuffer; + + public ClientGroup(ushort id, string name, int updateRate, bool active, ClientReader plcReader) + { + this._id = id; + this._name = name; + this._updateRate = updateRate; + this._active = active; + this._plcReader = plcReader; + this._server = plcReader.Parent; + this._tcpASynCl = plcReader.tcpASynCl; + this._tcpSynCl = plcReader.tcpASynCl; + tcpSynClBuffer = new byte[_tcpASynCl.ReceiveBufferSize]; + } + + private byte[] ReadSingleData(DeviceAddress address, DataSource source = DataSource.Cache) + { + short ID = (short)address.Start; + byte type = (byte)address.VarType; + byte[] idbits = BitConverter.GetBytes(ID); + byte[] write_data = new byte[6] { fctHead, fctReadSingle, + source == DataSource.Cache?(byte)0:(byte)1, idbits[0], idbits[1], type }; + byte[] data = new byte[type < 4 ? 1 : type < 6 ? 2 : 4]; + SocketError error; + _tcpSynCl.Send(write_data, 0, 6, SocketFlags.None, out error); + int result = _tcpSynCl.Receive(tcpSynClBuffer, 0, data.Length + 3, SocketFlags.None, out error); + Array.Copy(tcpSynClBuffer, 3, data, 0, data.Length); + if (error == SocketError.Success) + return data; + else + { + throw new SocketException((int)error); + } + } + + + private int WriteSingleData(DeviceAddress address, byte[] value) + { + short ID = (short)address.Start; + byte type = (byte)address.VarType; + byte[] idbits = BitConverter.GetBytes(ID); + byte[] write_data = new byte[6] { fctHead, fctWriteSingle, 1, idbits[0], idbits[1], type }; + byte[] data = new byte[6 + value.Length]; + write_data.CopyTo(data, 0); + value.CopyTo(data, 6); + SocketError error; + _tcpSynCl.Send(data, 0, data.Length, SocketFlags.None, out error); + int result = _tcpSynCl.Receive(tcpSynClBuffer, 0, 2, SocketFlags.None, out error); + if (error == SocketError.Success) + return tcpSynClBuffer[1]; + else + { + throw new SocketException((int)error); + } + } + + + public void Init() + { + if (_items != null) + { + for (int i = 0; i < _items.Length; i++) + { + _items[i].Value = _items[i].Read(DataSource.Cache);//DataSource.Device + } + } + } + + private void ReciveData(object state) + { + if (state == null || !_active) return; + byte[] bytes = new byte[_tcpASynCl.ReceiveBufferSize]; + int result = 0; + SocketError error; + do + { + result = _tcpASynCl.Receive(bytes, 0, bytes.Length, SocketFlags.None, out error); + if (result > 5 && bytes[0] == 0xAB) + { + short len = BitConverter.ToInt16(bytes, 1); + short count = BitConverter.ToInt16(bytes, 3); + int j = 5; + DateTime time = DateTime.UtcNow; + Storage value = Storage.Empty; + for (int i = 0; i < count; i++) + { + short id = BitConverter.ToInt16(bytes, j); + j += 2; + ITag tag = GetItemByID(id); + if (tag != null) + { + DataType type = (DataType)bytes[j++]; + switch (type) + { + case DataType.BOOL: + value.Boolean = BitConverter.ToBoolean(bytes, j++); + break; + case DataType.BYTE: + value.Byte = bytes[j++]; + break; + case DataType.SHORT: + value.Int16 = BitConverter.ToInt16(bytes, j); + j += 2; + break; + case DataType.INT: + value.Int32 = BitConverter.ToInt32(bytes, j); + j += 4; + break; + case DataType.FLOAT: + value.Single = BitConverter.ToSingle(bytes, j); + j += 4; + break; + } + tag.Update(value, time, QUALITIES.QUALITY_GOOD); + } + else + { + byte type = bytes[j]; + j += (type < 4 ? 2 : type < 6 ? 3 : 5); + } + } + //Array.Clear(bytes, 0, count); + } + } + while (result > 0); + } + + public bool AddItems(ItemMetaData[] items) + { + int count = items.Length; + if (_items == null) _items = new ITag[count]; + for (int i = 0; i < count; i++) + { + ITag dataItem = null; + ItemMetaData meta = items[i]; + DeviceAddress addr = new DeviceAddress(0, 0, meta.ID, meta.Size, 0, meta.DataType); + switch (meta.DataType) + { + case DataType.BOOL: + dataItem = new BoolTag(meta.ID, addr, this); + break; + case DataType.BYTE: + dataItem = new ByteTag(meta.ID, addr, this); + break; + case DataType.WORD: + case DataType.SHORT: + dataItem = new ShortTag(meta.ID, addr, this); + break; + case DataType.TIME: + case DataType.INT: + dataItem = new IntTag(meta.ID, addr, this); + break; + case DataType.FLOAT: + dataItem = new FloatTag(meta.ID, addr, this); + break; + case DataType.STR: + dataItem = new StringTag(meta.ID, addr, this); + break; + default: + dataItem = new BoolTag(meta.ID, addr, this); + break; + } + _items[i] = dataItem; + _server.AddItemIndex(meta.Name, dataItem); + } + Array.Sort(_items); + Init(); + return true; + } + + public bool RemoveAll() + { + Array.Clear(_items, 0, _items.Length); + return true; + } + + public bool SetActiveState(bool active, params short[] items) + { + return true; + } + + public int FindItemByAddress(DeviceAddress addr) + { + return Array.BinarySearch(_items, new BoolTag(0, addr, null)); + } + + public ITag GetItemByID(short id) + { + return _server[id]; + } + + public int BatchRead(DataSource source, bool isSync, params ITag[] itemArray) + { + if (itemArray == null) return -1; + int len = itemArray.Length; + byte[] bt = new byte[4]; + byte[] data = new byte[3 + len * 2]; + int j=0; + data[j++] = fctHead; + data[j++] = fctReadMultiple; + data[j++] = source == DataSource.Cache ? (byte)0 : (byte)1; + bt = BitConverter.GetBytes(itemArray.Length); + data[j++] = bt[0]; + data[j++] = bt[1]; + data[j++] = bt[2]; + data[j++] = bt[3]; + for (int i = 0; i < len; i++) + { + ITag tag = itemArray[i]; + bt = BitConverter.GetBytes(tag.ID); + data[j++] = bt[0]; + data[j++] = bt[1]; + data[j++] = (byte)(tag.Address.DataSize >> 3); + } + SocketError error; + _tcpSynCl.Send(data, 0, data.Length, SocketFlags.None, out error); + int result = _tcpSynCl.Receive(tcpSynClBuffer, 0, tcpSynClBuffer.Length, SocketFlags.None, out error); + j = 2; + if (error == SocketError.Success) + { + DateTime time=DateTime.UtcNow; + Storage value=Storage.Empty; + for (int i = 0; i < len; i++) + { + ITag tag = itemArray[i]; + switch (tag.Address.VarType) + { + case DataType.BOOL: + value.Boolean = BitConverter.ToBoolean(tcpSynClBuffer, j++); + break; + case DataType.BYTE: + value.Byte = tcpSynClBuffer[j++]; + break; + case DataType.SHORT: + value.Int16 = BitConverter.ToInt16(tcpSynClBuffer, j); + j += 2; + break; + case DataType.INT: + value.Int32 = BitConverter.ToInt32(tcpSynClBuffer, j); + j += 4; + break; + case DataType.FLOAT: + value.Single = BitConverter.ToSingle(tcpSynClBuffer, j); + j += 4; + break; + } + tag.Update(value, time, QUALITIES.QUALITY_GOOD); + } + return 0; + } + else + { + throw new SocketException((int)error); + } + } + + public int BatchWrite(IDictionary items, bool isSync = true) + { + List list = new List(new byte[] { fctHead, fctWriteMultiple }); + list.AddRange(BitConverter.GetBytes(items.Count)); + foreach (var item in items) + { + ITag tag = item.Key; + list.AddRange(BitConverter.GetBytes(tag.ID)); + switch (tag.Address.VarType) + { + case DataType.BOOL: + list.Add((bool)item.Value ? (byte)1 : (byte)0); + break; + case DataType.BYTE: + list.Add((byte)item.Value); + break; + case DataType.SHORT: + list.AddRange(BitConverter.GetBytes((short)item.Value)); + break; + case DataType.INT: + list.AddRange(BitConverter.GetBytes((int)item.Value)); + break; + case DataType.FLOAT: + list.AddRange(BitConverter.GetBytes((float)item.Value)); + break; + } + } + SocketError error; + _tcpSynCl.Send(list.ToArray(), 0, list.Count, SocketFlags.None, out error); + int result = _tcpSynCl.Receive(tcpSynClBuffer, 0, 2, SocketFlags.None, out error); + if (error == SocketError.Success) + return tcpSynClBuffer[1]; + else + { + throw new SocketException((int)error); + } + } + + + public ItemData ReadInt32(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt32(data, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt16(data, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(data[0], 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadFloat(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + if (data == null) + return new ItemData(0.0f, 0, QUALITIES.QUALITY_BAD); + else + { + int value = BitConverter.ToInt32(data, 0); + return new ItemData(*(((float*)&value)), 0, QUALITIES.QUALITY_GOOD); + } + } + + public ItemData ReadBool(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(false, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToBoolean(data, address.Bit), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, DataSource source = DataSource.Cache) + { + var data = ReadSingleData(address, source); + return data == null ? new ItemData(string.Empty, 0, QUALITIES.QUALITY_BAD) : + new ItemData(Encoding.Default.GetString(data, 0, address.DataSize), 0, QUALITIES.QUALITY_GOOD); + } + + public int WriteInt32(DeviceAddress address, int value) + { + return WriteSingleData(address, BitConverter.GetBytes(value)); + } + + public int WriteInt16(DeviceAddress address, short value) + { + return WriteSingleData(address, BitConverter.GetBytes(value)); + } + + public int WriteFloat(DeviceAddress address, float value) + { + return WriteSingleData(address, BitConverter.GetBytes(value)); + } + + public int WriteString(DeviceAddress address, string value) + { + return WriteSingleData(address, Encoding.ASCII.GetBytes(value)); + } + + public int WriteBit(DeviceAddress address, bool value) + { + return WriteSingleData(address, new byte[] { (byte)(value ? 1 : 0) }); + } + + public int WriteBits(DeviceAddress address, byte value) + { + return WriteSingleData(address, new byte[] { value }); + } + + public event DataChangeEventHandler DataChange; + + public void Dispose() + { + RemoveAll(); + _items = null; + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/Condition.cs b/SCADA/Program/CoreApp/DataService/DataService/Condition.cs new file mode 100644 index 0000000..1a0c23d --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/Condition.cs @@ -0,0 +1,1104 @@ +锘縰sing System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace DataService +{ + public delegate void AlarmEventHandler(object sender, AlarmItem e); + + public interface IEvent + { + bool IsEnabled { get; set; } + bool IsAcked { get; set; } + bool IsActived { get; set; } + Severity Severity { get; } + EventType EventType { get; } + DateTime LastActive { get; set; } + string Comment { get; } + } + + public abstract class ICondition : IEvent, IDisposable, IComparable, IEquatable + { + public const string ALARMSTOP = "Alarm Clear"; + protected bool _enable, _ack, _active; + protected int _id; + protected DateTime _timeStamp; + protected SubAlarmType _tempType; + protected SubCondition[] _subConditions; + + public int ID + { + get + { + return _id; + } + set + { + _id = value; + } + } + + public bool IsEnabled + { + get + { + return _enable; + } + set + { + _enable = value; + } + } + + public bool IsActived + { + get + { + return _active; + } + set + { + _active = value; + } + } + + public bool IsAcked + { + get + { + return _ack; + } + set + { + _ack = value; + if (_ack) + { + _tempType = SubAlarmType.None; + _lastAckTime = DateTime.Now; + if (_ack && AlarmAck != null) + { + foreach (EventHandler deleg in AlarmAck.GetInvocationList()) + { + deleg.BeginInvoke(this, EventArgs.Empty, null, null); + } + } + } + } + } + + public abstract AlarmType AlarmType + { + get; + } + + public EventType EventType + { + get + { + return EventType.ConditionEvent; + } + } + + + protected ConditionType _conditionType; + public ConditionType ConditionType + { + get + { + return _conditionType; + } + set + { + _conditionType = value; + } + } + + protected DateTime _lastAckTime, _condLastActive, _lastInactive; + public DateTime LastAckTime + { + get + { + return _lastAckTime; + } + set + { + _lastAckTime = value; + } + } + + public DateTime SubCondLastActive + { + get + { + return _current.StartTime; + } + //set + //{ + // _subCondLastActive = value; + //} + } + + public DateTime LastActive + { + get + { + return _condLastActive; + } + set + { + _condLastActive = value; + } + } + + public DateTime LastInactive + { + get + { + return _lastInactive; + } + set + { + _lastInactive = value; + } + } + + protected AlarmItem _current; + + protected SubAlarmType _activeSub; + public SubAlarmType ActiveSubCondition + { + get + { + return _activeSub; + } + protected set + { + _activeSub = value; + } + } + + public Severity Severity + { + get + { + return _current.Severity; + } + } + + public string Message + { + get + { + return _current.AlarmText; + } + } + + public abstract string Value + { + get; + } + + protected float _para; + public float Para + { + get + { + return _para; + } + set + { + _para = value; + } + } + + protected float _deadBand; + public float DeadBand + { + get + { + return _deadBand; + } + set + { + _deadBand = value; + } + } + + protected int _delay; + public int Delay + { + get + { + return _delay; + } + set + { + _delay = value; + } + } + + protected string _comment; + public string Comment + { + get + { + return _comment; + } + set + { + _comment = value; + } + } + + protected string _source; + public string Source + { + get + { + return _source; + } + } + + public IList SubConditions + { + get + { + return _subConditions; + } + } + + public AlarmEventHandler AlarmActive; + public EventHandler AlarmAck; + + protected ICondition(int id, ConditionType conditionType, string source, string comment, float para, float deadBand, int delay) + { + this._id = id; + this._conditionType = conditionType; + this._para = para; + this._source = source; + this._comment = comment; + this._deadBand = deadBand; + this._delay = delay; + this._current = new AlarmItem(); + } + + public abstract bool AddSubCondition(SubCondition condition); + + public abstract bool RemoveSubCondition(SubCondition condition); + + protected abstract void OnActive(SubCondition condition, Storage value, DateTime timeStamp); + + protected abstract void OnInActive(Storage value); + + public int CompareTo(ICondition other) + { + int comp1 = ((int)this.Severity).CompareTo((int)other.Severity); + return comp1 == 0 ? this.LastActive.CompareTo(other.LastActive) : -comp1; + } + + public bool Equals(ICondition other) + { + if (other == null) return false; + return this._id == other._id; + } + + public virtual void Dispose() + { + _current = null; + AlarmAck = null; + AlarmActive = null; ; + } + } + + public abstract class SimpleCondition : ICondition, INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + public override string Value + { + get + { + return _tag == null ? null : _tag.ToString(); + } + } + + protected ITag _tag; + public ITag Tag + { + get + { + return _tag; + } + set + { + if (_tag != null) + _tag.ValueChanging -= CheckAlarm; + _tag = value; + if (_tag != null) + _tag.ValueChanging += CheckAlarm; + } + } + + protected SimpleCondition(int id, ConditionType conditionType, string source, string comment, float para, float deadBand, int delay) : + base(id, conditionType, source, comment, para, deadBand, delay) + { + } + + protected override void OnActive(SubCondition condition, Storage value, DateTime timeStamp) + { + if (condition.SubAlarmType != ActiveSubCondition) + { + if (condition.SubAlarmType != _tempType) + { + _timeStamp = timeStamp; + _tempType = condition.SubAlarmType; + } + if (_delay == 0 || (timeStamp - _timeStamp).TotalMilliseconds > _delay) + { + if (ActiveSubCondition == SubAlarmType.None) + { + _active = true; + _condLastActive = timeStamp; + } + _ack = false; + ActiveSubCondition = condition.SubAlarmType; + _current.Duration = timeStamp - SubCondLastActive; + _current = new AlarmItem(timeStamp, condition.Message, _tag.GetValue(value), ActiveSubCondition, condition.Severity, _id, _source); + if (AlarmActive != null) + { + foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList()) + { + deleg.BeginInvoke(this, _current, null, null); + } + } + RaiseChanged("Value"); + } + } + else + { + RaiseChanged("Value"); + } + } + + protected override void OnInActive(Storage value) + { + if (ActiveSubCondition != SubAlarmType.None) + { + _active = false; + ActiveSubCondition = SubAlarmType.None; + _current.Duration = DateTime.Now - SubCondLastActive; + _current = new AlarmItem(DateTime.Now, string.Concat("銆", _current.AlarmText, "銆", ALARMSTOP), _tag.GetValue(value), SubAlarmType.None, Severity.Normal, _id, _source); + if (AlarmActive != null) + { + foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList()) + { + deleg.BeginInvoke(this, _current, null, null); + } + } + } + } + + protected void RaiseChanged(string property) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(property)); + } + } + + public override void Dispose() + { + base.Dispose(); + PropertyChanged = null; + if (_tag != null) + _tag.ValueChanging -= CheckAlarm; + } + + protected abstract void CheckAlarm(object sender, ValueChangingEventArgs e); + + public override AlarmType AlarmType + { + get + { + return AlarmType.None; + } + } + + public override bool AddSubCondition(SubCondition condition) + { + return true; + } + + public override bool RemoveSubCondition(SubCondition condition) + { + return true; + } + } + + public sealed class ComplexCondition : ICondition, INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + public override string Value + { + get + { + return Convert.ToString(_current.AlarmValue); + } + } + + public ComplexCondition(int id, string source, string comment, float deadBand, int delay) : + base(id, ConditionType.Absolute, source, comment, 0f, deadBand, delay) + { + _subConditions = new SubCondition[1] + { + new SubCondition(SubAlarmType.Dsc) + }; + } + + protected override void OnActive(SubCondition condition, Storage value, DateTime timeStamp) + { + if (condition.SubAlarmType != ActiveSubCondition) + { + if (condition.SubAlarmType != _tempType) + { + _timeStamp = timeStamp; + _tempType = condition.SubAlarmType; + } + if (_delay == 0 || (timeStamp - _timeStamp).TotalMilliseconds > _delay) + { + if (ActiveSubCondition == SubAlarmType.None) + { + _active = true; + _condLastActive = timeStamp; + } + _ack = false; + ActiveSubCondition = condition.SubAlarmType; + _current.Duration = timeStamp - SubCondLastActive; + _current = new AlarmItem(timeStamp, condition.Message, true, ActiveSubCondition, condition.Severity, _id, _source); + if (AlarmActive != null) + { + foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList()) + { + deleg.BeginInvoke(this, _current, null, null); + } + } + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("Value")); + } + } + } + else + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("Value")); + } + } + } + + protected override void OnInActive(Storage value) + { + if (ActiveSubCondition != SubAlarmType.None) + { + _active = false; + ActiveSubCondition = SubAlarmType.None; + _current.Duration = DateTime.Now - SubCondLastActive; + _current = new AlarmItem(DateTime.Now, string.Concat("銆", _current.AlarmText, "銆", ALARMSTOP), false, SubAlarmType.None, Severity.Normal, _id, _source); + if (AlarmActive != null) + { + foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList()) + { + deleg.BeginInvoke(this, _current, null, null); + } + } + } + } + + public Action SetFunction(Delegate tagChanged) + { + var _func = tagChanged as Func; + if (_func != null) + { + return delegate + { + if (_enable) + { + SubCondition condition = _subConditions[0]; + if (condition.IsEnabled) + { + if (_func()) + { + OnActive(condition, Storage.Empty, DateTime.Now); + return; + } + } + OnInActive(Storage.Empty); + } + }; + } + else + return null; + } + + public override void Dispose() + { + base.Dispose(); + PropertyChanged = null; + } + + public override AlarmType AlarmType + { + get + { + return AlarmType.Complex; + } + } + + public override bool AddSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.Dsc: + _subConditions[0] = condition; + return true; + default: + return false; + } + } + + public override bool RemoveSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.Dsc: + _subConditions[0] = SubCondition.Empty; + return true; + default: + return false; + } + } + + } + + public sealed class LevelAlarm : SimpleCondition + { + public override AlarmType AlarmType + { + get { return AlarmType.Level; } + } + + public LevelAlarm(int id, string source, string comment, float deadBand = 0f, int delay = 0) : + base(id, ConditionType.Absolute, source, comment, 0, deadBand, delay) + { + _subConditions = new SubCondition[4] + { + new SubCondition(SubAlarmType.HiHi), + new SubCondition(SubAlarmType.High), + new SubCondition(SubAlarmType.LoLo), + new SubCondition(SubAlarmType.Low) + }; + } + + protected override void CheckAlarm(object sender, ValueChangingEventArgs e) + { + if (_enable) + { + SubCondition condition; + float value = _tag.ScaleToValue(e.NewValue); + for (int i = 0; i < _subConditions.Length; i++) + { + if (_subConditions[i].IsEnabled) + { + condition = _subConditions[i]; + if (i < 2)//Hi Alarm + { + if (value > condition.Threshold) + { + OnActive(condition, e.NewValue, e.NewTimeStamp); + return; + } + else if (_deadBand > 0 && ActiveSubCondition == condition.SubAlarmType && value > condition.Threshold - _deadBand) + { + return; + } + } + else//Low Alarm + { + if (value < condition.Threshold) + { + OnActive(condition, e.NewValue, e.NewTimeStamp); + return; + } + else if (_deadBand > 0 && ActiveSubCondition == condition.SubAlarmType && value > condition.Threshold + _deadBand) + { + return; + } + } + } + } + OnInActive(e.NewValue); + } + } + + public override bool AddSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.HiHi: + _subConditions[0] = condition; + return true; + case SubAlarmType.High: + _subConditions[1] = condition; + return true; + case SubAlarmType.LoLo: + _subConditions[2] = condition; + return true; + case SubAlarmType.Low: + _subConditions[3] = condition; + return true; + default: + return false; + } + } + + public override bool RemoveSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.HiHi: + _subConditions[0] = SubCondition.Empty; + return true; + case SubAlarmType.High: + _subConditions[1] = SubCondition.Empty; + return true; + case SubAlarmType.LoLo: + _subConditions[2] = SubCondition.Empty; + return true; + case SubAlarmType.Low: + _subConditions[3] = SubCondition.Empty; + return true; + default: + return false; + } + } + } + + public sealed class DevAlarm : SimpleCondition + { + public override AlarmType AlarmType + { + get { return AlarmType.Dev; } + } + + public DevAlarm(int id, ConditionType conditionType, string source, string comment, float para, float deadBand = 0f, int delay = 0) : + base(id, conditionType, source, comment, para, deadBand, delay) + { + _subConditions = new SubCondition[2] + { + new SubCondition(SubAlarmType.MajDev), + new SubCondition(SubAlarmType.MinDev) + }; + } + + protected override void CheckAlarm(object sender, ValueChangingEventArgs e) + { + if (_enable) + { + float value = _tag.ScaleToValue(e.NewValue) - _para; + SubCondition condition; + for (int i = 0; i < _subConditions.Length; i++) + { + if (_subConditions[i].IsEnabled) + { + condition = _subConditions[i]; + if (value > (_conditionType == ConditionType.Absolute ? condition.Threshold : _para * condition.Threshold)) + { + OnActive(condition, e.NewValue, e.NewTimeStamp); + return; + } + else if (_deadBand > 0 && ActiveSubCondition == condition.SubAlarmType && + ((_conditionType == ConditionType.Absolute && value > condition.Threshold - _deadBand) + || (_conditionType == ConditionType.Percent && value > _para * (condition.Threshold - _deadBand)))) + { + return; + } + } + } + OnInActive(e.NewValue); + } + } + + public override bool AddSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.MajDev: + _subConditions[0] = condition; + return true; + case SubAlarmType.MinDev: + _subConditions[1] = condition; + return true; + default: + return false; + } + } + + public override bool RemoveSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.MajDev: + _subConditions[0] = SubCondition.Empty; + return true; + case SubAlarmType.MinDev: + _subConditions[1] = SubCondition.Empty; + return true; + default: + return false; + } + } + } + + public sealed class DigitAlarm : SimpleCondition + { + public override AlarmType AlarmType + { + get { return AlarmType.Dsc; } + } + + public DigitAlarm(int id, string source = null, string comment = null, int delay = 0) : + base(id, ConditionType.Absolute, source, comment, 0, 0f, delay) + { + _subConditions = new SubCondition[1] + { + new SubCondition(SubAlarmType.Dsc) + }; + } + + protected override void CheckAlarm(object sender, ValueChangingEventArgs e) + { + if (_enable) + { + SubCondition condition = _subConditions[0]; + if (condition.IsEnabled) + { + if (e.NewValue.Boolean == condition.Threshold > 0) + { + OnActive(condition, e.NewValue, e.NewTimeStamp); + return; + } + } + OnInActive(e.NewValue); + } + } + + public override bool AddSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.Dsc: + _subConditions[0] = condition; + return true; + default: + return false; + } + } + + public override bool RemoveSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.Dsc: + _subConditions[0] = SubCondition.Empty; + return true; + default: + return false; + } + } + } + + public sealed class WordDigitAlarm : SimpleCondition + { + public override AlarmType AlarmType + { + get { return AlarmType.WordDsc; } + } + + public WordDigitAlarm(int id, string source = null, string comment = null, int delay = 0) : + base(id, ConditionType.Absolute, source, comment, 0, 0f, delay) + { + _subConditions = new SubCondition[16]; + for (int i = 0; i < 16; i++) + { + _subConditions[i].SubAlarmType = SubAlarmType.Dsc; + _subConditions[i].Threshold = i; + }; + } + + protected override void CheckAlarm(object sender, ValueChangingEventArgs e) + { + if (_enable) + { + short newvalue = e.NewValue.Int16; + short oldvlaue = e.OldValue.Int16; + if (newvalue == 0 && oldvlaue != 0) + { + OnInActive(e.NewValue); + return; + } + for (short i = 0; i < _subConditions.Length; i++) + { + SubCondition condition = _subConditions[i]; + if (condition.IsEnabled) + { + int mask = 1 << i; + int newval = mask & newvalue; + int oldval = mask & oldvlaue; + if (newval != 0 && oldval == 0) + { + OnActive(condition, new Storage { Int16 = i }, e.NewTimeStamp); + } + } + } + } + } + + public override bool AddSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.Dsc: + int index = (int)condition.Threshold; + if (index >= 0 && index < 16) + _subConditions[index] = condition; + return true; + default: + return false; + } + } + + public override bool RemoveSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.Dsc: + int index = (int)condition.Threshold; + if (index >= 0 && index < 16) + _subConditions[index] = SubCondition.Empty; + return true; + default: + return false; + } + } + + protected override void OnActive(SubCondition condition, Storage value, DateTime timeStamp) + { + if (ActiveSubCondition == SubAlarmType.None) + { + _active = true; + _condLastActive = timeStamp; + } + _ack = false; + ActiveSubCondition = condition.SubAlarmType; + _current = new AlarmItem(timeStamp, condition.Message, value.Int16, ActiveSubCondition, condition.Severity, _id, _source); + if (AlarmActive != null) + { + foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList()) + { + deleg.BeginInvoke(this, _current, null, null); + } + } + RaiseChanged("Value"); + } + + protected override void OnInActive(Storage value) + { + if (ActiveSubCondition != SubAlarmType.None) + { + _active = false; + ActiveSubCondition = SubAlarmType.None; + _current.Duration = DateTime.Now - LastActive; + _current = new AlarmItem(DateTime.Now, string.Concat("銆", Comment, "銆", ALARMSTOP), 0, SubAlarmType.None, Severity.Normal, _id, _source); + if (AlarmActive != null) + { + foreach (AlarmEventHandler deleg in AlarmActive.GetInvocationList()) + { + deleg.BeginInvoke(this, _current, null, null); + } + } + } + } + } + + public sealed class QualitiesAlarm : SimpleCondition + { + public override AlarmType AlarmType + { + get { return AlarmType.Quality; } + } + + public QualitiesAlarm(int id, string source, string comment, int delay = 0) : + base(id, ConditionType.Absolute, source, comment, 0, 0f, delay) + { + _subConditions = new SubCondition[1] + { + new SubCondition(SubAlarmType.BadPV) + }; + } + + protected override void CheckAlarm(object sender, ValueChangingEventArgs e) + { + if (_enable) + { + SubCondition condition = _subConditions[0]; + if (condition.IsEnabled) + { + if (e.Quality != QUALITIES.QUALITY_GOOD) + OnActive(condition, e.NewValue, e.NewTimeStamp); + return; + } + OnInActive(e.NewValue); + } + } + + public override bool AddSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.BadPV: + _subConditions[0] = condition; + return true; + default: + return false; + } + } + + public override bool RemoveSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.BadPV: + _subConditions[0] = SubCondition.Empty; + return true; + default: + return false; + } + } + } + + public sealed class ROCAlarm : SimpleCondition + { + public override AlarmType AlarmType + { + get { return AlarmType.ROC; } + } + + + public ROCAlarm(int id, string souce, string comment, float deadBand = 0f, int delay = 0) : + base(id, ConditionType.Percent, souce, comment, 0, deadBand, delay) + { + _subConditions = new SubCondition[2] + { + new SubCondition(SubAlarmType.MajROC), + new SubCondition(SubAlarmType.MinROC) + }; + } + + protected override void CheckAlarm(object sender, ValueChangingEventArgs e) + { + if (_enable) + { + float value = (float)((_tag.ScaleToValue(e.NewValue) - e.OldValue.Single) / (e.NewTimeStamp - e.OldTimeStamp).TotalMilliseconds); + SubCondition condition; + for (int i = 0; i < _subConditions.Length; i++) + { + if (_subConditions[i].IsEnabled) + { + condition = _subConditions[i]; + if (value > condition.Threshold) + { + OnActive(condition, e.NewValue, e.NewTimeStamp); + return; + } + else if (_deadBand > 0 && ActiveSubCondition == condition.SubAlarmType && value > condition.Threshold - _deadBand) + { + return; + } + } + } + OnInActive(e.NewValue); + } + } + + public override bool AddSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.MajROC: + _subConditions[0] = condition; + return true; + case SubAlarmType.MinROC: + _subConditions[1] = condition; + return true; + default: + return false; + } + } + + public override bool RemoveSubCondition(SubCondition condition) + { + switch (condition.SubAlarmType) + { + case SubAlarmType.MajROC: + _subConditions[0] = SubCondition.Empty; + return true; + case SubAlarmType.MinROC: + _subConditions[1] = SubCondition.Empty; + return true; + default: + return false; + } + } + } + + public struct SubCondition + { + public bool IsEnabled; + + public SubAlarmType SubAlarmType; + + public Severity Severity; + + public float Threshold; + + public string Message; + + public SubCondition(SubAlarmType type, float threshold = 0f, Severity severity = Severity.Normal, string message = "", bool enabled = true) + { + this.SubAlarmType = type; + this.Threshold = threshold; + this.Severity = severity; + this.Message = message; + this.IsEnabled = enabled; + } + + public static readonly SubCondition Empty = new SubCondition(SubAlarmType.None, 0f, Severity.Normal, "姝e父", false); + } + + public class CompareCondBySource : IComparer + { + public int Compare(ICondition x, ICondition y) + { + if (x == null || x.Source == null) + { + return y == null || y.Source == null ? 0 : 1; + } + else + { + return y == null || y.Source == null ? 1 : x.Source.CompareTo(y.Source); + } + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/DataService.csproj b/SCADA/Program/CoreApp/DataService/DataService/DataService.csproj new file mode 100644 index 0000000..fe04d3e --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/DataService.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp2.0 + + + + true + + + + + + + diff --git a/SCADA/Program/CoreApp/DataService/DataService/DeviceAddress.cs b/SCADA/Program/CoreApp/DataService/DataService/DeviceAddress.cs new file mode 100644 index 0000000..927ec42 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/DeviceAddress.cs @@ -0,0 +1,43 @@ +锘縰sing System; +using System.Runtime.InteropServices; + +namespace DataService +{ + [StructLayout(LayoutKind.Sequential)] + public struct DeviceAddress : IComparable + { + public int Area; + public int Start; + public ushort DBNumber; + public ushort DataSize; + public ushort CacheIndex; + public byte Bit; + public DataType VarType; + + public DeviceAddress(int area, ushort dbnumber, ushort cIndex, int start, ushort size, byte bit, DataType type) + { + Area = area; + DBNumber = dbnumber; + CacheIndex = cIndex; + Start = start; + DataSize = size; + Bit = bit; + VarType = type; + } + + public static readonly DeviceAddress Empty = new DeviceAddress(0, 0, 0, 0, 0, 0, DataType.NONE); + + public int CompareTo(DeviceAddress other) + { + return this.Area > other.Area ? 1 : + this.Area < other.Area ? -1 : + this.DBNumber > other.DBNumber ? 1 : + this.DBNumber < other.DBNumber ? -1 : + this.Start > other.Start ? 1 : + this.Start < other.Start ? -1 : + this.Bit > other.Bit ? 1 : + this.Bit < other.Bit ? -1 : 0; + } + } + +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/Eval.cs b/SCADA/Program/CoreApp/DataService/DataService/Eval.cs new file mode 100644 index 0000000..14cb0eb --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/Eval.cs @@ -0,0 +1,716 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace DataService +{ + public class ExpressionEval : IDisposable + { + Expression _param1; + List _tagList = new List(); + public List TagList + { + get + { + return _tagList; + } + } + + IDataServer _server; + + public ExpressionEval(IDataServer server) + { + _server = server; + _param1 = Expression.Constant(this); + } + + public Delegate Eval(string expression) + { + if (string.IsNullOrEmpty(expression)) return null; + var lambda = ComplieRpnExp(RpnExpression(expression)); + if (lambda != null) return lambda.Compile(); + return null; + } + + public Delegate WriteEval(string expression) + { + if (_server == null || string.IsNullOrEmpty(expression)) return null; + if (_server[expression.ToUpper()] != null) + { + return new Func((object value) => { return WriteTag(expression, value); }); + } + return null; + } + + public Func WriteEval(string expression1, string expression2) + { + if (_server == null || string.IsNullOrEmpty(expression2)) return null; + if (_server[expression1.ToUpper()] != null) + { + var dele = Eval(expression2); + var funcbool = dele as Func; + if (funcbool != null) + return () => { return WriteTag(expression1, funcbool()); }; + var funcint = dele as Func; + if (funcint != null) + return () => { return WriteTag(expression1, funcint()); }; + var funcfloat = dele as Func; + if (funcfloat != null) + return () => { return WriteTag(expression1, funcfloat()); }; + var funcstring = dele as Func; + if (funcstring != null) + return () => { return WriteTag(expression1, funcstring()); }; + } + return null; + } + + public static bool ValidationExpression(string expression) + { + return true;//鍙姞鍏ユ鍒欒〃杈惧紡楠岃瘉 + } + + /// + /// 鎿嶄綔绗﹁繍绠楃骇鍒 + /// + /// 鎿嶄綔绗 + /// 鎿嶄綔杩愮畻绗︼紝绌烘牸杩斿洖0锛屽嚭閿欒繑鍥-1 + private static byte GetOperatorLevel(char strOperator) + { + switch (strOperator) + { + case '~': + return 10; + case '*': + case '/': + case '%': + return 9; + case '+': + case '-': + return 8; + case '>': + case '<': + return 7; + case '&': + return 6; + case '^': + return 5; + case '|': + return 4; + case '=': + case '!': + case '?': + return 3; + case '(': + return 2; + case ')': + return 1; + //case ':': + default: + return 0; + + } + } + + /// + /// 灏嗕腑缂琛ㄨ揪寮忚浆鎹负閫嗘尝鍏拌〃杈惧紡 + /// + /// 鏍囧噯涓紑琛ㄨ揪寮 + /// 鏍囧噯閫嗘尝鍏拌〃杈惧紡 + public static List RpnExpression(string expression) + { + //鍔犲叆缁撴潫鏍囪顑 + //瀹氫箟鍑烘爤鍜屽叆鏍堝爢鏍 + string[] strNum = expression.Split('~', '%', '>', '<', '=', '!', '&', '|', '?', '#', '^', '+', '-', '*', '/', '(', ')'); + if (strNum.Length < 2) return new List() { expression }; + //鎿嶄綔杩愮畻绗﹀爢鏍 + Stack oper = new Stack(); + //瀹氫箟杈撳嚭鍫嗘爤 + List output = new List(); + + //瀹氫箟鍓嶇紑琛ㄨ揪寮忓瓧绗﹁鍙栨寚閽 + int i = 0; + + //瀹氫箟褰撳墠璇诲彇鏁板瓧鏁扮粍鎸囬拡 + int n = -1; + //瀹氫箟鎿嶄綔杩愮畻绗︾骇鍒嚱鏁 + Operator op = new Operator(); + //杈撳嚭鍫嗘爤鐨勫ぇ灏 + int intStackCount = 0; + + //浠庡乏鍒板彸璇诲彇鍓嶇紑琛ㄨ揪寮 + while (i < expression.Length) + { + //璇诲彇涓涓瓧绗 + char strChar = expression[i]; + //鍙栧瓧绗︾殑杩愮畻绾у埆 + if (strChar == '#') { i++; continue; } + byte intLevel = GetOperatorLevel(strChar); + if (intLevel == 0) + //鏁板瓧鐩存帴鎺ㄥ叆杈撳嚭鍫嗘爤 + { + while (n++ < strNum.Length) + { + if (strNum[n] != "") + { + output.Add(strNum[n]); + i += strNum[n].Length; + //绉诲姩鏁扮粍鎸囬拡 + break; + } + } + } + else //鎿嶄綔瀛楃鏍规嵁杩愮畻瀛楃绾у埆鎺ㄥ叆杩愮畻绗﹀爢鏍 + { + if (oper.Count == 0) + { + //杩愮畻绗﹀爢鏍堜负绌猴紝鐩存帴鎺ㄥ叆鍫嗘爤 + oper.Push(new Operator(strChar, intLevel)); + //绉诲姩瀛楃璇诲彇鎸囬拡 + i++; + } + else + { + op = oper.Peek(); + if (intLevel > op.Level || intLevel == 2) + { + //杩愮畻瀛楃姣旇繍绠楃鍫嗘爤鏈鍚庣殑绾у埆楂樻垨鑰呰繍绠楃涓'('鐩存帴鎺ㄥ叆杩愮畻绗﹀爢鏍 + oper.Push(new Operator(strChar, intLevel)); + //绉诲姩瀛楃璇诲彇鎸囬拡 + i++; + } + else + { + //杩愮畻瀛楃涓嶉珮浜庤繍绠楃鍫嗘爤鏈鍚庣殑绾у埆锛屽垯灏嗚繍绠楃鍫嗘爤鍑烘爤锛岀洿鍒版瘮鍏堕珮涓烘 + intStackCount = oper.Count; + for (int m = 0; m < intStackCount; m++) + { + op = oper.Peek(); + if (op.Level >= intLevel) + { + //灏嗘搷浣滅鍑烘爤骞跺帇鍏ヨ緭鍏ュ爢鏍 + char o = op.OperatorStack; + if (!(o == ')' || o == '(')) + { + output.Add(o.ToString()); + } + oper.Pop(); + if (op.Level == 2) + { + //濡傛灉鎿嶄綔绗﹀爢鏍堜腑鏈鍚庣殑鎿嶄綔绗︿负'('鍒欏仠姝㈠嚭鏍 + i++; + break; + } + } + else + { + //鐩村埌杩愮畻绗﹀凡缁忛珮鍑鸿繍绠楃鏍堜腑鏈鍚庣殑绾у埆锛屽垯鍏ユ爤 + oper.Push(new Operator(strChar, intLevel)); + i++; + break; + } + } + } + } + } + } + + intStackCount = oper.Count; + for (int m = 0; m < intStackCount; m++) + { + op = oper.Peek(); + output.Add(op.OperatorStack.ToString()); + oper.Pop(); + } + + return output; + } + + /// + /// 瑙i嗘尝鍏拌〃杈惧紡 + /// + /// 鏍囧噯閫嗘尝鍏拌〃杈惧紡 + /// 閫嗘尝鍏拌〃杈惧紡鐨勮В + public LambdaExpression ComplieRpnExp(List strNum) + { + _tagList.Clear(); + //鎷嗗垎閫嗘尝鍏拌〃杈惧紡 + int intLenth = strNum.Count; + if (intLenth == 0) return null; + //瀹氫箟鏁板瓧鍫嗘爤 + try + { + Stack number = new Stack(); + for (int i = 0; i < intLenth; i++) + { + string expr = strNum[i]; + switch (expr) + { + case "~": + if (number.Count > 0) + { + Expression left = number.Pop(); + number.Push(Expression.Not(left)); + } + break; + case "*": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.Multiply(left, right)); + } + break; + case "/": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.Divide(left, right)); + } + break; + case "%": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(int)) + left = Expression.Convert(left, typeof(int)); + if (right.Type != typeof(int)) + right = Expression.Convert(right, typeof(int)); + } + number.Push(Expression.Modulo(left, right)); + } + break; + case "+": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type == typeof(string) || right.Type == typeof(string)) + { + if (left.Type != typeof(string)) + left = Expression.Convert(left, typeof(object)); + if (right.Type != typeof(string)) + right = Expression.Convert(right, typeof(object)); + number.Push(Expression.Call(typeof(string).GetMethod("Concat", new Type[] { typeof(object), typeof(object) }), left, right)); + } + else + { + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.Add(left, right)); + } + } + break; + case "-": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.Subtract(left, right)); + } + break; + case ">": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.GreaterThan(left, right)); + } + break; + case "<": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.LessThan(left, right)); + } + break; + case "&": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + number.Push(Expression.And(left, right)); + } + break; + case "^": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + number.Push(Expression.ExclusiveOr(left, right)); + } + break; + case "|": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + number.Push(Expression.Or(left, right)); + } + break; + case "=": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.Equal(left, right)); + } + break; + case "!": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + number.Push(Expression.NotEqual(left, right)); + } + break; + case "?": + if (number.Count > 1) + { + Expression right = number.Pop(); + Expression left = number.Pop(); + if (left.Type != right.Type) + { + if (left.Type != typeof(float)) + left = Expression.Convert(left, typeof(float)); + if (right.Type != typeof(float)) + right = Expression.Convert(right, typeof(float)); + } + Expression test = number.Pop(); + number.Push(Expression.Condition(test, left, right)); + } + break; + default: + if (expr[0] == '@') + { + switch (expr.Substring(1).ToUpper()) + { + case "TIME": + { + Expression> f = () => DateTime.Now.ToShortTimeString(); + number.Push(f.Body); + } + goto lab1; + case "DATE": + { + Expression> f = () => DateTime.Now.ToShortDateString(); + number.Push(f.Body); + } + goto lab1; + case "DATETIME": + { + Expression> f = () => DateTime.Now.ToString(); + number.Push(f.Body); + } + goto lab1; + case "APP": + { + Expression> f = () => AppDomain.CurrentDomain.FriendlyName; + number.Push(f.Body); + } + goto lab1; + case "NAME": + { + Expression> f = () => Environment.MachineName; + number.Push(f.Body); + } + goto lab1; + case "PATH": + { + Expression> f = () => Environment.CurrentDirectory; + number.Push(f.Body); + } + goto lab1; + case "USER": + { + Expression> f = () => Environment.UserName; + number.Push(f.Body); + } + goto lab1; + case "REGION": + { + Expression> f = () => System.Globalization.CultureInfo.CurrentCulture.Name; + number.Push(f.Body); + } + goto lab1; + } + } + object result; + if (IsConstant(expr, out result)) + { + number.Push(Expression.Constant(result)); + } + else + { + number.Push(GetTagExpression(expr)); + } + lab1: + break; + } + } + + Expression d = number.Pop(); + return Expression.Lambda(d); + } + catch (Exception e) { return null; } + } + + MethodInfo _boolinfo = typeof(ExpressionEval).GetMethod("GetBool"); + MethodInfo _floatinfo = typeof(ExpressionEval).GetMethod("GetFloat"); + MethodInfo _intinfo = typeof(ExpressionEval).GetMethod("GetInt"); + MethodInfo _stringinfo = typeof(ExpressionEval).GetMethod("GetString"); + + public Expression GetTagExpression(string tagName) + { + if (_server == null) return Expression.Empty(); + ITag tag = _server[tagName]; + switch (tag.Address.VarType) + { + case DataType.BOOL: + return Expression.Call(_param1, _boolinfo, Expression.Constant(tagName)); + case DataType.BYTE: + case DataType.WORD: + case DataType.SHORT: + case DataType.TIME: + case DataType.INT: + return Expression.Call(_param1, _intinfo, Expression.Constant(tagName)); + case DataType.FLOAT: + return Expression.Call(_param1, _floatinfo, Expression.Constant(tagName)); + case DataType.STR: + return Expression.Call(_param1, _stringinfo, Expression.Constant(tagName)); + default: + return Expression.Empty(); + } + } + + public bool GetBool(string tagName) + { + if (_server == null) return false; + ITag tag = _server[tagName]; + switch (tag.Address.VarType) + { + case DataType.BOOL: + return tag.Value.Boolean; + case DataType.BYTE: + return Convert.ToBoolean(tag.Value.Byte); + case DataType.WORD: + case DataType.SHORT: + return Convert.ToBoolean(tag.Value.Int16); + case DataType.TIME: + case DataType.INT: + return Convert.ToBoolean(tag.Value.Int32); + case DataType.FLOAT: + return Convert.ToBoolean(tag.Value.Single); + case DataType.STR: + return Convert.ToBoolean(tag.ToString()); + default: + return false; + } + } + + public float GetFloat(string tagName) + { + if (_server == null) return 0f; + ITag tag = _server[tagName]; + return tag.ScaleToValue(tag.Value); + } + + public int GetInt(string tagName) + { + if (_server == null) return 0; + ITag tag = _server[tagName]; + switch (tag.Address.VarType) + { + case DataType.BOOL: + return tag.Value.Boolean ? 1 : 0; + case DataType.BYTE: + return (int)tag.Value.Byte; + case DataType.WORD: + case DataType.SHORT: + return (int)tag.Value.Int16; + case DataType.TIME: + case DataType.INT: + return tag.Value.Int32; + case DataType.FLOAT: + return Convert.ToInt32(tag.Value.Single); + case DataType.STR: + return int.Parse(tag.ToString()); + default: + return 0; + } + } + + public string GetString(string tagName) + { + return _server == null ? null : _server[tagName].ToString(); + } + + public int WriteTag(string tagName, object value) + { + if (_server == null || value == null) return -1; + ITag tag = _server[tagName]; + if (tag.Address.VarType == DataType.BOOL || tag.Address.VarType == DataType.STR) + return tag.Write(value); + else + { + float temp; + string str = value as string; + if (str == null) temp = Convert.ToSingle(value); + else + { + if (!float.TryParse(str, out temp)) + return -1; + } + return tag.Write(tag.ValueToScale(temp)); + } + } + + private bool IsConstant(string str, out object value) + { + if (str.Length > 1 & str[0] == '\'' && str[str.Length - 1] == '\'') + { + value = str.Trim('\''); + return true; + } + string upp = str.ToUpper(); + if (upp == "TRUE") + { + value = true; + return true; + } + else if (upp == "FALSE") + { + value = false; + return true; + } + if (_server != null) + { + var tag = _server[upp]; + if (tag != null) + { + if (!_tagList.Contains(tag)) + _tagList.Add(tag); + value = null; + return false; + } + } + int dotcount = 0; + for (int i = 0; i < str.Length; i++) + { + char opr = str[i]; + if (opr < '0' || opr > '9') + { + if (opr != '.') + { + value = str; + return true; + } + else + { + if (dotcount > 0) + { + value = str; + return true; + } + dotcount++; + } + } + } + //value = (dotcount == 0 ? int.Parse(str) : float.Parse(str)); + if (dotcount == 0) + value = int.Parse(str); + else value = float.Parse(str); + return true; + } + + public void Clear() + { + //_param1 = null; + _tagList.Clear(); + //_tagList = null; + } + + public void Dispose() + { + _param1 = null; + _tagList.Clear(); + _tagList = null; + _boolinfo = _floatinfo = _stringinfo = null; + } + } + + [StructLayout(LayoutKind.Sequential)] + /// + /// 鎿嶄綔绗︾粨鏋 + /// + public struct Operator + { + public char OperatorStack; + public byte Level; + public Operator(char OperatorStack, byte Level) + { + this.OperatorStack = OperatorStack; + this.Level = Level; + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/ExtensionMethods.cs b/SCADA/Program/CoreApp/DataService/DataService/ExtensionMethods.cs new file mode 100644 index 0000000..09ab545 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/ExtensionMethods.cs @@ -0,0 +1,811 @@ +锘縰sing System; +using System.Text; +using System.Net; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Data.SqlClient; + +namespace DataService +{ + public static class ExtMethods + { + public static string GetExceptionMsg(this Exception e) + { + string err = string.Empty; + Exception exp = e; + while (exp != null) + { + err += string.Format("\n {0}", exp.Message); + exp = exp.InnerException; + } + err += string.Format("\n {0}", e.StackTrace); + return err; + } + + public static bool ModifyItemName(this ITag tag, string name) + { + IDataServer server = tag.Parent.Server; + lock (server.SyncRoot) + { + int index = server.GetItemProperties(tag.ID); + if (index < 0) return false; + var meta = server.MetaDataList[index]; + if (meta.Name == name) return true; + server.MetaDataList[index] = new TagMetaData(meta.ID, meta.GroupID, name, meta.Address, meta.DataType, meta.Size, meta.Archive, meta.Maximum, meta.Minimum, meta.Cycle); + server.RemoveItemIndex(meta.Name); + server.AddItemIndex(name, tag); + return true; + } + } + + public static SubCondition FindSubConditon(this IAlarmServer server, string sourceName, SubAlarmType alarmType) + { + var conds = server.QueryConditions(sourceName); + if (conds == null) return SubCondition.Empty; + foreach (ICondition cond in conds) + { + SubCondition sub = cond.FindSubConditon(alarmType); + if (sub.SubAlarmType == alarmType) + return sub; + } + return SubCondition.Empty; + } + + public static SubCondition FindSubConditon(this ICondition cond, SubAlarmType alarmType) + { + var subs = cond.SubConditions; + if (subs != null && subs.Count > 0) + { + foreach (var sub in subs) + { + if (sub.SubAlarmType == alarmType) + { + return sub; + } + } + } + return SubCondition.Empty; + } + + public static bool HasScaling(this IDataServer server, string tagName) + { + ITag tag = server[tagName]; + if (tag == null) return false; + int scaleid = server.GetScaleByID(tag.ID); + return scaleid >= 0; + } + + public static bool HasAlarm(this IDataServer dserver, string sourceName) + { + IAlarmServer server = dserver as IAlarmServer; + if (server == null) return false; + List conds = server.ConditionList as List; + return conds == null || conds.Count == 0 ? false : conds.BinarySearch(new DigitAlarm(0, sourceName)) >= 0; + } + + public static bool HasSubCondition(this IDataServer dserver, string sourceName, SubAlarmType alarmType) + { + IAlarmServer server = dserver as IAlarmServer; + if (server == null) return false; + var conds = server.QueryConditions(sourceName); + if (conds == null) return false; + foreach (ICondition cond in conds) + { + var subs = cond.SubConditions; + if (subs != null && subs.Count > 0) + { + foreach (var sub in subs) + { + if (sub.SubAlarmType == alarmType) + { + return true; + } + } + } + } + return false; + } + + public static ItemData ReadValueEx(this IReaderWriter reader, DeviceAddress address) + { + switch (address.VarType) + { + case DataType.BOOL: + var bit = reader.ReadBit(address); + return new ItemData(bit.Value, bit.TimeStamp, bit.Quality); + case DataType.BYTE: + var bt = reader.ReadByte(address); + return new ItemData(bt.Value, bt.TimeStamp, bt.Quality); + case DataType.WORD: + case DataType.SHORT: + var sh = reader.ReadInt16(address); + return new ItemData(sh.Value, sh.TimeStamp, sh.Quality); + case DataType.TIME: + case DataType.INT: + var it = reader.ReadInt32(address); + return new ItemData(it.Value, it.TimeStamp, it.Quality); + case DataType.FLOAT: + var fl = reader.ReadFloat(address); + return new ItemData(fl.Value, fl.TimeStamp, fl.Quality); + case DataType.STR: + var str = reader.ReadString(address, address.DataSize); + return new ItemData(str.Value, str.TimeStamp, str.Quality); + } + return new ItemData(null, 0, QUALITIES.QUALITY_BAD); + } + + public static int WriteValueEx(this IReaderWriter writer, DeviceAddress address, object value) + { + switch (address.VarType) + { + case DataType.BOOL: + return writer.WriteBit(address, Convert.ToBoolean(value)); + case DataType.BYTE: + return writer.WriteBits(address, Convert.ToByte(value)); + case DataType.WORD: + case DataType.SHORT: + return writer.WriteInt16(address, Convert.ToInt16(value)); + case DataType.TIME: + case DataType.INT: + return writer.WriteInt32(address, Convert.ToInt32(value)); + case DataType.FLOAT: + return writer.WriteFloat(address, Convert.ToSingle(value)); + case DataType.STR: + return writer.WriteString(address, value.ToString()); + } + return -1; + } + + public static HistoryData[] BatchRead(DataSource source, params ITag[] itemArray) + { + int len = itemArray.Length; + HistoryData[] values = new HistoryData[len]; + for (int i = 0; i < len; i++) + { + itemArray[i].Refresh(source); + values[i].ID = itemArray[i].ID; + values[i].Value = itemArray[i].Value; + values[i].TimeStamp = itemArray[i].TimeStamp; + } + return values; + } + + public static int BatchWrite(IDictionary items) + { + int rev = 0; + foreach (var tag in items) + { + if (tag.Key.Write(tag.Value) < 0) + rev = -1; + } + return rev; + } + + public static List AssignFromPDU(this ICache cacheReader, int PDU, params DeviceAddress[] addrsArr) + { + List rangeList = new List(); + int count = addrsArr.Length; + if (count > 0) + { + //Array.Sort(addrsArr); + DeviceAddress start = addrsArr[0]; + start.Bit = 0; + int bitCount = cacheReader.ByteCount; + if (count > 1) + { + int cacheLength = 0;//缂撳啿鍖虹殑澶у皬 + int cacheIndexStart = 0; + int startIndex = 0; + DeviceAddress segmentEnd, tagAddress; + DeviceAddress segmentStart = start; + for (int j = 1, i = 1; i < count; i++, j++) + { + tagAddress = addrsArr[i];//褰撳墠鍙橀噺鍦板潃 + int offset1 = cacheReader.GetOffset(tagAddress, segmentStart); + if (offset1 > (PDU / cacheReader.ByteCount)) + { + segmentEnd = addrsArr[i - 1]; + int len = cacheReader.GetOffset(segmentEnd, segmentStart); + len += segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; + tagAddress.CacheIndex = (ushort)(cacheIndexStart + len); + addrsArr[i] = tagAddress; + rangeList.Add(new PDUArea(segmentStart, len, startIndex, j)); + startIndex += j; j = 0; + cacheLength += len;//鏇存柊缂撳瓨闀垮害 + cacheIndexStart = cacheLength; + segmentStart = tagAddress;//鏇存柊鏁版嵁鐗囨鐨勮捣濮嬪湴鍧 + } + else + { + tagAddress.CacheIndex = (ushort)(cacheIndexStart + offset1); + addrsArr[i] = tagAddress; + } + if (i == count - 1) + { + segmentEnd = addrsArr[i]; + int segmentLength = cacheReader.GetOffset(segmentEnd, segmentStart); + if (segmentLength > PDU / cacheReader.ByteCount) + { + segmentEnd = addrsArr[i - 1]; + segmentLength = segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; + } + tagAddress.CacheIndex = (ushort)(cacheIndexStart + segmentLength); + addrsArr[i] = tagAddress; + segmentLength += segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; + rangeList.Add(new PDUArea(segmentStart, segmentLength, startIndex, j + 1)); + cacheLength += segmentLength; + } + } + cacheReader.Size = cacheLength; + } + else + cacheReader.Size = start.DataSize <= bitCount ? 1 : start.DataSize / bitCount;//鏀瑰彉Cache鐨凷ize灞炴у煎皢鍒涘缓Cache鐨勫唴瀛樺尯鍩 + } + return rangeList; + } + + //璋冪敤鍓嶅簲瀵瑰湴鍧鏁扮粍鎺掑簭(鏄惁鍔犻攣锛) + public static ItemData[] PLCReadMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrsArr) + { + if (addrsArr == null || cache == null || addrsArr.Length == 0) return null; + int len = addrsArr.Length; + ItemData[] items = new ItemData[len]; + int offset = 0; long now = DateTime.Now.ToFileTime(); + List areas = cache.AssignFromPDU(plc.PDU, addrsArr); + foreach (PDUArea area in areas) + { + byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len); + Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length); + offset += rcvBytes.Length / cache.ByteCount; + } + for (int i = 0; i < len; i++) + { + switch (addrsArr[i].VarType) + { + case DataType.BOOL: + items[i].Value.Boolean = cache.ReadBit(addrsArr[i]).Value; + break; + case DataType.BYTE: + items[i].Value.Byte = cache.ReadByte(addrsArr[i]).Value; + break; + case DataType.WORD: + case DataType.SHORT: + items[i].Value.Int16 = cache.ReadInt16(addrsArr[i]).Value; + break; + case DataType.TIME: + case DataType.INT: + items[i].Value.Int32 = cache.ReadInt32(addrsArr[i]).Value; + break; + case DataType.FLOAT: + items[i].Value.Single = cache.ReadFloat(addrsArr[i]).Value; + break; + case DataType.STR: + var item = cache.ReadString(addrsArr[i], addrsArr[i].DataSize); + break; + } + items[i].Quality = QUALITIES.QUALITY_GOOD; + items[i].TimeStamp = now; + } + return items; + } + + public static int PLCWriteMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrArr, object[] buffer, int limit) + { + if (cache == null || addrArr == null || buffer == null || addrArr.Length != buffer.Length) return -1; + if (addrArr.Length == 1) return plc.WriteValue(addrArr[0], buffer[0]); + lock (plc)//涓嶉攣瀹氫細鏈夊苟鍙戝啿绐侀棶棰橈紱閿佸畾涔熶笉鑳戒繚闅滅粷瀵瑰畨鍏紝濡傛湁浜虹幇鍦烘搷浣滀細瀵艰嚧鏁版嵁鍒锋柊 + { + List areas = cache.AssignFromPDU(plc.PDU, addrArr); + int offset = 0; + foreach (PDUArea area in areas) + { + byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len); + if (rcvBytes == null) return -1; + Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length); + offset += rcvBytes.Length / cache.ByteCount; + } + DeviceAddress start = addrArr[0]; + int startIndex = 0; + int endIndex = 0; + while (endIndex < addrArr.Length) + { + if (start.Area != addrArr[endIndex].Area || start.DBNumber != addrArr[endIndex].DBNumber || endIndex - startIndex >= limit) + { + for (int i = startIndex; i < endIndex; i++) + { + cache.WriteValue(addrArr[i], buffer[i]); + } + int c1 = start.CacheIndex; int c2 = addrArr[endIndex - 1].CacheIndex; + byte[] bytes = new byte[cache.ByteCount * (c2 - c1 + 1)]; + Buffer.BlockCopy(cache.Cache, c1, bytes, 0, bytes.Length); + if (plc.WriteBytes(start, bytes) < 0) return -1; + start = addrArr[endIndex]; + startIndex = endIndex; + } + endIndex++; + } + } + return 0; + } + /// + /// string RightFrom + /// + /// + /// + /// + public static string RightFrom(this string text, int index) + { + return text.Substring(index + 1, text.Length - index - 1); + } + + public static string Right(this string text, int length) + { + return text.Substring(text.Length - length, length); + } + + /// + /// Convert to Datetime + /// + /// + /// + + public static DateTime ToDateTime(this long filetime) + { + return filetime == 0 ? DateTime.Now : DateTime.FromFileTime(filetime); + } + + public static Type ToType(this DataType dataType) + { + switch (dataType) + { + case DataType.BOOL: + return typeof(bool); + case DataType.BYTE: + return typeof(byte); + case DataType.WORD: + return typeof(ushort); + case DataType.SHORT: + return typeof(short); + case DataType.INT: + case DataType.TIME: + return typeof(int); + case DataType.FLOAT: + return typeof(float); + case DataType.STR: + return typeof(string); + default: + return typeof(object); + } + } + + public static string ToFormatString(this int num, int len) + { + string str = num.ToString(); + int off = len - str.Length; + return off > 0 ? string.Concat(new string('0', off), str) : str; + } + + public static bool IsEquals(this byte[] b1, byte[] b2) + { + if (b1 == null || b2 == null) return false; + if (b1.Length != b2.Length) return false; + for (int i = 0; i < b1.Length; i++) + if (b1[i] != b2[i]) + return false; + return true; + } + + public static string ConvertToString(this byte[] bits) + { + char[] chars = new char[bits.Length]; + for (int i = 0; i < bits.Length; i++) + { + chars[i] = (char)bits[i]; + } + return new string(chars); + } + + public static byte[] ConvertToArray(this string bits) + { + var chars = bits.ToCharArray(); + byte[] arr = new byte[chars.Length]; + for (int i = 0; i < chars.Length; i++) + { + arr[i] = (byte)chars[i]; + } + return arr; + } + + public static int BitSwap(this byte bit) + { + return (bit < 8 ? bit + 8 : bit - 8); + } + + [Obsolete] + public static Storage ToStorage(this ITag tag, object obj) + { + Storage value = Storage.Empty; + var str = obj as string; + switch (tag.Address.VarType) + { + case DataType.BOOL: + value.Boolean = str == null ? Convert.ToBoolean(obj) : str == "0" ? false : str == "1" ? true : bool.Parse(str); + break; + case DataType.BYTE: + value.Byte = Convert.ToByte(obj); + break; + case DataType.WORD: + case DataType.SHORT: + value.Int16 = Convert.ToInt16(obj); + break; + case DataType.TIME: + case DataType.INT: + value.Int32 = Convert.ToInt32(obj); + break; + case DataType.FLOAT: + value.Single = Convert.ToSingle(obj); + break; + } + return value; + } + + public static byte[] ToByteArray(this ITag tag) + { + switch (tag.Address.VarType) + { + case DataType.BOOL: + return new byte[] { tag.Value.Boolean ? (byte)1 : (byte)0 }; + case DataType.BYTE: + return new byte[] { tag.Value.Byte }; + case DataType.WORD: + case DataType.SHORT: + return BitConverter.GetBytes(tag.Value.Int16); + case DataType.INT: + return BitConverter.GetBytes(tag.Value.Int32); + case DataType.FLOAT: + return BitConverter.GetBytes(tag.Value.Single); + case DataType.STR: + return Encoding.ASCII.GetBytes(tag.ToString()); + default: + return new byte[0]; + } + } + + public static byte[] ToByteArray(this ITag tag, Storage value) + { + switch (tag.Address.VarType) + { + case DataType.BOOL: + return new byte[] { value.Boolean ? (byte)1 : (byte)0 }; + case DataType.BYTE: + return new byte[] { value.Byte }; + case DataType.WORD: + case DataType.SHORT: + return BitConverter.GetBytes(value.Int16); + case DataType.INT: + return BitConverter.GetBytes(value.Int32); + case DataType.FLOAT: + return BitConverter.GetBytes(value.Single); + case DataType.STR: + return Encoding.ASCII.GetBytes(tag.ToString()); + default: + return new byte[0]; + } + } + + public static object GetValue(this ITag tag, Storage value) + { + switch (tag.Address.VarType) + { + case DataType.BOOL: + return value.Boolean; + case DataType.BYTE: + return value.Byte; + case DataType.WORD: + case DataType.SHORT: + return value.Int16; + case DataType.TIME: + case DataType.INT: + return value.Int32; + case DataType.FLOAT: + return value.Single; + case DataType.STR: + return tag.ToString(); + default: + return null; + } + } + + public static float ValueToScale(this ITag tag, float value) + { + IDataServer srv = tag.Parent.Server; + int ind = srv.GetScaleByID(tag.ID); + Scaling meta = ind < 0 ? Scaling.Empty : srv.ScalingList[ind]; + if (meta.ScaleType == ScaleType.None) + { + return value; + } + else + { + double temp = (value - meta.EULo) / (meta.EUHi - meta.EULo); + if (meta.ScaleType == ScaleType.SquareRoot) + temp = temp * temp; + return (meta.RawHi - meta.RawLo) * (float)temp + meta.RawLo; + } + } + + public static float ScaleToValue(this ITag tag, Storage value) + { + DataType type = tag.Address.VarType; + if (type == DataType.BOOL) return value.Boolean ? 1f : 0f; + IDataServer srv = tag.Parent.Server; + int ind = srv.GetScaleByID(tag.ID); + Scaling meta = ind < 0 ? Scaling.Empty : srv.ScalingList[ind]; + if (meta.ScaleType == ScaleType.None) + { + switch (type) + { + case DataType.BYTE: + return (float)value.Byte; + case DataType.WORD: + case DataType.SHORT: + return (float)value.Int16; + case DataType.INT: + return (float)value.Int32; + case DataType.FLOAT: + return value.Single; + case DataType.STR: + return float.Parse(tag.ToString()); + default: + return 0f; + } + } + else + { + double temp; + switch (type) + { + case DataType.BYTE: + temp = (value.Byte - meta.RawLo) / (meta.RawHi - meta.RawLo); + break; + case DataType.WORD: + case DataType.SHORT: + temp = (value.Int16 - meta.RawLo) / (meta.RawHi - meta.RawLo); + break; + case DataType.INT: + temp = (value.Int32 - meta.RawLo) / (meta.RawHi - meta.RawLo); + break; + case DataType.FLOAT: + temp = (value.Single - meta.RawLo) / (meta.RawHi - meta.RawLo); + break; + default: + return 0f; + } + if (meta.ScaleType == ScaleType.SquareRoot) + temp = Math.Sqrt(temp); + return (meta.EUHi - meta.EULo) * (float)temp + meta.EULo; + } + } + + public static float ScaleToValue(this ITag tag) + { + return ScaleToValue(tag, tag.Value); + } + + public static string GetTagName(this ITag tag) + { + IDataServer srv = tag.Parent.Server; + int ind = srv.GetItemProperties(tag.ID); + return ind < 0 ? null : srv.MetaDataList[ind].Name; + } + + public static string GetTagName(this IDataServer srv, short id) + { + int ind = srv.GetItemProperties(id); + return ind < 0 ? null : srv.MetaDataList[ind].Name; + } + + public static TagMetaData GetMetaData(this ITag tag) + { + IDataServer srv = tag.Parent.Server; + int index = srv.GetItemProperties(tag.ID); + return index < 0 ? new TagMetaData() : srv.MetaDataList[index]; + } + } + + public static class Utility + { + private static readonly ushort[] crcTable = { + 0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241, + 0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440, + 0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40, + 0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841, + 0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40, + 0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41, + 0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641, + 0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040, + 0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240, + 0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441, + 0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41, + 0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840, + 0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41, + 0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40, + 0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640, + 0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041, + 0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240, + 0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441, + 0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41, + 0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840, + 0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41, + 0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40, + 0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640, + 0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041, + 0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241, + 0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440, + 0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40, + 0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841, + 0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40, + 0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41, + 0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641, + 0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 + }; + + /// + /// Converts an array of bytes to an ASCII byte array + /// + /// The byte array + /// An array of ASCII byte values + public static string GetAsciiBytes(byte[] numbers) + { + string str = string.Empty; + for (int i = 0; i < numbers.Length; i++) + { + str += numbers[i].ToString("X2"); + } + return str; + } + + /// + /// Converts an array of UInt16 to an ASCII byte array + /// + /// The ushort array + /// An array of ASCII byte values + public static string GetAsciiBytes(ushort[] numbers) + { + string str = string.Empty; + for (int i = 0; i < numbers.Length; i++) + { + str += numbers[i].ToString("X4"); + } + return str; + } + + /// + /// Converts a network order byte array to an array of UInt16 values in host order + /// + /// The network order byte array + /// The host order ushort array + public static ushort[] NetworkBytesToHostUInt16(byte[] networkBytes) + { + if (networkBytes == null) + throw new ArgumentNullException("networkBytes"); + + if (networkBytes.Length % 2 != 0) + throw new FormatException("NetworkBytesNotEven"); + + ushort[] result = new ushort[networkBytes.Length / 2]; + + for (int i = 0; i < result.Length; i++) + result[i] = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(networkBytes, i * 2)); + + return result; + } + + /// + /// Converts a hex string to a byte array. + /// + /// The hex string + /// Array of bytes + public static byte[] HexToBytes(string hex) + { + if (string.IsNullOrEmpty(hex)) + throw new ArgumentNullException("hex"); + + if (hex.Length % 2 != 0) + throw new FormatException("HexCharacterCountNotEven"); + + byte[] bytes = new byte[hex.Length / 2]; + + for (int i = 0; i < bytes.Length; i++) + bytes[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16); + + return bytes; + } + + /// + /// Calculate Longitudinal Redundancy Check. + /// + /// The data used in LRC + /// LRC value + public static byte CalculateLrc(byte[] data, int len = 0) + { + if (data == null) + throw new ArgumentNullException("data"); + if (len == 0) len = data.Length; + byte lrc = 0; + for (int i = 0; i < len; i++) + { lrc += data[i]; } + + lrc = (byte)((lrc ^ 0xFF) + 1); + + return lrc; + } + + /// + /// Calculate Cyclical Redundancy Check + /// + /// The data used in CRC + /// CRC value + public static byte[] CalculateCrc(byte[] data, int len = 0) + { + if (data == null) + throw new ArgumentNullException("data"); + if (len == 0) len = data.Length; + ushort crc = ushort.MaxValue; + for (int i = 0; i < len; i++) + { + byte tableIndex = (byte)(crc ^ data[i]); + crc >>= 8; + crc ^= crcTable[tableIndex]; + } + + return BitConverter.GetBytes(crc); + } + + public static bool CheckSumCRC(byte[] frame) + { + int len = frame.Length; + byte[] chk = CalculateCrc(frame, len - 2); + return (chk[0] == frame[len - 2] && chk[1] == frame[len - 1]); + } + + public static unsafe short NetToInt16(byte[] value, int startIndex) + { + if (value == null || startIndex > value.Length - 2) + { + throw new NotImplementedException(); + } + fixed (byte* numRef = &(value[startIndex])) + { + return (short)((numRef[0] << 8) | numRef[1]); + } + } + + public static unsafe int NetToInt32(byte[] value, int startIndex) + { + if (value == null || startIndex > value.Length - 4) + { + throw new NotImplementedException(); + } + fixed (byte* numRef = &(value[startIndex])) + { + return (int)((numRef[0] << 24) | (numRef[1] << 16) | (numRef[2] << 8) | numRef[3]); + } + } + + public static unsafe float NetToSingle(byte[] value, int startIndex) + { + int a = NetToInt32(value, startIndex); + return *(float*)&a; + } + + public static string ConvertToString(byte[] bytes, int start = 0, int len = 0) + { + //瑗块棬瀛300銆400 + if (bytes == null || bytes.Length == 0) + return string.Empty; + var klen = bytes[start + 1]; + return Encoding.ASCII.GetString(bytes, start + 2, klen).Trim((char)0); + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/HistoryData.cs b/SCADA/Program/CoreApp/DataService/DataService/HistoryData.cs new file mode 100644 index 0000000..fd00199 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/HistoryData.cs @@ -0,0 +1,83 @@ +锘縰sing System; +using System.Collections.Generic; + +namespace DataService +{ + public struct HistoryData : IComparable + { + public short ID; + public QUALITIES Quality; + public Storage Value; + public DateTime TimeStamp; + + public HistoryData(short id, QUALITIES qualitie, Storage value, DateTime timeStamp) + { + ID = id; + Quality = qualitie; + Value = value; + TimeStamp = timeStamp; + } + + public override bool Equals(object obj) + { + if (obj == null) return false; + if (obj is HistoryData) + { + return this == (HistoryData)obj; + } + else return false; + } + + public override int GetHashCode() + { + return ID.GetHashCode() ^ TimeStamp.GetHashCode(); + } + + + public static bool operator ==(HistoryData x, HistoryData y) + { + return x.ID == y.ID && x.TimeStamp == y.TimeStamp; + } + + public static bool operator !=(HistoryData x, HistoryData y) + { + return x.ID != y.ID || x.TimeStamp != y.TimeStamp; + } + + public static readonly HistoryData Empty = new HistoryData(); + + public int CompareTo(HistoryData other) + { + int comp = this.TimeStamp.CompareTo(other.TimeStamp); + return comp == 0 ? this.ID.CompareTo(other.ID) : comp; + } + } + + public struct FileData : IComparable + { + public short ID; + public Storage Value; + public string Text; + + public FileData(short id, Storage value, string text) + { + ID = id; + Value = value; + Text = text; + } + + public int CompareTo(FileData other) + { + return this.ID.CompareTo(other.ID); + } + } + + public class CompareHistoryData : IComparer + { + public int Compare(HistoryData x, HistoryData y) + { + int c1 = x.TimeStamp.CompareTo(y.TimeStamp); + return c1 == 0 ? x.ID.CompareTo(y.ID) : c1; + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/IGroup.cs b/SCADA/Program/CoreApp/DataService/DataService/IGroup.cs new file mode 100644 index 0000000..a3928d4 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/IGroup.cs @@ -0,0 +1,70 @@ +锘縰sing System; +using System.Collections.Generic; + +namespace DataService +{ + public interface IGroup : IDisposable + { + bool IsActive { get; set; } + short ID { get; } + int UpdateRate { get; set; } + float DeadBand { get; set; } + string Name { get; set; } + IDriver Parent { get; } + IDataServer Server { get; } + IEnumerable Items { get; } + bool AddItems(IList items); + bool AddTags(IEnumerable tags); + bool RemoveItems(params ITag[] items); + bool SetActiveState(bool active, params short[] items); + ITag FindItemByAddress(DeviceAddress addr); + HistoryData[] BatchRead(DataSource source, bool isSync, params ITag[] itemArray); + int BatchWrite(SortedDictionary items, bool isSync = true); + ItemData ReadInt32(DeviceAddress address, DataSource source = DataSource.Cache); + ItemData ReadInt16(DeviceAddress address, DataSource source = DataSource.Cache); + ItemData ReadByte(DeviceAddress address, DataSource source = DataSource.Cache); + ItemData ReadFloat(DeviceAddress address, DataSource source = DataSource.Cache); + ItemData ReadBool(DeviceAddress address, DataSource source = DataSource.Cache); + ItemData ReadString(DeviceAddress address, DataSource source = DataSource.Cache); + int WriteInt32(DeviceAddress address, int value); + int WriteInt16(DeviceAddress address, short value); + int WriteFloat(DeviceAddress address, float value); + int WriteString(DeviceAddress address, string value); + int WriteBit(DeviceAddress address, bool value); + int WriteBits(DeviceAddress address, byte value); + event DataChangeEventHandler DataChange; + } + + public class DataChangeEventArgs : EventArgs + { + public DataChangeEventArgs(int transactionID, IList pValues) + { + this.TransactionID = transactionID; + this.Values = pValues; + } + + public int TransactionID; + public IList Values; + } + + public class WriteCompleteEventArgs : EventArgs + { + public WriteCompleteEventArgs(int transactionID, short[] pIds, int[] errors) + { + this.TransactionID = transactionID; + this.Values = pIds; + this.Errors = errors; + } + + public int TransactionID; + public short[] Values; + public int[] Errors; + } + + public delegate void DataChangeEventHandler(object sender, DataChangeEventArgs e); + + public delegate void ReadCompleteEventHandler(object sender, DataChangeEventArgs e); + + public delegate void WriteCompleteEventHandler(object sender, WriteCompleteEventArgs e); + +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/IReader.cs b/SCADA/Program/CoreApp/DataService/DataService/IReader.cs new file mode 100644 index 0000000..2e28be0 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/IReader.cs @@ -0,0 +1,82 @@ +锘縰sing System; +using System.Collections.Generic; + +namespace DataService +{ + public interface IReaderWriter + { + byte[] ReadBytes(DeviceAddress address, ushort size); + ItemData ReadInt32(DeviceAddress address); + ItemData ReadInt16(DeviceAddress address); + ItemData ReadByte(DeviceAddress address); + ItemData ReadString(DeviceAddress address, ushort size); + ItemData ReadFloat(DeviceAddress address); + ItemData ReadBit(DeviceAddress address); + ItemData ReadValue(DeviceAddress address); + + int WriteBytes(DeviceAddress address, byte[] bit); + int WriteBit(DeviceAddress address, bool bit); + int WriteBits(DeviceAddress address, byte bits); + int WriteInt16(DeviceAddress address, short value); + int WriteInt32(DeviceAddress address, int value); + int WriteFloat(DeviceAddress address, float value); + int WriteString(DeviceAddress address, string str); + int WriteValue(DeviceAddress address, object value); + } + + + public interface ICache : IReaderWriter + { + int Size { get; set; } + int ByteCount { get; } + Array Cache { get; } + int GetOffset(DeviceAddress start, DeviceAddress end); + } + + public interface IMultiReadWrite + { + int Limit { get; } + ItemData[] ReadMultiple(DeviceAddress[] addrsArr); + int WriteMultiple(DeviceAddress[] addrArr, object[] buffer); + } + + public interface IDriver : IDisposable + { + short ID { get; } + string Name { get; } + string ServerName { get; set; }//鍙互鑰冭檻澧炲姞涓涓檮鍔犲弬鏁帮紝Sever鍙畾涔夋湰鏈哄悕 + bool IsClosed { get; } + int TimeOut { get; set; } + IEnumerable Groups { get; } + IDataServer Parent { get; } + bool Connect(); + IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false); + bool RemoveGroup(IGroup group); + event ShutdownRequestEventHandler OnClose; + } + + public interface IPLCDriver : IDriver, IReaderWriter + { + int PDU { get; } + DeviceAddress GetDeviceAddress(string address); + string GetAddress(DeviceAddress address); + } + + public interface IFileDriver : IDriver, IReaderWriter + { + string FileName { get; set; } + FileData[] ReadAll(short groupId); + //bool RecieveData(string data); + } + + public class ShutdownRequestEventArgs : EventArgs + { + public ShutdownRequestEventArgs(string reson) + { + shutdownReason = reson; + } + public string shutdownReason; + } + + public delegate void ShutdownRequestEventHandler(object sender, ShutdownRequestEventArgs e); +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/IServer.cs b/SCADA/Program/CoreApp/DataService/DataService/IServer.cs new file mode 100644 index 0000000..4ad8815 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/IServer.cs @@ -0,0 +1,102 @@ +锘縰sing System; +using System.Collections.Generic; + +namespace DataService +{ + //鍘嗗彶鏁版嵁銆佹姤璀︽暟鎹殑鎻愪氦鍜屾暟鎹潎浠庢湇鍔″櫒 + public interface IHDAServer : IDisposable + { + IEnumerable ReadAtTime(params DateTime[] timeStamps); + IEnumerable ReadAtTime(short ID, params DateTime[] timeStamps); + IEnumerable ReadRaw(DateTime start, DateTime end); + IEnumerable ReadRaw(DateTime start, DateTime end, short ID); + //IEnumerable ReadProcessed(DateTime start, DateTime end, HDAAggregate aggregates, params short[] aggregateIDs); + } + + public interface IAlarmServer : IDisposable + { + int DisableCondition(string sourceName, AlarmType type); + int EnableCondition(string sourceName, AlarmType type); + int RemoveConditon(string sourceName, AlarmType type); + int RemoveConditons(string sourceName); + int AckConditions(params ICondition[] conditions); + IList QueryConditions(string sourceName); + IEnumerable AlarmList { get; } + IList ConditionList { get; } + IList ActivedConditionList { get; } + } + + public interface IDataServer : IDisposable + { + ITag this[short id] { get; } + ITag this[string name] { get; } + ExpressionEval Eval { get; } + Object SyncRoot { get; }//瀵规墍鏈夋秹鍙婇泦鍚堟洿鏀归」鐩娇鐢紱鍖呮嫭IGROUP鐨凙DDITEMS + IList MetaDataList { get; } + IList ScalingList { get; } + IEnumerable Drivers { get; } + IEnumerable BrowseItems(BrowseType browseType, string tagName, DataType dataType); + IDriver AddDriver(short id, string name, string server, int timeOut, + string assembly, string className, string spare1, string spare2); + IGroup GetGroupByName(string name); + int GetScaleByID(short id); + int GetItemProperties(short id);//杩斿洖鐨勬槸鍏冩暟鎹湪鍏冩暟鎹垪琛ㄧ殑绱㈠紩 + bool RemoveDriver(IDriver device); + bool AddItemIndex(string key, ITag value); + bool RemoveItemIndex(string key); + void ActiveItem(bool active, params ITag[] items); + int BatchWrite(Dictionary tags, bool sync); + HistoryData[] BatchRead(DataSource source, bool sync, params ITag[] itemArray); + } + + public class FCTCOMMAND + { + public const byte fctHead = 0xAB;//鎶ュご鍙姞瀵嗭紝濡傛姤澶翠笉绗︼紝鍒欎笉杩涜浠讳綍鎿嶄綔锛涘鎴风Socket鍙戦佹姤璀﹁姹傦紝灏佽浜嶴erver + public const byte fctHdaIdRequest = 30; + public const byte fctHdaRequest = 31; + public const byte fctAlarmRequest = 32; + public const byte fctOrderChange = 33; + public const byte fctReset = 34; + public const byte fctXMLHead = 0xEE;//xml鍗忚 + public const byte fctReadSingle = 1; + public const byte fctReadMultiple = 2; + public const byte fctWriteSingle = 5; + public const byte fctWriteMultiple = 15; + } + + public enum HDAAggregate + { + HDANoAggregate, + HDAInterpolative, + HDATotal, + HDAAverage, + HDATimeAverage, + HDACount, + HDAStDev, + HDAMinimumActualTime, + HDAMinimum, + HDAMaximumActualTime, + HDAMaximum, + HDAStart, + HDAEnd, + HDADelta, + HDARegSlope, + HDARegConst, + HDARegDev, + HDAVariance, + HDARange, + HDADurationGood, + HDADurationBad, + HDAPercentGood, + HDAPercentBad, + HDAWorstQuality, + HDAAnnotations, + } + + public enum BrowseType + { + Branch = 1, + Leaf = 2, + Flat = 3 + } +} \ No newline at end of file diff --git a/SCADA/Program/CoreApp/DataService/DataService/ITag.cs b/SCADA/Program/CoreApp/DataService/DataService/ITag.cs new file mode 100644 index 0000000..a08c8df --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/ITag.cs @@ -0,0 +1,633 @@ +锘縰sing System; + +namespace DataService +{ + public abstract class ITag : IComparable + { + protected short _id; + public short ID + { + get + { + return _id; + } + } + + protected bool _active = true; + public bool Active + { + get + { + return _active; + } + set + { + _group.SetActiveState(value, _id); + _active = value; + } + } + + protected QUALITIES _quality; + public QUALITIES Quality + { + get + { + return _quality; + } + } + + protected Storage _value; + public Storage Value + { + get + { + return _value; + } + } + + protected DateTime _timeStamp = DateTime.MinValue; + public DateTime TimeStamp + { + get + { + return _timeStamp; + } + } + + protected DeviceAddress _plcAddress; + public DeviceAddress Address + { + get + { + return _plcAddress; + } + set + { + _plcAddress = value; + } + } + + protected IGroup _group; + public IGroup Parent + { + get + { + return _group; + } + } + + protected ITag(short id, DeviceAddress address, IGroup group) + { + _id = id; + _group = group; + _plcAddress = address; + } + + public void Update(Storage newvalue, DateTime timeStamp, QUALITIES quality) + { + if (_timeStamp > timeStamp) return;//濡傛灉鏃堕棿鎴虫洿鏃ф垨鍊兼湭鏀瑰彉 + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(quality, _value, newvalue, _timeStamp, timeStamp)); + } + _timeStamp = timeStamp; + _quality = quality; + if (quality == QUALITIES.QUALITY_GOOD) + { + _value = newvalue; + if (ValueChanged != null) + { + ValueChanged(this, new ValueChangedEventArgs(_value)); + } + } + } + + public abstract bool Refresh(DataSource source = DataSource.Device); + + public abstract Storage Read(DataSource source = DataSource.Cache); + + protected abstract int InnerWrite(Storage value); + + public abstract int Write(object value); + + public int Write(Storage value, bool bForce) + { + DateTime time = DateTime.Now; + _timeStamp = time; + if (bForce) + { + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(QUALITIES.QUALITY_GOOD, _value, value, _timeStamp, time)); + } + } + int result = InnerWrite(value); + if (bForce || result != 0) + { + var data = Read(DataSource.Device); + if (data != value) + { + time = DateTime.Now; + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(QUALITIES.QUALITY_GOOD, _value, data, _timeStamp, time)); + } + _value = data; + _timeStamp = time; + return result; + } + } + return 0; + } + + public ValueChangingEventHandler ValueChanging; + + public ValueChangedEventHandler ValueChanged; + + #region IComparable Members + + public override int GetHashCode() + { + return _id.GetHashCode(); + } + + public int CompareTo(ITag other) + { + return _plcAddress.CompareTo(other._plcAddress); + } + + #endregion + } + + public sealed class BoolTag : ITag + { + public BoolTag(short id, DeviceAddress addr, IGroup group) + : base(id, addr, group) + { + } + + #region IDevice Members + + public override bool Refresh(DataSource source = DataSource.Cache) + { + var _newvalue = _group.ReadBool(_plcAddress, source); + if (_newvalue.Value != _value.Boolean) + { + Storage value = Storage.Empty; + value.Boolean = _newvalue.Value; + DateTime time = _newvalue.TimeStamp.ToDateTime(); + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(_newvalue.Quality, _value, value, _timeStamp, time)); + } + _timeStamp = time; + _quality = _newvalue.Quality; + if (_quality == QUALITIES.QUALITY_GOOD) + { + _value = value; + if (ValueChanged != null) + { + ValueChanged(this, new ValueChangedEventArgs(value)); + } + } + return true; + } + return false; + } + + public override Storage Read(DataSource source = DataSource.Cache) + { + Storage value = Storage.Empty; + value.Boolean = _group.ReadBool(_plcAddress, source).Value; + return value; + } + + public override int Write(object value) + { + if (value == null) return -1; + bool temp = _value.Boolean; + var str = value as string; + if (str == null) + temp = Convert.ToBoolean(value); + else if (!Boolean.TryParse(str, out temp)) + return -1; + _timeStamp = DateTime.Now; + return _group.WriteBit(_plcAddress, temp); + } + + protected override int InnerWrite(Storage value) + { + return _group.WriteBit(_plcAddress, value.Boolean); + } + + #endregion + + public override string ToString() + { + return _value.Boolean.ToString(); + } + } + + public sealed class ByteTag : ITag + { + + public ByteTag(short id, DeviceAddress addr, IGroup group) + : base(id, addr, group) + { + } + + + #region IDevice Members + public override bool Refresh(DataSource source = DataSource.Device) + { + var _newvalue = _group.ReadByte(_plcAddress, source); + if (_newvalue.Value != _value.Byte) + { + Storage value = Storage.Empty; + value.Byte = _newvalue.Value; + DateTime time = _newvalue.TimeStamp.ToDateTime(); + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(_newvalue.Quality, _value, value, _timeStamp, time)); + } + _timeStamp = time; + _quality = _newvalue.Quality; + if (_quality == QUALITIES.QUALITY_GOOD) + { + _value = value; + if (ValueChanged != null) + { + ValueChanged(this, new ValueChangedEventArgs(value)); + } + } + return true; + } + return false; + } + + public override Storage Read(DataSource source = DataSource.Cache) + { + Storage value = Storage.Empty; + value.Byte = _group.ReadByte(_plcAddress, source).Value; + return value; + } + + public override int Write(object value) + { + byte temp = _value.Byte; + var str = value as string; + if (str == null) + temp = Convert.ToByte(value); + else if (!Byte.TryParse(str, out temp)) + return -1; + _timeStamp = DateTime.Now; + return _group.WriteBits(_plcAddress, temp); + } + + protected override int InnerWrite(Storage value) + { + return _group.WriteBits(_plcAddress, value.Byte); + } + + #endregion + + public override string ToString() + { + return _value.Byte.ToString(); + } + } + + public sealed class ShortTag : ITag + { + + public ShortTag(short id, DeviceAddress addr, IGroup group) + : base(id, addr, group) + { + } + + + #region IDevice Members + public override bool Refresh(DataSource source = DataSource.Device) + { + var _newvalue = _group.ReadInt16(_plcAddress, source); + if (_newvalue.Value != _value.Int16) + { + Storage value = Storage.Empty; + value.Int16 = _newvalue.Value; + DateTime time = _newvalue.TimeStamp.ToDateTime(); + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(_newvalue.Quality, _value, value, _timeStamp, time)); + } + _timeStamp = time; + _quality = _newvalue.Quality; + if (_quality == QUALITIES.QUALITY_GOOD) + { + _value = value; + if (ValueChanged != null) + { + ValueChanged(this, new ValueChangedEventArgs(value)); + } + } + return true; + } + return false; + } + + public override Storage Read(DataSource source = DataSource.Cache) + { + Storage value = Storage.Empty; + value.Int16 = _group.ReadInt16(_plcAddress, source).Value; + return value; + } + + public override int Write(object value) + { + var temp = _value.Int16; + var str = value as string; + if (str == null) + temp = Convert.ToInt16(value); + else if (!short.TryParse(str, out temp)) + return -1; + _timeStamp = DateTime.Now; + return _group.WriteInt16(_plcAddress, temp); + } + + protected override int InnerWrite(Storage value) + { + return _group.WriteInt16(_plcAddress, value.Int16); + } + + #endregion + + public override string ToString() + { + return _value.Int16.ToString(); + } + } + + public sealed class IntTag : ITag + { + + public IntTag(short id, DeviceAddress addr, IGroup group) + : base(id, addr, group) + { + } + + #region IDevice Members + public override bool Refresh(DataSource source = DataSource.Device) + { + var _newvalue = _group.ReadInt32(_plcAddress, source); + if (_newvalue.Value != _value.Int32) + { + Storage value = Storage.Empty; + value.Int32 = _newvalue.Value; + DateTime time = _newvalue.TimeStamp.ToDateTime(); + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(_newvalue.Quality, _value, value, _timeStamp, time)); + } + _timeStamp = time; + _quality = _newvalue.Quality; + if (_quality == QUALITIES.QUALITY_GOOD) + { + _value = value; + if (ValueChanged != null) + { + ValueChanged(this, new ValueChangedEventArgs(value)); + } + } + return true; + } + return false; + } + + public override Storage Read(DataSource source = DataSource.Cache) + { + Storage value = Storage.Empty; + value.Int32 = _group.ReadInt32(_plcAddress, source).Value; + return value; + } + + public override int Write(object value) + { + var temp = _value.Int32; + var str = value as string; + if (str == null) + temp = Convert.ToInt32(value); + else if (!int.TryParse(str, out temp)) + return -1; + _timeStamp = DateTime.Now; + return _group.WriteInt32(_plcAddress, temp); + } + + protected override int InnerWrite(Storage value) + { + return _group.WriteInt32(_plcAddress, value.Int32); + } + + #endregion + + public override string ToString() + { + return _value.Int32.ToString(); + } + } + + public sealed class FloatTag : ITag + { + + public FloatTag(short id, DeviceAddress addr, IGroup group) + : base(id, addr, group) + { + } + + + #region IDevice Members + public override bool Refresh(DataSource source = DataSource.Device) + { + var _newvalue = _group.ReadFloat(_plcAddress, source); + if (_newvalue.Value != _value.Single) + { + Storage value = Storage.Empty; + value.Single = _newvalue.Value; + DateTime time = _newvalue.TimeStamp.ToDateTime(); + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(_newvalue.Quality, _value, value, _timeStamp, time)); + } + _timeStamp = time; + _quality = _newvalue.Quality; + if (_quality == QUALITIES.QUALITY_GOOD) + { + _value = value; + if (ValueChanged != null) + { + ValueChanged(this, new ValueChangedEventArgs(value)); + } + } + return true; + } + return false; + } + + public override Storage Read(DataSource source = DataSource.Cache) + { + Storage value = Storage.Empty; + value.Single = _group.ReadFloat(_plcAddress, source).Value; + return value; + } + + public override int Write(object value) + { + var temp = _value.Single; + var str = value as string; + if (str == null) + temp = Convert.ToSingle(value); + else if (!float.TryParse(str, out temp)) + return -1; + _timeStamp = DateTime.Now; + return _group.WriteFloat(_plcAddress, temp); + } + + protected override int InnerWrite(Storage value) + { + return _group.WriteFloat(_plcAddress, value.Single); + } + + #endregion + + public override string ToString() + { + return _value.Single.ToString(); + } + } + + public sealed class StringTag : ITag + { + string _str; + public string String + { + get + { + return _str; + } + set + { + _str = value; + } + } + + public StringTag(short id, DeviceAddress addr, IGroup group) + : base(id, addr, group) + { + } + + + #region IDevice Members + public override bool Refresh(DataSource source = DataSource.Device) + { + var _newvalue = _group.ReadString(_plcAddress, source); + if (_newvalue.Value != _str) + { + DateTime time = _newvalue.TimeStamp.ToDateTime(); + if (ValueChanging != null) + { + ValueChanging(this, new ValueChangingEventArgs(_newvalue.Quality, _value, _value, _timeStamp, time)); + } + _timeStamp = time; + _quality = _newvalue.Quality; + if (_quality == QUALITIES.QUALITY_GOOD) + { + _str = _newvalue.Value; + if (ValueChanged != null) + { + ValueChanged(this, new ValueChangedEventArgs(_value)); + } + } + return true; + } + return false; + } + + public override Storage Read(DataSource source = DataSource.Cache) + { + var value = _group.ReadString(_plcAddress, source); + if (value.Quality == QUALITIES.QUALITY_GOOD) + _str = value.Value; + return Storage.Empty; + } + + public override int Write(object value) + { + if (value == null) return -1; + var str = (value is String) ? (String)value : value.ToString(); + _timeStamp = DateTime.Now; + return _group.WriteString(_plcAddress, str); + } + + protected override int InnerWrite(Storage value) + { + return _group.WriteString(_plcAddress, _str); + } + + #endregion + + public override string ToString() + { + return _str ?? string.Empty; + } + } + + public enum DataSource + { + Cache = 1, + Device = 2 + } + + public enum DataType : byte + { + NONE = 0, + BOOL = 1, + BYTE = 3, + SHORT = 4, + WORD = 5, + TIME = 6, + INT = 7, + FLOAT = 8, + SYS = 9, + STR = 11 + } + + public delegate void ValueChangingEventHandler(object sender, ValueChangingEventArgs e); + public delegate void ValueChangedEventHandler(object sender, ValueChangedEventArgs e); + + public class ValueChangingEventArgs : EventArgs + { + public ValueChangingEventArgs(QUALITIES quality, T oldValue, T newValue, DateTime oldTime, DateTime newTime) + { + this.Quality = quality; + this.OldValue = oldValue; + this.NewValue = newValue; + this.OldTimeStamp = oldTime; + this.NewTimeStamp = newTime; + } + + public QUALITIES Quality; + public T OldValue; + public T NewValue; + public DateTime OldTimeStamp; + public DateTime NewTimeStamp; + } + + public class ValueChangedEventArgs : EventArgs + { + public ValueChangedEventArgs(Storage value) + { + this.Value = value; + } + + public Storage Value; + } + +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/PLCGroup.cs b/SCADA/Program/CoreApp/DataService/DataService/PLCGroup.cs new file mode 100644 index 0000000..07bbd7e --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/PLCGroup.cs @@ -0,0 +1,684 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Timers; + +namespace DataService +{ + public class PLCGroup : IGroup + { + protected Timer _timer; + + protected bool _isActive; + public virtual bool IsActive + { + get + { + return _isActive; + } + set + { + _isActive = value; + if (value) + { + //_timer.Start((uint)_updateRate, true); + //_timer.Timer += new EventHandler(timer_Timer); + _timer.Interval = _updateRate; + _timer.Elapsed += new ElapsedEventHandler(timer_Timer); + _timer.Start(); + } + else + { + _timer.Elapsed -= new ElapsedEventHandler(timer_Timer); + _timer.Stop(); + } + } + } + + protected short _id; + public short ID + { + get + { + return _id; + } + } + + protected int _updateRate; + public int UpdateRate + { + get + { + return _updateRate; + } + set + { + _updateRate = value; + } + } + + protected string _name; + public string Name + { + get + { + return _name; + } + set + { + _name = value; + } + } + + protected float _deadband; + public float DeadBand + { + get + { + return _deadband; + } + set + { + _deadband = value; + } + } + + + protected ICache _cacheReader; + + protected IPLCDriver _plcReader; + public IDriver Parent + { + get + { + return _plcReader; + } + } + + protected List _changedList; + public List ChangedList + { + get + { + return _changedList; + } + } + + + protected List _items; + public IEnumerable Items + { + get { return _items; } + } + + protected IDataServer _server; + public IDataServer Server + { + get + { + return _server; + } + } + + protected List _rangeList = new List(); + + protected PLCGroup() + { + } + + public PLCGroup(short id, string name, int updateRate, bool active, IPLCDriver plcReader) + { + this._id = id; + this._name = name; + this._updateRate = updateRate; + this._isActive = active; + this._plcReader = plcReader; + this._server = _plcReader.Parent; + this._changedList = new List(); + this._cacheReader = new ByteCacheReader(); + this._timer = new Timer(); + } + + public bool AddItems(IList items) + { + int count = items.Count; + if (_items == null) _items = new List(count); + lock (_server.SyncRoot) + { + for (int i = 0; i < count; i++) + { + ITag dataItem = null; + TagMetaData meta = items[i]; + if (meta.GroupID == this._id) + { + DeviceAddress addr = _plcReader.GetDeviceAddress(meta.Address); + if (addr.DataSize == 0) addr.DataSize = meta.Size; + if (addr.VarType == DataType.NONE) addr.VarType = meta.DataType; + if (addr.VarType != DataType.BOOL) addr.Bit = 0; + switch (meta.DataType) + { + case DataType.BOOL: + dataItem = new BoolTag(meta.ID, addr, this); + break; + case DataType.BYTE: + dataItem = new ByteTag(meta.ID, addr, this); + break; + case DataType.WORD: + case DataType.SHORT: + dataItem = new ShortTag(meta.ID, addr, this); + break; + case DataType.TIME: + case DataType.INT: + dataItem = new IntTag(meta.ID, addr, this); + break; + case DataType.FLOAT: + dataItem = new FloatTag(meta.ID, addr, this); + break; + case DataType.STR: + dataItem = new StringTag(meta.ID, addr, this); + break; + } + if (dataItem != null) + { + //dataItem.Active = meta.Active; + _items.Add(dataItem); + _server.AddItemIndex(meta.Name, dataItem); + } + } + } + } + _items.TrimExcess(); + _items.Sort(); + UpdatePDUArea(); + return true; + } + + public bool AddTags(IEnumerable tags) + { + if (_items == null) + { + _items = new List(); + } + foreach (ITag tag in tags) + { + if (tag != null) + { + _items.Add(tag); + } + } + _items.TrimExcess(); + _items.Sort(); + UpdatePDUArea(); + return true; + } + + public bool RemoveItems(params ITag[] items) + { + foreach (var item in items) + { + _server.RemoveItemIndex(item.GetTagName()); + _items.Remove(item); + } + UpdatePDUArea(); + return true; + } + + protected void UpdatePDUArea() + { + int count = _items.Count; + if (count > 0) + { + DeviceAddress _start = _items[0].Address; + _start.Bit = 0; + int bitCount = _cacheReader.ByteCount; + if (count > 1) + { + int cacheLength = 0;//缂撳啿鍖虹殑澶у皬 + int cacheIndexStart = 0; + int startIndex = 0; + DeviceAddress segmentEnd = DeviceAddress.Empty; + DeviceAddress tagAddress = DeviceAddress.Empty; + DeviceAddress segmentStart = _start; + for (int j = 1, i = 1; i < count; i++, j++) + { + tagAddress = _items[i].Address;//褰撳墠鍙橀噺鍦板潃 + int offset1 = _cacheReader.GetOffset(tagAddress, segmentStart); + if (offset1 > (_plcReader.PDU - tagAddress.DataSize) / bitCount) + { + segmentEnd = _items[i - 1].Address; + int len = _cacheReader.GetOffset(segmentEnd, segmentStart); + len += segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; + tagAddress.CacheIndex = (ushort)(cacheIndexStart + len); + _items[i].Address = tagAddress; + _rangeList.Add(new PDUArea(segmentStart, len, startIndex, j)); + startIndex += j; j = 0; + cacheLength += len;//鏇存柊缂撳瓨闀垮害 + cacheIndexStart = cacheLength; + segmentStart = tagAddress;//鏇存柊鏁版嵁鐗囨鐨勮捣濮嬪湴鍧 + } + else + { + tagAddress.CacheIndex = (ushort)(cacheIndexStart + offset1); + _items[i].Address = tagAddress; + } + if (i == count - 1) + { + segmentEnd = _items[i].Address; + int segmentLength = _cacheReader.GetOffset(segmentEnd, segmentStart); + if (segmentLength > (_plcReader.PDU - segmentEnd.DataSize) / bitCount) + { + segmentEnd = _items[i - 1].Address; + segmentLength = segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; + } + tagAddress.CacheIndex = (ushort)(cacheIndexStart + segmentLength); + _items[i].Address = tagAddress; + segmentLength += segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; + _rangeList.Add(new PDUArea(segmentStart, segmentLength, startIndex, j + 1)); + cacheLength += segmentLength; + } + } + _cacheReader.Size = cacheLength; + } + else + _cacheReader.Size = _start.DataSize <= bitCount ? 1 : _start.DataSize / bitCount;//鏀瑰彉Cache鐨凷ize灞炴у煎皢鍒涘缓Cache鐨勫唴瀛樺尯鍩 + } + } + + public ITag FindItemByAddress(DeviceAddress addr) + { + int index = _items.BinarySearch(new BoolTag(0, addr, null)); + return index < 0 ? null : _items[index]; + } + + public bool SetActiveState(bool active, params short[] items) + { + return false; + } + + object sync = new object(); + protected void timer_Timer(object sender, EventArgs e) + { + if (_isActive) + { + lock (sync) + { + Poll(); + if (_changedList.Count > 0) + Update(); + } + } + else + return; + } + + protected virtual int Poll() + { + if (_plcReader.IsClosed) return -1; + byte[] cache = (byte[])_cacheReader.Cache; + int offset = 0; + foreach (PDUArea area in _rangeList) + { + byte[] rcvBytes = _plcReader.ReadBytes(area.Start, (ushort)area.Len);//浠嶱LC璇诲彇鏁版嵁 + if (rcvBytes == null) + { + //_plcReader.Connect(); + return -1; + } + else + { + int index = area.StartIndex;//index鎸囧悜_items涓殑Tag鍏冩暟鎹 + int count = index + area.Count; + while (index < count) + { + DeviceAddress addr = _items[index].Address; + int iByte = addr.CacheIndex; + int iByte1 = iByte - offset; + if (addr.VarType == DataType.BOOL) + { + int tmp = rcvBytes[iByte1] ^ cache[iByte]; + DeviceAddress next = addr; + if (tmp != 0) + { + while (addr.Start == next.Start) + { + if ((tmp & (1 << next.Bit)) > 0) _changedList.Add(index); + if (++index < count) + next = _items[index].Address; + else + break; + } + } + else + { + while (addr.Start == next.Start && ++index < count) + { + next = _items[index].Address; + } + } + } + else + { + ushort size = addr.DataSize; + for (int i = 0; i < size; i++) + { + if (rcvBytes[iByte1 + i] != cache[iByte + i]) + { + _changedList.Add(index); + break; + } + } + index++; + } + } + for (int j = 0; j < rcvBytes.Length; j++) + cache[j + offset] = rcvBytes[j];//灏哖LC璇诲彇鐨勬暟鎹啓鍏ュ埌CacheReader涓 + } + offset += rcvBytes.Length; + } + return 1; + } + + protected void Update() + { + DateTime dt = DateTime.Now; + if (DataChange != null) + { + HistoryData[] values = new HistoryData[_changedList.Count]; + int i = 0; + foreach (int index in _changedList) + { + ITag item = _items[index]; + var itemData = item.Read(); + if (item.Active) + item.Update(itemData, dt, QUALITIES.QUALITY_GOOD); + if (_deadband == 0 || (item.Address.VarType == DataType.FLOAT && + (Math.Abs(itemData.Single / item.Value.Single - 1) > _deadband))) + { + values[i].ID = item.ID; + values[i].Quality = item.Quality; + values[i].Value = itemData; + values[i].TimeStamp = item.TimeStamp; + i++; + } + } + foreach (DataChangeEventHandler deleg in DataChange.GetInvocationList()) + { + deleg.BeginInvoke(this, new DataChangeEventArgs(1, values), null, null); + } + } + else + { + foreach (int index in _changedList) + { + ITag item = _items[index]; + if (item.Active) + item.Update(item.Read(), dt, QUALITIES.QUALITY_GOOD); + } + } + _changedList.Clear(); + } + + public void Dispose() + { + if (_timer != null) + _timer.Dispose(); + //if (_items != null) + // _items.Clear(); + } + + public virtual HistoryData[] BatchRead(DataSource source, bool isSync, params ITag[] itemArray) + { + int len = itemArray.Length; + HistoryData[] values = new HistoryData[len]; + if (source == DataSource.Device) + { + IMultiReadWrite multi = _plcReader as IMultiReadWrite; + if (multi != null) + { + Array.Sort(itemArray); + var itemArr = multi.ReadMultiple(Array.ConvertAll(itemArray, x => x.Address)); + for (int i = 0; i < len; i++) + { + values[i].ID = itemArray[i].ID; + values[i].Value = itemArr[i].Value; + values[i].TimeStamp = itemArr[i].TimeStamp.ToDateTime(); + itemArray[i].Update(itemArr[i].Value, values[i].TimeStamp, itemArr[i].Quality); + } + } + else + { + for (int i = 0; i < len; i++) + { + itemArray[i].Refresh(source); + values[i].ID = itemArray[i].ID; + values[i].Value = itemArray[i].Value; + values[i].Quality = itemArray[i].Quality; + values[i].TimeStamp = itemArray[i].TimeStamp; + } + } + } + else + { + for (int i = 0; i < len; i++) + { + values[i].ID = itemArray[i].ID; + values[i].Value = itemArray[i].Value; + values[i].Quality = itemArray[i].Quality; + values[i].TimeStamp = itemArray[i].TimeStamp; + } + } + return values; + } + + public virtual int BatchWrite(SortedDictionary items, bool isSync = true) + { + int len = items.Count; + int rev = 0; + IMultiReadWrite multi = _plcReader as IMultiReadWrite; + if (multi != null) + { + DeviceAddress[] addrs = new DeviceAddress[len]; + object[] objs = new object[len]; + int i = 0; + foreach (var item in items) + { + addrs[i] = item.Key.Address; + objs[i] = item.Value; + i++; + } + rev = multi.WriteMultiple(addrs, objs); + } + else + { + foreach (var tag in items) + { + if (tag.Key.Write(tag.Value) < 0) + rev = -1; + } + } + if (DataChange != null && rev >= 0) + { + HistoryData[] data = new HistoryData[len]; + int i = 0; + foreach (var item in items) + { + ITag tag = item.Key; + data[i].ID = tag.ID; + data[i].TimeStamp = tag.TimeStamp; + data[i].Quality = tag.Quality; + data[i].Value = item.Key.ToStorage(item.Value); + i++; + } + foreach (DataChangeEventHandler deleg in DataChange.GetInvocationList()) + { + deleg.BeginInvoke(this, new DataChangeEventArgs(1, data), null, null); + } + } + return rev; + } + + public ItemData ReadInt32(DeviceAddress address, DataSource source = DataSource.Cache) + { + return source == DataSource.Cache ? _cacheReader.ReadInt32(address) : _plcReader.ReadInt32(address); + } + + public ItemData ReadInt16(DeviceAddress address, DataSource source = DataSource.Cache) + { + return source == DataSource.Cache ? _cacheReader.ReadInt16(address) : _plcReader.ReadInt16(address); + } + + public ItemData ReadByte(DeviceAddress address, DataSource source = DataSource.Cache) + { + return source == DataSource.Cache ? _cacheReader.ReadByte(address) : _plcReader.ReadByte(address); + } + + public ItemData ReadFloat(DeviceAddress address, DataSource source = DataSource.Cache) + { + return source == DataSource.Cache ? _cacheReader.ReadFloat(address) : _plcReader.ReadFloat(address); + } + + public ItemData ReadBool(DeviceAddress address, DataSource source = DataSource.Cache) + { + return source == DataSource.Cache ? _cacheReader.ReadBit(address) : _plcReader.ReadBit(address); + } + + public ItemData ReadString(DeviceAddress address, DataSource source = DataSource.Cache) + { + ushort siz = address.DataSize; + return source == DataSource.Cache ? _cacheReader.ReadString(address, siz) : + _plcReader.ReadString(address, siz); + } + + public int WriteInt32(DeviceAddress address, int value) + { + int rs = _plcReader.WriteInt32(address, value); + if (rs >= 0) + { + if (DataChange != null) + { + ITag tag = GetTagByAddress(address); + if (tag != null) + DataChange(this, new DataChangeEventArgs(1, new HistoryData[1] + { + new HistoryData(tag.ID,QUALITIES.QUALITY_GOOD,new Storage{Int32=value}, DateTime.Now) + })); + } + } + return rs; + } + + public int WriteInt16(DeviceAddress address, short value) + { + int rs = _plcReader.WriteInt16(address, value); + if (rs >= 0) + { + if (DataChange != null) + { + ITag tag = GetTagByAddress(address); + if (tag != null) + DataChange(this, new DataChangeEventArgs(1, new HistoryData[1] + { + new HistoryData(tag.ID,QUALITIES.QUALITY_GOOD,new Storage{Int16=value}, DateTime.Now) + })); + } + } + return rs; + } + + public int WriteFloat(DeviceAddress address, float value) + { + int rs = _plcReader.WriteFloat(address, value); + if (rs >= 0) + { + if (DataChange != null) + { + ITag tag = GetTagByAddress(address); + if (tag != null) + DataChange(this, new DataChangeEventArgs(1, new HistoryData[1] + { + new HistoryData(tag.ID,QUALITIES.QUALITY_GOOD,new Storage{Single=value}, DateTime.Now) + })); + } + } + return rs; + } + + public int WriteString(DeviceAddress address, string value) + { + int rs = _plcReader.WriteString(address, value); + if (rs >= 0) + { + if (DataChange != null) + { + ITag tag = GetTagByAddress(address); + if (tag != null) + DataChange(this, new DataChangeEventArgs(1, new HistoryData[1] + { + new HistoryData(tag.ID,QUALITIES.QUALITY_GOOD,Storage.Empty, DateTime.Now) + })); + } + } + return rs; + } + + public int WriteBit(DeviceAddress address, bool value) + { + int rs = _plcReader.WriteBit(address, value); + if (rs >= 0) + { + if (DataChange != null) + { + ITag tag = GetTagByAddress(address); + if (tag != null) + DataChange(this, new DataChangeEventArgs(1, new HistoryData[1] + { + new HistoryData(tag.ID,QUALITIES.QUALITY_GOOD,new Storage{Boolean=value}, DateTime.Now) + })); + } + } + return rs; + } + + public int WriteBits(DeviceAddress address, byte value) + { + int rs = _plcReader.WriteBits(address, value); + if (rs >= 0) + { + if (DataChange != null) + { + ITag tag = GetTagByAddress(address); + if (tag != null) + DataChange(this, new DataChangeEventArgs(1, new HistoryData[1] + { + new HistoryData(tag.ID,QUALITIES.QUALITY_GOOD,new Storage{Byte=value}, DateTime.Now) + })); + } + } + return rs; + } + + private ITag GetTagByAddress(DeviceAddress addr) + { + int index = _items.BinarySearch(new BoolTag(0, addr, null)); + return index < 0 ? null : _items[index]; + } + + public event DataChangeEventHandler DataChange; + } + + + public struct PDUArea + { + public DeviceAddress Start; + public int Len; + public int StartIndex; + public int Count; + + public PDUArea(DeviceAddress start, int len, int startIndex, int count) + { + Start = start; + Len = len; + StartIndex = startIndex; + Count = count; + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/DataService/Storage.cs b/SCADA/Program/CoreApp/DataService/DataService/Storage.cs new file mode 100644 index 0000000..1c2df0b --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/Storage.cs @@ -0,0 +1,95 @@ +锘縰sing System.Runtime.InteropServices; +using System; + +namespace DataService +{ + [StructLayout(LayoutKind.Explicit, Size = 4)] + public struct Storage + { + // Fields + [FieldOffset(0)] + public bool Boolean; + [FieldOffset(0)] + public byte Byte; + [FieldOffset(0)] + public short Int16; + [FieldOffset(0)] + public int Int32; + [FieldOffset(0)] + public float Single; + + public static readonly Storage Empty ; + + static Storage() + { + Empty = new Storage(); + } + + public override bool Equals(object obj) + { + if (obj == null) return false; + Type type = obj.GetType(); + if (type == typeof(Storage)) + return this.Int32 == ((Storage)obj).Int32; + else + { + if (type == typeof(Int32)) + return this.Int32 == (Int32)obj; + if (type == typeof(Int16)) + return this.Int16 == (Int16)obj; + if (type == typeof(Byte)) + return this.Byte == (Byte)obj; + if (type == typeof(Boolean)) + return this.Boolean == (Boolean)obj; + if (type == typeof(Single)) + return this.Single == (Single)obj; + if (type == typeof(String)) + return this.ToString() == obj.ToString(); + } + return false; + } + + public override int GetHashCode() + { + return Int32.GetHashCode(); + } + + public static bool operator ==(Storage x, Storage y) + { + return x.Int32 == y.Int32; + } + + public static bool operator !=(Storage x, Storage y) + { + return x.Int32 != y.Int32; + } + } + + public enum QUALITIES : short + { + // Fields + LIMIT_CONST = 3, + LIMIT_HIGH = 2, + LIMIT_LOW = 1, + //LIMIT_MASK = 3, + //LIMIT_OK = 0, + QUALITY_BAD = 0, + QUALITY_COMM_FAILURE = 0x18, + QUALITY_CONFIG_ERROR = 4, + QUALITY_DEVICE_FAILURE = 12, + QUALITY_EGU_EXCEEDED = 0x54, + QUALITY_GOOD = 0xc0, + QUALITY_LAST_KNOWN = 20, + QUALITY_LAST_USABLE = 0x44, + QUALITY_LOCAL_OVERRIDE = 0xd8, + QUALITY_MASK = 0xc0, + QUALITY_NOT_CONNECTED = 8, + QUALITY_OUT_OF_SERVICE = 0x1c, + QUALITY_SENSOR_CAL = 80, + QUALITY_SENSOR_FAILURE = 0x10, + QUALITY_SUB_NORMAL = 0x58, + QUALITY_UNCERTAIN = 0x40, + QUALITY_WAITING_FOR_INITIAL_DATA = 0x20, + STATUS_MASK = 0xfc, + } +} \ No newline at end of file diff --git a/SCADA/Program/CoreApp/DataService/DataService/TagMetaData.cs b/SCADA/Program/CoreApp/DataService/DataService/TagMetaData.cs new file mode 100644 index 0000000..b8f9fec --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/DataService/TagMetaData.cs @@ -0,0 +1,108 @@ +锘縰sing System; +using System.Runtime.InteropServices; + +namespace DataService +{ + [StructLayout(LayoutKind.Sequential)] + public struct TagMetaData : IComparable + { + public bool Archive; + + public DataType DataType; + + public ushort Size; + + public short ID; + + public short GroupID; + + public float Maximum; + + public float Minimum; + + public int Cycle; + + public string Address; + + public string Name; + + public TagMetaData(short id, short grpId, string name, string address, + DataType type, ushort size, bool archive = false, float max = 0, float min = 0, int cycle = 0) + { + ID = id; + GroupID = grpId; + Name = name; + Address = address; + DataType = type; + Size = size; + Archive = archive; + Maximum = max; + Minimum = min; + Cycle = cycle; + } + + public int CompareTo(TagMetaData other) + { + return this.ID.CompareTo(other.ID); + } + + public override string ToString() + { + return Name; + } + } + + [StructLayout(LayoutKind.Sequential)] + public struct Scaling : IComparable + { + public short ID; + + public ScaleType ScaleType; + + public float EUHi; + + public float EULo; + + public float RawHi; + + public float RawLo; + + public Scaling(short id, ScaleType type, float euHi, float euLo, float rawHi, float rawLo) + { + ID = id; + ScaleType = type; + EUHi = euHi; + EULo = euLo; + RawHi = rawHi; + RawLo = rawLo; + } + + public int CompareTo(Scaling other) + { + return ID.CompareTo(other.ID); + } + + public static readonly Scaling Empty = new Scaling { ScaleType = ScaleType.None }; + } + + public struct ItemData + { + public T Value; + public long TimeStamp; + public QUALITIES Quality; + + public ItemData(T value, long timeStamp, QUALITIES quality) + { + Value = value; + TimeStamp = timeStamp; + Quality = quality; + } + } + + public enum ScaleType : byte + { + None = 0, + Linear = 1, + SquareRoot = 2 + } +} diff --git a/SCADA/Program/CoreApp/DataService/GateWay/DAService.cs b/SCADA/Program/CoreApp/DataService/GateWay/DAService.cs new file mode 100644 index 0000000..521595b --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/GateWay/DAService.cs @@ -0,0 +1,1838 @@ +锘縰sing ClientDriver; +using DatabaseLib; +using DataService; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Console; +using Microsoft.Extensions.Logging.Debug; +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Timers; +using System.Xml; + +namespace BatchCoreService +{ + + public class DAService : IDataServer, IAlarmServer + { + const int PORT = 6543; + + const char SPLITCHAR = '.'; + const string SERVICELOGSOURCE = "DataProcess"; + const string SERVICELOGNAME = "DataProcess"; + const string PATH = @"C:\DataConfig\"; + const string FILENAME = "server.xml"; + + + //鍙厤缃弬鏁帮紝浠嶺ML鏂囦欢璇诲彇 + int DELAY = 3000; + int MAXHDACAP = 10000; + int ALARMLIMIT = 1000; + int CYCLE = 60000; + int CYCLE2 = 600000; + int SENDTIMEOUT = 60000; + //int SENDSIZE = ushort.MaxValue; + int HDALEN = 1024 * 1024; + int MAXLOGSIZE = 1024; + int HDADELAY = 3600 * 1000; + int ALARMDELAY = 3600 * 1000; + int ARCHIVEINTERVAL = 100; + + static ILogger Log; + + private System.Timers.Timer timer1 = new System.Timers.Timer(); + private System.Timers.Timer timer2 = new System.Timers.Timer(); + private System.Timers.Timer timer3 = new System.Timers.Timer(); + private DateTime _hdastart = DateTime.Now; + private DateTime _alarmstart = DateTime.Now; + + #region DAServer锛堟爣绛炬暟鎹湇鍔″櫒锛 + public ITag this[short id] + { + get + { + int index = GetItemProperties(id); + if (index >= 0) + { + return this[_list[index].Name]; + } + return null; + } + } + + public ITag this[string name] + { + get + { + if (string.IsNullOrEmpty(name)) return null; + ITag dataItem; + _mapping.TryGetValue(name.ToUpper(), out dataItem); + return dataItem; + } + } + + List _list; + public IList MetaDataList + { + get + { + return _list; + } + } + + public IList ScalingList + { + get + { + return _scales; + } + } + + object _syncRoot; + public object SyncRoot + { + get + { + if (this._syncRoot == null) + { + Interlocked.CompareExchange(ref this._syncRoot, new object(), null); + } + return this._syncRoot; + } + } + + bool _hasHda = false; + List _hda; + Dictionary _archiveTimes = new Dictionary(); + + Socket tcpServer = null; + + Dictionary _socketThreadList; + public Dictionary SocketList + { + get + { + return _socketThreadList; + } + } + + Dictionary _mapping; + + List _scales; + + SortedList _drivers; + public IEnumerable Drivers + { + get { return _drivers.Values; } + } + + CompareCondBySource _compare; + + ExpressionEval reval; + public ExpressionEval Eval + { + get + { + return reval; + } + } + + private object _myLock = new object(); + Dictionary _archiveList = null;//鏄惁闇瑕乴ock + public Dictionary ArchiveList + { + get + { + lock (_myLock) + { + if (_archiveList == null) + { + var list = MetaDataList.Where(x => x.Archive).Select(y => y.ID);//&& x.DataType != DataType.BOOL + if (list != null && list.Count() > 0) + { + string sql = "SELECT TAGID,DESCRIPTION FROM META_TAG WHERE TAGID IN(" + string.Join(",", list) + ");"; + using (var reader = DataHelper.Instance.ExecuteReader(sql)) + { + if (reader != null) + { + _archiveList = new Dictionary(); + while (reader.Read()) + { + _archiveList.Add(reader.GetInt16(0), reader.GetNullableString(1)); + } + } + } + } + } + } + return _archiveList; + } + } + + public DAService() + { + var loggerFactory = new LoggerFactory(); + Func filter = (category, level) => true; + loggerFactory.AddProvider( new ConsoleLoggerProvider(filter, false)); + loggerFactory.AddProvider(new DebugLoggerProvider(filter)); + Log = loggerFactory.CreateLogger(SERVICELOGSOURCE); + InitServerByXml(); + _scales = new List(); + _drivers = new SortedList(); + _alarmList = new List(ALARMLIMIT + 10); + reval = new ExpressionEval(this); + _hda = new List(); + InitServerByDatabase(); + InitConnection(); + _socketThreadList = new Dictionary(); + InitHost(); + + timer1.Elapsed += timer1_Elapsed; + timer2.Elapsed += timer2_Elapsed; + timer3.Elapsed += timer3_Elapsed; + timer1.Interval = CYCLE; + timer1.Enabled = true; + timer1.Start(); + timer2.Interval = CYCLE2; + timer2.Enabled = true; + timer2.Start(); + if (_hasHda) + { + foreach (var item in _archiveTimes.Values) + { + if (item != null) + { + timer3.Interval = ARCHIVEINTERVAL; + timer3.Enabled = true; + timer3.Start(); + return; + } + } + } + } + + public void Dispose() + { + lock (this) + { + try + { + if (timer1 != null) + timer1.Dispose(); + if (timer2 != null) + timer2.Dispose(); + if (timer3 != null) + timer3.Dispose(); + if (_drivers != null) + { + foreach (var driver in Drivers) + { + driver.OnClose -= this.reader_OnClose; + driver.Dispose(); + } + foreach (var condition in _conditionList) + { + if (condition != null) + condition.AlarmActive -= cond_SendAlarm; + } + + if (_hasHda) + { + Flush(); + //hda.Clear(); + } + SaveAlarm(); + foreach (var socket in _socketThreadList.Values) + { + socket.Dispose(); + } + if (tcpServer != null && tcpServer.Connected) + tcpServer.Disconnect(false); + + _mapping.Clear(); + _conditionList.Clear(); + reval.Dispose(); + } + } + catch (Exception e) + { + AddErrorLog(e); + } + } + } + + public void AddErrorLog(Exception e) + { + Log.LogError(e.GetExceptionMsg()); + } + + private void timer1_Elapsed(object sender, ElapsedEventArgs e) + { + foreach (IDriver d in Drivers) + { + if (d.IsClosed) + { + d.Connect();//t.IsAlive鍙姞鍏ュ垽鏂紱濡傜嚎绋嬪紓甯革紝閲嶆柊鍚姩銆 + } + } + } + + private void timer2_Elapsed(object sender, ElapsedEventArgs e) + { + if (HDADELAY > 0 && _hda.Count > 0 && (DateTime.Now - _hdastart).TotalMilliseconds > HDADELAY) + { + lock (_hdaRoot) + { + ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.SaveCachedData), _hda.ToArray()); + _hda.Clear(); + } + } + if (ALARMDELAY > 0 && _alarmList.Count > 0 && (DateTime.Now - _alarmstart).TotalMilliseconds > ALARMDELAY) + SaveAlarm(); + DateTime today = DateTime.Today; + try + { + if (e.SignalTime > today.AddHours(2)) + { + DateTime startTime = DateTime.MinValue; + DateTime endTime = DateTime.MaxValue; + HDAIOHelper.GetRangeFromDatabase(null, ref startTime, ref endTime); + if (startTime >= today || startTime == DateTime.MinValue) + { + return; + } + bool success = true; + if (endTime < today && _hda.Count > 0 && _hda[0].TimeStamp < today) + { + success = SaveRange(endTime, today); + } + if (success) + { + startTime = startTime.Date.AddDays(1); + endTime = endTime.Date.AddDays(1); + if (endTime >= today) endTime = today; + while (startTime <= endTime) + { + HDAIOHelper.BackUpFile(startTime); + startTime = startTime.AddDays(1); + } + } + } + } + catch (Exception err) + { + AddErrorLog(err); + } + } + + private void timer3_Elapsed(object sender, ElapsedEventArgs e) + { + var now = e.SignalTime; + List tempData = new List(); + foreach (var archive in _archiveTimes) + { + var archiveTime = archive.Value; + if (archiveTime != null && (now - archiveTime.LastTime).TotalMilliseconds > archiveTime.Cycle) + { + var tag = this[archive.Key]; + if (tag != null && tag.TimeStamp > archiveTime.LastTime) + { + tempData.Add(new HistoryData(tag.ID, tag.Quality, tag.Value, now)); + archive.Value.LastTime = now; + } + } + } + if (tempData.Count > 0) + { + ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.OnUpdate), tempData); + } + //var result = from item in _archiveTimes where item.Value.Cycle > 0 && (now - item.Value.LastTime).Milliseconds > item.Value.Cycle select item.Key; + } + + #region 鍒濆鍖栵紙鏍囩鏁版嵁鏈嶅姟鍣級 + void InitConnection() + { + foreach (IDriver reader in _drivers.Values) + { + reader.OnClose += new ShutdownRequestEventHandler(reader_OnClose); + if (reader.IsClosed) + { + //if (reader is IFileDriver) + reader.Connect(); + } + foreach (IGroup grp in reader.Groups) + { + grp.DataChange += new DataChangeEventHandler(grp_DataChange); + //鍙湪姝ゅ姞鍏ュ垽鏂紝濡備负ClientDriver鍙戝嚭锛屽垯鍙樺寲鏁版嵁姣嬮』骞挎挱锛屽彧闇褰掓。銆 + grp.IsActive = grp.IsActive; + } + } + //姝ゅ闇鏀硅繘,涓嶤ondition閲囩敤鐩稿悓鐨勫鐞嗘柟寮忥紝鍙厤缃 + } + + void InitServerByDatabase() + { + using (var dataReader = DataHelper.Instance.ExecuteProcedureReader("InitServer", DataHelper.CreateParam("@TYPE", SqlDbType.Int, 0))) + { + if (dataReader == null) return;// Stopwatch sw = Stopwatch.StartNew(); + while (dataReader.Read()) + { + AddDriver(dataReader.GetInt16(0), dataReader.GetNullableString(1), + dataReader.GetNullableString(2), dataReader.GetInt32(3), dataReader.GetNullableString(4), dataReader.GetNullableString(5), + dataReader.GetNullableString(6), dataReader.GetNullableString(7)); + } + + dataReader.NextResult(); + dataReader.Read(); + int count = dataReader.GetInt32(0); + _list = new List(count); + _mapping = new Dictionary(count); + dataReader.NextResult(); + while (dataReader.Read()) + { + var meta = new TagMetaData(dataReader.GetInt16(0), dataReader.GetInt16(1), dataReader.GetString(2), dataReader.GetString(3), (DataType)dataReader.GetByte(4), + (ushort)dataReader.GetInt16(5), dataReader.GetBoolean(6), dataReader.GetFloat(7), dataReader.GetFloat(8), dataReader.GetInt32(9)); + _list.Add(meta); + if (meta.Archive) + { + _archiveTimes.Add(meta.ID, meta.Cycle == 0 ? null : new ArchiveTime(meta.Cycle, DateTime.MinValue)); + } + //Advise(DDETOPIC, meta.Name); + } + _list.Sort(); + dataReader.NextResult(); + while (dataReader.Read()) + { + IDriver dv; + _drivers.TryGetValue(dataReader.GetInt16(0), out dv); + if (dv != null) + { + IGroup grp = dv.AddGroup(dataReader.GetString(1), dataReader.GetInt16(2), dataReader.GetInt32(3), + dataReader.GetFloat(4), dataReader.GetBoolean(5)); + if (grp != null) + grp.AddItems(_list); + } + } + dataReader.NextResult(); + while (dataReader.Read()) + { + ITag tag = this[dataReader.GetNullableString(0)]; + if (tag != null) + { + tag.ValueChanged += OnValueChanged; + } + } + dataReader.NextResult(); + _conditions = new List(); + _conditionList = new List(); + while (dataReader.Read()) + { + int id = dataReader.GetInt32(0); + AlarmType type = (AlarmType)dataReader.GetInt32(2); + ICondition cond; + string source = dataReader.GetString(1); + if (_conditions.Count > 0) + { + cond = _conditions[_conditions.Count - 1]; + if (cond.ID == id) + { + cond.AddSubCondition(new SubCondition((SubAlarmType)dataReader.GetInt32(9), dataReader.GetFloat(10), + (Severity)dataReader.GetByte(11), dataReader.GetString(12), dataReader.GetBoolean(13))); + continue; + } + } + switch (type) + { + case AlarmType.Complex: + cond = new ComplexCondition(id, source, dataReader.GetString(6), dataReader.GetFloat(7), dataReader.GetInt32(8)); + break; + case AlarmType.Level: + cond = new LevelAlarm(id, source, dataReader.GetString(6), dataReader.GetFloat(7), dataReader.GetInt32(8)); + break; + case AlarmType.Dev: + cond = new DevAlarm(id, (ConditionType)dataReader.GetByte(4), source, dataReader.GetString(6), + dataReader.GetFloat(5), dataReader.GetFloat(7), dataReader.GetInt32(8)); + break; + case AlarmType.ROC: + cond = new ROCAlarm(id, source, dataReader.GetString(6), dataReader.GetFloat(7), dataReader.GetInt32(8)); + break; + case AlarmType.Quality: + cond = new QualitiesAlarm(id, source, dataReader.GetString(6)); + break; + case AlarmType.WordDsc: + cond = new WordDigitAlarm(id, source, dataReader.GetString(6), dataReader.GetInt32(8)); + break; + default: + cond = new DigitAlarm(id, source, dataReader.GetString(6), dataReader.GetInt32(8)); + break; + } + cond.AddSubCondition(new SubCondition((SubAlarmType)dataReader.GetInt32(9), dataReader.GetFloat(10), + (Severity)dataReader.GetByte(11), dataReader.GetString(12), dataReader.GetBoolean(13))); + + cond.IsEnabled = dataReader.GetBoolean(3); + var simpcond = cond as SimpleCondition; + if (simpcond != null) + { + simpcond.Tag = this[source]; + } + else + { + var complexcond = cond as ComplexCondition; + if (complexcond != null) + { + var action = complexcond.SetFunction(reval.Eval(source)); + if (action != null) + { + ValueChangedEventHandler handle = (s1, e1) => { action(); }; + foreach (ITag tag in reval.TagList) + { + tag.ValueChanged += handle;// tag.Refresh(); + } + } + } + } + cond.AlarmActive += new AlarmEventHandler(cond_SendAlarm); + //_conditions.Add(cond);// UpdateCondition(cond); + _conditions.Add(cond); + } + dataReader.NextResult(); + while (dataReader.Read()) + { + _scales.Add(new Scaling(dataReader.GetInt16(0), (ScaleType)dataReader.GetByte(1), + dataReader.GetFloat(2), dataReader.GetFloat(3), dataReader.GetFloat(4), dataReader.GetFloat(5))); + } + } + if (_archiveTimes.Count > 0) + { + _hasHda = true; + _hda.Capacity = MAXHDACAP; + } + reval.Clear(); + _scales.Sort(); + _compare = new CompareCondBySource(); + _conditions.Sort(_compare); + } + + void InitHost() + { + /*瀵瑰叧闂姸鎬佺殑鍒ゆ柇锛屾渶濂界敤蹇冭烦妫娴嬶紱鍐椾綑鍒囨崲锛屽彲骞挎挱鍐椾綑鍛戒护锛屽寘鍚柊涓绘満鍚嶃佹暟鎹簱杩炴帴銆両P鍦板潃绛夈 + * 鏈嶅姟鍚姩鏃讹紝鍚戞暣涓眬鍩熺綉UDP骞挎挱鍔犲瘑鐨勪富鏈哄悕銆佽繛鎺ュ瓧绗︿覆绛変俊鎭 + */ + //socketThreadList = new Dictionary(); + tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + IPEndPoint LocalPort = new IPEndPoint(IPAddress.Any, PORT); + tcpServer.Bind(LocalPort); + tcpServer.Listen(100); + ThreadPool.QueueUserWorkItem(new WaitCallback(AcceptWorkThread)); + } + + void InitServerByXml() + { + string path = PATH + '\\' + FILENAME; + if (File.Exists(path)) + { + try + { + using (var reader = XmlTextReader.Create(path)) + { + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "Server": + { + if (reader.MoveToAttribute("MaxLogSize")) + int.TryParse(reader.Value, out MAXLOGSIZE); + } + break; + case "Data": + { + if (reader.MoveToAttribute("TestCycle")) + int.TryParse(reader.Value, out CYCLE); + if (reader.MoveToAttribute("SendTimeout")) + int.TryParse(reader.Value, out SENDTIMEOUT); + } + break; + case "Hda": + { + if (reader.MoveToAttribute("MaxHdaCap")) + { + int.TryParse(reader.Value, out MAXHDACAP); + } + if (reader.MoveToAttribute("HdaLen")) + int.TryParse(reader.Value, out HDALEN); + if (reader.MoveToAttribute("WriteCycle")) + int.TryParse(reader.Value, out CYCLE2); + if (reader.MoveToAttribute("Delay")) + int.TryParse(reader.Value, out HDADELAY); + if (reader.MoveToAttribute("Interval")) + int.TryParse(reader.Value, out ARCHIVEINTERVAL); + } + break; + case "Alarm": + { + if (reader.MoveToAttribute("AlarmLimit")) + int.TryParse(reader.Value, out ALARMLIMIT); + if (reader.MoveToAttribute("Delay")) + int.TryParse(reader.Value, out ALARMDELAY); + } + break; + } + } + } + } + } + catch (Exception err) + { + AddErrorLog(err); + } + } + } + #endregion + + void AcceptWorkThread(object state) + { + while (true) + { + //if (tcpServer.Poll(0, SelectMode.SelectRead)) + Socket s_Accept = tcpServer.Accept(); + //IPAddress addr = (s_Accept.RemoteEndPoint as IPEndPoint).Address; + s_Accept.SendTimeout = SENDTIMEOUT; + IPAddress addr = (s_Accept.RemoteEndPoint as IPEndPoint).Address; + try + { + if (!_socketThreadList.ContainsKey(addr)) + _socketThreadList.Add(addr, s_Accept); + } + catch (Exception err) + { + AddErrorLog(err); + } + ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(ReceiveWorkThread), s_Accept); + } + } + + void ReceiveWorkThread(object obj) + { + Socket s_Receive = (Socket)obj; + IPAddress addr = null; + try + { + addr = (s_Receive.RemoteEndPoint as IPEndPoint).Address; + } + catch (Exception err) + { + AddErrorLog(err); + return; + } + byte[] buffer = new byte[s_Receive.ReceiveBufferSize]; // 鍒涘缓鎺ユ敹缂撳啿 + while (true) + { + try + { + if (addr == null || !_socketThreadList.ContainsKey(addr)) return; + /*if (!s_Receive.Connected) return; + 鍏充簬鏁版嵁浼犺緭鍗忚锛氬懡浠ゅ彲鍒嗕负锛氳鍗曟寚浠わ紙璁㈠崟绫诲瀷锛屽鍒犳敼鏍囪鍙悇鐢ㄤ竴涓瓧娈碉紝璺緞ID鐢℅UID锛岃矾寰勭姸鎬佸寘鎷殏鍋溿佺户缁 + 銆佺粓姝€佸惎鍔級锛涘彲杩斿洖瀹㈡埛绔竴涓彲琛岀殑璺緞璁惧閾俱丒RP浜ゆ崲鏁版嵁鎸囦护锛堝寘鍚獶ATASET)锛屽啑浣欏垏鎹㈡寚浠ょ瓑锛 + */ + int ReceiveCount = s_Receive.Receive(buffer); + + if (buffer[0] == FCTCOMMAND.fctHead) + { + //buffer[0]鏄崗璁ご锛1鏄寚浠ゅ彿锛2鏄鏂瑰紡锛堢紦瀛樿繕鏄澶囷級锛3銆4鏄疘D锛5鏄暱搴︼紝鍚庢帴鍙橀噺鍊 + byte command = buffer[1]; + switch (command) + { + case FCTCOMMAND.fctReadSingle: + { + //DataSource source = buffer[2] == 0 ? DataSource.Cache : DataSource.Device; + short id = BitConverter.ToInt16(buffer, 3); + byte length = buffer[5]; + byte[] send = new byte[5 + length]; + for (int i = 0; i < 5; i++) + { + send[i] = buffer[i]; + } + ITag tag = this[id]; + if (tag != null) + { + Storage value = buffer[2] == 0 ? tag.Value : tag.Read(DataSource.Device); + byte[] bt = tag.ToByteArray(value); + for (int k = 0; k < bt.Length; k++) + { + send[5 + k] = bt[k]; + } + } + else + { + //鍑洪敊澶勭悊,鍙冭檻杩斿洖涓涓狣ATATYPE.NONE绫诲瀷 + } + s_Receive.Send(send); + } + break; + case FCTCOMMAND.fctReadMultiple: + { + //buffer[0]鏄崗璁ご锛1鏄寚浠ゅ彿锛2鏄鏂瑰紡锛堢紦瀛樿繕鏄澶囷級锛3銆4鏄彉閲忔暟锛屽悗鎺ュ彉閲忓 + //DataSource source = buffer[2] == 0 ? DataSource.Cache : DataSource.Device; + byte[] send = new byte[s_Receive.SendBufferSize]; + send[0] = FCTCOMMAND.fctHead; + short count = BitConverter.ToInt16(buffer, 3);//瑕佽鍙栫殑鍙橀噺鏁 + int j = 5; int l = 5; + if (buffer[2] == 0) + { + for (int i = 0; i < count; i++) + { + short id = BitConverter.ToInt16(buffer, l); + send[j++] = buffer[l++]; + send[j++] = buffer[l++]; + ITag tag = this[id]; + if (tag != null) + { + byte[] bt = tag.ToByteArray(); + var length = (byte)bt.Length; + send[j++] = length; + for (int k = 0; k < length; k++) + { + send[j + k] = bt[k]; + } + j += length; + } + else + {//绫诲瀷鍚庤窡闀垮害 + send[j++] = 0; + } + } + } + else + { + Dictionary> dict = new Dictionary>(); + for (int i = 0; i < count; i++) + { + short id = BitConverter.ToInt16(buffer, l); + l += 2; + ITag tag = this[id]; + if (tag != null) + { + IGroup grp = tag.Parent; + if (!dict.ContainsKey(grp)) + dict.Add(grp, new List { tag }); + else + dict[grp].Add(tag); + } + } + foreach (var dev in dict) + { + var list = dev.Value; + var array = dev.Key.BatchRead(DataSource.Device, true, list.ToArray()); + if (array == null) continue; + for (int i = 0; i < list.Count; i++) + { + byte[] bt = list[i].ToByteArray(array[i].Value); + var length = (byte)bt.Length; + send[j++] = length; + for (int k = 0; k < bt.Length; k++) + { + send[j + k] = bt[k]; + } + j += length; + } + } + } + s_Receive.Send(send, 0, j, SocketFlags.None); + } + break; + case FCTCOMMAND.fctWriteSingle: + { + //buffer[0]鏄崗璁ご锛1鏄寚浠ゅ彿锛2鏄啓鏂瑰紡锛堢紦瀛樿繕鏄澶囷級锛3銆4鏄疘D锛5鏄暱搴 + short id = BitConverter.ToInt16(buffer, 3); + byte rs = 0; + ITag tag = this[id]; + if (tag != null)//姝ゅ搴旇冭檻涓囦竴鍐欏け璐ワ紝鏄惁闇瑕佹洿鏂板 + { + if (tag.Address.VarType == DataType.STR) + { + StringTag strTag = tag as StringTag; + if (strTag != null) + { + string txt = Encoding.ASCII.GetString(buffer, 6, buffer[5]).Trim((char)0); + rs = (byte)tag.Write(txt); + if (rs == 0) + strTag.String = txt; + } + } + else + { + Storage value = Storage.Empty; + switch (tag.Address.VarType) + { + case DataType.BOOL: + value.Boolean = BitConverter.ToBoolean(buffer, 6); + break; + case DataType.BYTE: + value.Byte = buffer[6]; + break; + case DataType.WORD: + case DataType.SHORT: + value.Int16 = BitConverter.ToInt16(buffer, 6); + break; + case DataType.TIME: + case DataType.INT: + value.Int32 = BitConverter.ToInt32(buffer, 6); + break; + case DataType.FLOAT: + value.Single = BitConverter.ToSingle(buffer, 6); + break; + default: + break; + } + rs = (byte)tag.Write(value, false); + } + } + else + { + rs = 0xFF;//姝ゅ闀垮害搴旀敞鎰;濡傛棤姝ゅ彉閲忥紝搴旇繑鍥炰竴涓敊璇唬鐮 + } + s_Receive.Send(new byte[] { FCTCOMMAND.fctWriteSingle, rs }, 0, 2, SocketFlags.None);//搴旇繑鍥炰竴涓敊璇唬鐮; + } + break; + case FCTCOMMAND.fctWriteMultiple: + { //int BatchWrite(IDictionary items, bool isSync = true); + int count = BitConverter.ToInt16(buffer, 2); + int j = 4; byte rs = 0; + Dictionary> dict = new Dictionary>(); + for (int i = 0; i < count; i++) + { + short id = BitConverter.ToInt16(buffer, j); + j += 2; + byte length = buffer[j++]; + ITag tag = this[id]; + IGroup grp = tag.Parent; + SortedDictionary values; + if (!dict.ContainsKey(grp)) + { + values = new SortedDictionary(); + dict.Add(grp, values); + } + else + values = dict[grp]; + if (tag != null) + { + switch (tag.Address.VarType) + { + case DataType.BOOL: + values.Add(tag, BitConverter.ToBoolean(buffer, j)); + break; + case DataType.BYTE: + values.Add(tag, buffer[j]); + break; + case DataType.WORD: + case DataType.SHORT: + values.Add(tag, BitConverter.ToInt16(buffer, j)); + break; + case DataType.TIME: + case DataType.INT: + values.Add(tag, BitConverter.ToInt32(buffer, j)); + break; + case DataType.FLOAT: + values.Add(tag, BitConverter.ToSingle(buffer, j)); + break; + case DataType.STR: + values.Add(tag, Encoding.ASCII.GetString(buffer, j, length).Trim((char)0)); + break; + } + } + j += length; + } + foreach (var dev in dict) + { + if (dev.Key.BatchWrite(dev.Value) < 0) rs = 0xFF; + } + s_Receive.Send(new byte[] { FCTCOMMAND.fctWriteMultiple, rs }, 0, 2, SocketFlags.None); + } + break; + case FCTCOMMAND.fctAlarmRequest://鍒锋柊鎶ヨ鏁版嵁 + { + if (_alarmList.Count > 0) + { + long startTime = BitConverter.ToInt64(buffer, 2); + long endTime = BitConverter.ToInt64(buffer, 10); + if (_alarmstart > DateTime.FromFileTime(startTime) || DateTime.FromFileTime(endTime) > _alarmstart) + { + SaveAlarm(); + } + } + s_Receive.Send(new byte[] { FCTCOMMAND.fctAlarmRequest, 0 }, 0, 2, SocketFlags.None); + } + break; + case FCTCOMMAND.fctReset://閲嶇疆杩炴帴 + { + byte[] iparry = new byte[4]; + Array.Copy(buffer, 2, iparry, 0, 4); + IPAddress ipaddr = new IPAddress(iparry); + if (_socketThreadList.Count > 0 && _socketThreadList.ContainsKey(ipaddr)) + { + var scok = _socketThreadList[ipaddr]; + _socketThreadList.Remove(ipaddr); + if (scok != null) + { + scok.Dispose(); + } + } + } + break; + case FCTCOMMAND.fctHdaRequest: + { + DateTime start = DateTime.FromFileTime(BitConverter.ToInt64(buffer, 2)); + DateTime end = DateTime.FromFileTime(BitConverter.ToInt64(buffer, 10)); + try + { + SendHData(GetHData(start, end), new byte[HDALEN], s_Receive); + } + catch (Exception err) + { + AddErrorLog(err); + } + s_Receive.Send(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 24, SocketFlags.None); + } + break; + case FCTCOMMAND.fctHdaIdRequest://浼樺厛璇诲彇鏈湴HDA鏂囦欢澶逛笅鐨勪簩杩涘埗褰掓。鏂囦欢 + { + DateTime start = DateTime.FromFileTime(BitConverter.ToInt64(buffer, 2)); + DateTime end = DateTime.FromFileTime(BitConverter.ToInt64(buffer, 10)); + short ID = BitConverter.ToInt16(buffer, 18); + try + { + SendHData(GetHData(start, end, ID), new byte[HDALEN], s_Receive, this[ID]); + } + catch (Exception err) + { + AddErrorLog(err); + } + s_Receive.Send(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 24, SocketFlags.None); + } + break; + } + } + } + catch (SocketException ex) + { + var err = ex.SocketErrorCode; + if (err == SocketError.ConnectionAborted || err == SocketError.HostDown || err == SocketError.NetworkDown || err == SocketError.Shutdown || err == SocketError.ConnectionReset) + { + s_Receive.Dispose(); + if (addr != null) + _socketThreadList.Remove(addr); + //s_Receive.Dispose(); + } + AddErrorLog(ex); + } + catch (Exception ex) + { + AddErrorLog(ex); + } + } + } + + #region 鍘嗗彶鏁版嵁褰掓。鏌ヨ + private IEnumerable GetHData(DateTime start, DateTime end, short ID) + { + if (start > end) yield break; + DateTime now = DateTime.Now; + if (start > now) yield break; + if (end > now) end = now; + if (now.Date > start.Date) + { + DateTime tempstart = DateTime.MinValue; + DateTime tempend = end; + HDAIOHelper.GetRangeFromDatabase(ID, ref tempend, ref tempstart); + if (tempend > end) tempend = end; + if (tempend > start) + { + int eyear = tempend.Year; + int syear = start.Year; + int emonth = tempend.Month; + int smonth = start.Month; + int year = syear; + while (year <= eyear) + { + int month = (year == syear ? smonth : 1); + while (month <= (year == eyear ? emonth : 12)) + { + var result = HDAIOHelper.LoadFromFile((year == syear && month == smonth ? start : new DateTime(year, month, 1)), + (year == eyear && month == emonth ? tempend : new DateTime(year, month, 1).AddMonths(1).AddMilliseconds(-2)), ID);//鑰冭檻鎸夋湀閬嶅巻 + if (result != null) + { + foreach (var data in result) + { + yield return data; + } + } + month++; + } + year++; + } + } + } + var tempdata = _hda.ToArray(); + DateTime ftime = (tempdata.Length > 0 ? tempdata[0].TimeStamp : DateTime.Now); + if (start < ftime) + { + var result = HDAIOHelper.LoadFromDatabase(start, ftime > end ? end : ftime, ID);//鑼冨洿鍐茬獊 + if (result != null) + { + foreach (var data in result) + { + yield return data; + } + } + } + if (end > ftime) + { + var result = tempdata.Where(x => x.ID == ID && x.TimeStamp >= ftime && x.TimeStamp <= end); + if (result != null) + { + foreach (var data in result) + { + yield return data; + } + } + } + yield break; + } + + private IEnumerable GetHData(DateTime start, DateTime end) + { + if (start > end) yield break; + DateTime now = DateTime.Now; + if (start > now) yield break; + if (end > now) end = now; + if (now.Date > start.Date) + { + DateTime tempstart = DateTime.MinValue; + DateTime tempend = end; + HDAIOHelper.GetRangeFromDatabase(null, ref tempend, ref tempstart); + if (tempend > start) + { + int eyear = tempend.Year; + int syear = start.Year; + int emonth = tempend.Month; + int smonth = start.Month; + int year = syear; + while (year <= eyear) + { + int month = (year == syear ? smonth : 1); + while (month <= (year == eyear ? emonth : 12)) + { + var result = HDAIOHelper.LoadFromFile((year == syear && month == smonth ? start : new DateTime(year, month, 1)), + (year == eyear && month == emonth ? tempend : new DateTime(year, month, 1).AddMonths(1).AddMilliseconds(-2)));//鑰冭檻鎸夋湀閬嶅巻 + if (result != null) + { + foreach (var data in result) + { + yield return data; + } + } + month++; + } + year++; + } + } + } + var tempdata = _hda.ToArray(); + DateTime ftime = (tempdata.Length > 0 ? tempdata[0].TimeStamp : DateTime.Now); + if (start < ftime) + { + var result = HDAIOHelper.LoadFromDatabase(start, ftime > end ? end : ftime);//鑼冨洿鍐茬獊 + if (result != null) + { + foreach (var data in result) + { + yield return data; + } + } + } + if (end > ftime) + { + var result = tempdata.Where(x => x.TimeStamp >= ftime && x.TimeStamp <= end); + if (result != null) + { + foreach (var data in result) + { + yield return data; + } + } + } + yield break; + } + + private void SendHData(IEnumerable result, byte[] buffer, Socket socket, ITag tag) + { + if (result == null || tag == null || socket == null || !socket.Connected) return; + int index = 0; + int len = buffer.Length; + int size = tag.Address.DataSize; + foreach (var data in result) + { + if (index + 8 + size >= len) + { + //s_Receive.BeginSend(tempbuffer, 0, index, SocketFlags.None, null, null); + socket.Send(buffer, index, SocketFlags.None); + index = 0; + } + byte[] bits = tag.ToByteArray(data.Value); + bits.CopyTo(buffer, index); + index += size; + bits = BitConverter.GetBytes(data.TimeStamp.ToFileTime()); + bits.CopyTo(buffer, index); + index += 8; + } + socket.Send(buffer, index, SocketFlags.None); + } + + private void SendHData(IEnumerable result, byte[] buffer, Socket socket) + { + if (result == null || socket == null || !socket.Connected) return; + int index = 0; + int len = buffer.Length; + short tempid = short.MinValue; + ITag tag = null; + byte[] idarray = new byte[2]; + foreach (var data in result) + { + if (tempid != data.ID) + { + tempid = data.ID; + idarray = BitConverter.GetBytes(tempid); + tag = this[tempid]; + } + if (tag == null) continue; + int size = tag.Address.DataSize; + if (index + 10 + size >= len) + { + //s_Receive.BeginSend(tempbuffer, 0, index, SocketFlags.None, null, null);杩欓噷鏈変竴涓悓姝ョ殑闂锛屽彂鐢烮D鍙烽敊浣嶃 + socket.Send(buffer, index, SocketFlags.None); + index = 0; + } + idarray.CopyTo(buffer, index); + index += 2; + byte[] bits = tag.ToByteArray(data.Value); + bits.CopyTo(buffer, index); + index += size; + bits = BitConverter.GetBytes(data.TimeStamp.ToFileTime()); + bits.CopyTo(buffer, index); + index += 8; + } + socket.Send(buffer, index, SocketFlags.None); + } + + private object _hdaRoot = new object(); + public void Flush() + { + lock (_hdaRoot) + { + if (_hda.Count == 0) return; + if (DataHelper.Instance.BulkCopy(new HDASqlReader(_hda, this), "Log_HData", + string.Format("DELETE FROM Log_HData WHERE [TIMESTAMP]>'{0}'", _hda[0].TimeStamp.ToString()))) + { + _hda.Clear(); + _hdastart = DateTime.Now; + } + } + } + + public bool SaveRange(DateTime startTime, DateTime endTime) + { + var tempdata = _hda.ToArray(); + if (tempdata.Length == 0) return true; + return DataHelper.Instance.BulkCopy(new HDASqlReader(GetData(tempdata, startTime, endTime), this), "Log_HData", + string.Format("DELETE FROM Log_HData WHERE [TIMESTAMP] BETWEEN '{0}' AND '{1}'", startTime, endTime)); + } + + public void OnUpdate(object stateInfo) + { + lock (_hdaRoot) + { + var tempData = (List)stateInfo; + _hda.AddRange(tempData); + if (_hda.Count >= MAXHDACAP) + { + //Reverse(data); + DateTime start = _hda[0].TimeStamp; + //_array.CopyTo(data, 0); + if (DataHelper.Instance.BulkCopy(new HDASqlReader(_hda, this), "Log_HData", + string.Format("DELETE FROM Log_HData WHERE [TIMESTAMP]>'{0}'", start.ToString()))) + _hdastart = DateTime.Now; + else ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.SaveCachedData), _hda.ToArray()); + _hda.Clear(); + } + } + } + + public void SaveCachedData(object stateInfo) + { + var tempData = (HistoryData[])stateInfo; + if (tempData.Length == 0) return; + DateTime startTime = tempData[0].TimeStamp; + DateTime endTime = tempData[tempData.Length - 1].TimeStamp; + //Thread.Sleep(TimeSpan.FromMinutes(10)); + int count = 0; + while (true) + { + if (count >= 5) return; + if (DataHelper.Instance.BulkCopy(new HDASqlReader(tempData, this), "Log_HData", + string.Format("DELETE FROM Log_HData WHERE [TIMESTAMP] BETWEEN '{0}' AND '{1}'", + startTime, endTime))) + { + stateInfo = null; + _hdastart = DateTime.Now; + } + count++; + Thread.Sleep(CYCLE2); + } + } + + public IEnumerable GetData(HistoryData[] hdaarray, DateTime startTime, DateTime endTime) + { + //if (hdaarray.Length == 0) yield break; + foreach (var data in hdaarray) + { + if (data.TimeStamp >= startTime) + { + if (data.TimeStamp <= endTime) + yield return data; + else + yield break; + } + } + } + #endregion + + void OnValueChanged(object sender, ValueChangedEventArgs e) + { + var tag = sender as ITag; + DataHelper.Instance.ExecuteStoredProcedure("AddEventLog", + DataHelper.CreateParam("@StartTime", SqlDbType.DateTime, tag.TimeStamp), + DataHelper.CreateParam("@Source", SqlDbType.NVarChar, tag.ID.ToString(), 50), + DataHelper.CreateParam("@StartTime", SqlDbType.NVarChar, tag.ToString(), 50)); + } + + public HistoryData[] BatchRead(DataSource source, bool sync, params ITag[] itemArray) + { + int count = itemArray.Length; + HistoryData[] data = new HistoryData[count]; + Dictionary> dict = new Dictionary>(); + for (int i = 0; i < count; i++) + { + short id = itemArray[i].ID; + ITag tag = this[id]; + if (tag != null) + { + IGroup grp = tag.Parent; + if (!dict.ContainsKey(grp)) + dict.Add(grp, new List { tag }); + else + dict[grp].Add(tag); + } + } + int j = 0; + foreach (var dev in dict) + { + var list = dev.Value; + var array = dev.Key.BatchRead(source, sync, list.ToArray()); + if (array == null) continue; + Array.Copy(array, 0, data, j, array.Length); + j += array.Length; + } + return data; + } + + public int BatchWrite(Dictionary tags, bool sync) + { + int rs = -1; + Dictionary> dict = new Dictionary>(); + foreach (var item in tags) + { + var tag = this[item.Key]; + if (tag != null) + { + IGroup grp = tag.Parent; + SortedDictionary values; + if (!dict.ContainsKey(grp)) + { + values = new SortedDictionary(); + if (tag.Address.VarType != DataType.BOOL && tag.Address.VarType != DataType.STR) + { + values.Add(tag, tag.ValueToScale(Convert.ToSingle(item.Value))); + } + else + values.Add(tag, item.Value); + dict.Add(grp, values); + } + else + { + values = dict[grp]; + if (tag.Address.VarType != DataType.BOOL && tag.Address.VarType != DataType.STR) + { + values.Add(tag, tag.ValueToScale(Convert.ToSingle(item.Value))); + } + else + values.Add(tag, item.Value); + } + } + else Log.LogError(string.Format("鍙橀噺{0}涓嶅湪鍙橀噺琛ㄤ腑锛屾棤娉曚笅杞", item.Key)); + } + foreach (var dev in dict) + { + rs = dev.Key.BatchWrite(dev.Value, sync); + } + return rs; + } + + void grp_DataChange(object sender, DataChangeEventArgs e) + { + var data = e.Values; + var now = DateTime.Now; + if (_hasHda) + { + ArchiveTime archiveTime; + List tempData = new List(20); + for (int i = 0; i < data.Count; i++) + { + if (_archiveTimes.TryGetValue(data[i].ID, out archiveTime) && archiveTime == null && data[i].TimeStamp != DateTime.MinValue) + { + tempData.Add(data[i]); + } + } + if (tempData.Count > 0) + { + ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.OnUpdate), tempData); + } + } + if (_socketThreadList != null && _socketThreadList.Count > 0) + { + IPAddress addr = null; + var grp = sender as ClientGroup; + if (grp != null) + addr = grp.RemoteAddress; + ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(this.SendData), new TempCachedData(addr, data)); + } + } + //姝ゅ鍙戠敓鍐呭瓨娉勬紡锛涢渶瑕佽瘯楠孋LRProfile纭畾娉勬紡鍘熷洜锛涙敼鍥炲師鏂规硶娴嬭瘯锛涚湅鏄惁瑙e喅闃熷垪鍫靛闂銆傚浜庡鎴风Grp,瑕佽繃婊ゆ帀 + private void SendData(object obj) + { + var tempdata = obj as TempCachedData; + var data = tempdata.Data; + byte[] sendBuffer = new byte[8192]; + sendBuffer[0] = FCTCOMMAND.fctHead; + sendBuffer[1] = FCTCOMMAND.fctReadMultiple; + //bytes[2] = 0; + int len = data.Count; + short j = 5; + for (int i = 0; i < len; i++) + { + short id = data[i].ID; + byte[] dt = BitConverter.GetBytes(id); + sendBuffer[j++] = dt[0]; + sendBuffer[j++] = dt[1]; + switch (_list[GetItemProperties(id)].DataType) + { + case DataType.BOOL: + sendBuffer[j++] = 1; + sendBuffer[j++] = data[i].Value.Boolean ? (byte)1 : (byte)0; + break; + case DataType.BYTE: + sendBuffer[j++] = 1; + sendBuffer[j++] = data[i].Value.Byte; + break; + case DataType.WORD: + case DataType.SHORT: + { + sendBuffer[j++] = 2; + byte[] bt = BitConverter.GetBytes(data[i].Value.Int16); + sendBuffer[j++] = bt[0]; + sendBuffer[j++] = bt[1]; + } + break; + case DataType.TIME: + case DataType.INT: + { + sendBuffer[j++] = 4; + byte[] bt = BitConverter.GetBytes(data[i].Value.Int32); + sendBuffer[j++] = bt[0]; + sendBuffer[j++] = bt[1]; + sendBuffer[j++] = bt[2]; + sendBuffer[j++] = bt[3]; + } + break; + case DataType.FLOAT: + { + sendBuffer[j++] = 4; + byte[] bt = BitConverter.GetBytes(data[i].Value.Single); + sendBuffer[j++] = bt[0]; + sendBuffer[j++] = bt[1]; + sendBuffer[j++] = bt[2]; + sendBuffer[j++] = bt[3]; + } + break; + case DataType.STR: + { + byte[] bt = Encoding.ASCII.GetBytes(this[data[i].ID].ToString()); + sendBuffer[j++] = (byte)bt.Length; + for (int k = 0; k < bt.Length; k++) + { + sendBuffer[j++] = bt[k]; + } + } + break; + default: + break; + } + Array.Copy(BitConverter.GetBytes((data[i].TimeStamp == DateTime.MinValue ? DateTime.Now : data[i].TimeStamp).ToFileTime()), 0, sendBuffer, j, 8); + j += 8; + } + byte[] dt1 = BitConverter.GetBytes(j); + sendBuffer[3] = dt1[0]; + sendBuffer[4] = dt1[1]; + SocketError err; + //bytes.CopyTo(bytes2, 0); + List sockets = new List(_socketThreadList.Count); + foreach (var socket in _socketThreadList) + { + if (!socket.Key.Equals(tempdata.Address)) + sockets.Add(socket.Value); + } + data = null; + obj = null; + tempdata = null; + foreach (var socket in sockets) + { + try + { + socket.Send(sendBuffer, 0, j, SocketFlags.None, out err); + if (err == SocketError.ConnectionAborted || err == SocketError.HostDown || + err == SocketError.NetworkDown || err == SocketError.Shutdown) + { + _socketThreadList.Remove((socket.RemoteEndPoint as IPEndPoint).Address); + } + } + catch (Exception ex1) + { + AddErrorLog(ex1); + } + } + } + + public IDriver AddDriver(short id, string name, string server, int timeOut, + string assembly, string className, string spare1, string spare2) + { + if (_drivers.ContainsKey(id)) + return _drivers[id]; + IDriver dv = null; + try + { + Assembly ass = Assembly.LoadFrom(assembly); + var dvType = ass.GetType(className); + if (dvType != null) + { + //dv = new ModbusDriver.ModbusTCPReader(this, id, name, server, timeOut); + dv = Activator.CreateInstance(dvType, new object[] { this, id, name, server, timeOut, spare1, spare2 }) as IDriver; + if (dv != null) + _drivers.Add(id, dv); + } + } + catch (Exception e) + { + AddErrorLog(e); + } + return dv; + } + + public bool RemoveDriver(IDriver device) + { + lock (SyncRoot) + { + if (_drivers.Remove(device.ID)) + { + device.Dispose(); + device = null; + return true; + } + return false; + } + } + + void reader_OnClose(object sender, ShutdownRequestEventArgs e) + { + Log.LogWarning(e.shutdownReason); + //AddErrorLog(new Exception(e.shutdownReason)); + } + + public bool AddItemIndex(string key, ITag value) + { + key = key.ToUpper(); + if (_mapping.ContainsKey(key)) + return false; + _mapping.Add(key, value); + return true; + } + + public bool RemoveItemIndex(string key) + { + return _mapping.Remove(key.ToUpper()); + } + + + object _alarmsync = new object(); + + string[] itemList = null; + public IEnumerable BrowseItems(BrowseType browseType, string tagName, DataType dataType) + { + lock (SyncRoot) + { + if (_list.Count == 0) yield break; + int len = _list.Count; + if (itemList == null) + { + itemList = new string[len]; + for (int i = 0; i < len; i++) + { + itemList[i] = _list[i].Name; + } + Array.Sort(itemList); + } + int ii = 0; + bool hasTag = !string.IsNullOrEmpty(tagName); + bool first = true; + string str = hasTag ? tagName + SPLITCHAR : string.Empty; + if (hasTag) + { + ii = Array.BinarySearch(itemList, tagName); + if (ii < 0) first = false; + //int strLen = str.Length; + ii = Array.BinarySearch(itemList, str); + if (ii < 0) ii = ~ii; + } + //while (++i < len && temp.Length >= strLen && temp.Substring(0, strLen) == str) + do + { + if (first && hasTag) + { + first = false; + yield return tagName; + } + string temp = itemList[ii]; + if (hasTag && !temp.StartsWith(str, StringComparison.Ordinal)) + break; + if (dataType == DataType.NONE || _mapping[temp].Address.VarType == dataType) + { + bool b3 = true; + if (browseType != BrowseType.Flat) + { + string curr = temp + SPLITCHAR; + int index = Array.BinarySearch(itemList, ii, len - ii, curr); + if (index < 0) index = ~index; + b3 = itemList[index].StartsWith(curr, StringComparison.Ordinal); + if (browseType == BrowseType.Leaf) + b3 = !b3; + } + if (b3) + yield return temp; + } + } while (++ii < len); + } + } + + public int GetScaleByID(short Id) + { + if (_scales == null || _scales.Count == 0) return -1; + return _scales.BinarySearch(new Scaling { ID = Id }); + } + + public IGroup GetGroupByName(string name) + { + if (string.IsNullOrEmpty(name)) return null; + foreach (IDriver device in Drivers) + { + foreach (IGroup grp in device.Groups) + { + if (grp.Name == name) + return grp; + } + } + return null; + } + + public void ActiveItem(bool active, params ITag[] items) + { + Dictionary> dict = new Dictionary>(); + for (int i = 0; i < items.Length; i++) + { + List list = null; + ITag item = items[i]; + dict.TryGetValue(item.Parent, out list); + if (list != null) + { + list.Add(item.ID); + } + else + dict.Add(item.Parent, new List { item.ID }); + + } + foreach (var grp in dict) + { + grp.Key.SetActiveState(active, grp.Value.ToArray()); + } + } + + public int GetItemProperties(short id) + { + return _list.BinarySearch(new TagMetaData { ID = id }); + } + #endregion + + #region Condition & Alarm锛堟姤璀﹀拰鏉′欢锛 + List _conditions; + List _conditionList; + + List _alarmList; + public IEnumerable AlarmList + { + get + { + return _alarmList; + } + } + + public IList ActivedConditionList + { + get + { + return _conditionList; + } + } + + public IList ConditionList + { + get + { + return _conditions; + } + } + + void cond_SendAlarm(object sender, AlarmItem e) + { + lock (_alarmsync) + { + int index2 = _conditions.BinarySearch(new DigitAlarm(0, e.Source), _compare); + if (index2 > -1) + { + var cond = _conditions[index2]; + _conditionList.Remove(cond); + if (e.SubAlarmType != SubAlarmType.None) + { + _conditionList.Add(cond); + } + } + + if (_alarmList.Count < ALARMLIMIT) + { + _alarmList.Add(e); + } + else + { + SaveAlarm(); + _alarmList.Add(e); + } + } + /*搴斿姞鍏ュ垽鏂紝鏄惁闇瑕佹洿鏂版暟鎹簱锛坕f(Index>=ALARMLIMIT){Save(); Index=0;}else Index++; + * 瀹㈡埛绔煡璇㈠墠鍏堝彂閫佷竴涓煡璇㈡姤璀(alarmQuery)璇锋眰锛屽寘鍚捣濮嬫椂闂村弬鏁帮紝鏈嶅姟鍣ㄤ粠鍒ゆ柇鏄惁瑕佸皢缂撳瓨鍐欏叆鏁版嵁搴擄紝 + * 寰呮湇鍔″櫒杩斿洖灏辩华鍚庯紝瀹㈡埛绔啀浠庢暟鎹簱鏌ヨ鎶ヨ璁板綍銆 + */ + } + + private bool SaveAlarm() + { + if (_alarmList.Count == 0) return true; + if (DataHelper.Instance.BulkCopy(new AlarmDataReader(_alarmList), "Log_Alarm", null)) + { + _alarmList.Clear(); + _alarmstart = DateTime.Now; + return true; + } + return false; + } + + public ICondition GetCondition(string tagName, AlarmType type) + { + ITag tag = this[tagName]; + if (tag == null) return null; + short id = tag.ID; + int index = _conditions.BinarySearch(new DigitAlarm(0, tagName)); + if (index < 0) return null; + int ind1 = index - 1; + ICondition cond = _conditions[index]; + while (index < _conditions.Count && cond.Source == tagName) + { + cond = _conditions[index++]; + if (cond.AlarmType == type) + { + return cond; + } + } + while (ind1 >= 0 && cond.Source == tagName) + { + cond = _conditions[ind1--]; + if (cond.AlarmType == type) + { + return cond; + } + } + return null; + } + + public IList QueryConditions(string sourceName) + { + if (_conditions == null || sourceName == null) return null; + ITag tag = this[sourceName]; + if (tag == null) return null; + int index = _conditions.BinarySearch(new DigitAlarm(0, sourceName)); + if (index < 0) return null; + List condList = new List(); + ICondition cond = _conditions[index]; + int ind1 = index - 1; + while (cond.Source == sourceName) + { + condList.Add(cond); + if (++index < _conditions.Count) + cond = _conditions[index]; + else + break; + } + while (ind1 >= 0) + { + if (cond.Source == sourceName) + condList.Add(cond); + } + return condList; + } + + public int DisableCondition(string sourceName, AlarmType type) + { + var cond = GetCondition(sourceName, type); + if (cond != null) + { + cond.IsEnabled = false; + return 1; + } + return -1; + } + + public int EnableCondition(string sourceName, AlarmType type) + { + var cond = GetCondition(sourceName, type); + if (cond != null) + { + cond.IsEnabled = true; + return 1; + } + return -1; + } + + public int RemoveConditon(string sourceName, AlarmType type) + { + var cond = GetCondition(sourceName, type); + if (cond != null) + { + _conditions.Remove(cond); + return 1; + } + return -1; + } + + public int RemoveConditons(string sourceName) + { + ITag tag = this[sourceName]; + if (_conditions == null || tag == null) return -1; + int index = _conditions.BinarySearch(new DigitAlarm(0, sourceName)); + if (index < 0) return index; + int ind1 = index - 1; + ICondition cond = _conditions[index]; + List li = new List(); + while (cond.Source == sourceName) + { + li.Add(index); + if (++index < _conditions.Count) + cond = _conditions[index]; + else + break; + } + while (ind1 >= 0) + { + cond = _conditions[ind1--]; + if (cond.Source == sourceName) + li.Add(ind1); + } + if (li.Count == 0) return -1; + for (int i = li.Count - 1; i >= 0; i--) + { + _conditions.RemoveAt(i); + } + return 1; + } + + public int AckConditions(params ICondition[] conditions) + { + if (conditions == null || conditions.Length == 0) return -1; + foreach (ICondition cond in conditions) + { + cond.IsAcked = true; + cond.LastAckTime = DateTime.Now; + } + return 1; + } + #endregion + } + + class TempCachedData + { + IPAddress _addr; + public IPAddress Address + { + get { return _addr; } + } + + IList _data; + public IList Data + { + get { return _data; } + } + + public TempCachedData(IPAddress addr, IList data) + { + _addr = addr; + _data = data; + } + } + + internal sealed class ArchiveTime + { + public int Cycle; + public DateTime LastTime; + public ArchiveTime(int cycle, DateTime last) + { + Cycle = cycle; + LastTime = last; + } + } +} diff --git a/SCADA/Program/CoreApp/DataService/GateWay/GateWay.csproj b/SCADA/Program/CoreApp/DataService/GateWay/GateWay.csproj new file mode 100644 index 0000000..58c9ec4 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/GateWay/GateWay.csproj @@ -0,0 +1,22 @@ + + + + Exe + netcoreapp2.0 + + + + + + + + + + + + + + + + + diff --git a/SCADA/Program/CoreApp/DataService/GateWay/Program.cs b/SCADA/Program/CoreApp/DataService/GateWay/Program.cs new file mode 100644 index 0000000..d73799c --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/GateWay/Program.cs @@ -0,0 +1,17 @@ +锘縰sing BatchCoreService; +using System; + +namespace GateWay +{ + class Program + { + static void Main(string[] args) + { + //Console.WriteLine("Hello World!"); + DAService dataService = new DAService(); + Console.ReadLine(); + } + + + } +} diff --git a/SCADA/Program/CoreApp/DataService/GateWay/SqlMapping.cs b/SCADA/Program/CoreApp/DataService/GateWay/SqlMapping.cs new file mode 100644 index 0000000..c7a9ec8 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/GateWay/SqlMapping.cs @@ -0,0 +1,556 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Data; +using DataService; + +namespace BatchCoreService +{ + internal class AlarmDataReader : IDataReader + { + IEnumerator _enumer; + + public AlarmDataReader(IEnumerable list) + { + this._enumer = list.GetEnumerator(); + } + + #region IDataReader Members + + public void Close() + { + + } + public int Depth + { + get { return 0; } + } + + public DataTable GetSchemaTable() + { + DataTable table = new DataTable("AlarmItem"); + table.Columns.Add("StartTime", typeof(DateTime)); + table.Columns.Add("Source", typeof(string)); + table.Columns.Add("ConditionId", typeof(int)); + table.Columns.Add("AlarmText", typeof(string)); + table.Columns.Add("AlarmValue", typeof(object)); + table.Columns.Add("Duration", typeof(int)); + table.Columns.Add("Severity", typeof(int)); + table.Columns.Add("SubAlarmType", typeof(int)); + return table; + } + public bool IsClosed + { + get { return false; } + } + + public bool NextResult() + { + return false; + } + + public bool Read() + { + return _enumer.MoveNext(); + } + + public int RecordsAffected + { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + } + + #endregion + + #region IDataRecord Members + + public int FieldCount + { + get { return 8; } + } + + public bool GetBoolean(int i) + { + return (bool)GetValue(i); + } + + public byte GetByte(int i) + { + return (byte)GetValue(i); + } + + public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + throw new NotImplementedException(); + } + + public char GetChar(int i) + { + return (char)GetValue(i); + } + + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + throw new NotImplementedException(); + } + + public IDataReader GetData(int i) + { + throw new NotImplementedException(); + } + + public string GetDataTypeName(int i) + { + throw new NotImplementedException(); + } + + public DateTime GetDateTime(int i) + { + return (DateTime)GetValue(i); + } + + public decimal GetDecimal(int i) + { + return (decimal)GetValue(i); + } + + public double GetDouble(int i) + { + return (double)GetValue(i); + } + + public Type GetFieldType(int i) + { + switch (i) + { + case 0: + return typeof(DateTime); + case 1: + return typeof(string); + case 2: + return typeof(int); + case 3: + return typeof(string); + case 4: + return typeof(object); + case 5: + return typeof(int); + case 6: + return typeof(int); + case 7: + return typeof(int); + default: + return typeof(string); + } + } + + public float GetFloat(int i) + { + return (float)GetValue(i); + } + + public Guid GetGuid(int i) + { + return (Guid)GetValue(i); + } + + public short GetInt16(int i) + { + return (short)GetValue(i); + } + public int GetInt32(int i) + { + return (int)GetValue(i); + } + + public long GetInt64(int i) + { + return (long)GetValue(i); + } + + public string GetName(int i) + { + switch (i) + { + case 0: + return "StartTime"; + case 1: + return "Source"; + case 2: + return "ConditionId"; + case 3: + return "AlarmText"; + case 4: + return "AlarmValue"; + case 5: + return "Duration"; + case 6: + return "Severity"; + case 7: + return "SubAlarmType"; + default: + return ""; + } + } + + public int GetOrdinal(string name) + { + switch (name) + { + case "StartTime": + return 0; + case "Source": + return 1; + case "ConditionId": + return 2; + case "AlarmText": + return 3; + case "AlarmValue": + return 4; + case "Duration": + return 5; + case "Severity": + return 6; + case "SubAlarmType": + return 7; + default: + return -1; + } + } + + public string GetString(int i) + { + return (string)GetValue(i); + } + + public object GetValue(int i) + { + switch (i) + { + case 0: + return _enumer.Current.StartTime; + case 1: + return _enumer.Current.Source; + case 2: + return _enumer.Current.ConditionId; + case 3: + return _enumer.Current.AlarmText; + case 4: + return _enumer.Current.AlarmValue; + case 5: + return _enumer.Current.Duration.Seconds; + case 6: + return _enumer.Current.Severity; + case 7: + return _enumer.Current.SubAlarmType; + default: + return null; + } + } + + public int GetValues(object[] values) + { + throw new NotImplementedException(); + } + + public bool IsDBNull(int i) + { + switch (i) + { + case 0: + return _enumer.Current.StartTime == DateTime.MinValue; + case 1: + return string.IsNullOrEmpty(_enumer.Current.Source); + case 2: + return _enumer.Current.ConditionId == 0; + case 3: + return string.IsNullOrEmpty(_enumer.Current.AlarmText); + case 4: + return _enumer.Current.AlarmValue == null; + case 5: + case 6: + case 7: + default: + return false; + } + } + + public object this[string name] + { + get + { + return GetValue(GetOrdinal(name)); + } + } + + public object this[int i] + { + get + { + return GetValue(i); + } + } + + #endregion + } + + internal class HDASqlReader : IDataReader + { + IEnumerator _enumer; + IDataServer _server; + + public HDASqlReader(IEnumerable list, IDataServer server) + { + this._enumer = list.GetEnumerator(); + _server = server; + } + + #region IDataReader Members + + public void Close() + { + + } + + public int Depth + { + get { return 0; } + } + + public DataTable GetSchemaTable() + { + DataTable table = new DataTable("Log_HData"); + table.Columns.Add("ID", typeof(short)); + table.Columns.Add("TimeStamp", typeof(DateTime)); + table.Columns.Add("Value", typeof(float)); + return table; + } + public bool IsClosed + { + get { return false; } + } + + public bool NextResult() + { + return false; + } + + public bool Read() + { + return _enumer.MoveNext(); + } + + public int RecordsAffected + { + get { throw new NotImplementedException(); } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + } + + #endregion + + #region IDataRecord Members + + public int FieldCount + { + get { return 3; } + } + + public bool GetBoolean(int i) + { + return (bool)GetValue(i); + } + + public byte GetByte(int i) + { + return (byte)GetValue(i); + } + + public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { + throw new NotImplementedException(); + } + + public char GetChar(int i) + { + return (char)GetValue(i); + } + + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { + throw new NotImplementedException(); + } + + public IDataReader GetData(int i) + { + return this; + } + + public string GetDataTypeName(int i) + { + throw new NotImplementedException(); + } + + public DateTime GetDateTime(int i) + { + return (DateTime)GetValue(i); + } + + public decimal GetDecimal(int i) + { + return (decimal)GetValue(i); + } + + public double GetDouble(int i) + { + return (double)GetValue(i); + } + + public Type GetFieldType(int i) + { + switch (i) + { + case 0: + return typeof(Int16); + case 1: + return typeof(DateTime); + case 2: + return typeof(Single); + default: + return typeof(Int32); + } + } + + public float GetFloat(int i) + { + return Convert.ToSingle(GetValue(i)); + } + + public Guid GetGuid(int i) + { + return (Guid)GetValue(i); + } + + public short GetInt16(int i) + { + return (short)GetValue(i); + } + public int GetInt32(int i) + { + return (int)GetValue(i); + } + + public long GetInt64(int i) + { + return (long)GetValue(i); + } + + public string GetName(int i) + { + switch (i) + { + case 0: + return "ID"; + case 1: + return "TimeStamp"; + case 2: + return "Value"; + default: + return string.Empty; + } + } + + public int GetOrdinal(string name) + { + switch (name) + { + case "ID": + return 0; + case "TimeStamp": + return 1; + case "Value": + return 2; + default: + return -1; + } + } + + public string GetString(int i) + { + return (string)GetValue(i); + } + + public object GetValue(int i) + { + switch (i) + { + case 0: + return _enumer.Current.ID; + case 1: + return _enumer.Current.TimeStamp; + case 2: + var index = _server.GetItemProperties(_enumer.Current.ID); + if (index < 0) return 0f; + switch (_server.MetaDataList[index].DataType) + { + case DataType.FLOAT: + var ff = _enumer.Current.Value.Single; + return ff > -2E-38 && ff < 2E-38 ? 0f : ff; + case DataType.BOOL: + return _enumer.Current.Value.Boolean ? 1f : 0f; + case DataType.INT: + return _enumer.Current.Value.Int32; + case DataType.WORD: + case DataType.SHORT: + return _enumer.Current.Value.Int16; + case DataType.BYTE: + return _enumer.Current.Value.Byte; + default: + return 0f; + } + default: + return 0f; ; + } + } + + public int GetValues(object[] values) + { + throw new NotImplementedException(); + } + + public bool IsDBNull(int i) + { + return false; + } + + public object this[string name] + { + get + { + return GetValue(GetOrdinal(name)); + } + } + + public object this[int i] + { + get + { + return GetValue(i); + } + } + + #endregion + } +} diff --git a/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusDriver.csproj b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusDriver.csproj new file mode 100644 index 0000000..aa8334b --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusDriver.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.0 + + + + true + + + + + + + + + + + diff --git a/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusRTUDriver.cs b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusRTUDriver.cs new file mode 100644 index 0000000..dd5f896 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusRTUDriver.cs @@ -0,0 +1,563 @@ +锘縰sing System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Text; +using System.Timers; +using DataService; +using RJCP.IO.Ports; + +namespace ModbusDriver +{ + [Description("Modbus RTU鍗忚")] + public sealed class ModbusRTUReader : IPLCDriver + { + short _id; + public short ID + { + get + { + return _id; + } + } + + private SerialPortStream _serialPort; + public int PDU + { + get { return 0x100; } + } + + public DeviceAddress GetDeviceAddress(string address) + { + DeviceAddress dv = DeviceAddress.Empty; + if (string.IsNullOrEmpty(address)) + return dv; + switch (address[0]) + { + case '0': + { + dv.Area = Modbus.fctReadCoil; + int st; + int.TryParse(address, out st); + dv.Bit = (byte)(st % 16); + st /= 16; + dv.Start = st; + } + break; + case '1': + { + dv.Area = Modbus.fctReadDiscreteInputs; + int st; + int.TryParse(address.Substring(1), out st); + dv.Bit = (byte)(st % 16); + st /= 16; + dv.Start = st; + } + break; + case '4': + { + int index = address.IndexOf('.'); + dv.Area = Modbus.fctReadHoldingRegister; + if (index > 0) + { + dv.Start = int.Parse(address.Substring(1, index - 1)); + dv.Bit = byte.Parse(address.Substring(index + 1)); + } + else + dv.Start = int.Parse(address.Substring(1)); + dv.Start--; + } + break; + case '3': + { + int index = address.IndexOf('.'); + dv.Area = Modbus.fctReadInputRegister; + if (index > 0) + { + dv.Start = int.Parse(address.Substring(1, index - 1)); + dv.Bit = byte.Parse(address.Substring(index + 1)); + } + else + dv.Start = int.Parse(address.Substring(1)); + dv.Start--; + } + break; + } + return dv; + } + + public string GetAddress(DeviceAddress address) + { + return string.Empty; + } + + string _name; + public string Name + { + get + { + return _name; + } + } + + string _port; + public string ServerName + { + get { return _port; } + set { _port = value; } + } + + public bool IsClosed + { + get + { + return _serialPort.IsOpen == false; + } + } + + private int _timeOut; + public int TimeOut + { + get { return _timeOut; } + set { _timeOut = value; } + } + + List _grps = new List(); + public IEnumerable Groups + { + get { return _grps; } + } + + IDataServer _server; + public IDataServer Parent + { + get { return _server; } + } + + public ModbusRTUReader(IDataServer server, short id, string name, string remote = null, int timeOut = 10000, string port = "COM1", string baudRate = "9600") + { + _id = id; + _name = name; + _server = server; + _port = port; + _serialPort = new SerialPortStream(port); + _timeOut = timeOut; + _serialPort.ReadTimeout = _timeOut; + _serialPort.WriteTimeout = _timeOut; + _serialPort.BaudRate = int.Parse(baudRate); + _serialPort.DataBits = 8; + _serialPort.Parity = Parity.Even; + _serialPort.StopBits = StopBits.One; + } + + public bool Connect() + { + try + { + _serialPort.Open(); + return true; + } + catch (IOException error) + { + if (OnClose != null) + { + OnClose(this, new ShutdownRequestEventArgs(error.Message)); + } + return false; + } + } + + public IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false) + { + ModbusRtuGroup grp = new ModbusRtuGroup(id, name, updateRate, active, this); + _grps.Add(grp); + return grp; + } + + public bool RemoveGroup(IGroup grp) + { + grp.IsActive = false; + return _grps.Remove(grp); + } + + public void Dispose() + { + foreach (IGroup grp in _grps) + { + grp.Dispose(); + } + _grps.Clear(); + _serialPort.Close(); + } + + private byte[] CreateReadHeader(int startAddress, ushort length, byte function) + { + byte[] data = new byte[8]; + data[0] = (byte)_id; // Slave id high byte + data[1] = function; // Message size + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + byte[] _length = BitConverter.GetBytes((short)length); + data[4] = _length[0]; // Number of data to read + data[5] = _length[1]; // Number of data to read + byte[] arr = Utility.CalculateCrc(data, 6); + data[6] = arr[0]; + data[7] = arr[1]; + return data; + } + + public byte[] WriteSingleCoils(int startAddress, bool OnOff) + { + byte[] data = new byte[8]; + data[0] = (byte)_id; // Slave id high byte + data[1] = Modbus.fctWriteSingleCoil; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + if (OnOff) data[4] = 0xFF; + byte[] arr = Utility.CalculateCrc(data, 6); + data[6] = arr[0]; + data[7] = arr[1]; + return data; + } + + public byte[] WriteMultipleCoils(int startAddress, ushort numBits, byte[] values) + { + int len = values.Length; + byte[] data = new byte[len + 9]; + data[0] = (byte)_id; // Slave id high byte + data[1] = Modbus.fctWriteMultipleCoils; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + byte[] _length = BitConverter.GetBytes((short)numBits); + data[4] = _length[0]; // Number of data to read + data[5] = _length[1]; // Number of data to read + data[6] = (byte)len; + Array.Copy(values, 0, data, 7, len); + byte[] arr = Utility.CalculateCrc(data, len + 7); + data[len + 7] = arr[0]; + data[len + 8] = arr[1]; + return data; + } + + public byte[] WriteSingleRegister(int startAddress, byte[] values) + { + byte[] data = new byte[8]; + data[0] = (byte)_id; // Slave id high byte + data[1] = Modbus.fctWriteSingleRegister; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + data[4] = values[0]; + data[5] = values[1]; + byte[] arr = Utility.CalculateCrc(data, 6); + data[6] = arr[0]; + data[7] = arr[1]; + return data; + } + + public byte[] WriteMultipleRegister(int startAddress, byte[] values) + { + int len = values.Length; + if (len % 2 > 0) len++; + byte[] data = new byte[len + 9]; + data[0] = (byte)_id; // Slave id high byte + data[1] = Modbus.fctWriteMultipleRegister; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + byte[] _length = BitConverter.GetBytes((short)(len >> 1)); + data[4] = _length[0]; // Number of data to read + data[5] = _length[1]; // Number of data to read + data[6] = (byte)len; + Array.Copy(values, 0, data, 7, len); + byte[] arr = Utility.CalculateCrc(data, len + 7); + data[len + 7] = arr[0]; + data[len + 8] = arr[1]; + return data; + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + int area = address.Area; + try + { + byte[] header = area == Modbus.fctReadCoil ? CreateReadHeader(address.Start * 16, (ushort)(16 * size), (byte)area) : + CreateReadHeader(address.Start, size, (byte)area); + _serialPort.Write(header, 0, header.Length); + byte[] frameBytes = new byte[size * 2 + 5]; + byte[] data = new byte[size * 2]; + int numBytesRead = 0; + while (numBytesRead != size) + numBytesRead += _serialPort.Read(frameBytes, numBytesRead, size - numBytesRead); + if (frameBytes[0] == (byte)_id && Utility.CheckSumCRC(frameBytes)) + { + Array.Copy(frameBytes, 3, data, 0, size); + return data; + } + return null; + } + catch (Exception e) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(e.Message)); + return null; + } + } + + public ItemData ReadInt32(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 2); + return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt32(bit, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 1); + return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt16(bit, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 1); + return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(bit[0], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size) + { + byte[] bit = ReadBytes(address, size); + return bit == null ? new ItemData(string.Empty, 0, QUALITIES.QUALITY_BAD) : + new ItemData(Encoding.ASCII.GetString(bit), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadFloat(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 2); + return bit == null ? new ItemData(0f, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToSingle(bit, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadBit(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 1); + return bit == null ? new ItemData(false, 0, QUALITIES.QUALITY_BAD) : + new ItemData((bit[0] & (1 << (address.Bit))) > 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + var data = WriteMultipleRegister(address.Start, bit); + _serialPort.Write(data, 0, data.Length); + _serialPort.ReadByte(); + var chr = _serialPort.ReadByte(); + return (chr & 0x80) > 0 ? -1 : 0; + } + + public int WriteBit(DeviceAddress address, bool bit) + { + var data = WriteSingleCoils(address.Start + address.Bit, bit); + _serialPort.Write(data, 0, data.Length); + _serialPort.ReadByte(); + var chr = _serialPort.ReadByte(); + return (chr & 0x80) > 0 ? -1 : 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + var data = WriteSingleRegister(address.Start, new byte[] { bits }); + _serialPort.Write(data, 0, data.Length); + _serialPort.ReadByte(); + var chr = _serialPort.ReadByte(); + return (chr & 0x80) > 0 ? -1 : 0; + } + + public int WriteInt16(DeviceAddress address, short value) + { + var data = WriteSingleRegister(address.Start, BitConverter.GetBytes(value)); + _serialPort.Write(data, 0, data.Length); + var chr = _serialPort.ReadByte(); + return (chr & 0x80) > 0 ? -1 : 0; + } + + public int WriteInt32(DeviceAddress address, int value) + { + var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value)); + _serialPort.Write(data, 0, data.Length); + _serialPort.ReadByte(); + var chr = _serialPort.ReadByte(); + return (chr & 0x80) > 0 ? -1 : 0; + } + + public int WriteFloat(DeviceAddress address, float value) + { + var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value)); + _serialPort.Write(data, 0, data.Length); + _serialPort.ReadByte(); + var chr = _serialPort.ReadByte(); + return (chr & 0x80) > 0 ? -1 : 0; + } + + public int WriteString(DeviceAddress address, string str) + { + var data = WriteMultipleRegister(address.Start, Encoding.ASCII.GetBytes(str)); + _serialPort.Write(data, 0, data.Length); + _serialPort.ReadByte(); + var chr = _serialPort.ReadByte(); + return chr == (byte)_id ? -1 : 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public event ShutdownRequestEventHandler OnClose; + } + + public sealed class ModbusRtuGroup : PLCGroup + { + public ModbusRtuGroup(short id, string name, int updateRate, bool active, ModbusRTUReader plcReader) + { + this._id = id; + this._name = name; + this._updateRate = updateRate; + this._isActive = active; + this._plcReader = plcReader; + this._server = _plcReader.Parent; + this._timer = new Timer(); + this._changedList = new List(); + this._cacheReader = new ShortCacheReader(); + } + + protected override unsafe int Poll() + { + short[] cache = (short[])_cacheReader.Cache; + int k = 0; + foreach (PDUArea area in _rangeList) + { + byte[] rcvBytes = _plcReader.ReadBytes(area.Start, (ushort)area.Len);//浠嶱LC璇诲彇鏁版嵁 + if (rcvBytes == null) + { + _plcReader.Connect(); + return -1; + } + else + { + int len = rcvBytes.Length / 2; + fixed (byte* p1 = rcvBytes) + { + short* prcv = (short*)p1; + int index = area.StartIndex;//index鎸囧悜_items涓殑Tag鍏冩暟鎹 + int count = index + area.Count; + while (index < count) + { + DeviceAddress addr = _items[index].Address; + int iShort = addr.CacheIndex; + int iShort1 = iShort - k; + if (addr.VarType == DataType.BOOL) + { + int tmp = prcv[iShort1] ^ cache[iShort]; + DeviceAddress next = addr; + if (tmp != 0) + { + while (addr.Start == next.Start) + { + if ((tmp & (1 << next.Bit)) > 0) _changedList.Add(index); + if (++index < count) + next = _items[index].Address; + else + break; + } + } + else + { + while (addr.Start == next.Start && ++index < count) + { + next = _items[index].Address; + } + } + } + else + { + if (addr.DataSize <= 2) + { + if (prcv[iShort1] != cache[iShort]) _changedList.Add(index); + } + else + { + int size = addr.DataSize / 2; + for (int i = 0; i < size; i++) + { + if (prcv[iShort1 + i] != cache[iShort + i]) + { + _changedList.Add(index); + break; + } + } + } + index++; + } + } + for (int j = 0; j < len; j++) + { + cache[j + k] = prcv[j]; + }//灏哖LC璇诲彇鐨勬暟鎹啓鍏ュ埌CacheReader涓 + } + k += len; + } + } + return 1; + } + + } + + + public sealed class Modbus + { + public const byte fctReadCoil = 1; + public const byte fctReadDiscreteInputs = 2; + public const byte fctReadHoldingRegister = 3; + public const byte fctReadInputRegister = 4; + public const byte fctWriteSingleCoil = 5; + public const byte fctWriteSingleRegister = 6; + public const byte fctWriteMultipleCoils = 15; + public const byte fctWriteMultipleRegister = 16; + public const byte fctReadWriteMultipleRegister = 23; + + /// Constant for exception illegal function. + public const byte excIllegalFunction = 1; + /// Constant for exception illegal data address. + public const byte excIllegalDataAdr = 2; + /// Constant for exception illegal data value. + public const byte excIllegalDataVal = 3; + /// Constant for exception slave device failure. + public const byte excSlaveDeviceFailure = 4; + /// Constant for exception acknowledge. + public const byte excAck = 5; + /// Constant for exception slave is busy/booting up. + public const byte excSlaveIsBusy = 6; + /// Constant for exception gate path unavailable. + public const byte excGatePathUnavailable = 10; + /// Constant for exception not connected. + public const byte excExceptionNotConnected = 253; + /// Constant for exception connection lost. + public const byte excExceptionConnectionLost = 254; + /// Constant for exception response timeout. + public const byte excExceptionTimeout = 255; + /// Constant for exception wrong offset. + public const byte excExceptionOffset = 128; + /// Constant for exception send failt. + public const byte excSendFailt = 100; + } + +} diff --git a/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusRTU_TCP.cs b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusRTU_TCP.cs new file mode 100644 index 0000000..e8243f0 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusRTU_TCP.cs @@ -0,0 +1,462 @@ +锘縰sing System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Net.Sockets; +using System.Text; +using DataService; + +namespace ModbusDriver +{ + [Description("Modbus RTU_TCP鍗忚")] + public sealed class ModbusRTU_TCPReader : IPLCDriver, IMultiReadWrite + { + private int _timeout; + + private Socket tcpSynCl; + private byte[] tcpSynClBuffer = new byte[0xFF]; + + short _id; + public short ID + { + get + { + return _id; + } + } + + string _name; + public string Name + { + get + { + return _name; + } + } + + int _slave = 1; + string _ip; + public string ServerName + { + get { return _ip; } + set { _ip = value; } + } + + public bool IsClosed + { + get + { + return tcpSynCl == null || tcpSynCl.Connected == false; + } + } + + public int TimeOut + { + get { return _timeout; } + set { _timeout = value; } + } + + List _grps = new List(20); + public IEnumerable Groups + { + get { return _grps; } + } + + IDataServer _server; + public IDataServer Parent + { + get { return _server; } + } + + public ModbusRTU_TCPReader(IDataServer server, short id, string name, string ip, int timeOut = 500, string spare1 = "1", string spare2 = null) + { + _id = id;//id + _name = name; + _server = server; + _ip = ip; + _timeout = timeOut; + if (!string.IsNullOrEmpty(spare1)) + _slave = int.Parse(spare1); + } + + public bool Connect() + { + int port = 7000; + try + { + if (tcpSynCl != null) + tcpSynCl.Close(); + //IPAddress ip = IPAddress.Parse(_ip); + // ---------------------------------------------------------------- + // Connect synchronous client + tcpSynCl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + tcpSynCl.SendTimeout = _timeout; + tcpSynCl.ReceiveTimeout = _timeout; + tcpSynCl.NoDelay = true; + tcpSynCl.Connect(_ip, port); + return true; + } + catch (SocketException error) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(error.Message)); + return false; + } + } + + private byte[] CreateReadHeader(int startAddress, ushort length, byte function) + { + byte[] data = new byte[8]; + data[0] = (byte)_slave; // Slave id high byte + data[1] = function; // Message size + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + byte[] _length = BitConverter.GetBytes((short)length); + data[4] = _length[0]; // Number of data to read + data[5] = _length[1]; // Number of data to read + byte[] arr = Utility.CalculateCrc(data, 6); + data[6] = arr[0]; + data[7] = arr[1]; + return data; + } + + public byte[] WriteSingleCoils(int startAddress, bool OnOff) + { + byte[] data = new byte[8]; + data[0] = (byte)_slave; // Slave id high byte + data[1] = Modbus.fctWriteSingleCoil; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + if (OnOff) data[4] = 0xFF; + byte[] arr = Utility.CalculateCrc(data, 6); + data[6] = arr[0]; + data[7] = arr[1]; + return data; + } + + public byte[] WriteMultipleCoils(int startAddress, ushort numBits, byte[] values) + { + int len = values.Length; + byte[] data = new byte[len + 9]; + data[0] = (byte)_slave; // Slave id high byte + data[1] = Modbus.fctWriteMultipleCoils; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + byte[] _length = BitConverter.GetBytes((short)numBits); + data[4] = _length[0]; // Number of data to read + data[5] = _length[1]; // Number of data to read + data[6] = (byte)len; + Array.Copy(values, 0, data, 7, len); + byte[] arr = Utility.CalculateCrc(data, len + 7); + data[len + 7] = arr[0]; + data[len + 8] = arr[1]; + return data; + } + + public byte[] WriteSingleRegister(int startAddress, byte[] values) + { + byte[] data = new byte[8]; + data[0] = (byte)_slave; // Slave id high byte + data[1] = Modbus.fctWriteSingleRegister; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + data[4] = values[0]; + data[5] = values[1]; + byte[] arr = Utility.CalculateCrc(data, 6); + data[6] = arr[0]; + data[7] = arr[1]; + return data; + } + + public byte[] WriteMultipleRegister(int startAddress, byte[] values) + { + int len = values.Length; + if (len % 2 > 0) len++; + byte[] data = new byte[len + 9]; + data[0] = (byte)_slave; // Slave id high byte + data[1] = Modbus.fctWriteMultipleRegister; // Function code + byte[] _adr = BitConverter.GetBytes((short)startAddress); + data[2] = _adr[0]; // Start address + data[3] = _adr[1]; // Start address + byte[] _length = BitConverter.GetBytes((short)(len >> 1)); + data[4] = _length[0]; // Number of data to read + data[5] = _length[1]; // Number of data to read + data[6] = (byte)len; + Array.Copy(values, 0, data, 7, len); + byte[] arr = Utility.CalculateCrc(data, len + 7); + data[len + 7] = arr[0]; + data[len + 8] = arr[1]; + return data; + } + + public int PDU + { + get { return 252; } + //get { return 256; } + } + + public DeviceAddress GetDeviceAddress(string address) + { + DeviceAddress dv = DeviceAddress.Empty; + if (string.IsNullOrEmpty(address)) + return dv; + switch (address[0]) + { + case '0': + { + dv.Area = Modbus.fctReadCoil; + int st; + int.TryParse(address, out st); + //dv.Start = (st / 16) * 16;//??????????????????? + dv.Bit = (byte)(st % 16); + st /= 16; + dv.Start = st; + } + break; + case '1': + { + dv.Area = Modbus.fctReadDiscreteInputs; + int st; + int.TryParse(address.Substring(1), out st); + //dv.Start = (st / 16) * 16;//??????????????????? + dv.Bit = (byte)(st % 16); + st /= 16; + dv.Start = st; + } + break; + case '4': + { + int index = address.IndexOf('.'); + dv.Area = Modbus.fctReadHoldingRegister; + if (index > 0) + { + dv.Start = int.Parse(address.Substring(1, index - 1)); + dv.Bit = byte.Parse(address.Substring(index + 1)); + } + else + dv.Start = int.Parse(address.Substring(1)); + dv.Start--; + } + break; + case '3': + { + int index = address.IndexOf('.'); + dv.Area = Modbus.fctReadInputRegister; + if (index > 0) + { + dv.Start = int.Parse(address.Substring(1, index - 1)); + dv.Bit = byte.Parse(address.Substring(index + 1)); + } + else + dv.Start = int.Parse(address.Substring(1)); + dv.Start--; + } + break; + } + return dv; + } + + public string GetAddress(DeviceAddress address) + { + return string.Empty; + } + + + public IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false) + { + ModbusTcpGroup grp = new ModbusTcpGroup(id, name, updateRate, active, this); + _grps.Add(grp); + return grp; + } + + public bool RemoveGroup(IGroup grp) + { + grp.IsActive = false; + return _grps.Remove(grp); + } + + public void Dispose() + { + if (tcpSynCl != null) + { + if (tcpSynCl.Connected) + { + try { tcpSynCl.Shutdown(SocketShutdown.Both); } + catch { } + tcpSynCl.Close(); + } + tcpSynCl = null; + } + foreach (IGroup grp in _grps) + { + grp.Dispose(); + } + _grps.Clear(); + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + int area = address.Area; + try + { + if (!tcpSynCl.Connected) return null; + byte[] header = area == Modbus.fctReadCoil ? CreateReadHeader(address.Start * 16, (ushort)(16 * size), (byte)area) : + CreateReadHeader(address.Start, size, (byte)area); + tcpSynCl.Send(header, 0, header.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + byte[] frameBytes = new byte[size * 2 + 3]; + int result = tcpSynCl.Receive(frameBytes, 0, frameBytes.Length, SocketFlags.None); + byte[] data = new byte[size * 2]; + if (frameBytes[0] == (byte)_slave) + { + Array.Copy(frameBytes, 3, data, 0, data.Length); + return data; + } + else return new byte[0]; + } + catch (Exception e) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(e.Message)); + return null; + } + } + + public ItemData ReadInt32(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 2); + return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt32(bit, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 1); + return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToInt16(bit, 0), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 1); + return bit == null ? new ItemData(0, 0, QUALITIES.QUALITY_BAD) : + new ItemData(bit[0], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size) + { + byte[] bit = ReadBytes(address, size); + return bit == null ? new ItemData(string.Empty, 0, QUALITIES.QUALITY_BAD) : + new ItemData(Encoding.ASCII.GetString(bit), 0, QUALITIES.QUALITY_GOOD); + } + + public unsafe ItemData ReadFloat(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 2); + return bit == null ? new ItemData(0f, 0, QUALITIES.QUALITY_BAD) : + new ItemData(BitConverter.ToSingle(bit, 0), 0, QUALITIES.QUALITY_GOOD); + //int value = BitConverter.ToInt32(bit, 0); + //return new ItemData(*(((float*)&value)), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadBit(DeviceAddress address) + { + byte[] bit = ReadBytes(address, 1); + return bit == null ? new ItemData(false, 0, QUALITIES.QUALITY_BAD) : + new ItemData((bit[0] & (1 << (address.Bit))) > 0, 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + if (!tcpSynCl.Connected) return -1; + var data = WriteMultipleRegister(address.Start, bit); + tcpSynCl.Send(data, 0, data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + return (tcpSynClBuffer[1] & 0x80) > 0 ? -1 : 0; + } + + public int WriteBit(DeviceAddress address, bool bit) + { + if (!tcpSynCl.Connected) return -1; + var data = WriteSingleCoils(address.Start + address.Bit, bit); + tcpSynCl.Send(data, 0, data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + return (tcpSynClBuffer[1] & 0x80) > 0 ? -1 : 0; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + if (!tcpSynCl.Connected) return -1; + var data = WriteSingleRegister(address.Start, new byte[] { bits }); + tcpSynCl.Send(data, 0, data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + return (tcpSynClBuffer[1] & 0x80) > 0 ? -1 : 0; + } + + public int WriteInt16(DeviceAddress address, short value) + { + if (!tcpSynCl.Connected) return -1; + var data = WriteSingleRegister(address.Start, BitConverter.GetBytes(value)); + tcpSynCl.Send(data, 0, data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + return (tcpSynClBuffer[1] & 0x80) > 0 ? -1 : 0; + } + + public int WriteInt32(DeviceAddress address, int value) + { + if (!tcpSynCl.Connected) return -1; + var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value)); + tcpSynCl.Send(data, 0, data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + return (tcpSynClBuffer[1] & 0x80) > 0 ? -1 : 0; + } + + public int WriteFloat(DeviceAddress address, float value) + { + if (!tcpSynCl.Connected) return -1; + var data = WriteMultipleRegister(address.Start, BitConverter.GetBytes(value)); + tcpSynCl.Send(data, 0, data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + return (tcpSynClBuffer[1] & 0x80) > 0 ? -1 : 0; + } + + public int WriteString(DeviceAddress address, string str) + { + if (!tcpSynCl.Connected) return -1; + var data = WriteMultipleRegister(address.Start, Encoding.ASCII.GetBytes(str)); + tcpSynCl.Send(data, 0, data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + return (tcpSynClBuffer[1] & 0x80) > 0 ? -1 : 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public event ShutdownRequestEventHandler OnClose; + + public int Limit + { + get { return 60; } + } + + public ItemData[] ReadMultiple(DeviceAddress[] addrsArr) + { + return this.PLCReadMultiple(new NetShortCacheReader(), addrsArr); + } + + public int WriteMultiple(DeviceAddress[] addrArr, object[] buffer) + { + return this.PLCWriteMultiple(new NetShortCacheReader(), addrArr, buffer, Limit); + } + } +} + diff --git a/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusTCPReader.cs b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusTCPReader.cs new file mode 100644 index 0000000..9f9a234 --- /dev/null +++ b/SCADA/Program/CoreApp/DataService/ModbusDriver/ModbusTCPReader.cs @@ -0,0 +1,634 @@ +锘縰sing System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Timers; +using DataService; + +namespace ModbusDriver +{ + [Description("Modbus TCP鍗忚")] + public sealed class ModbusTCPReader : IPLCDriver, IMultiReadWrite + { + private int _timeout; + + private Socket tcpSynCl; + private byte[] tcpSynClBuffer = new byte[0xFF]; + + short _id; + public short ID + { + get + { + return _id; + } + } + + string _name; + public string Name + { + get + { + return _name; + } + } + + string _ip; + public string ServerName + { + get { return _ip; } + set { _ip = value; } + } + + public bool IsClosed + { + get + { + return tcpSynCl == null || tcpSynCl.Connected == false; + } + } + + public int TimeOut + { + get { return _timeout; } + set { _timeout = value; } + } + + byte _slaveId;//璁惧ID 鍗曞厓鍙 瀛楄妭鍙 + /// + /// 璁惧ID 鍗曞厓鍙 瀛楄妭鍙 + /// + public byte SlaveId + { + get { return _slaveId; } + set { _slaveId = value; } + } + + List _grps = new List(20); + public IEnumerable Groups + { + get { return _grps; } + } + + IDataServer _server; + public IDataServer Parent + { + get { return _server; } + } + + public ModbusTCPReader(IDataServer server, short id, string name, string ip, int timeOut = 500, string spare1 = null, string spare2 = null) + { + _id = id; + _name = name; + _server = server; + _ip = ip; + _timeout = timeOut; + byte.TryParse(spare1, out _slaveId); + } + + public bool Connect() + { + int port = 502; + try + { + if (tcpSynCl != null) + tcpSynCl.Close(); + //IPAddress ip = IPAddress.Parse(_ip); + // ---------------------------------------------------------------- + // Connect synchronous client + tcpSynCl = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + tcpSynCl.SendTimeout = _timeout; + tcpSynCl.ReceiveTimeout = _timeout; + tcpSynCl.NoDelay = true; + tcpSynCl.Connect(_ip, port); + return true; + } + catch (SocketException error) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(error.Message)); + return false; + } + } + + private byte[] CreateReadHeader(int id, int startAddress, ushort length, byte function) + { + byte[] data = new byte[12]; + data[0] = 0; // Slave id high byte + data[1] = 0; // Slave id low byte + data[5] = 6; // Message size + data[6] = (byte)id; // Slave address + data[7] = function; // Function code + byte[] _adr = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)startAddress)); + data[8] = _adr[0]; // Start address + data[9] = _adr[1]; // Start address + byte[] _length = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)length)); + data[10] = _length[0]; // Number of data to read + data[11] = _length[1]; // Number of data to read + return data; + } + + private byte[] CreateWriteHeader(int id, int startAddress, ushort numData, ushort numBytes, byte function) + { + byte[] data = new byte[numBytes + 11]; + data[0] = 0; // Slave id high byte + data[1] = 0; // Slave id low byte+ + byte[] _size = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)(5 + numBytes))); + data[4] = _size[0]; // Complete message size in bytes + data[5] = _size[1]; // Complete message size in bytes + data[6] = (byte)id; // Slave address + data[7] = function; // Function code + byte[] _adr = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)startAddress)); + data[8] = _adr[0]; // Start address + data[9] = _adr[1]; // Start address + if (function >= Modbus.fctWriteMultipleCoils) + { + byte[] _cnt = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)numData)); + data[10] = _cnt[0]; // Number of bytes + data[11] = _cnt[1]; // Number of bytes + data[12] = (byte)(numBytes - 2); + } + return data; + } + + private byte[] WriteSyncData(byte[] write_data) + { + short id = BitConverter.ToInt16(write_data, 0); + if (IsClosed) CallException(id, write_data[7], Modbus.excExceptionConnectionLost); + else + { + try + { + tcpSynCl.Send(write_data, 0, write_data.Length, SocketFlags.None);//鏄惁瀛樺湪lock鐨勯棶棰橈紵 + int result = tcpSynCl.Receive(tcpSynClBuffer, 0, 0xFF, SocketFlags.None); + + byte function = tcpSynClBuffer[7]; + byte[] data; + + if (result == 0) CallException(id, write_data[7], Modbus.excExceptionConnectionLost); + + // ------------------------------------------------------------ + // Response data is slave ModbusModbus.exception + if (function > Modbus.excExceptionOffset) + { + function -= Modbus.excExceptionOffset; + CallException(id, function, tcpSynClBuffer[8]); + return null; + } + // ------------------------------------------------------------ + // Write response data + else if ((function >= Modbus.fctWriteSingleCoil) && (function != Modbus.fctReadWriteMultipleRegister)) + { + data = new byte[2]; + Array.Copy(tcpSynClBuffer, 10, data, 0, 2); + } + // ------------------------------------------------------------ + // Read response data + else + { + data = new byte[tcpSynClBuffer[8]]; + Array.Copy(tcpSynClBuffer, 9, data, 0, tcpSynClBuffer[8]); + } + return data; + } + catch (SocketException) + { + CallException(id, write_data[7], Modbus.excExceptionConnectionLost); + } + } + return null; + } + + public byte[] WriteSingleCoils(int id, int startAddress, bool OnOff) + { + byte[] data; + data = CreateWriteHeader(id, startAddress, 1, 1, Modbus.fctWriteSingleCoil); + if (OnOff == true) data[10] = 255; + else data[10] = 0; + return WriteSyncData(data); + } + + public byte[] WriteMultipleCoils(int id, int startAddress, ushort numBits, byte[] values) + { + byte numBytes = Convert.ToByte(values.Length); + byte[] data; + data = CreateWriteHeader(id, startAddress, numBits, (byte)(numBytes + 2), Modbus.fctWriteMultipleCoils); + Array.Copy(values, 0, data, 13, numBytes); + return WriteSyncData(data); + } + + public byte[] WriteSingleRegister(int id, int startAddress, byte[] values) + { + byte[] data; + data = CreateWriteHeader(id, startAddress, 1, 1, Modbus.fctWriteSingleRegister); + data[10] = values[0]; + data[11] = values[1]; + return WriteSyncData(data); + } + + public byte[] WriteMultipleRegister(int id, int startAddress, byte[] values) + { + ushort numBytes = Convert.ToUInt16(values.Length); + if (numBytes % 2 > 0) numBytes++; + byte[] data; + + data = CreateWriteHeader(id, startAddress, Convert.ToUInt16(numBytes / 2), Convert.ToUInt16(numBytes + 2), Modbus.fctWriteMultipleRegister); + Array.Copy(values, 0, data, 13, values.Length); + return WriteSyncData(data); + } + + public int PDU + { + get { return 252; } + //get { return 256; } + } + + public DeviceAddress GetDeviceAddress(string address) + { + DeviceAddress dv = DeviceAddress.Empty; + if (string.IsNullOrEmpty(address)) + return dv; + dv.Area = _slaveId; + switch (address[0]) + { + case '0': + { + dv.DBNumber = Modbus.fctReadCoil; + int st; + int.TryParse(address, out st); + //dv.Start = (st / 16) * 16;//??????????????????? + dv.Bit = (byte)(st % 16); + st /= 16; + dv.Start = st; + } + break; + case '1': + { + dv.DBNumber = Modbus.fctReadDiscreteInputs; + int st; + int.TryParse(address.Substring(1), out st); + //dv.Start = (st / 16) * 16;//??????????????????? + dv.Bit = (byte)(st % 16); + st /= 16; + dv.Start = st; + } + break; + case '4': + { + int index = address.IndexOf('.'); + dv.DBNumber = Modbus.fctReadHoldingRegister; + if (index > 0) + { + dv.Start = int.Parse(address.Substring(1, index - 1)); + dv.Bit = byte.Parse(address.Substring(index + 1)); + } + else + dv.Start = int.Parse(address.Substring(1)); + dv.Start--; + } + break; + case '3': + { + int index = address.IndexOf('.'); + dv.DBNumber = Modbus.fctReadInputRegister; + if (index > 0) + { + dv.Start = int.Parse(address.Substring(1, index - 1)); + dv.Bit = byte.Parse(address.Substring(index + 1)); + } + else + dv.Start = int.Parse(address.Substring(1)); + dv.Start--; + } + break; + } + return dv; + } + + public string GetAddress(DeviceAddress address) + { + return string.Empty; + } + + + public IGroup AddGroup(string name, short id, int updateRate, float deadBand = 0f, bool active = false) + { + ModbusTcpGroup grp = new ModbusTcpGroup(id, name, updateRate, active, this); + _grps.Add(grp); + return grp; + } + + public bool RemoveGroup(IGroup grp) + { + grp.IsActive = false; + return _grps.Remove(grp); + } + + public void Dispose() + { + if (tcpSynCl != null) + { + if (tcpSynCl.Connected) + { + try { tcpSynCl.Shutdown(SocketShutdown.Both); } + catch { } + tcpSynCl.Close(); + } + tcpSynCl = null; + } + foreach (IGroup grp in _grps) + { + grp.Dispose(); + } + _grps.Clear(); + } + + internal string GetErrorString(byte exception) + { + switch (exception) + { + case Modbus.excIllegalFunction: + return "Constant for ModbusModbus.exception illegal function."; + case Modbus.excIllegalDataAdr: + return "Constant for ModbusModbus.exception illegal data address."; + case Modbus.excIllegalDataVal: + return "Constant for ModbusModbus.exception illegal data value."; + case Modbus.excSlaveDeviceFailure: + return "Constant for ModbusModbus.exception slave device failure."; + case Modbus.excAck: + return "Constant for ModbusModbus.exception acknowledge."; + case Modbus.excSlaveIsBusy: + return "Constant for ModbusModbus.exception slave is busy/booting up."; + case Modbus.excGatePathUnavailable: + return "Constant for ModbusModbus.exception gate path unavailable."; + case Modbus.excExceptionNotConnected: + return "Constant for ModbusModbus.exception not connected."; + case Modbus.excExceptionConnectionLost: + return "Constant for ModbusModbus.exception connection lost."; + case Modbus.excExceptionTimeout: + return "Constant for ModbusModbus.exception response timeout."; + case Modbus.excExceptionOffset: + return "Constant for ModbusModbus.exception wrong offset."; + case Modbus.excSendFailt: + return "Constant for ModbusModbus.exception send failt."; + } + return string.Empty; + } + + internal void CallException(int id, byte function, byte exception) + { + if (tcpSynCl == null) return; + if (exception == Modbus.excExceptionConnectionLost && IsClosed == false) + { + if (OnClose != null) + OnClose(this, new ShutdownRequestEventArgs(GetErrorString(exception))); + } + } + + public byte[] ReadBytes(DeviceAddress address, ushort size) + { + int area = address.DBNumber; + return area < 2 ? WriteSyncData(CreateReadHeader(address.Area, address.Start * 16, (ushort)(16 * size), (byte)area)) + : WriteSyncData(CreateReadHeader(address.Area, address.Start, size, (byte)area)); + } + + public ItemData ReadInt32(DeviceAddress address) + { + byte[] data = WriteSyncData(CreateReadHeader(address.Area, address.Start, 2, (byte)address.DBNumber)); + if (data == null) + return new ItemData(0, 0, QUALITIES.QUALITY_BAD); + else + return new ItemData(IPAddress.HostToNetworkOrder(BitConverter.ToInt32(data, 0)), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadInt16(DeviceAddress address) + { + byte[] data = WriteSyncData(CreateReadHeader(address.Area, address.Start, 1, (byte)address.DBNumber)); + if (data == null) + return new ItemData(0, 0, QUALITIES.QUALITY_BAD); + else + return new ItemData(IPAddress.HostToNetworkOrder(BitConverter.ToInt16(data, 0)), 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadByte(DeviceAddress address) + { + byte[] data = WriteSyncData(CreateReadHeader(address.Area, address.Start, 1, (byte)address.DBNumber)); + if (data == null) + return new ItemData(0, 0, QUALITIES.QUALITY_BAD); + else + return new ItemData(data[0], 0, QUALITIES.QUALITY_GOOD); + } + + public ItemData ReadString(DeviceAddress address, ushort size) + { + byte[] data = WriteSyncData(CreateReadHeader(address.Area, address.Start, size, (byte)address.DBNumber)); + if (data == null) + return new ItemData(string.Empty, 0, QUALITIES.QUALITY_BAD); + else + return new ItemData(Encoding.ASCII.GetString(data, 0, data.Length), 0, QUALITIES.QUALITY_GOOD);//鏄惁鑰冭檻瀛楄妭搴忛棶棰橈紵 + } + + public unsafe ItemData ReadFloat(DeviceAddress address) + { + byte[] data = WriteSyncData(CreateReadHeader(address.Area, address.Start, 2, (byte)address.DBNumber)); + if (data == null) + return new ItemData(0.0f, 0, QUALITIES.QUALITY_BAD); + else + { + int value = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(data, 0)); + return new ItemData(*(((float*)&value)), 0, QUALITIES.QUALITY_GOOD); + } + } + + public ItemData ReadBit(DeviceAddress address) + { + byte[] data = address.DBNumber > 2 ? WriteSyncData(CreateReadHeader(address.Area, address.Start, 1, (byte)address.DBNumber)) : + WriteSyncData(CreateReadHeader(address.Area, address.Start * 16 + address.Bit, 1, (byte)address.DBNumber)); + if (data == null) + return new ItemData(false, 0, QUALITIES.QUALITY_BAD); + if (data.Length == 1) return new ItemData(data[0] > 0, 0, QUALITIES.QUALITY_GOOD); + unsafe + { + fixed (byte* p = data) + { + short* p1 = (short*)p; + return new ItemData((*p1 & (1 << address.Bit.BitSwap())) + != 0, 0, QUALITIES.QUALITY_GOOD); + } + } + } + + public ItemData ReadValue(DeviceAddress address) + { + return this.ReadValueEx(address); + } + + public int WriteBytes(DeviceAddress address, byte[] bit) + { + var data = address.DBNumber > 2 ? WriteMultipleRegister(address.Area, address.Start, bit) + : WriteMultipleCoils(address.Area, address.Start, (ushort)(8 * bit.Length), bit);//搴旇冭檻鍒 + return data == null ? -1 : 0; + } + + public int WriteBit(DeviceAddress address, bool bit) + { + if (address.DBNumber < 3) + { + var data = WriteSingleCoils(address.Area, address.Start + address.Bit, bit); + return data == null ? -1 : 0; + } + return -1; + } + + public int WriteBits(DeviceAddress address, byte bits) + { + var data = WriteSingleRegister(address.Area, address.Start, new byte[] { bits }); + return data == null ? -1 : 0; + } + + public int WriteInt16(DeviceAddress address, short value) + { + var data = WriteSingleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); + return data == null ? -1 : 0; + } + + public int WriteInt32(DeviceAddress address, int value) + { + var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); + return data == null ? -1 : 0; + } + + public int WriteFloat(DeviceAddress address, float value) + { + var data = WriteMultipleRegister(address.Area, address.Start, BitConverter.GetBytes(value)); + return data == null ? -1 : 0; + } + + public int WriteString(DeviceAddress address, string str) + { + var data = WriteMultipleRegister(address.Area, address.Start, Encoding.ASCII.GetBytes(str)); + return data == null ? -1 : 0; + } + + public int WriteValue(DeviceAddress address, object value) + { + return this.WriteValueEx(address, value); + } + + public event ShutdownRequestEventHandler OnClose; + + public int Limit + { + get { return 60; } + } + + public ItemData[] ReadMultiple(DeviceAddress[] addrsArr) + { + return this.PLCReadMultiple(new NetShortCacheReader(), addrsArr); + } + + public int WriteMultiple(DeviceAddress[] addrArr, object[] buffer) + { + return this.PLCWriteMultiple(new NetShortCacheReader(), addrArr, buffer, Limit); + } + } + + public sealed class ModbusTcpGroup : PLCGroup + { + public ModbusTcpGroup(short id, string name, int updateRate, bool active, IPLCDriver plcReader) + { + this._id = id; + this._name = name; + this._updateRate = updateRate; + this._isActive = active; + this._plcReader = plcReader; + this._server = _plcReader.Parent; + this._timer = new Timer(); + this._changedList = new List(); + this._cacheReader = new NetShortCacheReader(); + } + + protected override unsafe int Poll() + { + short[] cache = (short[])_cacheReader.Cache; + int offset = 0; + foreach (PDUArea area in _rangeList) + { + byte[] rcvBytes = _plcReader.ReadBytes(area.Start, (ushort)area.Len);//浠嶱LC璇诲彇鏁版嵁 + if (rcvBytes == null || rcvBytes.Length == 0) + { + //_plcReader.Connect(); + return -1; + } + else + { + int len = rcvBytes.Length / 2; + fixed (byte* p1 = rcvBytes) + { + short* prcv = (short*)p1; + int index = area.StartIndex;//index鎸囧悜_items涓殑Tag鍏冩暟鎹 + int count = index + area.Count; + while (index < count) + { + DeviceAddress addr = _items[index].Address; + int iShort = addr.CacheIndex; + int iShort1 = iShort - offset; + if (addr.VarType == DataType.BOOL) + { + int tmp = prcv[iShort1] ^ cache[iShort]; + DeviceAddress next = addr; + if (tmp != 0) + { + while (addr.Start == next.Start) + { + if ((tmp & (1 << next.Bit)) > 0) _changedList.Add(index); + if (++index < count) + next = _items[index].Address; + else + break; + } + } + else + { + while (addr.Start == next.Start && ++index < count) + { + next = _items[index].Address; + } + } + } + else + { + if (addr.DataSize <= 2) + { + if (prcv[iShort1] != cache[iShort]) _changedList.Add(index); + } + else + { + int size = addr.DataSize / 2; + for (int i = 0; i < size; i++) + { + if (prcv[iShort1 + i] != cache[iShort + i]) + { + _changedList.Add(index); + break; + } + } + } + index++; + } + } + for (int j = 0; j < len; j++) + { + cache[j + offset] = prcv[j]; + }//灏哖LC璇诲彇鐨勬暟鎹啓鍏ュ埌CacheReader涓 + } + offset += len; + } + } + return 1; + } + + } +} diff --git a/SCADA/Program/HMIControl/bin/Debug/DataHelper.dll b/SCADA/Program/HMIControl/bin/Debug/DataHelper.dll deleted file mode 100644 index 5ab722f..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/DataHelper.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/DataService.dll b/SCADA/Program/HMIControl/bin/Debug/DataService.dll deleted file mode 100644 index 5e2ae61..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/DataService.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/Femiani.Forms.UI.dll b/SCADA/Program/HMIControl/bin/Debug/Femiani.Forms.UI.dll deleted file mode 100644 index 5d16d74..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/Femiani.Forms.UI.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/HMIControl.Expression.Design.dll b/SCADA/Program/HMIControl/bin/Debug/HMIControl.Expression.Design.dll deleted file mode 100644 index 5278b57..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/HMIControl.Expression.Design.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/HMIControl.VisualStudio.Design.dll b/SCADA/Program/HMIControl/bin/Debug/HMIControl.VisualStudio.Design.dll deleted file mode 100644 index 529fb0c..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/HMIControl.VisualStudio.Design.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/HMIControl.VisualStudio.Design.dll.config b/SCADA/Program/HMIControl/bin/Debug/HMIControl.VisualStudio.Design.dll.config deleted file mode 100644 index 243a005..0000000 --- a/SCADA/Program/HMIControl/bin/Debug/HMIControl.VisualStudio.Design.dll.config +++ /dev/null @@ -1,10 +0,0 @@ -锘 - - - - - - - \ No newline at end of file diff --git a/SCADA/Program/HMIControl/bin/Debug/HMIControl.dll b/SCADA/Program/HMIControl/bin/Debug/HMIControl.dll deleted file mode 100644 index d3c90cc..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/HMIControl.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Expression.Controls.dll b/SCADA/Program/HMIControl/bin/Debug/Microsoft.Expression.Controls.dll deleted file mode 100644 index 48e2331..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Expression.Controls.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Expression.Drawing.dll b/SCADA/Program/HMIControl/bin/Debug/Microsoft.Expression.Drawing.dll deleted file mode 100644 index d2a5f7b..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Expression.Drawing.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Extensibility.dll b/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Extensibility.dll deleted file mode 100644 index 10e6653..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Extensibility.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Extensibility.xml b/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Extensibility.xml deleted file mode 100644 index f9446f4..0000000 --- a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Extensibility.xml +++ /dev/null @@ -1,1119 +0,0 @@ -锘 - - - Microsoft.Windows.Design.Extensibility - - - - A context item that maintains the set of references the designer is using to resolve type information. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with the specified set of references. - The new set of references. This may not be null and it may not contain null values. - - is null, or if one of the values in the array is null. - - - Initializes a new instance of the class with the specified local assembly name and set of references. - The local assembly name. This can only be set one time. - The new set of references. This may not be null and it may not contain null values. - - is null, or if one of the values in the array is null. - - - Returns all the types in the set of referenced assemblies that derive from or implement the specified base type. - An enumeration of types. An empty enumeration is returned if there are no matching types. - The base type that all returned types should derive from. If is an interface, all returned types will implement the interface. - - is null. - - - Gets a key in the context item manager that is used to determine what type of context item this object is. - A key in the context item manager that is used to determine what type of context item this object is. - - - Gets the local assembly name. - The local assembly name. - - - Called on a context item before it is stored in the context item manager. - The editing context that is receiving this object. - The existing object. - - - Gets an enumerable that can be used to enumerate the set of referenced assemblies. - An enumerable that can be used to enumerate the set of referenced assemblies. - - - Represents a single piece of state in the designer. - - - Initializes a new instance of the class. - - - When overridden in a derived class, gets the item type for this editing context item. - The for this editing context item. - - - Called on a context item before it is stored in the context item manager. - The editing context that is making this change. - The previously active item in the context. - - - Maintains a set of context items. - - - Initializes a new instance of the class. - - - Returns a value indicating whether the context item manager contains an item of the specified type. - true if the context contains an instance of this item type; otherwise, false. - - - - When overridden in a derived class, returns a value indicating whether the context item manager contains an item of the specified type. - true if the context contains an instance of this item type; otherwise, false. - The type of item to check. - - is null. - - - When overridden in a derived class, gets an enumeration of context items in the editing context. - An enumeration of context items. - - - A utility method that returns the target object for a delegate. - The target object of the callback. - The callback whose target you want. - - is null. - - - Returns an instance of the requested item type. - A context item of the requested type. If there is no item in the context of this type, a default one will be created. - - - - When overridden in a derived class, returns an instance of the requested item type. - A context item of the requested type. If there is no item in the context of this type, a default one will be created. - The type of item to return. - - is null. - - - Invokes the protected method on the specified . - The editing context in use. - The new context item. - The previous context item. - - , , or is null. - - - A helper method that performs a Delegate.Remove, but knows how to unwrap delegates that are proxies to generic callbacks. - The new delegate that should be assigned to existing. - The existing delegate. - The delegate to be removed from existing. - - - When overridden in a derived class, sets a context item to the specified value. - The value to set into the context item manager. Cannot be null. - - - Adds a callback that is invoked when a context item of the specified item type changes. - A callback that is invoked when changes. - - - is null. - - - When overridden in a derived class, adds a callback that is invoked when a context item of the specified item type changes. - The type of item to subscribe to. - A callback that will be invoked when changes. - - or is null. - - - For a description of this member, see . - An enumeration of context items. - - - Removes a subscription. - The callback to remove. - - - is null. - - - When overridden in a derived class, removes a subscription. - The type of context item to remove the callback from. - The callback to remove. - - or is null. - - - Contains contextual state about a designer. - - - Initializes a new instance of the class. - - - Creates an instance of the context item manager to be returned from the property. - An implementation of the class. - - - Creates an instance of the service manager to be returned from the property. - An implementation of the class. - - - Releases all resources used by the . - - - Releases the unmanaged resources used by the and optionally releases the managed resources. - true to release both managed and unmanaged resources; false to release only unmanaged resources. - - - Occurs when the method is called. - - - Finalizer that implements the pattern. - - - Gets the local collection of context items offered by this editing context. - A of context items offered by this editing context. - The method returned a null. - - - Gets the service manager for this editing context. - A for this editing context. - The method returned a null. - - - A delegate that is called back when an object should publish an instance of a service. - An instance of type . - The type of service to be published. - - - A generic delegate that is called back when an object should publish an instance of a service. - An instance of the specified service type. - - - - Defines attributes used by the class. - - - Initializes a new instance of the class. - - - Gets a value indicating whether all requirement attributes of the same type are required. - true if all requirement attributes of the same type are required; otherwise, false. - - - Returns a object that can be used to be notified when the requirement contained in this attribute has changed. - A new object. - The editing context to check. - - is null. - - - Determines if the meets the requirements specified in this attribute. - true if the attribute's requirements are met; otherwise, false. - The editing context to check. - - is null. - - - Provides a notification when changes in the editing context may have satisfied the attached requirement. - - - Initializes a new instance of the class. - The requirement to create a subscription for. - - is null. - - - Raises the event. - - - Gets the requirement attribute that is attached to this subscription. - A that is attached to this subscription. - - - Occurs when the requirement has changed. - - - Subscribes to context events. - - - Removes subscriptions to context events. - - - Determines whether the required context and services are available for the specified type. - - - Initializes a new instance of the class for the specified and type. - The feature manager to validate requirements against. - The type to get requirement attributes from. - - - Gets a value that indicates whether the type requirements exist in the editing context. - true if the type requirements exist in the editing context, or false if one or more requirements is missing. - - - Gets a list of pending requirement attributes. - A list of pending requirement attributes. These are requirements that have not yet been met. - - - Gets an enumeration of all requirements for the type contained in this validator. - An enumeration of objects for . - - - Occurs when the set of requirements necessary to use the type have changed. - - - Gets the type of object to validate requirements for. - A representing the object to validate requirements for. - - - Indicates that the class relies on the specified context. - - - Initializes a new instance of the class. - The type of context that is required. - - - Gets the context item type the class requires. - A that indicates the type the class requires. - - - Creates an object that enables notification when the requirement specified by this attribute is fulfilled by the editing context. - A object that you can use to handle events. - The editing context to check. - - is null. - - - Indicates whether the editing context contains a context item of type . - true if the attribute's requirements are met; otherwise, false. - The editing context to check. - - is null. - - - Gets the type ID of this attribute. - An object that indicates the type ID of this attribute. - - - Indicates that the class relies on the specified service. - - - Initializes a new instance of the class. - The type of service the class requires. - - - Creates an object that enables notification when the requirement specified by this attribute is fulfilled by the editing context. - A object that you can use to handle events. - The editing context to check. - - is null. - - - Indicates whether the editing context contains a service of type . - true if the attribute's requirements are met; otherwise, false. - The editing context to check. - - is null. - - - Gets the service type the class requires. - A that indicates the service type the class requires. - - - Gets the type ID of this attribute. - An object that indicates the type ID of this attribute. - - - Represents the behavior associated with an . - - - Initializes a new instance of the class. - - - Determines if the contains a service of the specified type. - true if contains ; otherwise, false. - - - - When overridden in a derived class, determines whether the contains a service of the specified type. - true if contains ; otherwise, false. - The type of service to search for. - - - When overridden in a derived class, retrieves an enumerator of the published services of this . - An enumeration of published services. - - - Retrieves an instance of a service of the specified type. - An instance of the type of service requested. This method never returns null. - - There is no service of the type requested. - - - Retrieves an instance of a service of the specified generic type. - An instance of the type of service requested; otherwise, null. - - - - When overridden in a derived class, retrieves an instance of a service of the specified type. - An instance of the type of service requested; otherwise, null. - The type of service to retrieve. - - - A helper method that gets the target object for a delegate. - The target of . - The delegate for which to get the target. - - is null. - - - Publishes a service of the specified type, represented by the specified method. - The method to invoke when the service is requested. - - - is null. - - - When overridden in a derived class, publishes a service of the specified type, represented by the specified method. - The type of service that is being published. - The method to invoke when the service is requested. - - - When overridden in a derived class, publishes the specified service instance of the specified type. - The type of service that is being published. - An instance of the service. - - - Publishes the specified service instance of the specified type. - An instance of the service. - - - is null. - - - Removes a callback method from a delegate. - A new delegate to replace the existing delegate. If is null, returns null. If is null, returns . - The delegate to remove the callback from. - The callback method to remove from the delegate. - - - Requests that the specified method is called when a service of the specified type is available. - The method to invoke when the service is available. - - - is null. - - - When overridden in a derived class, requests that the specified method is called when a service of the specified type is available. - The type of service to subscribe to. - The method to invoke when the service is available. - - - For a description of this member, see . - An enumeration of published services. - - - Requests that the specified method is no longer called when a service of the specified type is available. - The method to no longer invoke when the service is available. - - - is null. - - - When overridden in a derived class, requests that the specified method is no longer called when a service of the specified type is available. - The type of service to unsubscribe from. - The method to no longer invoke when the service is available. - - - Defines a callback method that is invoked when a context item changes. - The context item that has changed. - - - Defines a callback method that is invoked when a context item changes. - The context item that has changed. - - - - A delegate that is a callback for service subscriptions. - The type of service that has just been published. - The instance of the service. - - - A generic delegate that is a callback for service subscriptions. - The instance of the service. - - - - Stores a object that represents a type. - - - Initializes a new instance of the class. - The type of feature provider this attribute describes. - - is null. - The feature provider is not assignable from . - - - true if the specified object equals this attribute; otherwise, false. - The object to compare to. - - - Gets the type to instantiate. - A representing the class of the feature provider to attach to the target control. - - - The hash code for this object. - - - Gets a unique identifier for this attribute. - An that is a unique identifier for the attribute. - - - Provides data for the event. - - - Initializes a new instance of the class. - The type of feature provider that is now available to be created. - - is null. - - - Gets the type of feature provider that is available for creation. - A object that represents the feature provider that is available for creation. - - - Provides a base implementation for all feature connector-based extensibility. - The type of feature provider. - - - Initializes a new instance of the class. - The feature manager associated with this feature connector. - - - Gets the editing context for the feature connector. - An associated with the feature connector. - - - Creates a new list of feature providers associated with the feature connector, based on the provided type. - An enumeration of feature providers. - The to query for feature providers. - - is null. - - - Creates a new list of feature providers associated with the feature connector, based on the provided type and subtype. - An enumeration of feature providers, filtered by the subtype. - The to query for feature providers. - The subtype of the feature provider type. - - is null. - - - Releases all resources used by the . - - - Releases the unmanaged resources used by the and optionally releases the managed resources. - true to release both managed and unmanaged resources; false to release only unmanaged resources. - - - - Gets the for the feature connector. - A associated with the feature connector. - - - Indicates the type of required to handle the . - - - Initializes a new instance of the class. - The type of feature manager. - - is null. - - - true if the object is equal to this object; otherwise, false. - The object to compare. - - - Gets the type of to instantiate. - A object that represents the type to instantiate. - - - A hash code for this object. - - - Gets an object that is used to determine unique attributes. - A object that is used to determine unique attributes. - - - Contains information describing a specified feature connector. - - - Initializes a new instance of the class. - - - Gets the type of feature connector this describes. - A object that represents the type of feature connector for this object. - - - Gets a list of context items that are required by the feature connector, but are not yet available in the editing context. - An enumeration of required context item types that are not available in the editing context. - - - Gets a list of services that are required by the feature connector, but are not yet available in the editing context. - An enumeration of required service types that are not available in the editing context. - - - Gets a list of context items the feature connector requires. - An enumeration of required context item types that must be available in the editing context before the feature connector is created. - - - Gets a list of services the feature connector requires. - An enumeration of required service types that must be available in the editing context before the feature connector is created. - - - Manages feature providers and feature connectors. - - - Initializes a new instance of the class. - The editing context this feature manager uses to resolve services and context items. - - is null. - - - Gets the editing context for this feature manager. - An for this feature manager. - - - Creates and returns a set of feature providers for the specified type. - An enumeration of feature providers. If no feature providers for are available, this method returns an empty enumeration. - The type of feature provider to return. - - is null. - - does not derive from . - - - Creates and returns a set of feature providers for the specified type. - An enumeration of feature providers. If no feature providers for or are available, this method returns an empty enumeration. - The type of feature provider to return. - A predicate to use when creating feature providers. If the predicate returns true, the feature provider will be included in the enumeration. - - or is null. - - does not derive from . - - - Creates and returns a set of feature providers that exist for the specified type. - An enumeration of feature providers. If no feature providers for or are available, this method returns an empty enumeration. - The type of feature provider to return. - The type to create feature providers for. - - or is null. - - does not derive from . - - - Creates and returns a set of feature providers that exist for the specified type. - An enumeration of feature providers. If no feature providers for , , or are available, this method returns an empty enumeration. - The type of feature provider to return. - The type to create feature providers for. - A predicate to use when creating feature providers. If the predicate returns true, the feature provider will be included in the enumeration. - - , or is null. - - does not derive from . - - - Releases all resources used by the . - - - Disposes all running feature connectors. - true if this object is being disposed, false if it is being finalized. - - - Occurs when a new type of feature is available. - - - Finalizer that calls . - - - Enumerates attributes on the specified type. - An enumeration of custom attributes. - The type whose attributes are to be enumerated. - The type of attribute to return. - - - Initializes any feature connectors for the feature providers defined on the specified type. - The type to initialize feature connectors for. - - is null. - - - Gets or sets a custom metadata provider that can provide type metadata for this feature manager. - A that provides the type metadata. - - - Raises the event. - The to pass to the event. - - - Gets an enumeration of all connectors that have not been activated yet because they are waiting on context items or services. - An enumeration of feature connectors that are waiting for services or context items to become available in the editing context. - - - Gets an enumeration of all connectors that are currently running. - An enumeration of feature connectors that are currently running. - - - Adds a class-specific contribution to a feature. - - - Initializes a new instance of the class. - - - Specifies a custom mechanism for providing metadata attributes to the class. - An enumeration of attributes. - The type to get attributes for. - The type of attribute to enumerate. Can not be null. - - - Called when attributes are needed for a type. - An that can be used to add attributes. delegates can build attributes only for the type that is requesting metadata. - - - An instance of this class is passed to callback delegates to lazily populate the attributes for a type. - - - Adds the contents of the specified attributes to this builder. - An array of new attributes to add. - - is null. - - - Adds attributes to the member with the specified name. - The member to add attributes for. Only property and event members are supported; all others will be ignored. - An array of new attributes to add. - - or is null. - - - Gets the type this callback is being invoked for. - The type this callback is being invoked for. - - - A table of metadata attributes for defining design-time appearance and behavior. - - - Gets an enumeration of all types which have attribute overrides of some kind, for example, on a property or on the type itself. - An enumeration of types which have attribute overrides. - - - Returns a value indicating whether this table contains any metadata for the specified type. - true if the table contains attributes for the specified type; otherwise, false. - The type to check for metadata attributes. - - is null. - - - Returns an enumeration of all attributes provided for the specified assembly. - An enumeration of attributes. - The assembly to get assembly-level attributes for. - - is null. - - - Returns an enumeration of all attributes provided for the specified type. - An enumeration of attributes. - The type to get class-level attributes for. - - is null. - - - Returns an enumeration of all attributes provided for the specified type and member name. - An enumeration of attributes. - The owning type of the dependency property. - The name of the member to provide attributes for. - - or is null. - - - Creates an attribute table that defines design-time metadata. - - - Initializes a new instance of the class. - - - Adds a callback that is invoked when metadata for the specified type is needed. - The type to add metadata attributes to. - An which adds metadata to . - - - Adds the contents of the provided attributes array to the table builder. - The assembly to add assembly-level attributes to. - The new attributes to add to . - - or is null. - - - Adds the contents of the provided attributes to the table builder. - The type to add class-level attributes to. - The new attributes to add to . - - or is null. - - - Adds attributes to the member with the specified name. - The owning type of the member. - The member to add attributes for. - The attributes to add. - - , , or is null. - - - Adds the contents of the provided attribute table to the table builder. - An existing attribute table. - - is null. - - - Creates an attribute table that contains all the attribute definitions provided through calls. - An attribute table that can be used to define design-time metadata. - - - This method is used to verify the attribute table which is being built contains valid attribute information. - The state of the table is invalid. - - - Provides a collection of instances. - - - Initializes a new instance of the class. - - - Adds the specified table to the set of attribute tables in the current container. - The attribute table to add. - - is null. - - - Gets an enumeration of added attribute tables. - An enumeration of added attribute tables. - - - Enumerates the attributes of the specified assembly. - An enumeration of attributes. - The assembly to enumerate attributes. - The attribute type to enumerate, or null to enumerate all attributes. - - is null. - - - Enumerates the attributes of the specified assembly. - An enumeration of attributes. - The assembly to enumerate attributes. - The attribute type to enumerate or null to enumerate all attributes. - An optional mapping function to map the incoming reflection metadata to runtime metadata. - - is null. - - - Enumerates custom attributes for the specified member, including inherited attributes from base members. - An enumeration of attributes. - The member to get attributes for. - The attribute type to retrieve, or null for all attributes. - - is null. - - - Enumerates custom attributes for the specified member, including inherited attributes from base members. - An enumeration of attributes. - The member to get attributes for. - The attribute type to retrieve, or null for all attributes. - An optional mapping function to map the incoming reflection metadata to runtime metadata. - - is null. - - - Enumerates custom attributes for the specified member, including inherited attributes from base members. - An enumeration of attributes. - The member to get attributes for. - The attribute type to retrieve, or null for all attributes. - - is null. - - - Enumerates custom attributes for the specified member, including inherited attributes from base members. - An enumeration of attributes. - The member to get attributes for. - The attribute type to retrieve, or null for all attributes. - An optional mapping function to map the incoming reflection metadata to runtime metadata. - - is null. - - - Raised when the metadata provided in an does not match properties, methods and events on existing types. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with serialization information. - The serialization store. - The serialization context. - - - Initializes a new instance of the class with a message. - A string describing the exception. - - - Initializes a new instance of the class with a collection of validation errors. - The message provided to the user. - A collection of errors which occurred during validation. - - - Initializes a new instance of the class with an inner exception. - The message provided to the user. - An optional inner exception. - - - Initializes a new instance of the class with a message, a collection of error strings, and an inner exception. - The message provided to the user. - An optional inner exception. - A collection of errors which occurred during validation. - - - Override of the Exception type's method that is used to perform serialization. - The serialization store. - The serialization context. - - - Gets a collection of validation errors. - An enumerable collection of error strings. - - - Represents an event, which is independent of the platform. - - - Initializes a new instance of the class with the specified existing type identifier and event name. - The of the type on which the event is declared. - The name of the event. - - is null. - - was created by using an empty constructor. - - - Initializes a new instance of the class with the specified existing type and event name. - The type on which the event is declared. - The name of the event. - - or is null. - - - Gets the type that declares this event, if it was set in the constructor. - A type that declares the event, or null if the event identifier was created by using a . - - - Gets the type identifier for the type that declares the event. - A type identifier for the type that declares the event. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Gets the type-qualified name of the event. - The type-qualified name of the event. - - - Returns the hash code for the current instance. - The hash code for the current instance. - - - Gets a value that indicates whether the current identifier was created by using an empty constructor. - true if this identifier was created by using an empty constructor; otherwise, false. - - - Gets the name of the event. - The name of the event. - - - Determines whether the specified instances are considered equal. - true if is equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether the specified instances are considered not equal. - true if is not equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Gets the property as a string. - The property as a string. - - - Defines a class that provides an attribute table. - - - Gets the attribute table provided by the class. - The provided by the class. - - - Represents a property, which is independent of the platform. - - - Initializes a new instance of the class with the specified existing type identifier and property name. - The of the type on which the property is declared. - The name of the property. - - is null. - - was created by using an empty constructor. - - - Initializes a new instance of the class with the specified existing type and property name. - The type on which the property is declared. - The name of the property. - - or is null. - - - Gets the type that declares this property, if it was set in the constructor. - A type that declares the property, or null if the property identifier was created by using a . - - - Gets the type identifier for the type that declares the property. - A type identifier for the type that declares the property. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Gets the type-qualified name of the property. - The type-qualified name of the property. - - - Returns the hash code for the current instance. - The hash code for the current instance. - - - Gets a value that indicates whether the current identifier was created by using an empty constructor. - true if this identifier was created by using an empty constructor; otherwise, false. - - - Gets the name of the property. - The name of the property. - - - Determines whether the specified instances are considered equal. - true if is equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether the specified instances are considered not equal. - true if is not equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Gets the property as a string. - The property a string. - - - Represents a class that provides metadata. - - - Initializes a new instance of the class. - The of the class that implements the interface. - - - Gets the type that implements the interface. - A type that implements the interface. - - - Identifies a type, which is independent of the platform. - - - Initializes a new instance of the class. - The fully-qualified name of the type. - - is null. - - - Initializes a new instance of the class with the specified XML namespace and type name. - The XML namespace in which the type is declared. - The name of the type. - - or is null. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Returns the hash code for the current instance. - The hash code for the current instance. - - - Gets a value that indicates whether the current identifier was created by using an empty constructor. - true if this identifier was created by using an empty constructor; otherwise, false. - - - Gets the name of the type. - The name of the type. If is null, this is a fully-qualified CLR type name. - - - Determines whether the specified instances are considered equal. - true if is equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether the specified instances are considered not equal. - true if is not equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Gets the property as a string. - The property as a string. - - - Gets the XML namespace of this type. - The XML namespace of this type. If this property is set, the type name is a simple name in the namespace. - - - \ No newline at end of file diff --git a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Interaction.dll b/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Interaction.dll deleted file mode 100644 index 1f2bdc9..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Interaction.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Interaction.xml b/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Interaction.xml deleted file mode 100644 index c36a24c..0000000 --- a/SCADA/Program/HMIControl/bin/Debug/Microsoft.Windows.Design.Interaction.xml +++ /dev/null @@ -1,5841 +0,0 @@ -锘 - - - Microsoft.Windows.Design.Interaction - - - - Enables a designer to determine the data context inheritance in the visual tree for a particular property. - - - Initializes a new instance of the class with the specified property name and collection information. - The name of the property that is the source of the data context鈥檚 value. - Indicates whether the data context is an item in a collection. - - - Initializes a new instance of the class with the specified property name, ancestor path, and collection information. - The name of the property that is the source of the data context鈥檚 value. - The property path that indicates the set of ancestor properties to traverse to reach the data context property. - Indicates whether the data context is an item in a collection. - - - Gets the property path that indicates the set of ancestor properties to traverse to reach the data context property. - The path to the data context property. - - - Gets the name of the property that is the source of the data context鈥檚 value. - The name of the property that is the source of the data context鈥檚 value. - - - Gets a value that indicates whether the data context is an item in a collection. - true if the data context is an item in a collection; otherwise, false. - - - Determines the property to use when displaying an instance of an object in a designer. - - - Initializes a new instance of the class with the specified property name. - The name of the property to use for display in a designer. - - - Initializes a new instance of the class with the specified property name and value converter. - The name of the property to use for display in a designer. - The type of the value converter. - - - Gets the name of the property to use for display in a designer. - The name of the property. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - A 32-bit signed integer hash code. - - - - Gets the type of the value converter to use when displaying the property. - The value converter type, or null if no value converter was specified. - - - Specifies an example instance of an item in the toolbox of a visual designer. - - - Creates an example instance of an item in the toolbox with preset properties. - A that corresponds to the example instance. - The editing context. - - - The localizable display name in the toolbox. - The localizable display name in the toolbox. - - - Gets a stream for use by the property. - A that represents the toolbox bitmap of the example instance. - The target size of the toolbox bitmap. - - - Provides a list of examples in an asset toolbox that reference the same . - - - Initializes a new instance of the class. - - - Gets a list of examples in an asset toolbox that reference the same . - An enumeration of objects. - - - A generic class that identifies the sort order of hierarchical items. - - - Initializes a new instance of the class based on the specified referenced , precedence, and conflict resolution semantics. - Precedence of this token based on the referenced token. - Referenced token. May be null for the root token case. A root token is a token that is not dependent on any token. - Conflict resolution semantics. - - - Compares this order token with the specified order token. - 0 when the tokens have an equal order priority, -1 if this order comes before the specified order, 1 otherwise. - The token to compare to this token. - - - The to compare with the current . - - - - Determines whether two specified order tokens are equal. - true if equals ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether the first specified order token is greater than the second. - true if is greater than ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether two specified order tokens are not equal. - true if does not equal ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether the first specified order token is less than the second. - true if is less than ; otherwise, false. - The first to compare. - The second to compare. - - - Called by the default implementation when two objects appear to be equivalent. - 0, if the two are equal, -1, if left comes before right, 1 otherwise. - Left . - Right . - - - An enumeration used to specify the winner of ordering ties. - - - Indicates that this token should win during conflicts. If two tokens are compared that are equivalent and both have their set to , they are considered equal. - - - Indicates that this token should lose during conflicts. - - - An enumeration that specifies the precedence of order tokens. - - - Indicates that this token comes before. - - - Indicates that this token comes after. - - - Associates an icon with a custom Windows Presentation Foundation (WPF) or Silverlight control in the toolbox for Visual Studio or Expression Blend.聽 - - - Initializes a new instance of the class. - Specifies the assembly in which to look for the image. - Specifies the fully-qualified name of the image, including the namespace. - - - Gets the assembly that contains the icon image. - The that contains the icon image. - - - Gets name of the icon image. - The fully-qualified name of the icon image. - - - Specifies whether a control is visible in a designer's toolbox browser. - - - Initializes a new instance of the class. - true to enable visibility for a control in a toolbox browser; otherwise, false. - - - Gets the flag associated with this attribute. - true if a control is visible in the toolbox browser; otherwise, false. - - - Gets a with set to false. - A pre-defined static instance of the with set to false. - - - Gets a with set to true. - A pre-defined static instance of the with set to false. - - - Specifies the category in which a class appears in a designer's toolbox. - - - Initializes a new instance of the class with the specified category path. - The path under which this class is categorized. Represents multiple levels by using the forward slash (/) as a delimiter. - - - Initializes a new instance of the class with the specified category path and parent category visibility. - The path under which this class is categorized. Represents multiple levels by using the forward slash (/) as a delimiter. - true to indicate whether this class appears in all parent categories; otherwise, false. - - - Gets a value that indicates whether this class appears in all parent categories. - true if this class appears in all parent categories; otherwise, false. - - - Gets the path under which this class is categorized. - The path under which this class is categorized. - - - Specifies the type that implements the interface. - - - Initializes a new instance of the class. - A type that implements the interface. - - - Gets a that provides a list of examples in an asset toolbox that references the associated . - A that provides a list of examples in an asset toolbox that references the associated . - - - Specifies the tab in which a class appears in a designer's toolbox. - - - Initializes a new instance of the class. - The name of the Visual Studio toolbox tab.聽 - - - Specifies the Common tab of the toolbox. - - - Gets the Visual Studio聽toolbox tab that is used when this item is installed. - The name of the toolbox tab. - - - Used to adapt logic for a particular item. - - - Initializes a new instance of the class. - - - When overridden in a derived class, gets the type of adapter this object represents. - A that represents the adapter type. - - - Provides a set of common brushes that can be used on adorners. - - - Gets the brush used for the alignment marks. - A representing the standard brush for alignment marks in the WPF Designer. - - - Gets a resource key for the color of alignment marks. - A for the dictionary representing the standard brush for alignment marks in the WPF Designer. - - - Gets the color that is used for the alignment marks. - A representing the standard color for alignment marks in the WPF Designer. - - - Gets a resource key for the color of alignment marks. - A for the dictionary representing the standard color for alignment marks in the WPF Designer. - - - Gets the brush used for the borders of elements. - A representing the standard brush for elements in the WPF Designer. - - - Gets a resource key for the brush of borders of elements. - A for the dictionary representing the standard brush for elements in the WPF Designer. - - - Gets the color that is used for the borders of elements. - A representing the standard color for elements in the WPF Designer. - - - Gets a resource key for the color of borders of elements. - A for the dictionary representing the standard color for elements in the WPF Designer. - - - Gets the brush used for the fill of any glyph. - A representing the standard brush for glyphs in the WPF Designer. - - - Gets a resource key for the brush used to fill a glyph. - A for the dictionary representing the standard brush for glyphs in the WPF Designer. - - - Gets the color that is used for the fill of any glyph. - A representing the standard color for glyphs in the WPF Designer. - - - Gets a resource key for the color that is used to fill a glyph. - A for the dictionary representing the standard color for glyphs in the WPF Designer. - - - Gets a brush to paint the border of a handle. - A representing the standard brush for handle borders in the WPF Designer. - - - Gets a resource key for the border brush of a handle. - A for the dictionary representing the standard border brush for handles in the WPF Designer. - - - Gets the color of a handle border. - A representing the standard color for handle borders in the WPF Designer. - - - Gets a resource key for the color of a handle border. - A for the dictionary representing the standard border color for handles in the WPF Designer. - - - Gets the brush to paint the fill of a handle when it is not resizable. - A that represents the standard brush for a handle in the WPF Designer. - - - Gets the resource key for the brush of a handle when it is not resizable. - A for the dictionary that represents the standard brush for a handle in the WPF Designer. - - - Gets the color of a handle when not it is not resizable. - A that represents the standard color for a handle in the WPF Designer. - - - Gets the resource key for the color of a handle when it is not resizable. - A for the dictionary that represents the standard color for a handle in the WPF Designer. - - - Gets a brush to paint the fill of a handle. - A representing the standard brush for handles in the WPF Designer. - - - Gets a resource key for the brush of a handle. - A for the dictionary representing the standard brush for handles in the WPF Designer. - - - Gets the color of a handle. - A representing the standard color for handles in the WPF Designer. - - - Gets a resource key for the color of a handle. - A for the dictionary representing the standard color for handles in the WPF Designer. - - - Gets a brush to paint the fill of a handle when the mouse pointer is over it. - A representing the standard brush for a handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets a resource key for the brush of a handle when the mouse pointer is over it. - A for the dictionary representing the standard brush for a handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets the color of a handle when the mouse pointer is over it. - A representing the standard color for a handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets a resource key for the color of a handle when the mouse pointer is over it. - A for the dictionary representing the standard color for a handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets a brush to paint the fill of a handle when it is pressed. - A representing the standard brush for a pressed handle in the WPF Designer. - - - Gets a resource key for the brush of a handle when it is pressed. - A for the dictionary representing the standard brush for a pressed handle in the WPF Designer. - - - Gets the color of a handle when it is pressed. - A representing the standard color for a pressed handle in the WPF Designer. - - - Gets a resource key for the color of a handle when it is pressed. - A for the dictionary representing the standard color for a pressed handle in the WPF Designer. - - - Gets the brush used for the content of a move handle. - A representing the standard brush for a move handle's content in the WPF Designer. - - - Gets a resource key for the brush used for the content of a move handle. - A for the dictionary representing the standard brush for the content of a move handle in the WPF Designer. - - - Gets the color that is used for the content of a move handle. - A representing the standard color for a move handle's content in the WPF Designer. - - - Gets a resource key for the color that is used for the content of a move handle. - A for the dictionary representing the standard color for the content of a move handle in the WPF Designer. - - - Gets the brush used for the fill of a move handle when the mouse pointer is not over it. - A representing the standard brush for move handles in the WPF Designer. - - - Gets a resource key for the brush used for the fill of a move handle when the mouse pointer is not over it. - A for the dictionary representing the standard brush for move handles in the WPF Designer. - - - Gets the color that is used for the fill of a move handle when the mouse pointer is not over it. - A representing the standard color for move handles content in the WPF Designer. - - - Gets a resource key for the color that is used for the fill of a move handle when the mouse pointer is not over it. - A for the dictionary representing the standard color for move handles in the WPF Designer. - - - Gets the brush used for the fill of a move handle when the mouse pointer is over it. - A representing the standard brush for a move handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets a resource key for the brush used for the fill of a move handle when the mouse pointer is over it. - A for the dictionary representing the standard brush for a move handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets the color that is used for the fill of a move handle when the mouse pointer is over it. - A representing the standard color for a move handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets a resource key for the color that is used for the fill of a move handle when the mouse pointer is over it. - A for the dictionary representing the standard color for a move handle when the mouse pointer is moved over it in the WPF Designer. - - - Gets the fill brush for rails. - A representing the standard brush for rails in the WPF Designer. - - - Gets a resource key for the brush used for rails. - A for the dictionary representing the standard brush for rails in the WPF Designer. - - - Gets the fill color for rails. - A representing the standard color for rails in the WPF Designer. - - - Gets a resource key for the color that is used for rails. - A for the dictionary representing the standard color for rails in the WPF Designer. - - - Gets the brush used for the selection frame around controls. - A representing the standard brush for the selection frame in the WPF Designer. - - - Gets a resource key for the brush used for the selection frame around controls. - A for the dictionary representing the standard brush for the selection frame in the WPF Designer. - - - Gets the color that is used for the selection frame around controls. - A representing the standard color for the selection frame in the WPF Designer. - - - Gets a resource key for the color that is used for the selection frame around controls. - A for the dictionary representing the standard color for the selection frame in the WPF Designer. - - - Gets the fill brush for the selection frame used on controls. - A representing the standard fill brush for the selection frame in the WPF Designer. - - - Gets a resource key for the brush used for the selection frame used on controls. - A for the dictionary representing the standard fill brush for the selection frame in the WPF Designer. - - - Gets the fill color for the selection frame used on controls. - A representing the standard fill color for the selection frame in the WPF Designer. - - - Gets a resource key for the color that is used for the selection frame on controls. - A for the dictionary representing the standard fill color for the selection frame in the WPF Designer. - - - Gets a simple wash brush. - A representing the standard brush for a simple wash in the WPF Designer. - - - Gets a resource key for the brush used for simple washes. - A for the dictionary representing the standard brush for a simple wash in the WPF Designer. - - - Gets a simple wash color. - A representing the standard color for a simple wash in the WPF Designer. - - - Gets a resource key for the color that is used for simple washes. - A for the dictionary representing the standard color for a simple wash in the WPF Designer. - - - Gets the brush for a toggled glyph鈥檚 fill. - A representing the standard brush for a toggled glyph in the WPF Designer. - - - Gets a resource key for the brush used for a toggled glyph's fill. - A for the dictionary representing the standard brush for a toggled glyph in the WPF Designer. - - - Gets the color for a toggled glyph鈥檚 fill. - A representing the standard color for a toggled glyph in the WPF Designer. - - - Gets a resource key for the color for a toggled glyph's fill. - A for the dictionary representing the standard color for a toggled glyph in the WPF Designer. - - - Defines a 2D coordinate space for use in . - - - Defines the two common coordinate spaces used in the designer. - - - Gets the default coordinate space for adorners. - An specifying the default adorner space. - - - Provides a set of common brushes that can be used on adorners. - - - Gets a for the current item. - A representing the standard font family in the WPF Designer. - - - Gets a resource key for the for the adorner. - A for the dictionary representing the standard font family in the WPF Designer. - - - Gets the font size to paint the current . - A double representing the standard font size in the WPF Designer. - - - Gets a resource key for the font size for the adorner. - A for the dictionary representing the standard font size in the WPF Designer. - - - An enumeration that defines the horizontal alignment of an adorner relative to an element on a design surface. - - - The adorner is aligned to the left. - - - The adorner is centered. - - - The adorner is aligned to the right. - - - The adorner is stretched. - - - The adorner is aligned to the left, on the outside. - - - The adorner is aligned to the right, on the outside. - - - Performs the layout of an adorner on the . - - - Initializes a new instance of the class. - - - Invoked on the adorner layout whenever one of the properties stored in the class changes. - The adorner whose property has changed. - A that contains details of the property change. - - - Performs the layout arrangement on the specified adorner. - The adorner to be arranged. - - is null. - - - Performs the layout arrangement on the . - The size of the after the layout arrangement. - The parent . - The in the parent. - The final size that wants the to assume. - - - Gets a value indicating whether the adorner remains in the UI tree. - true if should remain in the UI tree. false if one or more visuals it is associated with are no longer part of the UI tree. - The designer view that is evaluating the layout. - The adorner to be evaluated. - - or is null. - - - Gets a value indicating whether the specified model item is associated with this adorner. - true if the adorner is associated with the specified model item. - The adorner to check. - The item to compare. - - or is null. - - - Performs the layout measurement on the specified adorner. - The adorner to be measured. - The constrained size of the adorner. - - is null. - - - Specifies the z-order of adorners in Design view. - - - Gets a value indicating that the adorner is placed after the content. - An specifying the bottom of the z-order. - - - Gets a value indicating that the adorner is placed with other content adorners. This is the default. - An specifying the z-order of the . - - - Creates a new adorner order that places the adorner above the provided reference in the z-order. - A new that places the adorner above adorners with the specified reference. - The to place the adorner above. - - is null. - - - Creates a new adorner order that places the adorner below the provided reference in the z-order. - A new that places the adorner below adorners with the specified reference. - The to place the adorner below. - - is null. - - - Gets a value indicating that the adorner is placed before content adorners. - An specifying the top of the z-order. - - - Provides a container for Windows Presentation foundation (WPF) controls, which are used at design time as adorners. - - - Initializes a new instance of the class. - - - Gets or sets the value of a child element within a parent . - The of the . - - - Identifies the dependency property. - Identifier for the dependency property. - - - Gets or sets the value of a child element within a parent . - A that represents the margin of the . - - - Identifies the dependency property. - Identifier for the dependency property. - - - Gets or sets the value of a child element within a parent . - The of the . - - - Identifies the dependency property. - Identifier for the dependency property. - - - A object that represents the arranged size. - The final size allowed for the arrange. - - - Returns the that is the parent of the specified . - An that is the parent of the visual, or null if the visual does not have a parent view. - A or that is a child of the . - - is null. - - - Gets the 聽attached property for the specified . - The property value for . - The element from which the property value is read. - - - Gets the 聽attached property for the specified . - A that represents the for . - The element from which the property value is read. - - - Gets the 聽attached property for the specified . - The property value for . - The element from which the property value is read. - - - Gets the value of the 聽attached property for the specified . - An for the adorner panel along the x-axis. The default value is . - The from which to read the attached property. - - is null. - - - Returns the layout clip of the . - A that represents the layout clip of the . - The size of the . - - - Note: This API is now obsolete. Gets the value of the 聽attached property for the specified . - An which holds objects representing 's size and position. - The to get placements for. - - is null. - - - Reads the 聽attached property from the specified element. - A that represents the task associated with . - The from which to read the attached property. - - is null. - - - Gets the value of the 聽attached property for the specified . - An for the adorner panel along the y-axis. The default value is . - The from which to read the attached property. - - is null. - - - Gets or sets the value for the x-axis. - An for the adorner panel along the x-axis. The default value is . - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets or sets the value. - true if the adorner panel's content may receive focus; otherwise, false. The default is false. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Measure adorner. - A Size object that represents the size of the element. - The available size the element can occupy. - - - Gets or sets the associated with the adorner panel. - The associated with the adorner panel. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Get or sets the rectangle that defines the adorner panel offset from the adorned control. - A rectangle that defines the adorner panel offset from the adorned control. - - - Invoked when an unhandled 聽attached event reaches an element in its route that is derived from this class.. - The that contains the event data. - - - Gets or sets the value. - An instance that specifies the z-order of the adorner panel. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Note: This API is now obsolete. Gets or sets a collection of objects specifying the size and position of adorners in the adorner panel. - An which holds objects representing 's size and position. - - - Note: This API is now obsolete. Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Sets the 聽attached property for the provided element. - The element to which the attached property is written. - - to be set to the . - - - Sets the specified 聽attached property for the provided element. - The element to which the attached property is written. - The of the margin to be set to the . - - - Sets the specified 聽attached property for the provided element. - The element to which the attached property is written. - The to be set to the . - - - Sets the value of the 聽attached property for the provided element. - The to which the attached property is written. - The value for the horizontal dimension. - - is null. - - - Note: This API is now obsolete. Sets the value of the 聽attached property for the provided element. - The to which the attached property is written. - An which holds objects representing 's size and position. - - is null. - - - Writes the 聽attached property to the specified element. - The element to which the attached property is written. - The to set. - - is null. - - - Sets the value of the 聽attached property for the provided element. - The element to which the attached property is written. - The value for the vertical dimension. - - is null. - - - Determines whether to use the mirror transform. - true if mirror transform is being used; otherwise, false. Always returns true. - - - Gets or sets the value for the y-axis. - An for the adorner panel along the y-axis. The default value is . - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets or sets the adorner panel's associated view. - A that represents the associated view. - - - Enables precise placement of adorners within an . - - - Initializes a new instance of the class. - - - Adds a placement term that positions the adorner panel relative to the adorner's height. - A factor that is multiplied against the adorner's height. - An offset that is added to the result. - - - Adds a placement term that positions the adorner panel relative to the specified adorner's height. - A factor that is multiplied against the adorner's height. - An offset that is added to the result. - An optional adorner. If provided, the position is relative to the adorner's height. - - - Adds a placement term that positions the adorner panel relative to the adorner's width. - A factor that is multiplied against the adorner's width. - An offset that is added to the result. - - - Adds a placement term that positions the adorner panel relative to the specified adorner's width. - A factor that is multiplied against the adorner's width. - An offset that is added to the result. - An optional adorner. If provided, the position is relative to the adorner's width. - - - Adds a placement term that positions the adorner panel relative to the adorned content's height. - A factor that is multiplied against the adorned content's height. - An offset that is added to the result. - - - Adds a placement term to this group that positions the adorner panel relative to the content's height. - A factor that is multiplied against the content's height. - An offset that is added to the result. - If provided, the position is relative to the element's height, rather than the height of the content. This an optional element. - - - Adds a placement term that positions the adorner panel relative to the adorned content's width. - A factor that is multiplied against the adorned content's width. - An offset that is added to the result. - - - Adds a placement term to this group that positions the adorner panel relative to the content's width. - A factor that is multiplied against the content's width. - An offset that is added to the result. - If provided, the position is relative to the element's width, rather than the width of the content. This is an optional element. - - - Adds a placement term that sizes the adorner panel relative to the adorner's desired height. - A factor that is multiplied against the adorner's desired height. - An offset that is added to the result. - - - Add a placement term that sizes the adorner panel relative to the specified adorner's desired height. - A factor that is multiplied against the specified adorner's desired height. - An offset that is added to the result. - An optional adorner. If provided, the size is relative to the adorner's height. - - - Adds a placement term that sizes the adorner panel relative to the adorner's desired width. - A factor that is multiplied against the adorner's desired width. - An offset that is added to the result. - - - Adds a placement term that sizes the adorner panel relative to the specified adorner's desired width. - A factor that is multiplied against the adorner's desired width. - An offset that is added to the result. - An optional adorner. If provided, the size is relative to the adorner's width. - - - Adds a placement term that sizes the adorner panel relative to the adorned content's height. - A factor that is multiplied against the content's height. - An offset that is added to the result. - - - Adds a placement term to this group that sizes the adorner panel relative to the content's height. - A factor that is multiplied against the content's height. - An offset that is added to the result. - If provided, the size is relative to the element's height. This is an optional element. - - - Adds a placement term that sizes the adorner panel relative to the adorned content's width. - A factor that is multiplied against the content's width. - An offset that is added to the result. - - - Adds a placement term to this group that sizes the adorner panel relative to the content's width. - A factor that is multiplied against the content's width. - An offset that is added to the result. - If provided, the size is relative to the element's width. This is an optional element. - - - An enumeration that defines the dimension that should be applied to an structure. - - - The left side. - - - The top side. - - - The right side. - - - The bottom side. - - - The width. - - - The height. - - - Represents a single value in an . - - - Initializes a new instance of the class. - The term that should be applied to this value. - The contribution this value makes to the overall placement. - - - Gets or sets the distance the placement term is affected by. - A double that is the distance the placement term is affected by. - - - Returns a value indicating whether this instance is equal to a specified . - true if the objects are equal; otherwise, false. - The value to test. - - - Returns a value indicating whether this instance is equal to a specified object. - The object to test. - - - Returns the hash code for this structure. - The hash code of the structure. - - - Determines whether the two specified objects have the same value. - true if the values are equal; otherwise, false. - The first value to test. - The second value to test. - - - Determines whether the two specified objects have different values. - true if the values are not equal; otherwise, false. - The first value to test. - The second value to test. - - - Gets or sets the placement term affected by this contribution amount. - An that is the placement term affected by this contribution amount. - - - Defines a set of attached properties for a UI element to enable adorner appearance and behavior. - - - Gets a layout that is used to arrange the adorner with regard to its model or view. - The for . - The adorner element to retrieve the layout for. - - is null. - - - Gets the model item associated with the specified adorner. - The associated with . - The adorner element to retrieve the model item for. - - is null. - - - Gets the relative z-order of the specified adorner. - An specifying the relative z-order of . - The adorner element to retrieve the order for. - - is null. - - - Gets the render transform for the adorner. - The render transform associated with , or null if no view has been set. - The adorner element to retrieve the render transform for. - - is null. - - - Gets the task for the specified adorner. - The associated with . - The adorner element to retrieve the task for. - - is null. - - - Gets the view for the specified adorner. - The view associated with , or null if no view has been set. - The adorner element to retrieve the task for. - - is null. - - - Gets a layout that is used to arrange the adorner with regard to its model or view. This is an attached property. - The for the adorner. - - - Identifies the 聽attached property. - The identifier for the 聽attached property. - - - Gets the model item associated with the adorner. This is an attached property. - The associated with the adorner. - - - Identifies the 聽attached property. - The identifier for the 聽attached property. - - - Gets the relative z-order of the adorner. This is an attached property. - An specifying the relative z-order of the adorner. - - - Identifies the 聽attached property. - The identifier for the 聽attached property. - - - Gets or sets the render transform for the adorner. This is an attached property. - The render transform associated with the adorner, or null if no render transform has been set. - - - Identifies the attached property. - The identifier for the attached property. - - - Sets the layout for the specified adorner. - The adorner element to set the layout for. - The to associate with . - - is null. - - - Sets the model item associated with the specified adorner. - The adorner element to set the model for. - The to associate with . - - is null. - - - Sets the relative z-order of the specified adorner. - The adorner element to set the model for. - An specifying the relative z-order of . - - is null. - - - - Sets the task for the specified adorner. - The adorner element to set the task for. - The to associate with . - - is null. - - - Gets the task for the specified adorner. This is an attached property. - The associated with the adorner. - - - Identifies the 聽attached property. - The identifier for the 聽attached property. - - - A feature provider that you can add to a class to automatically add adorners to the designer surface. - - - Initializes a new instance of the class. - - - Called when adorners are requested for the first time by the designer. - A representing the adorned element. - - - Gets the collection of adorners that are provided by this adorner provider. - A collection of objects that have adorner attached properties. - - - Gets or sets the visibility of a set of adorners. - true if the adorners are added to the designer view. false if the adorners are removed from the designer view. - - - Gets the editing context that activated this adorner provider. - An that activated this adorner provider. - - - Called when an adorner provider is about to be discarded by the designer. - - - Gets a value indicating if the adorner provider supports the provided . - true if the adorner provider supports ; otherwise, false. - The to be checked. - - - Used to define a set of resources that can be used in XAML. - - - Creates a resource key for the specified type and member name. - A new resource key. - The type that owns this resource. - The name of the public static member that exposes this resource. - - or is null. - - - Locates a resource with the specified key. - The resource that corresponds with . - The resource key to find. - - is null. - - does not have a resource. - - - Updates the adorner resource dictionary. - - - Registers a callback that can provide a resource dictionary. - A callback used to return the resource dictionary. - - is null. - - - Locates a resource with the specified key. - The resource if it exists.-or-null if the specified resource does not exist. - The key of the resource to find. - - is null. - - - An enumeration used to identify how the particular dimension (X or Y) of an adorner behaves when Design view is scaled. - - - The dimension remains the same during scaling. Therefore, the adorner does not change size or scale during scaling. - - - The dimension stretches during scaling. Therefore, the adorner gets larger, but the stroke of rendered elements/lines/pens does not increase. - - - An enumeration that defines the vertical alignment of an adorner relative to an element on a design surface. - - - The adorner is aligned to the top. - - - The adorner is centered. - - - The adorner is aligned to the bottom. - - - The adorner is stretched. - - - The adorner is aligned to the top, on the outside. - - - The adorner is aligned to the bottom, on the outside. - - - Provides data for the event. - - - Get or sets whether the command can be executed. - true if the command can be executed; otherwise, false. - - - Gets the command associated with this . - An that represents a command associated with this . - - - Gets the parameter associated with this . - An object that represents the parameter associated with this . The return value may be null. - - - Represents the method that will handle the events for tool commands. - The source of the event. - A that contains the event data. - - - Provides data for the event defined on the class. - - - Initializes a new instance of the class. - The command that raised the exception. - The exception that the command threw. - - or is null. - - - Gets the command that was passed to the constructor. - An that represents the command that was passed to the constructor. - - - Gets the exception that was passed into the constructor. - An that was passed into the constructor. - - - Defines a set of menu items that are shown in a context menu. - - - Initializes a new instance of the class. - - - Gets the items to add to the context menu. - An of items. - - - Raises the event so the visibility and enabled status of menu items can be refreshed. - The to send in the . - - - Occurs when the menu item is about to be shown. - - - Represents a set of static command definitions for tool creation commands. - - - Gets a command identifier for creating new objects. - A command identifier for creating new objects. - - - Gets a tool command identifier for creating new objects at the current position. - A tool command identifier for creating new objects at the current position. - - - Gets a tool command identifier for creating new objects within gesture positions. - A tool command identifier for creating new objects within gesture positions. - - - A tool that is used to create new instances of objects on the designer. - - - Initializes a new instance of the class. - - - Occurs when the tool completes the creation of its object. - - - Gets or sets the type of object this tool should create. - A object representing the type of object this tool should create. For example, if this tool is to create a button, this property should be typeof(Button). - - - Raises the event. - The event to give to the creation complete event. - - is null. - - - Raises the event. - - - Identifies the creation tool that should be used to create an instance of a specified type. - - - Initializes a new instance of the class. - The type of tool this attribute describes. You can specify null to prevent a base class from surfacing. - - does not derive from . - - - Returns a value that indicates whether this instance is equal to a specified object. - true if the object is equal to this object; otherwise, false. - The object to compare. - - - Returns the hash code for this instance. - An integer hash code. - - - Gets the type to instantiate. - A object that represents the type of the to be instantiated. - - - A context item that is used to store and report the current designer view that is being used in the editing context. - - - Initializes a new instance of the class. - - - Gets the item type of this item. - A that represents the type of this item. - - - Gets the designer view that is currently being used. - A that is currently being used; or null if no view has been installed yet. - - - Represents commands associated with a designer. - - - Gets a command that cancels the current operation. - A command that cancels the current operation. - - - Provides a visual design surface for the designer. - - - Initializes a new instance of the class. - - - Gets the collection of adorners on this view. - A collection of all adorner panels on the design surface. - - - Gets or sets a value that indicates whether the adorners on the designer view are visible or hidden. - true if adorners are visible; otherwise, false. - - - Identifies the dependency property. - The identifier for the dependency property. - - - - overrides so it can make sure that all the layers it maintains are the same size as the view. - A object that represents the arranged size. - The final size allowed for the arrange. - - - Gets or sets the root element of the designer's UI. - The root of the designer's UI. - - - Occurs when an exception is raised in a command. - - - Gets or sets the editing context for this view. - The associated with the view. - - - Gets or sets the designer view attached property. - The for the UI tree. - - - Identifies the dependency property. - - - Returns the designer view stored in the specified context. - A stored in , or null if a view does not exist. - The editing context to retrieve the designer view from. - - is null. - - - Gets the value of the attached property for the specified element. - The attached property for . - The element in the tree to return the designer view for. - - - Returns the visual children of the designer view. - A at the specified index. - The zero-based index of the visual child collection. - - - Represents the zoom transform that is to the . - The that represents the zoom factor. - - - Gets or sets whether the content of the is hit-tested and can receive mouse and keyboard input. - true if the content is hit-tested; otherwise, false. The default is false. - - - Occurs when the is matching a user input gesture to a command. - - - Override to measure the layers. - A object that represents the size of the element. - The available size the element can occupy. - - - Raises the event. - The used when raising this event. - - - Creates and returns an for use by the automation infrastructure. - An for this object. - - - Raises the event. - The used when raising this event. - - - Returns a that represents the . - A that represents the . - - - Performs the processing of changes to the zoom level. - - - Gets the count of visual children on this object. - An integer representing the number of visual children on this object. - - - Represents the current zoom level of the . - The zoom level of the . - - - Occurs when the zoom level has changed. - - - Identifies the dependency property. - - - Provides additional information during a drag-and-drop operation. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - The model where the gesture began. - The model the gesture is currently over. - The input element representing the coordinate reference for the points. This should be an element that never moves around, such as the class. - The position of the mouse when the gesture was first initiated. - The current position of the mouse. - The allowed drag-and-drop effects. - The data for the drag. - - , , , or is null. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - This is the model where the gesture began. - This is the model the gesture is currently over. - The input element representing the coordinate reference for the points. This should be an element that never moves around, such as the class. - The position of the mouse when the gesture was first initiated. - The current position of the mouse. - The allowed drag-and-drop effects. - The data for the drag. - The source adorner to associate with the gesture, if it exists. This parameter can be null. - The target adorner to associate with the gesture, if it exists. This parameter can be null. - - - Gets the set of allowed drag-and-drop effects. - A object that represents the set of allowed drag-and-drop effects. - - - Gets the data passed in for the drag-and-drop operation. - An that represents drag-and-drop operation data. - - - Gets or sets the current drag-and-drop effects. - A object that represents the current drag-and-drop effects. - The effects are not in the allowed effects. - - - Provides a simple utility that returns a object from a object. - The object that is contained in the property of the object. - The object passed into a command callback. - - is null. - - - Provides a simple utility that returns a from an object. - The object that is contained in the property of the object. - The object passed into a command callback. - - is null. - - - Provides data for the event. - - - Gets the command associated with this object. - An that represents a command associated with this . - - - Gets the parameter associated with this object. - An object that represents the parameter associated with this object. The return value can be null. - - - Represents the method that will handle the events for tool commands. - The source of the event. - An that contains the event data. - - - Contains the task that currently has the focus in a tool. - - - Initializes a new instance of the class. - - - Gets the key that is used in the context item dictionary to identify this type of context item. - A object that represents the type of the . - - - Gets the task that has the focus. - A object representing the task that has the focus. - - - Provides information about a gesture. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - The model where the gesture began. - The model the gesture is currently over. - - , , or is null. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - The model where the gesture began. - The model the gesture is currently over. - The source adorner to associate with the gesture, if it exists. This parameter can be null. - The target adorner to associate with the gesture, if it exists. This parameter can be null. - - , , or is null. - - - Gets the adorner collection for the designer view stored in the context. - An that contains the adorner collection for this context's designer view. - - - Gets the editing context associated with this gesture data. - The associated with this gesture data. - - - Provides a object from an object. - The object that is contained in the property of the object. - The object passed into a command callback. - - is null. - - - Provides a object from an object. - The object that is contained in the property of the object. - The object passed into a command callback. - - is null. - - - Gets the model that is the source of this gesture. - The that is the source of this gesture. - - - Gets the model that is the target of this gesture. - The that represents the target of this gesture. - - - Gets the source adorner in the view. - A that is the adorner that initiated the gesture. The return value can be null if the gesture was not initiated by an adorner. - - - Gets the object that is the source of this gesture. - The that is the source of this gesture. - - - Gets the target adorner in the view. - A that is the adorner the gesture is currently over. The return value can be null if the gesture is not over an adorner. - - - Gets the object that is the target of this gesture. - The that represents the target of this gesture. - - - Specifies a placement term for an . - - - Returns an enumeration of positioning terms that is used to position an adorner. - An enumeration of positioning terms. If no positioning terms are used, returns an empty enumeration. - The coordinate space of the owning adorner panel. - The adorner to get position terms for. - The view being adorned by the adorner. - A vector that indicates the zoom for the designer. - The resulting size of the adorner after the terms returned by the method have been processed. - - or is null. - - - Returns an enumeration of sizing terms that is used to size the adorner. - An enumeration of sizing terms. If no size terms are used, this method must return an empty enumeration. - The coordinate space of the owning adorner panel. - The adorner to get size terms for. - The view being adorned by the adorner. - A vector that indicates the zoom for the designer. - The final size of the view after it has been arranged. - - - Used when a resource for the specified key must be located. - A to be inserted into the default theme dictionary. - - - Provides data for the event. - - - Gets or sets the input binding that was mapped to the input event. - The input binding that was mapped to the input event. - - - Gets or sets the gesture data associated with the input event. - The gesture data associated with the input event. - - - Gets the input event that caused this event to be raised. - An for the input event that caused this event to be raised. - - - A context menu item which represents an action to take in the designer. - - - Initializes a new instance of the class. - The text that appears in the context menu. - - - Gets or sets a value indicating whether the menu item requires user interface (UI) that displays a check box. - true if the menu item requires a check box; otherwise, false. The default is false. - - - Gets or sets a value indicating whether the menu item is checked. - true if the menu item should be rendered with a check mark; otherwise, false. The default is false. - - - Gets the command which represents the menu action. - An which represents the menu action. - - - Gets or sets a value indicating whether the menu action item is available to the user. - true if the menu action item is available to the user; otherwise, false. The default is true. - - - Occurs when the menu item is executed. - - - Gets or sets the path to an image associated with the . - A to the image associated with the . The default value is null. - - - Gets or sets a value indicating whether the item is displayed in the menu. - true if the action is displayed in the menu; otherwise, false. The default is true. - - - Provides data for events. - - - Initializes a new instance of the class. - The associated . - - is null. - - - Gets the currently active editing context. - An representing the active editing batch. - - - Gets the current selection on the design surface. - A representing the currently selected control. - - - Provides a base class for both actions and groups. - - - Initializes a new instance of the class. - - - Gets the current editing context. - An for the current context or null. - - - Gets or sets the localized text to display for the menu item. - The localized text to display for the menu item. - - - Gets or sets the unique identifier for the menu item. - The unique identifier for the menu item. - - - Raises the event. - The name of the property that is changing. - - - Occurs when a property has changed. - - - Represents a group of menu items. - - - Initializes a new instance of the class that has the specified group name. - The name of the instance. - - - Initializes a new instance of the class that has the specified group name and display name. - The name of the instance. - Localized text to display when equals true. - - - Gets or sets a value indicating whether the menu items in the collection are added to a submenu. - true if the menu items in the items collection will be added to a submenu; false if the items in the collection will be added directly to the current menu, rendered with a separator on each end. - - - Gets a list of menu items to display as siblings within the same menu group. - An of items. - - - A callback delegate that can be assigned to the property of a transacted task. - The filter behavior for this filter. - A model item under the mouse pointer. - - - Provides information about the mouse position. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - The model where the gesture began. - The model the gesture is currently over. - The input element representing the coordinate reference for the points. This should be an element that never moves around, such as the . - The position of the mouse when the gesture was first initiated. - The current position of the mouse. - - , , , or is null. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - The model where the gesture began. - The model the gesture is currently over. - The input element representing the coordinate reference for the points. This should be an element that never moves around, such as the . - The position of the mouse when the gesture was first initiated. - The current position of the mouse. - The source adorner to associate with the gesture, if it exists. This parameter can be null. - The target adorner to associate with the gesture, if it exists. This parameter can be null. - - - Gets the current position of the mouse. - A object that represents the current position of the mouse. - - - Provides a object from an object. - The object contained in the property of the object. - The object passed into a command callback. - - is null. - - - Provides a from an object. - The object contained in the property of the object. - The object passed into a command callback. - - is null. - - - Gets the offset between starting and ending positions. - A object that represents the offset between the starting and ending positions of the mouse. - - - Gets the starting position of the mouse. - A object that represents the starting position of the mouse. - - - Translates the specified point to the coordinate system of the visual for the specified model. - A object that represents the translated point. - The point to translate. - The model to translate coordinates into. - - is null. - - - An enumeration that indicates the method a uses to move controls during keyboard nudges. - - - Indicates that the intent of the placement call is to nudge the control to the left. - - - Indicates that the intent of the placement call is to nudge the control to the right. - - - Indicates that the intent of the placement call is to nudge the control upward. - - - Indicates that the intent of the placement call is to nudge the control downward. - - - Provides an extension point for any type that can be a parent of child objects. - - - Initializes a new instance of the class. - - - Gets the type of adapter this class represents. - A representing the class type of parent adapter. - - - Gets a value indicating whether the specified parent object can be a parent to an object of the specified type. - true if the specified parent can accept a child of the specified type; otherwise, false. The default is true. - A representing the parent. - The type of child item. - - or is null. - - - Gets a value indicating whether the specified child item is a child of the specified parent item. - true if is a child item of ; otherwise, false. - The parent item. - The child item. - - - Changes the parent of an object to another parent. - The new parent item for . - The child item. - - or is null. - - - Changes the parent of an object to another parent. - The new parent item for the child. - The child item. - The order of control in the children collection. - - or is null. - - - Redirect a reference from one parent to another. . - A redirected parent. The default implementation returns . - The parent item. - The type of child item. - - or is null. - - - Replaces the current parent of the specified child with a new parent. - The item that is currently the parent of . - The item that will become the new parent of . - The child item. - - , , or is null. - - - An adapter that is used to get and set positions of objects in parent coordinates. - - - Initializes a new instance of the class. - - - Gets the type of adapter this class represents. - Returns a type. - - - Begins the placement operation. - The for which the placement operation is started. - - - Returns a value that indicates whether the specified coordinate can be set. - true if the coordinate can be set; otherwise, false. - Specifies the reason for this placement call. - Coordinate to be set. - - is null. - - - Ends the placement operation. - - - Returns a collection of positions that describe the placement of the specified item. - A object that is a collection of placement coordinates. - The item to request placement information for. - The positions to request placement information for. - - is null. - - - Gets the boundary of the specified item parent. - A representing the boundary of the . - The parent to find the boundary for. - - is null. - - - Gets the boundary of the specified item's parent. - A representing the boundary of the parent of . - Item parent boundary to find. - Specifies the reason for this placement call. - Array of placement positions to set. - - is null. - - - Assigns the specified array of positions for moving controls during keyboard nudges. - The to position. - A that specifies the intent of this placement call. - An array of placement positions to set. - - - Assigns the specified collection of positions for moving controls during keyboard nudges. - The to position. - A that specifies the intent of this placement call. - A collection of placement positions to set. - - - Assigns the specified array of positions to the specified model item. - The to position. - A that specifies the intent of this placement call. - An array of placement positions to set. - - - Assigns the specified collection of positions to the specified model item. - The to position. - A that specifies the intent of this placement call. - A collection of placement positions to set. - - - An enumeration that indicates the method a uses to place controls. - - - Indicates that the intent of the placement call is to move the control. - - - Indicates that the intent of the placement call is to size the control. - - - Offers a set of adorners that are shown for the primary selection. - - - Initializes a new instance of the class. - - - Offers a set of items that are shown for the current selection. - - - Initializes a new instance of the class. - - - Provides a set of tasks that are available from the selection tool when a class is in the primary selection. - - - Initializes a new instance of the class. - - - Defines a point that consists of an X and Y location and a class that defines the relationship of those coordinates to some other object. - - - Initializes a new instance of the structure for specified , X, and Y values. - A object that defines the relationship between the specified X and Y locations and some other object. - An X coordinate. - A Y coordinate. - - - Initializes a new instance of the class for a specified a non-relative point. - A object that defines the relationship between the specified X and Y locations and some other object. - A structure containing the coordinates to create for this . - - - Specifies whether this contains the same coordinates as the specified . - true if the objects have the same coordinates; otherwise, false. - The to test. - - - Specifies whether this contains the same coordinates as the specified . - true if is a and has the same coordinates as this . - The to test. - - - Converts the specified to a that is relative to the top left corner. - A new . - The structure to convert. - - - - Compares two structures. The result specifies whether the values of the Position, X, and Y properties of the two structures are equal. - true if the Position, X, and Y properties are equal; otherwise, false. - The first to compare. - The second to compare. - - - Converts the specified structure to a structure. - A new created from . - The structure to convert. - - - Compares two structures. The result specifies whether the values of the Position, X, or Y properties of the two structures are not equal. - true if the values of either the Position, X, or Y properties of and are not equal; otherwise, false. - The first to compare. - The second to compare. - - - Gets or sets the relative position of the structure. - The relative position of the structure. - - - Gets or sets the X coordinate of the structure. - The X coordinate of the structure. - - - Gets or sets the Y coordinate of the structure. - The Y coordinate of the structure. - - - Represents a position on the designer that remains independent of coordinate systems. - - - Initializes a new instance of the class that contains zero or more existing reference positions. - An array of objects included in a composite. - - is null. - - - Initializes a new instance of the class that contains zero or more existing reference positions. - A name that describes this . This is only used for diagnostic purposes. - An array of objects included in a composite. - - is null. - - - Returns a value indicating whether the specified exists inside of this . - true if is contained within this ; otherwise, false. - The to check. - - is null. - - - Determines whether the specified is equal to this . - true if the objects are equal; otherwise, false. - The to test. - - - Determines whether the specified object is equal to this object. - true if the specified object and this are equal; otherwise, false. - The object to test. - - - Returns the hash code for this object. - The hash code for this object. - - - Compares two objects. - true if the two objects are equal; otherwise, false. - The first to compare. - The second to compare. - - - Compares two objects. - true if the two objects are not equal; otherwise, false. - The first to compare. - The second to compare. - - - For a description of this member, see . - An enumeration of context items objects. - - - Returns the name of this position. - The name of this position. If the object is not named, returns the base implementation. - - - Represents a set of static instances of common objects. - - - Gets the bottom-left corner of an item on the design surface. - A that represents the bottom-left corner of an item on the design surface. - - - Gets the bottom-right corner of an item on the design surface. - A that represents the bottom-right corner of an item on the design surface. - - - Gets the bottom side of an item on the design surface. - A that represents the bottom side of an item on the design surface. - - - Gets the , , , and of an item on the design surface. - A that represents the left side, top side, right side, and bottom side of an item on the design surface. - - - Gets the center of an item on the design surface. - A that represents the center of an item on the design surface. - - - Gets the external bottom-left corner of an item on the design surface. - A that represents the external bottom-left corner of an item on the design surface. - - - Gets the external bottom-right corner of an item on the design surface. - A that represents the external bottom-right corner of an item on the design surface. - - - Gets the external bottom side of an item on the design surface. - A that represents the external bottom side of an item on the design surface. - - - Gets the external left side of an item on the design surface. - A that represents the external left side of an item on the design surface. - - - Gets the external right side of an item on the design surface. - A that represents the external right side of an item on the design surface. - - - Gets the external top-left corner of an item on the design surface. - A that represents the external top-left corner of an item on the design surface. - - - Gets the external top-right corner of an item on the design surface. - A that represents the external top-right corner of an item on the design surface. - - - Gets the external top side of an item on the design surface. - A that represents the external top side of an item on the design surface. - - - Gets the internal bottom-left corner of an item on the design surface. - A that represents the internal bottom-left corner of an item on the design surface. - - - Gets the internal bottom-right corner of an item on the design surface. - A that represents the internal bottom-right corner of an item on the design surface. - - - Gets the internal bottom side of an item on the design surface. - A that represents the internal bottom side of an item on the design surface. - - - Gets the internal left side of an item on the design surface. - A that represents the internal left side of an item on the design surface. - - - Gets the internal right side of an item on the design surface. - A that represents the internal right side of an item on the design surface. - - - Gets the internal top-left corner of an item on the design surface. - A that represents the internal top-left corner of an item on the design surface. - - - Gets the internal top-right corner of an item on the design surface. - A that represents the internal top-right corner of an item on the design surface. - - - Gets the internal top side of an item on the design surface. - A that represents the internal top side of an item on the design surface. - - - Gets the left side of an item on the design surface. - A that represents the left side of an item on the design surface. - - - Gets the right side of an item on the design surface. - A that represents the right side of an item on the design surface. - - - Gets the top-left corner of an item on the design surface. - A that represents the top-left corner of an item on the design surface. - - - Gets the top-right corner of an item on the design surface. - A that represents the top-right corner of an item on the design surface. - - - Gets the top side of an item on the design surface. - A that represents the top side of an item on the design surface. - - - Represents a coordinate on the designer. - - - Initializes a new instance of the structure using a and a value. - The known relative position type for this value. - The value for this relative position. - - - Determines whether the specified object is equal to this structure. - true if the specified object and this are equal; otherwise, false. - The object to test. - - - - Compares two structures. - true if the two structures are equal; otherwise, false. - The first to compare. - The second to compare. - - - Compares two structures. - true if the two structures are not equal; otherwise, false. - The first to compare. - The second to compare. - - - Gets or sets the that identifies the kind for this value. - A that identifies the kind for this value. - - - Gets or sets the actual value of this position or coordinate. - The actual value of this position or coordinate. - - - Represents a collection of values that describe the placement of an item within a panel or container on the designer surface. - - - Initializes a new instance of the class. - - - Finds the position value of the specified position. - A of the specified position. - A to find. - - is null. - - - Provides placement support for any element that does not have a parent. - - - Initializes a new instance of the class. - - - Gets the adapter type. - - - Represents a set of objects selected by a user in a designer. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with the specified array of objects. - An array of objects to add to the selection. - The parameter is null. - - - Initializes a new instance of the class with the specified enumeration of objects. - An enumeration of objects to add to the selection. - The parameter is null. - - - Initializes a new instance of the class by using the specified enumeration of objects and predicate. - An enumeration of objects to add to the selection. - Only those objects in that match the predicate are added to the selection. - The or parameter is null. - - - Initializes a new instance of the class with the specified enumeration of objects. - An enumeration of objects to add to the selection. - The parameter is null. - - - Initializes a new instance of the class with the specified enumeration of objects and predicate. - An enumeration of objects to add to the selection. - Only those objects in that match the predicate are added to the selection. - The or parameter is null. - - - Gets the type of . - The type of . - - - Gets the primary selection object. - If the selection contains objects, the primary selection object; otherwise, null. - - - Gets an enumeration of the objects in the selection. - An enumeration of the objects in the selection. - - - Gets the number of objects in the selection. - The number of objects in the selection. - - - Gets a selection that contains model items that provide a view. - A that contains model items that provide a view. - - - Provides standard commands that control the selection of objects in a designer. - - - Gets a that represents a request to clear the existing selection. - A request to clear the existing selection. - - - Gets a that represents a request to select all objects in the designer. - A request to select all objects in the designer. - - - Gets a that represents a request to select the next object in the designer. - A request to select the next object in the designer. - - - Gets a that represents a request to select only the object under the mouse pointer in the designer. - A request to select only the object under the mouse pointer in the designer. - - - Gets a that represents a request to select the previous object in the designer. - A request to select the previous object in the designer. - - - Gets a that represents a request to select the object under the mouse pointer in the designer. - A request to select the object under the mouse pointer in the designer. - - - Gets a that represents a request to display the default event handler for the primary selection object in the designer. - A request to display the default event handler for the primary selection object in the designer. - - - Gets a that represents a request to toggle the selection state of the object under the mouse pointer in the designer. - A request to toggle the selection state of the object under the mouse pointer in the designer. - - - Gets a that represents a request to add the object under the mouse pointer in the designer to the existing selection. - A request to add the object under the mouse pointer in the designer to the existing selection. - - - Provides standard operations that control the programmatic selection of objects in a designer. - - - Processes a request to programmatically select an object in the designer. - A new empty selection, a new selection containing new objects, or the existing selection. See the remarks section for more information. - The current editing context. - The object to select. - - or is null. - - - Processes a request to programmatically select a single object in the designer. - A selection containing the object to select. - The current editing context. - The object to select. - - or is null. - - - Adds a callback method that is invoked when the selection in the editing context changes. - The editing context of interest. - The method to invoke when the selection changes. - - or is null. - - - Processes a request to programmatically toggle the selection state of an object in the designer. - A new selection that contains or does not contain the object to toggle. See the remarks section for more information. - The current editing context. - The object to select or deselect. - - or is null. - - - Processes a request to programmatically add an object in the designer to the existing selection. - A new selection containing the new object, or the existing selection. See the remarks section for more information. - The current editing context. - The object to select. - - or is null. - - - Removes a callback method so that it is not invoked when the selection in the editing context changes. - The editing context of interest. - The method that is removed. - - or is null. - - - Represents a tool that selects objects in a designer, such as a mouse pointer. - - - Initializes a new instance of the class. - - - Called when a is activated. - The tool that was previously active. - - - Called when a is deactivated. - - - Represents a collection of commands and input bindings to those commands. - - - Initializes a new instance of the class. - - - Gets or sets the filter that is used to filter the set of adorners seen by the designer's hit test algorithm. - A that is used to filter the set of adorners seen by the designer's hit test algorithm. - - - Begins to set the focus for the task. - The gesture data for the focus. - - is null. - The task already has the focus. - - - Gets the for a task. - A instance containing the command bindings for this task, - - - Completes changes that were made while this task has the focus. - The task does not have the focus. - - - Occurs when this task has completed. - - - Gets or sets the cursor for a task. - A for a task. - - - Gets or sets the description for this task. - A description for this task. - - - Occurs when focus for this task is deactivated. - - - Gets the for a task. - An instance that contains the input bindings for this task. - - - Gets a value indicating whether this task has the focus. - true if this task has the focus; otherwise, false. - - - Gets or sets the filter that is used to filter the set of model items seen by the designer's hit test algorithm. - A that is used to filter the set of model items seen by the designer's hit test algorithm. - - - Raises the event. - An that contains the event data. - - - Raises the event. - An that contains the event data. - - - Raises the event. - An that contains the event data. - - - Reverts this task. - The task is not active. - - - Occurs when this task is reverted. - - - Gets the for a task. - A instance that contains the tool command bindings for this task. - - - A feature provider that you can add to a class to automatically add tasks to the active tool. - - - Initializes a new instance of the class. - - - Called when a task provider's tasks are about to be requested for the first time. - A object. - - - Gets the editing context that activated this task provider. - An object that represents the object that activated the current task provider. - - - Called when a task provider is about to be discarded by the designer. - - - Returns a value indicating whether this task provider supports the specified tool. - true if the specified tool is supported; otherwise, false. - A object to check. - - - Gets a collection of tasks this task provider offers. - An that contains all of the tasks that this offers. - - - Represents a tool that determines the mode of the designer. - - - Initializes a new instance of the class. - - - Gets the editing context for code within the tool. - An for code within the tool. - - - Gets or sets the default cursor for the mouse. - A for the mouse. - - - Gets the currently focused task, if one exists. - A object that represents the task that currently has focus. - - - Gets the type of the tool. - A that represents the type of the tool. - - - Called when a tool is activated. - The tool that was in the context before this tool became active. The default implementation does nothing with this parameter. - - - Called when a tool is being deactivated. - - - Adds activate and deactivate semantics to the class. - The editing context where the change is occurring. - The previous tool. - - - Gets the set of tasks this tool provides. - A of tasks this tool provides. - - - Represents a user gesture. - - - No action. - - - A mouse button has been pressed. - - - A mouse button has been released. - - - The mouse has been moved. - - - The mouse wheel has been moved. - - - A mouse button has been clicked. - - - A mouse button has been double-clicked. Double-click and single-click interact as follows: , , . - - - The mouse has entered an element. If the mouse enters an adorner, an event is only raised if the target of the adorner is different from the last target. - - - The mouse has left an element. If the mouse leaves an adorner, a event is only raised if the new target is different from the adorner鈥檚 target. - - - The mouse has stopped for a short time over an element or adorner. A new hover event is raised when the mouse passes over a different element. - - - The user has held a mouse button down and moved the mouse beyond a certain threshold. This indicates the user鈥檚 intent to begin a drag operation. - - - A event that occurs because of a prior call to DragDrop.DoDragDrop. The source and target objects always refer to the elements, not the adorners. - - - A event that occurs because of a prior call to DragDrop.DoDragDrop. The source and target objects always refer to the elements, not the adorners. - - - A event that occurs because of a prior call to DragDrop.DoDragDrop. The source and target objects always refer to the elements, not the adorners. - - - A event that occurs because of a prior call to DragDrop.DoDragDrop. The source and target objects always refer to the elements, not the adorners. - - - A event that occurs because of a prior call to DragDrop.DoDragDrop. The source and target objects always refer to the elements, not the adorners. - - - The user held a mouse button down and moved the mouse. This causes a to be signaled. Next, the user has released that mouse button, signaling the drag has completed. - - - The user has dragged an item off the edge of the design surface. You may bind a command to this gesture to invoke a drag-and-drop operation. - - - Provides data for events. - - - Initializes a new instance of the class. - The tool action associated with this event. - The event that caused this action. - The input device to associate with this event. - The time when the input occurred. - - is null. - - - Initializes a new instance of the class. - The tool action associated with this event. - The event that caused this action. - - is null. - - - Gets the input event that caused this tool action event to occur. - An that represents the input event that caused this tool action event to occur. - - - Gets the tool action associated with this event. - The tool action associated with this event. - - - Returns a string describing the event for diagnostic purposes. - A diagnostic string describing the event. - - - Acts as a command identifier and as a unified way of invoking a particular command. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with the specified command name. - The name of the command. - - is null. - - - Locates a command binding for the command and asks if it is enabled. - true if the command is enabled; false if it is disabled or there is no binding for it. - The gesture data that is to be passed to the command. Gesture data is required as it provides a context object from which the method can locate the active tool. - - is null. - - .Context is null. - - - Occurs when the status of this command changes. - When used. - - - Locates a command binding for the command and executes it. - The gesture data that is to be passed to the command. Gesture data is required as it provides a context object from which the method can locate the active tool. - - is null. - - .Context is null. - - - Gets the name of this command. - A string representing the name of this command, or an empty string if the command has no name. - - - For a description of this member, see . - true if this command can be executed; otherwise, false. - Data used by the command. If the command does not require data to be passed, this object can be set to null. - - - For a description of this member, see . - Data used by the command. If the command does not require data to be passed, this object can be set to null. - - - Returns the name of this command. - The name of this command. - - - Acts as a bridge between a command and an event handler which implements it. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class. - The command to bind. - - is null. - - - Initializes a new instance of the class. - The command to bind. - The event handler to raise when the command is executed. - - or is null. - - - Initializes a new instance of the class. - The command to bind. - The event handler to raise when the command is executed. - The event handler to raise when the method is invoked. - - , , or is null. - - - Occurs when QueryEnabled for the command is called. - - - Gets or sets the tool command associated with this binding. - The tool command associated with this binding. - - - Occurs when the command is executed. - - - Represents a collection of tool command bindings. - - - Initializes a new instance of the class. - - - Adds the specified bindings to the collection. - The bindings to add. - - is null. - - - Inserts an item in to the collection. - The index where to add the item. - The item to add. - - is null. - - - Sets the value of an item in the collection. - The index of the value to set. - The value to set at the index. - - is null. - - - Represents a tool interaction with the mouse. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class. - The action to take. - - - Initializes a new instance of the class. - The action to take. - Modifies the button states to only allow the specified button. For example, if you wanted to make a "Click" action only valid for the left mouse button, you would pass in this parameter. The default is to allow all buttons. - - - Initializes a new instance of the class. - The action to take. - Modifies the button states to only allow the specified button. For example, if you wanted to make a "Click" action only valid for the left mouse button, you would pass in this parameter. The default is to allow all buttons. - The keyboard modifiers to use. By default, any keyboard modifiers are valid. You can restrict the set of valid modifiers by supplying them in this parameter. - - - Gets or sets whether this gesture is allowed to be performed while the left mouse button is pressed. - Returns if this gesture is allowed to be performed while the left mouse button is pressed. The default returns . - - - Returns a value indicating whether this gesture matches an input event. - true if this gesture matches the input event; otherwise, false. - The target element for this gesture. - The input event to compare with this gesture. - - is null. - - - Gets or sets whether if this gesture is allowed to be performed while the middle mouse button is pressed. - Returns if this gesture is allowed to be performed while the middle mouse button is pressed. The default returns . - - - Gets or sets the modifier keys that are allowed to be pressed for this gesture. - Returns the modifier keys that are allowed to be pressed for this gesture. The default returns the combination of all modifier keys. - - - Gets or sets whether this gesture is allowed to be performed while the right mouse button is pressed. - Returns if this gesture is allowed to be performed while the right mouse button is pressed. The default returns . - - - Gets or sets the action associated with this gesture. - A associated with this gesture. - - - Returns a string that describes the gesture for diagnostic purposes. - A diagnostic string that describes the gesture. - - - Gets or sets whether this gesture is allowed to be performed while the xbutton1 mouse button is pressed. - Returns if this gesture is allowed to be performed while the xbutton1 mouse button is pressed. The default returns . - - - Gets or sets whether this gesture is allowed to be performed while the xbutton2 mouse button is pressed. - Returns if this gesture is allowed to be performed while the xbutton2 mouse button is pressed. The default returns . - - - Represents the callback method that specifies which parts of the visual tree to omit from hit test processing in the method. - A that specifies the hit testing behavior for . - A to hit test. - - - Represents the return value from a hit test in the method. - - - Initializes a new instance of the class. - - - Gets the object that was hit. - The that was hit. - - - Represents a callback that is used to customize hit testing in the method. - A that specifies the hit testing behavior for . - A to get hit test behavior for. - - - An abstract class that enables interaction with view objects. - - - Initializes a new instance of the class. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Gets the FlowDirection property of the view. - The value for the view. - - - Serves as a hash function for a . - A hash code for the current . - - - Initiates a hit test on the , with caller-defined and methods. - A that holds the visual objects that were hit. - A delegate that specifies parts of the visual tree to omit from the hit test. - A delegate that customizes the hit test. - A that defines the hit test. - - - Determines whether the visual object is a descendant of the ancestor visual object. - true if the is a descendant of ; otherwise, false. - The to test for an ancestor relationship. - - - Gets a value that indicates whether the visual object is a descendant of the specified visual object. - true if the is a descendant of ; otherwise, false. - The to test for an ancestor relationship. - - - Gets a value that indicates whether the element is off the screen. - true if the element is off the screen; otherwise, false. - - - Gets a value that indicates whether an element is visible. - true if the element is visible; otherwise, false. - - - Gets the type of the underlying dependency object that represents this view. - The of the underlying dependency object. - - - Gets the layout transform of the current . - The layout transform of the current . - - - Gets a collection of the immediate logical children of the current . - An enumeration of objects that holds the logical children of the current . - - - Gets the logical parent of the current . - A that represents the logical parent of the current . - - - Gets the offset of the view. - A that represents the offset of the current view. - - - Determines whether the specified instances are considered equal. - true if is equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether the specified instances are considered not equal. - true if is not equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Gets the underlying dependency object that represents this view. - The underlying dependency object. - - - Converts a that represents the current coordinate system of the into a in screen coordinates. - The converted value in screen coordinates. - The value that represents the current coordinate system of the . - - - Gets the render size of the view. - A that represents the render size of the view. - - - Gets the layout rectangle for the view. - A that represents the render size and offset relative to the logical parent. - - - Gets the bounds of the selection frame. - A that represents the selection frame for the current . - - - Gets the transform value for the current . - A that represents the transform of the current . - - - Returns a transform that can be used to transform coordinates from the specified visual object to the view. - A that represents the conversion, or null if the transform could not be computed. - - to transform the coordinates to. - - is null. - - - Returns a transform that can be used to transform coordinates from the view to the specified view object. - A that represents the conversion, or null if the transform could not be computed. - The to transform the coordinates to. - - is null. - - - Returns a transform that can be used to transform coordinates from the view to the specified visual object. - A that represents the conversion, or null if the transform could not be computed. - The to transform the coordinates to. - - is null. - - - Calls the UpdateLayout method on the underlying platform object. - - - Gets the property of the view. - The value of the view. - - - Gets a collection of the immediate visual children of this . - An enumeration of objects that holds the visual children of the current . - - - Gets the visual parent of the current . - A that represents the logical parent of the current . - - - Provides gesture data about the mouse wheel. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - The model where the gesture began. - The model the gesture is currently over. - The amount the wheel has moved. - - , , or is null. - - - Initializes a new instance of the class. - The editing context that owns this gesture data. - The model where the gesture began. - The model the gesture is currently over. - The amount the wheel has moved. - The source adorner to associate with the gesture, if it exists. This parameter can be null. - The target adorner to associate with the gesture, if it exists. This parameter can be null. - - , or is null. - - - Gets the scroll delta from the mouse scroll wheel. - An integer representing the amount that the scroll wheel has moved. - - - Provides a object from an object. - The object that is contained in the property of the object. - The object passed into a command callback. - - is null. - - - Provides a object from an object. - The object that is contained in the property of the object. - The object passed into a command callback. - - is null. - - - Specifies how to create a new item. - - - Just creates the object and does not perform any operations on it. This is the default. - - - Creates the item and specifies that the object should perform any default initialization. This flag is generally passed in when a new control or object is being created by a user. - - - Used to configure a new object in the designer. - - - Initializes a new instance of the class. - - - Initializes default values for the specified item. - The item to initialize. This should not be null. - - is null. - - - Initializes default values for the specified item using the provided editing context. - The item to initialize. This should not be null. - The editing context. - - is null. - - - Captures property changes that are made by the user in the designer and provides new values at design time. - - - Initializes a new instance of the class. - An invalid property is added to . - - - Invalidates the specified property. - The to invalidate property changes for. - The property that is to be invalidated. - - is null. - - - Gets the set of properties to capture. - A that contains the set of properties to capture. - - - Captures property changes that were made by the user in the designer and uses custom logic to provide new values at design time. - The value to set the property to in the designer. - The to capture property changes for. - The property that the user is changing the value of. - The new value that the user is changing the property to. - - is null. - - is empty. - - - Adds LINQ extension methods to the and classes to support model items. - - - Creates feature providers of the specified type and model item. - An enumeration of created providers. - The feature manager to use. - The type of feature provider to create. - The model item to create the feature providers for. - - , or is null. - - - Creates feature providers of the specified type and model item. - An enumeration of created providers. - The feature manager to use. - The type of feature provider to create. - The model item to create the feature providers for. - A predicate to use when creating feature providers. If the predicate returns true, the feature provider is included in the enumeration. - - , , , or is null. - - - Represents a group of changes to the editing store. - - - Initializes a new instance of the class. - - - Determines whether the method can be called, or whether the change should instead be reverted. - true if completion can occur; false if the change should instead be reverted. - - - Completes the editing scope. - - has already been completed or reverted. - - - Gets or sets a description for the group. - A string containing the description for the group. - - - Releases all resources used by the . - - - Releases the unmanaged resources used by the class and optionally releases the managed resources. - true to release both managed and unmanaged resources; false to release only unmanaged resources. - - - Called during finalization to abort the group. - - - Performs the actual complete of the editing scope. - - - Performs the actual revert of the editing scope. - true if the abort occurs because the object is being finalized. Some undo systems may try to abort in this case, while others may abandon the change and record it as a reactive undo. - - - Abandons the changes that were made during the editing scope. - - has already been committed. - - - Performs a synchronous refresh of the view. - - - Represents an event on an item. - - - When overridden in a derived class, initializes a new instance of the class. - - - When overridden in a derived class, gets the data type of the delegate for this event. - A that represents the data type of this event. - - - Returns the attributes of the specified type that are declared on this event and the event's handler type. - An enumeration of objects that represent the attributes of the specified type. - A object for which attributes are needed. - - - Returns the attributes of the specified type that are declared on this event and the event's handler type. - An enumeration of objects that represent the attributes of the specified type. - A object for which attributes are needed. - - - When overridden in a derived class, gets a collection of method names that should handle this event. - An that represents the names of methods that should handle this event. - - - When overridden in a derived class, gets whether the event can be shown in a property window. - true if the event is shown in a property window; otherwise, false. - - - Determines whether this event is of the specified type, or implements the interface of the specified type. - true if this event is of the type represented by ; otherwise, false. - A object that represents the type. - - - Determines whether this event is of the specified type, or implements the interface of the specified type. - true if this event is of the type represented by ; otherwise, false. - A object that represents the type. - - is null. - - - When overridden in a derived class, gets the name of this event. - A string representing the name of this event. - - - When overridden in a derived class, gets the parent of this event. - A representing the parent of this event. - - - Represents an enumeration of events. - - - Initializes a new instance of the class. - - - Used to create instances of model items in the designer. - - - Creates a new model item for the specified type identifier. - A that represents the newly created item type. This method might return null if the type identifier could not be resolved. - The designer's editing context. - An identifier for the type of item to create. - A set of create options to use when creating the item. The default is . - An optional array of arguments that should be passed to the constructor of the item. - - is null. - - - Creates a new model item for the specified type identifier. - A that represents the newly created item type. This method might return null if the type identifier could not be resolved. - The designer's editing context. - An identifier for the type of item to create. - An optional array of arguments that should be passed to the constructor of the item. - - - Creates a new model item by creating a deep copy of the specified object. - A that represents the newly created item. - An representing the designer's editing context - An object representing the item to clone. - - or is null. - - - Creates a new model item for the specified item type. - A that represents the newly created item type. - An representing the designer's editing context. - A representing the type of item to create. - A set of create options to use when creating the item. The default value is . - An optional array of arguments that should be passed to the constructor of the item. - - or is null. - - is not valid. - There is no editing model in the context that can create new items. - - - Creates a new model item for the specified item type. - A that represents the newly created item type. - An representing the designer's editing context. - A representing the type of item to create. - An optional array of arguments that should be passed to the constructor of the item. - - or is null. - There is no editing model in the context that can create new items. - - - Creates a new model item that represents the value of a static member of the specified class. - A that represents the newly created item type. This method might return null if the type identifier could not be resolved. - The designer's editing context. - An identifier for the type being referenced. - The name of the static member being referenced. - - or is null. - - - Creates a new model item that represents the value of a static member of the specified class. - A that represents the value of the static member specified by on the type specified by . - The designer's editing context. - The type that contains the static member being referenced. - The name of the static member being referenced. - - , , or is null. - - - Gets a resolved type for the specified . - A type that matches from one of the designer's referenced assemblies. - The designer's editing context. - A platform-agnostic identifier for the type. - - or is null. - - - Represents a single item in the editing model. - - - Initializes a new instance of the class. - - - When overridden in a derived class, this method is called when performing multiple operations on an object or group of objects. - A that must be either completed or reverted. - - - When overridden in a derived class, this method is called when performing multiple operations on an object or group of objects. - An that must be either completed or reverted. - An optional description that describes the change. This string is set into the editing scope鈥檚 property. - - - When overridden in a derived class, gets a representing the item's . - A representing the item's . - - - Gets an object that contains contextual information about the designer this was created for. - An object that contains contextual information about the relevant designer. - - - When overridden in a derived class, gets the public events on this object. - A that contains the events on this object. - - - Gets the attributes of the requested type that are declared on this item. - A collection of attributes of the requested type declared on this item. - An identifier for the requested type. - - - Gets the attributes of the requested type that are declared on this item. - A collection of attributes of the requested type declared on this item. - The requested type. - - - When overridden in a derived class, returns the current value of the underlying model object the is wrapping. - Returns an object that represents the current value of the underlying model object the is wrapping. - - - Gets a value that indicates whether this item is of the specified type or implements the specified interface. - true if this item is of the specified type or implements the specified interface; otherwise, false. - An identifier for the type or interface to test. - - - Gets a value that indicates whether this item is of the specified type or implements the specified interface. - true if this item is of the specified type or implements the specified interface; otherwise, false. - The type or interface to test. - - - When overridden in a derived class, gets the type of object the item represents. - A object that represents the type of the underlying object. - - - When overridden in a derived class, gets or sets the name or ID of the item. - A string representing the name of the item. - - - When overridden in a derived class, gets the item that is the parent of this item. - A that represents the parent item of this object. - - - When overridden in a derived class, gets the public properties on this object. - A that contains the properties on this . - - - When overridden in a derived class, occurs when a property on the model changes. - - - When overridden in a derived class, gets the item that is the root of this tree. - The item that is the root of this tree, or null there if there is no root yet. - - - When overridden in a derived class, gets the property that provided this value. - A that represents the source of this . - - - When overridden in a derived class, gets the visual or visual3D representing the UI for this item. - A representing the UI for this item. - - - Implements support for a collection of objects. - - - Initializes a new instance of the class. - - - When overridden in a derived class, adds the specified item to the collection. - A to be added to the collection. - - - When overridden in a derived class, adds the specified object to the collection. - A representing the value. - An object to be added to the collection. - - - When overridden in a derived class, clears the contents of the collection. - - - When overridden in a derived class, occurs when the contents of this collection is changed. - - - When overridden in a derived class, returns a value indicating whether the collection contains the specified item. - true if the is contained in the collection; otherwise, false. - A to be tested. - - - When overridden in a derived class, returns a value indicating whether the collection contains the specified value. - true if the is contained in the collection; otherwise, false. - An object to be tested. - - - When overridden in a derived class, copies the contents of the collection into the specified array. - The array for the current to be copied to. - The location in the destination array to copy the items from the collection to. - - - When overridden in a derived class, gets the count of items in the collection. - An integer that represents the number of items in the collection. - - - When overridden in a derived class, returns an enumerator for the items in the collection. - An that can act as an enumerator for the items in this dictionary. - - - When overridden in a derived class, returns the index of the specified item. - Returns an integer representing the index of the specified . If the item is not found it returns -1. - The to find the index of. - - - When overridden in a derived class, inserts an item at the specified location. - The index for the item to be inserted. - A to be inserted at the specified index. - - - When overridden in a derived class, inserts an item at the specified location. - A representing the value. - The index for the item to be inserted. - A object to be inserted at the specified index. - - - When overridden in a derived class, gets a value indicating whether the collection is a fixed size. - true if the collection is a fixed size; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the collection can be modified. - true if the collection is read-only; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the collection is synchronized. - true if the collection is synchronized; otherwise, false. - - - When overridden in a derived class, gets or sets the item at the specified index. This is a dependency property. - A representing the item at the specified index. - The index to be set or retrieved. - - - Identifies the dependency property. - The identifier for the dependency property. - - - When overridden in a derived class, moves an item to a new index. - The index of the item to move. - The index to move it to. - - - When overridden in a derived class, removes an item from the collection. - true if the item is successfully removed; otherwise, false. - The item to be removed. - - - When overridden in a derived class, removes a value from the collection. - true if the item is successfully removed; otherwise, false. - The item to be removed from the collection. - - - When overridden in a derived class, removes an item at the specified index. - The index at which to remove the item. - - - When overridden in a derived class, gets an object that can be used to synchronize this collection. - An object that can be used to synchronize the collection. - - - For a description of this member, see . - The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. - The zero-based index in at which copying begins. - - - For a description of this member, see . - The number of elements contained in the . - - - For a description of this member, see . - true if access to the is synchronized (thread safe); otherwise, false. - - - For a description of this member, see . - An object that can be used to synchronize access to the . - - - For a description of this member, see . - An object that can be used to iterate through the collection. - - - For a description of this member, see . - The position into which the new element was inserted, or -1 to indicate that the item was not inserted into the collection. - The object to add to the . - - - For a description of this member, see . - - - For a description of this member, see . - true if the is found in the ; otherwise, false. - The object to locate in the . - - - For a description of this member, see . - The index of if found in the list; otherwise, -1. - The object to locate in the . - - - For a description of this member, see . - The zero-based index at which should be inserted. - The object to insert into the . - - - For a description of this member, see . - true if the has a fixed size; otherwise, false. - - - For a description of this member, see . - true if the is read-only; otherwise, false. - - - For a description of this member, see . - The element at the specified index. - The zero-based index of the element to get or set. - - - For a description of this member, see . - The object to remove from the . - - - For a description of this member, see . - The zero-based index of the item to remove. - - - Implements key/value dictionary support for objects. - - - Initializes a new instance of the class. - - - When overridden in a derived class, adds the item to the dictionary under the specified key. - A that is the key for this dictionary entry. - A that is the value for this dictionary entry. - - - When overridden in a derived class, adds the value to the dictionary under the specified key. - A representing the key in the dictionary. - A that is the key for this dictionary entry. - A that is the value for this dictionary entry. - - - When overridden in a derived class, clears the contents of the dictionary. - - - When overridden in a derived class, occurs when the contents of this dictionary is changed. - - - When overridden in a derived class, returns whether the dictionary contains the specified key value pair. - true if the dictionary contains the ; otherwise, false. - The item to be tested for inclusion in the dictionary. - - - When overridden in a derived class, returns a value indicating whether the dictionary contains the specified key. - true if the dictionary contains the ; otherwise, false. - A that represents the key to be tested. - - - When overridden in a derived class, returns a value indicating whether the dictionary contains the specified key. - true if the dictionary contains the ; otherwise, false. - A object that represents the key to be tested. - - - When overridden in a derived class, copies the contents of the dictionary into the specified array beginning at the specified index. - The array for the current to be copied to. - The location within the destination array to copy the items from the dictionary to. - - - When overridden in a derived class, gets the count of items in the dictionary. - An integer that represents the number of items in the dictionary. - - - When overridden in a derived class, returns an enumerator for the items in the dictionary. - An that can act as an enumerator for the items in this dictionary. - - - When overridden in a derived class, gets a value indicating whether the dictionary is a fixed size. - true if the dictionary is a fixed size; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the dictionary can be modified. - true if the dictionary is read-only; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the dictionary is synchronized. - true if the dictionary is synchronized; otherwise, false. - - - When overridden in a derived class, gets or sets the item at the specified key. - A representing the item at the specified key. - A that represents the key to an item in the . - - - When overridden in a derived class, gets or sets the item at the specified key. - A representing the item at the specified key. - An object that represents the key to an item in the . - - - ModelItemDictionary provides an attached property 鈥淜ey鈥, which is adds to all items contained in the dictionary. The data type of the Key property is 鈥淢odelItem鈥. - - - When overridden in a derived class, gets the keys of the dictionary. - An that contains the keys of the . - - - When overridden in a derived class, removes the item from the dictionary. - true if the item is successfully removed; otherwise, false. - A representing the key of the item to be removed. - - - When overridden in a derived class, removes the item from the dictionary. - true if the item is successfully removed; otherwise, false. - An object representing the key of the item to be removed. - - - When overridden in a derived class, gets the object used to synchronize this dictionary. - An object that can be used to synchronize the dictionary. - - - For a description of this member, see . - The key/value pair to add to the collection. - - - For a description of this member, see . - true if is found in the collection; otherwise, false. - The key/value pair to locate in the collection. - - - For a description of this member, see . - The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. - The zero-based index in at which copying begins. - - - For a description of this member, see . - true if was successfully removed from the collection; otherwise, false. This method also returns false if is not found in the original collection. - The key/value pair to remove from the collection. - - - For a description of this member, see . - The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. - The zero-based index in at which copying begins. - - - For a description of this member, see . - The number of elements contained in the . - - - For a description of this member, see . - true if access to the is synchronized (thread safe); otherwise, false. - - - For a description of this member, see . - An object that can be used to synchronize access to the . - - - For a description of this member, see . - The to use as the key of the element to add. - The to use as the value of the element to add. - - - For a description of this member, see . - - - For a description of this member, see . - true if the dictionary contains an element with ; otherwise, false. - The key to locate in the dictionary. - - - For a description of this member, see . - An object for the object. - - - For a description of this member, see . - true if the object has a fixed size; otherwise, false. - - - For a description of this member, see . - true if the object is read-only; otherwise, false. - - - For a description of this member, see . - The element with the specified key. - The key of the element to get or set. - - - For a description of this member, see . - An object containing the keys of the object. - - - For a description of this member, see . - The key of the element to remove. - - - For a description of this member, see . - An object containing the values in the object. - - - For a description of this member, see . - An that can act as an enumerator for the items in this dictionary. - - - When overridden in a derived class, retrieves the value for the specified key. - true if a value associated with is found; otherwise, false. - A representing the key to be tested. - If a value is found for the , this out parameter contains the value that is retrieved. - - - When overridden in a derived class, retrieves the value for the specified key. - true if a value associated with is found; otherwise, false. - An object representing the key to be tested. - If a value is found for the , this out parameter contains the value that is retrieved. - - - When overridden in a derived class, gets the values of the dictionary. - An that contains the items of the . - - - Provides data for events that use instances. - - - Initializes a new instance of the class. - A to include. - - is null. - - - Gets the associated instance. - The associated with the current instance. - - - Represents a collection for model members. - The type of item the collection represents. - - - - Searches the collection for an item with the specified key and returns it if it is found. - A TItemType with the specified key. If not found, this method returns null. - The key of the item to find. - - is null. - - - When overridden in a derived class, searches the collection for an item with the specified key and returns it if it is found. - A TItemType with the specified key. If not found, this method throws an exception or returns null, depending on the value passed to . - The key of the item to find. - true if an exception should be thrown if the item is not found; otherwise, false. - - is not found and is true. - - - Searches the collection for an item with the specified key and returns it if it is found. - A TItemType with the specified key. If not found, this method returns null. - The key of the item to find. - - is null. - - - When overridden in a derived class, searches the collection for an item with the specified key and returns it if it is found. - A TItemType with the specified key. If not found, this method throws an exception or returns null, depending on the value passed to . - The key of the item to find. - true if an exception should be thrown if the item is not found; otherwise, false. - - is not found and is true. - - - When overridden in a derived class, returns an enumerator to enumerate items. - An to enumerate items. - - - Searches the collection for an item with the specified key and returns it if it is found. - A TItemType with the specified key. If not found, this property throws an exception. - The key of the item to find. - - is null. - - is not found. - - - Searches the collection for an item with the specified key and returns it if it is found. - A TItemType with the specified key. If not found, this property throws an exception. - The key of the item to find. - - is null. - - is not found. - - - For a description of this member, see . - An to enumerate items. - - - A class that can be used to help set the parent of an item. - - - Determines if the specified type can be the parent of the specified child type. - true if the specified item can accept instances of as a child; otherwise, false. - The editing context to use. - The parent. - The type of item you wish to parent. - - - Finds a viable parent for the specified child and editing context. - An item that can accept a , or null if no viable parent could be found. - The editing context to use. - The item you wish to parent. - The item to use as a starting point for the search. - - - Finds a viable parent for the specified type of child and editing context. - An item that can accept an item of type , or null if no viable parent could be found. - The editing context to use. - The type of item you wish to parent. - The item to use as a starting point for the search. - - - Finds a viable parent for the specified type of child. - An item that can accept an item of type , or null if no viable parent could be found. - The type of item you wish to parent. - Gesture data that can be used to determine the starting item and position of the search. - - - Sets the specified item as the parent of the specified child item. - The editing context to use. - The parent to set the child into. - The child to be parented. - - - Represents a property on an item. - - - Initializes a new instance of the class. - - - When overridden in a derived class, gets the type which defines this property. - A which defines this property if the property returns true. Otherwise, returns null. - - - When overridden in a derived class, clears the local value for the property. - - - When overridden in a derived class, gets the property cast as a . - A that represents . - - - When overridden in a derived class, gets the currently computed value for this property. - An object representing the computed value for this property. - - - When overridden in a derived class, gets the default value for this property. - An object representing the default value for this property. If the property does not define a default value, this property returns null. - - - When overridden in a derived class, gets the property cast as a . - - cast as an . - - - Determines whether the specified object is equal to this object. - true if the properties are equal; otherwise, false. - An object to be tested for equality. - - - Gets the attributes of the requested type that are declared on this property and the property's property type. - A collection of attributes of the requested type that are declared on this property and the property's property type. - An identifier for the requested type. - - - Gets the attributes of the requested type that are declared on this property and the property's property type. - A collection of attributes of the requested type that are declared on this property and the property's property type. - The requested type. - - - - When overridden in a derived class, gets a value indicating whether the property represents an attached property from a different type. - true if the property represents an attached property from a different type; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the property can be shown in a property window. - true if the property can be shown in a property window; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the value contained in the property is an ItemCollection. - true if the property value is an ItemCollection; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the value contained in the property is an ItemDictionary. - true if the property value is an ItemDictionary; otherwise, false. - - - Gets a value that indicates whether this property is of the specified type or implements the specified interface. - true if this property is of the specified type or implements the specified interface; otherwise, false. - An identifier for the type or interface to test. - - - Gets a value that indicates whether this property is of the specified type or implements the specified interface. - true if this property is of the specified type or implements the specified interface; otherwise, false. - The type or interface to test. - - - When overridden in a derived class, gets a value indicating whether the property is read-only. - true if the property is read only; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the property's value is set locally. - true if the property鈥檚 value is set locally; otherwise, false. - - - When overridden in a derived class, gets the name of this property. - A string representing the name of this property. - - - Determines whether two specified objects are equal. - true if the properties are equal; otherwise, false. - A to compare. - A to compare. - - - Determines whether two specified objects are not equal. - true if the properties are not equal; otherwise, false. - A to compare. - A to compare. - - - When overridden in a derived class, gets the parent of this property. - A instance representing the parent of this property. - - - When overridden in a derived class, gets the data type of the property. - A representing the type of this property. - - - When overridden in a derived class, sets a local value on a property. - If the value is already a , the input value is returned. If the value is not a , a newly created wrapping the value is returned. - An object representing the value to be set. - - - When overridden in a derived class, gets the value of this property. - A instance representing the value of this property. - - - Represents a collection of properties. - - - Initializes a new instance of the class. - - - Represents a collection of property identifiers. - - - Initializes a new instance of the class. - - - Adds a new property identifier. - An identifier for the owning type of the property to be added. - The name of the property to be added to the collection. - - - Adds a new property identifier. - The owning type of the property to be added. - The name of the property to be added. - - - Inserts a new property identifier in the collection. - The index at which will be inserted. - The property identifier to insert. - - is null. - - already exists in the collection. - - - Sets the property identifier at the specified index. - The index that will be set to . - The property identifier to set. - - is null. - - already exists in the collection. - - - Provides data for the event. - - - Initializes a new instance of the class. - The associated with the invalidated property. - The of the property that was invalidated. - - or is null. - - - Gets the of the property that was invalidated. - The of the property that was invalidated. - - - Gets the associated with the invalidated property. - The associated with the invalidated property. - - - A policy that specifies a set of rules in the designer. - - - Initializes a new instance of the class. - - - Gets the editing context for the designer. - The for the designer. - The policy has not been activated. - - - Returns an optional set of surrogate items for this item. - An enumeration of surrogate items to check. The default returns an empty enumeration. - The item to retrieve the surrogate for. - - - Gets a value indicating whether the policy is a surrogate policy. - true if the policy is a surrogate policy; otherwise, false. - - - Called when a policy is activated. - - - Called when the policy is deactivated. - - - Raises the event. - A that contains the event data. - - - Gets an enumeration of all items in the policy. - An containing the set of items in the policy. - - - Occurs when the policy changes. - - - Provides data for the event. - - - Initializes a new instance of the class. - The newly added policy. - - - Gets the policy that was newly added. - The newly added . - - - Creates feature providers based on item policies. - The type of feature provider. - - - Initializes a new instance of the class. - The feature manager that manages this connector. - - is null. - - - Releases the unmanaged resources used by the and optionally releases the managed resources. - true to release both managed and unmanaged resources; false to release only unmanaged resources. - - - Gets an enumeration of all current feature providers. - An enumeration of all current feature providers. - - - Called by the policy feature connector when a policy changes and feature providers are added to the set of active feature providers. - The that offers the feature providers. - An enumeration of feature providers that have been added. - - - Called by the policy feature connector when a policy changes and feature providers are removed from the set of active feature providers. - The that offers the feature providers. - An enumeration of feature providers that have been removed. - - - Tests if a feature provider is valid for invocation. - true if is valid for invocation; otherwise, false. - The feature provider to test for validity. - - - Refreshes the feature providers based on the . - - - Identifies the feature providers that belong to a instance. - - - Gets the type of the feature provider. - The of the feature provider. - - - Gets the associated with the feature provider. - The associated with the feature provider - - - Provides data for the event. - - - Initializes a new instance of the class. - The policy that has changed. - The items that have been added to the policy since the last change event. - The items that have been removed from the policy since the last change event. - - is null. - - - Gets the items that have been added to the policy since the last change event. - An enumeration of objects that were added during the policy change. - - - Gets the items that have been removed from the policy since the last change event. - An enumeration of objects that were removed during the policy change. - - - Gets the policy that changed. - An object representing the policy that changed. - - - A policy that specifies the primarily selected element. - - - Initializes a new instance of the class. - - - Returns the policy item that represents the primary selection. - Either a single element that is the primary selection, or an empty enumeration. - The current selection. - - - A policy that specifies all items in the selection that are not the primary selection. - - - Initializes a new instance of the class. - - - Gets a value indicating whether the specified item is in the selection and is not the primary selection. - true if is not the primary selection; otherwise, false. - Selection state. - Item to be evaluated. - - - A policy that specifies the set of unique parents for the current set of selected items. - - - Initializes a new instance of the class. - - - Overrides the default method to return the unique parents of the specified selection. - An enumeration of unique parents for the given selection. - The current selection. - - - Evaluates whether the specified parent item is to be included in the policy. - true if is to be included in the policy; otherwise, false. - Selection state. - Item to be evaluated. - Parent of item to be evaluated. - - - A policy that makes all items in the selection available. - - - Initializes a new instance of the class. - - - Returns the policy items from the specified selection. - An enumeration of objects to use for this policy. - The current selection. - - - Gets a value indicating whether the specified item is to be included in the policy. - true if item is to be included in the policy; otherwise, false. - A to filter with policy logic. - Item to be evaluated. - - - Called when this policy is activated. - - - Called when this policy is deactivated. - - - Gets an enumeration of items that are affected by this policy. - An enumeration of objects that are affected by this policy. - - - Restricts a feature provider to a specified policy. - - - Initializes a new instance of the class. - The type of policy this extension can be associated with. - - is null. - - - Overrides the property to return false. - Always false. - - - Returns a object that can be used to be notified when this policy is available. - A new object. - The editing context to check. - - is null. - - - Determines whether the specified object is equal to this . - true if the specified object and this are equal; otherwise, false. - The object to test. - - - Returns the hash code for this attribute. - A hash code for this attribute. - - - Gets the type of policy the feature provider can be associated with. - A that represents the policy associated with the feature provider. - - - Returns a value indicating whether the specified editing context contains the associated with this attribute instance. - true if this requirement is met; otherwise, false. - The editing context to check. - - - Gets the type ID for this attribute. - - - Indicates that a non-content property should be displayed in the object tree. - - - Initializes a new instance of the class. - - - An abstract class for creating custom category editors. - - - Initializes a new instance of the class. - - - When overridden in a derived class, called once for each property in the category to determine which properties are edited by this . - true if this editor edits that property; otherwise, false. - The to check to see if it is edited by this . - - - Utility method that creates a new for the specified . - New for the specified . - - instance for which to create the new . - - - Utility method that creates a new for the specified type. - New for the specified type. - - type for which to create the new . - - - When overridden in a derived class, gets a that acts as the UI for a . - The object that represents the editor template. - - - When overridden in a derived class, returns an object that the host can place into a in order to display it. - An object that contain an icon for the category editor. - The desired size of the image to return. This method should make the best attempt in matching the requested size, but it does not guarantee it. - - - When overridden in a derived class, gets a localized string that indicates which category this editor belongs to. - A string representing the category that this editor belongs to. - - - Represents a category of properties. - - - Initializes a new instance of the class. - The localized name of the category as defined by the attribute. - - is empty or null. - - - Determines if the matches a filter and stores the information. - The filter to compare to. - - - Gets the name of the category. - The name of the category. - - - Represents the method that handles the event of the . - - - When overridden in a derived class, gets the specified property. - The property specified by . - The name of the property to return. - - - Gets or sets a value indicating whether this matches a filter. - true if the matches the filter; otherwise, false. - - - When overridden in a derived class, indicates whether a matches a predicate. - true if the matches the predicate; otherwise, false. - The predicate to compare to. - - - Raises the event. - The filter that is being applied. - - - Raises the event. - The name of the property that is changing. - - is null. - - - When overridden in a derived class, gets all the properties in the category. - An enumerable collection of all the properties in the category. - - - Represents the method that handles the event of the . - - - Represents the source of a dependency property value. - - - Gets a object that represents an ambient property. - A object that represents an ambient property. - - - Gets a object that represents a bound property. - A object that represents a bound property. - - - Gets a object that represents a property set to a custom markup extension. - A that represents a property set to a custom markup extension. - - - Gets a object that represents a data-bound property. - A that represents a data-bound property. - - - Gets a object that represents a property set to its default value. - A tha represents a property set to its default value. - - - Gets a object that represents a property set to a dynamic resource. - A object that represents a property set to a dynamic resource. - - - Gets a object that represents an inherited property. - A that represents an inherited property. - - - Gets a object that represents a property whose value was inherited. - A object that represents a property whose value was inherited. - - - Gets a value that indicates whether this represents an ambient property. - true if this object represents an ambient property; otherwise, false. - - - Gets a value that indicates whether this represents a bound property. - true if this object represents a bound property; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a custom markup extension. - true if this object represents a property set to a custom markup extension; otherwise, false. - - - Gets a value that indicates whether this represents a data-bound property. - true if this object represents a data-bound property; otherwise, false. - - - Gets a value that indicates whether this represents a property set to its default value. - true if this objects represents a property set to its default value; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a dynamic resource. - true if this object represents a property set to a dynamic resource; otherwise, false. - - - Gets a value that indicates whether this represents a property set to an expression. - true if this object represents a property set to an expression; otherwise, false. - - - Gets a value that indicates whether this represents an inherited property. - true if this object represent an inherited property; otherwise, false. - - - Gets a value that indicates whether this represents a property whose value was inherited. - true if this object represents a property whose value was inherited; otherwise, false. - - - Gets a value that indicates whether this represents a local property. - true if this object represents a local property; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a local resource. - true if this object represents a property set to a or a ; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a local value. - true if this object represents a property set to a local value; otherwise, false. - - - Gets a value indicating whether this represents a property set to a markup extension. - true if this object represents a property set to a markup extension; otherwise, false. - - - Gets a value that indicates whether this represents a property set to x:Null. - true if this object represents a property set to x:Null; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a resource. - true if this object represents a property set to a , , or a ; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a static value. - true if this object represents a property set to a static value; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a static resource. - true if this object represents a property set to a static resource; otherwise, false. - - - Gets a value that indicates whether this represents a property set to a system resource. - true if this object represents a property set to a ; otherwise, false. - - - Gets a value that indicates whether this represents a template-bound property. - true if this object represents a template-bound property; otherwise, false. - - - Gets a object that represents a local property. - A that represents a local property. - - - Gets a object that represents a property set to a local dynamic resource. - A that represents a property set to a local dynamic resource. - - - Gets a object that represents a property set to a local static resource. - A that represents a property set to a local static resource. - - - Gets a object that represents a property set to a local value. - A object that represents a property set to a local value. - - - Gets a object that represents a property set to x:Null. - a object that represents a property set to x:Null. - - - Gets a object that represents a property set to a static value. - A object that represents a property set to a static value. - - - Gets a object that represents a property set to a static resource. - A object that represents a property set to a static resource. - - - Gets a object that represents a property set to a system resource. - A that represents a property set to a system resource. - - - Gets a object that represents a template-bound property. - A that represents a template-bound property. - - - Container for all dialog box-editing logic for objects. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class. - A that is hosted in a host-specific dialog box and has its set to the that corresponds to the property being edited. - A that is used for the inline editor. If used, its will be set to the that corresponds to the property being edited. - - - Gets or sets the that is hosted by a host-specific dialog box and has its set to a . - The object that is the template for this value editor. - - - Called when the is null and a dialog box has been invoked by the user. - The for the property being edited - The that can be used as a source for execution of . - - - A convenience button that allows the user to switch between the different modes. - - - Initializes a new instance of the class. - - - Creates and returns an for use by the automation infrastructure. - An for this object. - - - Raises the event. - A that contains the event data. - - - Called when any dependency properties of this control was changed. - A that contains the event data. - - - Gets or sets a value that indicates whether to sync to the owning container. This is a dependency property. - true if the is calculated automatically to match the property of the owning . false if the mode to switch to is based on the property. The default is true. - - - Identifies the dependency property. - The identifier for the dependency property. - - - Gets or sets the mode to switch to when this control is clicked. This is a dependency property. - A object. - - - Identifies the dependency property. - The identifier for the dependency property. - - - Container for any and all extended editor logic for properties. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with the specified extended and inline editor objects. - The used for the extended popup/pinned editor that is viewed within the Properties window. When used, its property will be set to a . - The used for the inline editor. When used, its property will be set to a . - - - Get or sets the used for the extended popup/pinned editor. - A that defines the editor. - - - Defines an indexing operator on an attribute. - - - Gets the attribute with the specified key. - The that corresponds with . - The key to get the corresponding for. - - - Handles sorting and filtering functionality. - - - Determines if the matches a filter and stores the information. - The filter to compare to. - - - Occurs when a is changed through a call to the method. - - - Gets a value indicating whether this matches a filter. - true if the matches the filter; otherwise, false. - - - Indicates whether an matches a predicate. - true if the matches the predicate; otherwise, false. - The predicate to compare to. - - - Maps a string key to an instance. - The type of attribute. - - - Initializes a new instance of the class. - A unique string to associate with . - The to associate with . - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Returns the hash code for the current . - The hash code for the current . - - - Gets the key for the current . - The key for the current . - - - Determines whether the specified instances are considered equal. - true if is equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Determines whether the specified instances are considered not equal. - true if is not equal to ; otherwise, false. - The first to compare. - The second to compare. - - - Gets the for the current . - The for the current . - - - Represents a factory for creating new items for a collection or for a property value. - - - Initializes a new instance of the class. - - - Creates an instance of the specified that can be added to the collection editor or sub-property editor. - If a constructor is found for , returns an instance of ; otherwise, null. - The type of the object to create. - - is null. - - - Gets a display name for the specified that can be added to the collection editor or sub-property editor. - The name to display for . - The type for which to get a display name. - - is null. - - - Gets an image for the specified that can be used as an icon in the collection editor or sub-property editor. - A that represents an image to display for . - The type to get an image for. - The requested size of the image. - The name of the image that was found. - - is null. - - - Used to specify which object types can be assigned as the value of a property or as the value of a property type. - - - Initializes a new instance of the class. - A object that this attribute declares as being a valid new item type. - - is null. - - - Initializes a new instance of the class. - An array of objects that this attribute declares as being valid new item types. - - is null or empty. - - - Gets or sets the factory type associated with this attribute. - A object that represents the type associated with this attribute. - type does not derive from . - type is null. - - - Gets the type ID for this attribute. - An object representing the type ID. - - - Gets a list of objects that this attribute declares as being valid new item types. - An enumeration of the types that this attribute guarantees to be valid new item types. - - - Stores formatting information that is used for editing a number value. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with the specified array of instances. - An array of instances. - - - Initializes a new instance of the class with the specified format string, precision, and scale. - A number format string. - An integer that represents the maximum number of decimal places handled by the number editor. - A scale factor that is applied to the displayed value of the number. - - - Initializes a new instance of the class with the specified format string, precision, scale, and instances. - A number format string. - An integer that represents the maximum number of decimal places handled by the number editor. - A scale factor that is applied to the displayed value of the number. - An array of instances. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Gets the number format string for the current . - The number format string for the current . - - - Returns the hash code for the current . - The hash code for the current . - - - Gets the with the specified key. - The that corresponds with . - The key to get the corresponding for. - - - Gets the maximum number of decimal places handled by the number editor. - An integer that represents the maximum number of decimal places handled by the number editor. - - - Gets the scale factor that is applied to the displayed value of the number. - A scale factor that is applied to the displayed value of the number. - - - Contains information about the increments that are used to change a number value. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with the specified instances. - An array of instances. - - - Initializes a new instance of the class with the specified increment values. - The value for a small increment. - The value for the default increment. - The value for a large increment. - - - Initializes a new instance of the class with the specified parameters. - The value for a small increment. - The value for the default increment. - The value for a large increment. - An array of instances. - - - Gets the value for the default increment. - A double that represents the default increment. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Returns the hash code for the current . - The hash code for the current . - - - Gets the with the specified key. - The that corresponds with . - The key to get the corresponding for. - - - Gets the value for a large increment. - A double that represents a large increment. - - - Gets the value for a small increment. - A double that represents a small increment. - - - Defines a range on number-based attributes - - - Initializes a new instance of the class. - - - Initializes a new instance of the class with the specified instances. - An array of instances. - - - Initializes a new instance of the class with the specified hard and soft limit values. - The minimum value of the range, or null to use the default. - The soft minimum value of the range, or null to use the default. - The soft maximum value of the range, or null to use the default. - The maximum value of the range, or null to use the default. - true if the range can be set automatically; otherwise, false. - - - Initializes a new instance of the class. - The minimum value of the range, or null to use the default. - The soft minimum value of the range, or null to use the default. - The soft maximum value of the range, or null to use the default. - The maximum value of the range, or null to use the default. - true if the range can be set automatically; otherwise, false. - An array of instances. - - - Gets a value that indicates whether the range can be set automatically. - true if the range can be set automatically; otherwise, false. - - - Determines whether the specified is equal to the current . - true if the specified is equal to the current ; otherwise, false. - The to compare with the current . - - - Returns the hash code for the current . - The hash code for the current . - - - Get the hard limit on the maximum value. - A double that represents the hard limit on the maximum value, or null to use the default value. - - - Get the hard limit on the minimum value. - A double that represents the hard limit on the minimum value, or null to use the default value. - - - Gets the with the specified key. - The that corresponds with . - The key to get the corresponding for. - - - Get the soft limit on the maximum value. - A double that represents the soft limit on the maximum value, or null to use the default value. - - - Get the soft limit on the minimum value. - A double that represents the soft limit on the minimum value, or null to use the default value. - - - Used as a graphical container for instances. - - - Initializes a new instance of the class. - - - Gets or sets the currently displayed edit mode for this container. - A for this container. - - - Occurs when the active edit mode of this container is changed. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets or sets the default . - A that represents the default property value editor. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets or sets the default standard values editor. - A that represents the default standard values editor. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets or sets the to pass to the method as the command source. - An to pass to the method as the command source. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets the most appropriate for the current . - A that represents the most appropriate for the current . - - - Gets the most appropriate for the current . - A that represents the most appropriate for the current . - - - Gets or sets the for this . - A that represents the for this . - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets or sets the for this . - A that represents the for this . - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets the value of the 聽attached property for a specified dependency object. - The owning . - The to get the property from. - - - Gets the most appropriate for the current . - A that represents the most appropriate for the current . - - - Gets or sets the for the . - A that represents the for the . - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Gets the value for stored in the contained . - The value for stored in the contained . - - - Raises the event. - Name of the property. - - - Raises the event. - A that contains the event data. - - - Gets the command that is raised when the property is changed to . - A that is raised when the property is changed to . - - - Gets or sets the owning that can be used by UI elements of types to gain access to their parent . - A that represents the owning . - - - Identifies the 聽attached property. - The identifier for the 聽attached property. - - - Occurs when a property is changed. - - - Gets or sets the instance on which this operates. - A instance on which this operates. - - - Occurs when the property is changed. - - - Identifies the 聽dependency property. - The identifier for the 聽dependency property. - - - Sets the value of the 聽attached property for a specified dependency object. - The to set the property on. - The owning . - - - Defines the different edit modes for a . - - - Inline editor. - - - Extended editor that is displayed over the Properties window. - - - Extended editor that is pinned into place within the Properties window. - - - Dialog box editor. - - - Represents a property. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class that acts as a sub-property of the specified . - The parent . Root properties do not have a parent . - - - Determines if the matches a filter and stores the information. - The filter to compare to. - - - When overridden in a derived class, gets the name of the category that this property resides in. - The name of the category that this property resides in. - - - When overridden in a derived class, gets the current instance. - The current instance. - - - When overridden in a derived class, used by the host infrastructure to create a new host-specific instance. - A new instance. - - - When overridden in a derived class, gets the description of the encapsulated property. - The description of the encapsulated property. - - - Gets the display name for the property. - The display name for the property. - - - Occurs when a is changed through a call to the method. - - - Gets a value indicating whether there are standard values for this property. - true if there are standard values for this property; otherwise, false. - - - When overridden in a derived class, gets an identifier that uniquely identifies this property type and name on the current platform. - An identifier that uniquely identifies this property type and name on the current platform. - - - When overridden in a derived class, gets a value indicating whether the encapsulated property is an advanced property. - true if the encapsulated property is an advanced property; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the encapsulated property is read-only. - true if the encapsulated property is read-only; otherwise, false. - - - Gets or sets a value indicating whether this matches a filter. - true if the matches the filter; otherwise, false. - - - Indicates whether a matches a predicate. - true if the matches the predicate; otherwise, false. - The predicate to compare to. - - - When overridden in a derived class, gets the collection of model properties for this . - The collection of model properties for this . - - - Raises the event. - The filter that is being applied. - - - Raises the event. - A that contains the event data. - - - Raises the event. - The name of the property is changing. - - is null. - - - Gets the parent . - The parent . - - - Occurs when a property value changes. - - - When overridden in a derived class, gets the name of the encapsulated property. - The name of the encapsulated property. - - - When overridden in a derived class, gets the type of the encapsulated property. - The type of the encapsulated property. - - - Gets the (data model) for this . - The for this . - - - When overridden in a derived class, gets the that will be used to edit this . - The that will be used to edit this . - - - When overridden in a derived class, gets the standard values that the encapsulated property supports. - A of standard values that the encapsulated property supports. - - - Represents a collection of instances for sub-properties of a given . - - - Initializes a new instance of the class. - The parent . - - is null. - - - When overridden in a derived class, gets the number of instances in this collection. - The number of instances in this collection. - - - When overridden in a derived class, returns an of all the instances in this collection. - An object that can be used to iterate through the collection. - - - When overridden in a derived class, gets a from this collection of the specified name. - A instance of the specified name or null if it does not exist. - The name of the property. - - - Gets the parent . - A that represents the parent. - - - For a description of this member, see . - An object that can be used to iterate through the collection. - - - Used as part of the searching and filtering functionality that may be provided by the property editing host. - - - Initializes a new instance of the class. - An collection of predicates. - - - Initializes a new instance of the class. - String representation of predicates. The predicates are space delimited. - - - Gets a value indicating whether has any predicates. - true if this does not have any predicates; otherwise, false. - - - Compares this filter with a particular filter target. - true if there are no predicates or if one or more predicates match the filter target; otherwise, false. - Target to compare with. - - is null. - - - Provides data for the event. - - - Initializes a new instance of the class. - The that was applied. - - - Gets the that was applied. - A that was applied. - - - Represents a predicate for search and filtering. - - - Initializes a new instance of the class. - The predicate string. - - is null. - - - Returns a value indicating whether a case insensitive match of the predicate string is contained within the target string. - true if a case insensitive match of the predicate string is contained within the target string; otherwise, false. - The target string to compare with the predicate string. - - - Gets an upper-case version of the predicate string. - An upper-case version of the predicate string. - - - A control that appears with a property value in the property window and can contain information about the property value. - - - Initializes a new instance of the class. - - - Used to set the order in which properties appear in a category, or in a list of sub-properties. - - - Creates a object that is added after the specified token. - A new object. - The reference token. - - is null. - - - Creates a object that is added before the specified token. - A new object. - The reference token. - - is null. - - - Gets the system-defined default order position. - A instance that represents the default order position. - - - Gets the system-defined early order position. - A instance that represents the system-defined early order position. - - - Gets the system-defined late order position. - A instance that represents the system-defined late order position. - - - This attribute is attached to a property to specify the sort order of a property in a property browser. - - - Initializes a new instance of the class. - The to assign the property. - - is null. - - - Gets the associated . - The priority in which to display the property in the property browser. - - - Represents the value of a property. - - - Initializes a new instance of the class. - The property entry that is the parent of this property value. - - is null. - - - When overridden in a derived class, gets a value indicating whether can be converted from a string. - true if can be converted from a string; otherwise, false. - - - Gets a value indicating how to handle exceptions that occur during the get and set methods of the and properties. - true if the exception should be caught; false if the exception should be propagated to the caller. - - - When overridden in a derived class, clears the value so that it is not set. - - - When overridden in a derived class, gets a of objects that represents the value of the . - A collection of objects that represents the value of the . - - - When overridden in a derived class, attempts to convert the specified to an . - An object that represents . - The string to convert. - - - When overridden in a derived class, attempts to convert the specified to a . - A string that represents . - The object to convert. - - - When overridden in a derived class, returns the that should be returned by the property. - The object that should be returned by the property. - - - When overridden in a derived class, gets a value indicating whether this property value supports sub-properties. - true if the supports sub-properties; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether this is a collection. - true if is a collection; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether the current is the default value for the property. - true if is the default value for the property; otherwise, false. - - - When overridden in a derived class, gets a value indicating whether this property value represents a property for multiple objects that have more than one value. - true if this value represents a property for multiple objects that have more than one value; otherwise, false. - - - Raises the event. - - - Raises the event. - - - Raises the event with the specified . - The data for the event. - - - Raises the event with the specified string. - The name of the property that is changing. - - - Raises the event. - The data for the event. - - is null. - - - Gets the parent of this . - The parent of this . - - - Represents the method that handles the event of the . - - - Represents the method that handles the event of the . - - - Represents the method that handles the event of the . - - - When overridden in a derived class, sets the property to the specified . - The object to set as the value of the property. - - - When overridden in a derived class, gets a that contains information about the source of this property value. - Information about the source of this property value. - - - Gets or sets the value of this as a . - A string that contains the value of this . - - - When overridden in a derived class, gets the sub-properties of this property value. - A collection of sub-properties. - - - Represents the method that handles the event of the . - - - When overridden in a derived class, checks that the specified contains a valid value before setting the property to it. - The object to check for a valid value. - - - Gets or sets the value of this . - An object that contains the value of this . - - - Represents a collection of instances. - - - Initializes a new instance of the class. - The parent . This will be the property whose type is a collection. - - is null. - - - When overridden in a derived class, adds the specified object into the collection. - The for the added object. - The object to add to the collection - - - Occurs when the changes. - - - When overridden in a derived class, gets the number of items in the collection. - The number of items in the collection. - - - When overridden in a derived class, returns a strongly typed for the collection of objects. - An enumeration of objects. - - - When overridden in a derived class, inserts the specified object into the collection at the specified index. - A for the inserted object. - The object to insert into the collection. - The index of where to insert the object. - - - When overridden in a derived class, gets the at the specified index. - The at the specified index. - The index of a in the collection. - - - Raises the event. - A that contains the event data. - - - Gets the parent . - A that represents the parent. - - - When overridden in a derived class, removes the specified from the collection. - true if the was removed successfully; otherwise, false. - The to remove from the collection. - - - When overridden in a derived class, removes the from the collection at the specified index. - The index of the to remove. - - - When overridden in a derived class, swaps the order of objects in the collection. - The index of the first object. - The index of the second object. - - - For a description of this member, see . - An enumeration of objects. - - - Container for any and all inline editor logic for properties. - - - Initializes a new instance of the class. - - - Initializes a new instance of the class. - The that is used for an inline editor. This has its set to a . - - - Utility method that creates a new for the specified type. - A new for the specified type. - - instance for which to create the new . - - - Utility method that creates a new for the specified type. - A new for the specified type. - - type for which to create the new . - - - Gets or sets the that is used for an inline editor. - A that defines the inline editor. - - - Provides standard commands that control the behavior of a property window when the user edits properties. - - - Gets a that represents a request to cancel a transaction associated with a property edit. - A request to cancel a transaction associated with a property edit. - - - Gets a that represents a request to begin a new transaction associated with a property edit. - A request to begin a new transaction associated with a property edit. - - - Gets a that represents a request to commit a transaction associated with a property edit. - A request to commit a transaction associated with a property edit. - - - Gets a that represents a notification to the host that a property edit has been completed. - A notification to the host that a property edit has been completed. - - - Gets a that represents a request to display a context menu in the . - A request to display a context menu in the . - - - Gets a that represents a request to display a dialog box editor for a property. - A request to display a dialog box editor for a property. - - - Gets a that represents a request to show a validation error message. - A request to show a validation error message. - - - Gets a that represents a request to display a pinned editor for a property. - A request to display a pinned editor for a property. - - - Gets a that represents a request to display an extended editor for a property. - A request to display an extended editor for a property. - - - Gets a that represents a request to display an inline editor for a property. - A request to display an inline editor for a property. - - - Provides data for the event. - - - Initializes a new instance of the class. - A message that indicates what failed. - The for which the exception occurred. - The source that generated this exception (get or set). - The inner exception. - - is null. - - - Gets the contained exception. - An that is the contained exception. - - - Gets the message that indicates what failed. - The message that indicates what failed. - - - Gets the for which the exception is occurring. - A for which the exception is occurring. - - - Gets the source that generated the exception. - A that generated the exception. - - - Indicates the source of the exception thrown by a instance. - - - Indicates that the exception occurred during a get operation. - - - Indicates that the exception occurred during a set operation. - - - Represents the source of a property value. - - - Initializes a new instance of the class. - - - Provides adapters for a specified item. - - - Initializes a new instance of the class. - - - Returns an adapter of the specified adapter type for the specified item. - An of type for . - The item to get the adapter for. - The type of adapter. - - - Returns an adapter of the specified adapter type for the specified item. - An of type for . - The type of adapter to return. - The item to get the adapter for. - - - Represents a binary stream of information, such as a bitmap. - - - When overridden in a derived class, initializes a new instance of the class. - - - When overridden in a derived class, occurs when the content of the stream changes. - - - Gets a local file path of the stream. - A that represents a local file path of the stream; or null if the stream cannot be referenced as a local file. - - - Gets a value that indicates whether opening this resource is a valid operation. - true if opening this resource is a valid operation; otherwise, false. - - - When overridden in a derived class, opens a stream on the resource. - A on the resource. - The to use when opening the resource. For example, or . - - - When overridden in a derived class, gets a value representing the URI of the resource. - The URI of the resource. - - - A service that locates items to display on a context menu. - - - Gets a list of menu items. - An enumeration of currently applicable menu items. - - - Defines methods to create, remove, display and query the contents of the event handling class for the current editing context. - - - When overridden in a derived class, initializes a new instance of the class. - - - When overridden in a derived class, requests that a specified method be declared as handling a specified event. - true if the method can be successfully declared in the code-behind file to handle the given event; otherwise, false. - The event to handle. - The method to declare. - - - When overridden in a derived class, determines whether a class name can be used in creating a unique method name in a language. - true if a class name can be used in creating a unique method name in a language; otherwise, false. - - - Appends the specified collection of objects to the specified event handler. - The event definition whose handler will have statements added. - The method name of the event handler. - The collection of objects to append. - - - When overridden in a derived class, creates a method that handles an event. - true if the method is successfully created; otherwise, false. - The event that handles. - The method to create. - - - When overridden in a derived class, returns a unique method name for an event handler. - A unique event handler name. For example, Button1_Click or Button1_Click_1. - The event for which to create a unique event handler name. - - - Occurs when a method is associated with a as a result of a call to the method. - - - When overridden in a derived class, returns the names of methods that are compatible with a specified event. - The names of methods that are compatible with . - The event that the methods are compatible with. - - - When overridden in a derived class, returns a list of methods that handle a specified event. - The list of methods that handle . - The event that is being handled. - - - When overridden in a derived class, determines whether a method name that handles a specified event already exists. - true if the method name that handles already exists; otherwise, false. - The event that handles. - The name of the method to check. - - - Raises the event. - The instance that was associated with . - The method handler that was associated with the . - - - When overridden in a derived class, requests that a specific method stop handling a specific event by removing it from a Handles clause. - true if the event can be successfully removed from the method declaration in the code-behind file; otherwise, false. - The event to stop from handling. - The method to stop handling . - - - Removes the event handlers for the specified element. - true if event handlers were removed; otherwise, false. - The element to remove event handlers from. - - - When overridden in a derived class, requests that a specific method stop handling a specific event by removing it from an event handling class. - true if is successfully removed from the event handling class; otherwise, false. - The event to stop handling. - The method to stop handling . - - - When overridden in a derived class, identifies the methods that the binding service is referring to as belonging to the specified class. - The name of the class that the methods belong to. - - - When overridden in a derived class, attempts to display the specified method to the user. - true if the method is successfully displayed to the user; otherwise, false. - The event that handles. - The method to display. - - - When overridden in a derived class, determines whether a method name is a valid method name and raises an exception if it is not. - The event that handles. - The name of the method to check. - - - Provides data for the event. - - - Initializes a new instance of the class. - The that received a new event handler. - The event handler associated with . - - - Gets the event handler that was associated with a . - A name of the event handler method. - - - Gets the that received a new event handler. - The that received a new event handler. - - - Defines methods for converting model items to markup text and for parsing markup text into model items. - - - Initializes a new instance of the class. - - - When overridden in a derived class, parses the specified markup text and returns a model item representing that text. - A model item representing the markup. - A correctly formed XML document. - Assembly names to use when parsing . - - - - Provides access to resources external to the markup file. - - - Initializes a new instance of the class. - - - When overridden in a derived class, gets the application model. - The application model or null if there is no application model for this context. - - - When overridden in a derived class, gets the specified URI in the project system and returns its contents as a binary blob. - The resource specified by . - The URI to get the resource for. - - is null. - - - When overridden in a derived class, gets the specified URI in the project system, loads it, and returns a representing the root. - The model resource specified by . - The URI to get the resource for. - - is null. - - - When overridden in a derived class, gets an enumeration of URI values that can be loaded as resources. - An enumeration of URI values. - - - When overridden in a derived class, translates a local URI back to its original URI. - The URI that corresponds with . - The URI to translate. - - is null. - - - Creates a method in the code behind for a user's XAML file and enables appending statements to the method. - - - Appends a collection of CodeDOM statements to the specified event handler. - The method definition that is searched to append statements to. - A list of CodeDOM statements to append to the end of the method. - The line number to insert the statements. - - - Creates a method with the specified signature. - true if the method was created; otherwise, false. - A that specifies the signature. - - - Provides data for the event. - - - Initializes a new instance of the class. - - - Gets an enumeration of objects that have been added to the editing model. - An enumeration of objects that have been added to the editing model. - - - Gets an enumeration of objects that have been removed from the editing model. - An enumeration of objects that have been removed from the editing model. - - - Gets an enumeration of properties that have been changed in the editing model. - An enumeration of objects that represent changed properties in the editing model. - - - Gets an enumeration of property names that have been changed in the editing model. - An enumeration of objects that represent the names of the changed properties. - - - Represents an external resource that contains a model item. - - - When overridden in a derived class, initializes a new instance of the class. - - - When overridden in a derived class, occurs when the model item changes. - - - When overridden in a derived class, gets a value representing the model item of the resource. - The model item of the external resource. - - - Provides the main entry point that the designer uses to obtain the editing model. - - - Initializes a new instance of the class. - - - Converts a created in another designer to a for this designer. - The converted item, associated with this designer. - The item to convert. - - - When overridden in a derived class, creates a model item that is a deep copy of the specified instance. - A new model item that is a clone of the existing item. - The item to wrap. - - is null. - - - When overridden in a derived class, creates a object for a specified type. - A newly created model item. - The type of item to create. - Creation options. You can specify if you want to initialize default values for an item. - An array of arguments to pass to the constructor of the item. - - is null. - - - When overridden in a derived class, creates a new model item that represents the value of a static member of the specified class. - A newly created model item that represents a static member of . - The type that contains the static member being referenced. - The name of the static member being referenced. - - - When overridden in a derived class, finds matching model items for a specified starting point. - An enumeration of model items matching the query. - The model item to start the search. Items above this item in the hierarchy will be ignored. This item, and any item below it in the hierarchy, are included in the search. If this parameter is null, the root is used. - An identifier for the type of object to find. - - - When overridden in a derived class, finds matching model items for a specified starting point. - An enumeration of model items matching the query. - The model item to start the search. Items above this item are ignored. This item, and any item below it in the hierarchy, are included in the search. If this parameter is null, the root is used. - A predicate that allows more complex type matching to be used. For example, the predicate could return true for both the and types. - - is null. - - - When overridden in a derived class, finds matching model items for a specified starting point. - An enumeration of model items matching the query. - The model item to start the search. Items above this item will be ignored. This item, and any item below it in the hierarchy, are included in the search. If this parameter is null, the root is used. - The type of the object to find. - - is null. - - - Finds the model item in the specified scope with the specified name. - A model item whose name matches , or null if no match was found. - An optional scope to search. - The name of the item to locate. - - - When overridden in a derived class, finds the model item in the specified scope with the specified name and comparison criteria. - A model item whose name matches , or null if no match was found. - An optional scope to search. - The name of the item to locate. - Specifies how the name is compared. The default is to compare with the property. - - - When overridden in a derived class, occurs when an item in the model has changed. - - - Resolves the specified to a . - The type that matches the specified identifier, or null if the identifier cannot be resolved. - The identifier to resolve. - - - When overridden in a derived class, gets the root of the object hierarchy. - The which represents the root of the editing model tree. - - - Provides a mechanism for capturing property changes that are made by the user in the designer and providing new values at design time. - - - When overridden in a derived class, initializes a new instance of the class. - - - When overridden in a derived class, returns an enumeration that contains the properties to translate for the specified type. - An enumeration that contains the properties to translate for a specified type, if any. - The type for which to get the properties to translate. - - - Determines whether the specified property should be translated for the specified type. - true if the specified property should be translated for the specified type; otherwise, false. - The type for which to determine whether should be translated. - An identifier for the property to be checked. - - - Raises the event to indicate that the specified property was invalidated. - The item that contains the invalidated property. - The invalidated property. - - - Occurs when a property needs to be invalidated because of a change in a dependent property. - - - Calls custom logic to translate the specified property for the specified type and instance, and specifies the value to translate. - The translated value. - The type for which the user sets the property value in the designer. - The item that contains the property to be translated. - The property to be translated. - The value set by the user in the designer. - - - Associates visuals and editing model items. - - - Initializes a new instance of the class. - - - When overridden in a derived class, gets the model corresponding to the specified view. - The model corresponding to the specified view, or null if no model is found. - The view to get the model for. - - is null. - - - When overridden in a derived class, occurs when the layout of the view has been changed. - - - \ No newline at end of file diff --git a/SCADA/Program/HMIControl/bin/Debug/MySql.Data.dll b/SCADA/Program/HMIControl/bin/Debug/MySql.Data.dll deleted file mode 100644 index 7eaba45..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/MySql.Data.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/zh-Hans/Microsoft.Windows.Design.Extensibility.resources.dll b/SCADA/Program/HMIControl/bin/Debug/zh-Hans/Microsoft.Windows.Design.Extensibility.resources.dll deleted file mode 100644 index c1b786e..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/zh-Hans/Microsoft.Windows.Design.Extensibility.resources.dll and /dev/null differ diff --git a/SCADA/Program/HMIControl/bin/Debug/zh-Hans/Microsoft.Windows.Design.Interaction.resources.dll b/SCADA/Program/HMIControl/bin/Debug/zh-Hans/Microsoft.Windows.Design.Interaction.resources.dll deleted file mode 100644 index a03f399..0000000 Binary files a/SCADA/Program/HMIControl/bin/Debug/zh-Hans/Microsoft.Windows.Design.Interaction.resources.dll and /dev/null differ diff --git a/SCADA/Program/SiemensPLCDriver/SiemensPLCDriver.csproj b/SCADA/Program/SiemensPLCDriver/SiemensPLCDriver.csproj index 59142e1..d191a1a 100644 --- a/SCADA/Program/SiemensPLCDriver/SiemensPLCDriver.csproj +++ b/SCADA/Program/SiemensPLCDriver/SiemensPLCDriver.csproj @@ -98,7 +98,7 @@ - .\libnodave.net.dll + ..\..\dll\libnodave.net.dll diff --git a/SCADA/Program/clear.bat b/SCADA/Program/clear.bat new file mode 100644 index 0000000..c756dde --- /dev/null +++ b/SCADA/Program/clear.bat @@ -0,0 +1,13 @@ +@echo off +set nowPath=%cd% +cd / +cd %nowPath% + +::delete specify file(*.pdb,*.vshost.*) +for /r %nowPath% %%i in (*.pdb,*.vshost.*) do (del %%i) + +::delete specify folder(obj,bin) +for /r %nowPath% %%i in (obj,bin) do (IF EXIST %%i RD /s /q %%i) + +echo OK +pause \ No newline at end of file diff --git a/SCADA/dll/SiemensPLCDriver.dll b/SCADA/dll/SiemensPLCDriver.dll index 456766b..709ceca 100644 Binary files a/SCADA/dll/SiemensPLCDriver.dll and b/SCADA/dll/SiemensPLCDriver.dll differ