[{"server":null,"owner":null,"id":"b0c8e7ea-93c8-411c-9001-25a569bd4fb5","params":{"result":{"value":null,"datetime":1574514820,"status":null,"version":0},"hash":{"value":"uQfvbHL1/ZNpl5frhDJdxg==","datetime":1574685137,"status":null,"version":0},"enabled":{"value":true,"datetime":1574516332,"status":null,"version":0},"error_text":{"value":null,"datetime":1574673059,"status":null,"version":0},"type":{"value":"EgsScenario","datetime":1574684864,"status":null,"version":0},"settings":{"value":"{\r\n  \"source\": [\r\n    \"fd43b38c-571e-42ad-97cf-d5fca3618aaf\"\r\n  ],\r\n  \"condition\": \"alarm_*\",\r\n  \"target\": [\r\n    \"2c5a5d58-5d04-4325-81c6-830a0661bb41\",\r\n    \"VideoCamera\"\r\n  ],\r\n  \"action\": \"activate\",\r\n  \"schedule\": [\r\n    {\r\n      \"unit\": \"Minute\",\r\n      \"count\": 1,\r\n      \"time\": \"00:00:05\"\r\n    }\r\n  ]\r\n}","datetime":1574673148,"status":null,"version":0},"state":{"value":"ok.normal","datetime":1574673059,"status":null,"version":0},"script":{"value":"# имя: 'Conditional Reflex'\r\n# описание: условный рефлекс\r\n# тип триггера: 'EgsScenario'\r\n# создан: 2017.10.23 14:22:07, Сельченков Н.Ю.\r\n# изменен: '2019.11.25 16.32.16', Сельченков Н.Ю.\r\n# подробности: https://redmine.integra-s.com:11000/projects/eilyacuario/wiki/Conditional_Reflex\r\n\r\nuse System.Random\r\nuse System.Linq.Expressions.Expression\r\nuse acuario2.dynamic.DynamicExpression\r\nuse acuario2.utils.ReflectionExtension\r\nuse System.Collections.Generic.List(Object) as ObjectList\r\nuse System.Collections.Generic.List(Type) as TypeList\r\nuse System.Collections.Generic.List(string) as StringList\r\n\r\nuse json_schema\r\n`\r\n{\r\n    \"type\": \"object\",\r\n    \"properties\":\r\n    {\r\n        \"source\":    { \"type\": \"array\", \"items\": { \"type\": \"string\" } },\r\n        \"condition\": { \"type\": \"string\" },\r\n        \"schedule\":  \r\n        {\r\n            \"type\": \"array\",\r\n            \"items\":\r\n            {\r\n                \"type\": \"object\",\r\n                \"properties\":\r\n                {\r\n                    \"unit\":  { \"type\": \"string\", \"format\": \"ScheduleUnit\", \"default\": \"Day\" },\r\n                    \"count\": { \"type\": \"integer\", \"minimum\": 1, \"default\": 1 },\r\n                    \"time\":  { \"type\": \"string\", \"format\": \"TimeSpan\" }\r\n                }\r\n            }\r\n        },\r\n        \"target\":    { \"type\": \"array\", \"items\": { \"type\": \"string\" } },\r\n        \"action\":    { \"type\": \"string\" }\r\n    }\r\n}\r\n` as Settings\r\n\r\n\r\n####################################################################\r\n\r\nconst settings = Settings(trigger.settings)\r\n\r\nconst get_type(typename as string) = Type.GetType(\"acuario2.types.\"..typename..\",acuario2.types\", true)\r\n\r\nconst source_params = StringList()\r\nconst source_objs   = ObjectList()\r\nconst source_types  = TypeList()\r\neval from settings.source do\r\n    try\r\n        let obj = graph[Guid(it)] as Object\r\n        source_types.Add(obj.GetType())\r\n        source_objs.Add(obj) \r\n    else\r\n        source_types.Add(get_type(it))\r\nnow\r\n\r\nconst base_type = from ReflectionExtension.GetCommonBaseInterfaces(source_types) single\r\nuse (\"acuario2.types.\" + base_type.Name) as SourceType from acuario2.types\r\nconst state_type = (SourceType as Type).GetProperty(\"state\")?.PropertyType ?? EmptyEnum\r\n\r\nconst source_type(type as Type)     = from source_types any it.IsAssignableFrom(type)\r\nconst source_obj(obj as SourceType) = (source_objs is empty) or (obj in source_objs)\r\nconst allowed(obj as SourceType)    = (obj isnt null) and (obj.GetType() is source_type) and (obj is source_obj)\r\n\r\nconst triggered =  \r\n    if from state_type any it like settings.condition then\r\n        source_params.Add(\"state\")\r\n        let proc(obj as SourceType) = obj[\"state\"].Text like settings.condition\r\n        proc\r\n    else\r\n        let delegate = DynamicExpression.TryParseLambda(new [ Expression.Parameter(SourceType as Type) ], bool, settings.condition, null, source_params).Compile()\r\n        let proc(obj as SourceType) = delegate.DynamicInvoke(new [obj]) as bool\r\n        proc\r\nend\r\n\r\nconst expected(changes) = from source_params any it in changes\r\n\r\nconst target_type_name = from settings.target try last\r\nuse (\"acuario2.types.\" + target_type_name) as TargetType from acuario2.types\r\nconst command_type = (TargetType as Type).GetProperty(\"command\")?.PropertyType ?? EmptyEnum\r\n\r\nconst execute_action =  \r\n    if settings.action in command_type then\r\n        let proc(item as TargetType) = item[\"command\"].Value = settings.action\r\n        proc\r\n    else\r\n        let delegate = DynamicExpression.TryParseLambda(new [ Expression.Parameter(TargetType as Type) ], object, settings.action, null, null).Compile()\r\n        let proc(item as TargetType) = delegate.DynamicInvoke(new [item])\r\n        proc\r\nend\r\n\r\n####################################################################\r\n\r\nlet reflex(source as SourceType) = \r\n    if (source is allowed) and (source is triggered) then\r\n        from graph.Find(source, settings.target) of type TargetType do\r\n            execute_action(it)\r\n        now\r\n    end\r\nend\r\n\r\nlet on_update(obj as AbstractObject, changes as string[]) = if changes is expected then reflex(obj as SourceType)\r\n\r\nlet on_schedule() = from graph.Values of type SourceType do reflex(it) now\r\n\r\nif settings.schedule is empty then\r\n    this.RunOnCreated(on_update)\r\n    this.RunOnUpdated(on_update)\r\nelse\r\n    from settings.schedule do \r\n        this.RunOnSchedule(unit, count, time, on_schedule)\r\n    now\r\nend\r\n\r\n","datetime":1574685136,"status":null,"version":0},"name":{"value":"Conditional Reflex","datetime":1574514987,"status":null,"version":0}},"entity":"item","operation":"create"}]