[{"server":null,"owner":null,"id":"dbaf3c77-21b4-40dd-8cd6-9ffdce89b051","params":{"result":{"value":"","datetime":1577268552,"status":null,"version":0},"hash":{"value":"TpJRukouIaYXTTzRojbPbQ==","datetime":1577263265,"status":null,"version":0},"enabled":{"value":false,"datetime":1577266220,"status":null,"version":0},"error_text":{"value":null,"datetime":1577259570,"status":null,"version":0},"type":{"value":"EgsScenario","datetime":1577268501,"status":null,"version":0},"settings":{"value":"{\r\n  \"deviceUrl\": \"http://192.168.10.84:9000/onvif/device_service\",\r\n  \"initialTerminationTime\": \"PT10M\",\r\n  \"messageLimit\": 1024,\r\n  \"timeout\": \"PT10S\",\r\n  \"outputPath\": \"d:\\\\eily.acuario\\\\build\\\\1.xml\",\r\n  \"archive\": [\r\n    {\r\n      \"enabled\": true,\r\n      \"timeStart\": \"2019-12-13T19:00:00\",\r\n      \"timeStop\": \"2019-12-13T20:00:00\"\r\n    },\r\n    {\r\n      \"enabled\": true,\r\n      \"timeStart\": \"2019-12-13T20:00:00\",\r\n      \"timeStop\": \"2019-12-13T21:00:00\"\r\n    },\r\n    {\r\n      \"enabled\": true,\r\n      \"timeStart\": \"2019-12-13T21:00:00\",\r\n      \"timeStop\": \"2019-12-13T22:00:00\"\r\n    }\r\n  ],\r\n  \"runtime\": [\r\n    {\r\n      \"enabled\": true\r\n    },\r\n    {\r\n      \"enabled\": true\r\n    }\r\n  ]\r\n}","datetime":1577266054,"status":null,"version":0},"state":{"value":"ok.normal","datetime":1577259570,"status":null,"version":0},"script":{"value":"# имя: 'CCTMK Tester'\r\n# описание: тестирование протокола ССТМК\r\n# тип триггера: 'EgsScenario'\r\n# создан: 2018.01.19 16.53.25, Сельченков Н.Ю.\r\n# изменен: '2019.12.25 14.12.36', Сельченков Н.Ю.\r\n# подробности: https://redmine.integra-s.com:11000/projects/eilyacuario/wiki/CCTMK_Tester\r\n\r\nuse System.IO.StringReader\r\nuse System.IO.StringWriter\r\nuse System.IO.Stream\r\nuse System.IO.FileStream\r\nuse System.IO.FileMode\r\nuse System.Xml.Serialization.XmlSerializer\r\nuse System.Xml.XmlElement \r\nuse System.Xml.XmlDocument\r\nuse System.Xml.XmlConvert\r\nuse System.Uri\r\nuse System.Text.RegularExpressions.Regex\r\nuse System.Security.Cryptography.HashAlgorithm\r\nuse System.Text.Encoding\r\nuse System.Convert\r\nuse System.Threading.Tasks.Task\r\nuse System.Exception\r\nuse acuario2.webserver.soap12.UsernameToken\r\nuse acuario2.webserver.soap12.Security\r\nuse acuario2.webserver.soap12.ReplyTo\r\nuse acuario2.webserver.soap12.Header\r\nuse acuario2.webserver.soap12.Envelope\r\nuse acuario2.webserver.onvif.wsdl.GetSystemDateAndTimeRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.GetSystemDateAndTimeResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.GetDeviceInformationRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.GetDeviceInformationResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.GetScopesRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.GetScopesResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.GetServicesRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.GetServicesResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.CreatePullPointSubscriptionRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.CreatePullPointSubscriptionResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.PullMessagesRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.PullMessagesResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.Renew from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.RenewResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.SeekRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.SeekResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.SeekRequest from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.SeekResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.Unsubscribe from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.UnsubscribeResponse from acuario2.onvif\r\nuse acuario2.webserver.onvif.wsdl.NotificationMessageHolderType from acuario2.onvif\r\nuse acuario2.webserver.onvif.Message\r\nuse System.Collections.Generic.List(NotificationMessageHolderType) as MessageList\r\nuse System.Collections.Concurrent.ConcurrentBag(NotificationMessageHolderType) as MessageBag\r\nuse acuario2.utils.NameValueList(string) as NameValueList\r\n\r\nlet regexFind(text as string, pattern as string) = with Regex(pattern).Match(text) do if Success then Groups[1].Value\r\n\r\n### settings ###\r\n\r\nuse json_schema\r\n`\r\n{\r\n    \"type\": \"object\",\r\n    \"properties\":\r\n    {\r\n        \"deviceUrl\":              { \"type\": \"string\", \"default\": \"http://192.168.10.84:9000/onvif/device_service\" },\r\n        \"initialTerminationTime\": { \"type\": \"string\", \"default\": \"PT10M\" },\r\n        \"messageLimit\":           { \"type\": \"integer\",\"default\": 1024 },\r\n        \"timeout\":                { \"type\": \"string\", \"default\": \"PT10S\" },\r\n        \"outputPath\":             { \"type\": \"string\" },\r\n        \"runtime\":                \r\n        {\r\n            \"type\": \"array\",\r\n            \"items\":\r\n            {\r\n                \"type\": \"object\",\r\n                \"properties\":\r\n                {\r\n                    \"enabled\":   { \"type\": \"boolean\" }\r\n                }\r\n            }\r\n        },\r\n        \"archive\":\r\n        {\r\n            \"type\": \"array\",\r\n            \"items\":\r\n            {\r\n                \"type\": \"object\",\r\n                \"properties\":\r\n                {\r\n                    \"enabled\":   { \"type\": \"boolean\" },\r\n                    \"timeStart\": { \"type\": \"string\", \"format\": \"DateTime\" },\r\n                    \"timeStop\":  { \"type\": \"string\", \"format\": \"DateTime\" }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n` as SETTINGS\r\n\r\nuse json_schema\r\n`\r\n{\r\n    \"type\": \"object\",\r\n    \"properties\":\r\n    {\r\n        \"name\":            { \"type\": \"string\" },\r\n        \"manufacturer\":    { \"type\": \"string\" },\r\n        \"model\":           { \"type\": \"string\" },\r\n        \"firmwareVersion\": { \"type\": \"string\" },\r\n        \"serialNumber\":    { \"type\": \"string\" },\r\n        \"hardwareId\":      { \"type\": \"string\" },\r\n        \"eventsUrl\":       { \"type\": \"string\" },\r\n        \"beginsAt\":        { \"type\": \"string\", \"format\": \"DateTime\" },\r\n        \"endsAt\":          { \"type\": \"string\", \"format\": \"DateTime\" },\r\n        \"runtime\":\r\n        {\r\n            \"type\": \"array\",\r\n            \"items\":\r\n            {\r\n                \"type\": \"object\",\r\n                \"properties\":\r\n                {\r\n                    \"type\":   { \"type\": \"string\" },\r\n                    \"event\":  { \"type\": \"string\" },\r\n                    \"source\": { \"type\": \"object\", \"additionalProperties\": { \"type\": \"string\" } },\r\n                    \"key\":    { \"type\": \"object\", \"additionalProperties\": { \"type\": \"string\" } },\r\n                    \"data\":   { \"type\": \"object\", \"additionalProperties\": { \"type\": \"string\" } }\r\n                }\r\n            }\r\n        },\r\n        \"archive\":\r\n        {\r\n            \"type\": \"array\",\r\n            \"items\":\r\n            {\r\n                \"type\": \"object\",\r\n                \"properties\":\r\n                {\r\n                    \"timeStart\": { \"type\": \"string\", \"format\": \"DateTime\" },\r\n                    \"timeStop\":  { \"type\": \"string\", \"format\": \"DateTime\" },\r\n                    \"totalCount\":  { \"type\": \"integer\" },\r\n                    \"parsedCount\": { \"type\": \"integer\" },\r\n                    \"beginsAt\":    { \"type\": \"string\", \"format\": \"DateTime\" },\r\n                    \"endsAt\":      { \"type\": \"string\", \"format\": \"DateTime\" }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n` as RESULT\r\n\r\nconst RuntimeResult = typeof(RESULT().runtime[0])\r\nconst ArchiveResult = typeof(RESULT().archive[0])\r\n\r\nuse System.Collections.Generic.List(RuntimeResult) as RuntimeResultList\r\nuse System.Collections.Generic.List(ArchiveResult) as ArchiveResultList\r\n\r\nlet serializer = XmlSerializer(Message)\r\n \r\nlet parse(message as NotificationMessageHolderType) = \r\n    let topic  = message.Topic.Any[0].Value\r\n    let type   = regexFind(topic, \".+/(.+)/.+\")\r\n    let event  = regexFind(topic, \".+/.+/(.+)\")\r\n    let reader = StringReader(message.Message.OuterXml)\r\n    let msg    = serializer.Deserialize(reader) as Message\r\n    let source = NameValueList(from msg.Source bind Name to Value)\r\n    let key    = NameValueList(from msg.Key bind Name to Value)\r\n    let data   = NameValueList(from msg.Data bind Name to Value)\r\n    new { type, event, time = msg.UtcTime, source, key, data }\r\nend\r\n\r\nlet report(err as Exception) = \r\n    print err\r\n    this.error_text = string(err)\r\n    null\r\nend\r\n\r\nlet execute() = \r\n    print \"BEGIN\"\r\n    \r\n    let settings = SETTINGS(this.settings)\r\n    let uri      = Uri(settings.deviceUrl)\r\n    let result   = RESULT()\r\n    let messages = MessageBag()        \r\n    \r\n    print(\"CCTMK archive test\")\r\n    print(\"DeviceUrl:\", settings.deviceUrl)\r\n    print(\"initialTerminationTime:\", settings.initialTerminationTime)\r\n    print(\"messageLimit:\", settings.messageLimit)\r\n    print(\"timeout:\", settings.timeout)\r\n    print(\"outputPath:\", settings.outputPath)\r\n\r\n    result.beginsAt = DateTime.UtcNow\r\n\r\n    ### GetScopes ###\r\n        \r\n    let scopes = await Envelope(GetScopesRequest(), null, null).Post(GetScopesResponse, uri)\r\n       \r\n    from scopes.Scopes do \r\n        if ScopeItem.StartsWith(\"onvif://www.onvif.org/name/\") then \r\n            print(\"Name:\", result.name = Uri(ScopeItem).LocalPath.Substring(6))\r\n    now\r\n\r\n    ### GetDeviceInformation ###\r\n\r\n    let info = await Envelope(GetDeviceInformationRequest(), null, null).Post(GetDeviceInformationResponse, uri)\r\n\r\n    print(\"Manufacturer:\", result.manufacturer = info.Manufacturer)    \r\n    print(\"Model:\", result.model = info.Model)\r\n    print(\"FirmwareVersion:\", result.firmwareVersion = info.FirmwareVersion)\r\n    print(\"SerialNumber:\", result.serialNumber = info.SerialNumber)\r\n    print(\"HardwareId:\", result.hardwareId = info.HardwareId)\r\n\r\n    ### GetServices ###\r\n\r\n    let getServices               = GetServicesRequest() \r\n    getServices.IncludeCapability = false\r\n    let services                  = await Envelope(getServices, null, null).Post(GetServicesResponse, uri)\r\n    from services.Service do\r\n        let type = regexFind(Namespace, \"http://www.onvif.org/ver10/(.+)/wsdl\")\r\n        if type is \"events\" then \r\n            print(\"EventsUrl:\", result.eventsUrl = XAddr) \r\n    now\r\n\r\n    ### Test ###\r\n\r\n    uri = Uri(result.eventsUrl)\r\n\r\n    ### PullPoint ###\r\n\r\n    let subscribe() = \r\n        let header                     = Header()\r\n        let request                    = CreatePullPointSubscriptionRequest()\r\n        request.InitialTerminationTime = settings.initialTerminationTime\r\n        let envelope                   = Envelope(request, null, null)\r\n        let response                   = await envelope.Post(CreatePullPointSubscriptionResponse, uri)\r\n        header.To                      = response.SubscriptionReference.Address.Value\r\n        print(\"Subscription:\", header.To)\r\n        header\r\n    end\r\n\r\n    let unsubscribe(header as Header) = \r\n        let request     = Unsubscribe()\r\n        let envelope    = Envelope(request, null, null)\r\n        envelope.Header = header\r\n        await envelope.Post(UnsubscribeResponse, uri)\r\n    end\r\n\r\n    ### Runtime ###\r\n    \r\n    let header = subscribe()\r\n    \r\n    let test_runtime() = \r\n        let result = null as RuntimeResult\r\n        from 1 to int.MaxValue while result is null do\r\n            print(\"Generate runtime message now!\")\r\n            let request          = PullMessagesRequest()\r\n            request.MessageLimit = settings.messageLimit\r\n            request.Timeout      = settings.timeout\r\n            let envelope         = Envelope(request, null, null)\r\n            envelope.Header      = header\r\n            let response         = await envelope.Post(PullMessagesResponse, uri)\r\n            if response.NotificationMessage isnt empty then\r\n                let message   = from response.NotificationMessage first\r\n                let parsed    = parse(message)\r\n                result        = RuntimeResult(\"{}\")\r\n                result.type   = parsed.type\r\n                result.event  = parsed.event\r\n                result.source = parsed.source\r\n                result.key    = parsed.key\r\n                result.data   = parsed.data\r\n                messages.Add(message)\r\n            end    \r\n        now\r\n        result\r\n    end\r\n\r\n    result.runtime = from settings.runtime where enabled \r\n                     select try test_runtime() else report(last_error) as RuntimeResult \r\n                     to array\r\n                     \r\n    unsubscribe(header)\r\n    \r\n    ### Archive ###\r\n\r\n    let test_archive(timeStart as DateTime, timeStop as DateTime) =\r\n        print \"Testing archive...\"\r\n        print(\"TimeStart:\", timeStart)\r\n        print(\"TimeStop:\", timeStop)\r\n        \r\n        let header       = subscribe()        \r\n        let messages1    = MessageList() \r\n        let result       = ArchiveResult(\"{}\") \r\n        result.timeStart = timeStart\r\n        result.timeStop  = timeStop\r\n        result.beginsAt  = DateTime.UtcNow\r\n        \r\n        ### Seek ###\r\n\r\n        let request     = SeekRequest()\r\n        request.UtcTime = timeStart\r\n        request.Reverse = false\r\n        let envelope    = Envelope(request, null, null)\r\n        envelope.Header = header\r\n        await envelope.Post(SeekResponse, uri)\r\n\r\n        ### PullMessages ###\r\n\r\n        let timeCurr = timeStart \r\n        let timeLast = DateTime.MinValue \r\n        from 1 to int.MaxValue while timeCurr < timeStop do \r\n            let request          = PullMessagesRequest()\r\n            request.MessageLimit = settings.messageLimit\r\n            request.Timeout      = settings.timeout\r\n            let envelope         = Envelope(request, null, null)\r\n            envelope.Header      = header\r\n            let response         = await envelope.Post(PullMessagesResponse, uri)\r\n            if response.NotificationMessage isnt empty then\r\n                from response.NotificationMessage do \r\n                    timeLast = timeCurr = DateTime(it.Message.Attributes[\"UtcTime\"].Value).ToUniversalTime()\r\n                    if timeCurr < timeStop then messages1.Add(it)\r\n                now\r\n            else\r\n                timeCurr = timeStop \r\n            end    \r\n        now\r\n        \r\n        result.endsAt = DateTime.UtcNow\r\n        let parsed = from messages1 select try parse(it) where it isnt null to list\r\n        \r\n        print(\"ArchiveTimeSpent:\", result.endsAt - result.beginsAt)\r\n        print(\"ArchiveTotalCount:\", result.totalCount = messages1.Count)\r\n        print(\"ArchiveParsedCount:\", result.parsedCount = parsed.Count)\r\n        print(\"ArchiveLastTime:\", timeLast)\r\n\r\n        from messages1 do messages.Add(it) now\r\n        \r\n        unsubscribe(header)\r\n        \r\n        result\r\n    end\r\n    \r\n    let tasks = from settings.archive where enabled \r\n                select async try test_archive(timeStart, timeStop) else report(last_error) as ArchiveResult \r\n                to array\r\n    \r\n    Task.WaitAll(tasks)\r\n    \r\n    result.archive = from tasks select Result to array \r\n\r\n    ### Result ###\r\n\r\n    result.endsAt = DateTime.UtcNow\r\n    \r\n    print(\"TotalTimeSpent:\", result.endsAt - result.beginsAt)\r\n    \r\n    try with FileStream(settings.outputPath, FileMode.Create) as Stream do\r\n        XmlSerializer(NotificationMessageHolderType[]).Serialize(it, messages.ToArray())\r\n        Flush()\r\n        Close()\r\n    end\r\n    \r\n    print \"END\"\r\n    \r\n    string(result)\r\nend\r\n\r\nthis.result = \"\"\r\n\r\nasync try \r\n    this.result  = execute() \r\n    this.enabled = false\r\nelse \r\n    report(last_error)\r\n    this.enabled = false\r\n\r\neval this.result = \"\"\r\n    ","datetime":1577268756,"status":null,"version":0},"name":{"value":"CCTMK Tester","datetime":1577265027,"status":null,"version":0}},"entity":"item","operation":"create"}]