Beispiel #1
0
        public ProgramBlock SaveMacro(string options)
        {
            RecordingDisable();
            //
            var program = new ProgramBlock();

            program.Name    = "New Macro";
            program.Address = masterControlProgram.GeneratePid();
            program.Type    = "Wizard";
            foreach (var migCommand in macroCommands)
            {
                var command = new ProgramCommand();
                command.Domain           = migCommand.Domain;
                command.Target           = migCommand.NodeId;
                command.CommandString    = migCommand.Command;
                command.CommandArguments = "";
                if (!string.IsNullOrEmpty(migCommand.GetOption(0)) && migCommand.GetOption(0) != "null")
                {
                    //TODO: should we pass entire command option string? migCmd.OptionsString
                    command.CommandArguments = migCommand.GetOption(0) + (options != "" && options != "null" ? "/" + options : "");
                }
                program.Commands.Add(command);
            }
            masterControlProgram.ProgramAdd(program);
            //
            return(program);
        }
Beispiel #2
0
 public ProgramBlock SaveMacro(string options)
 {
     RecordingDisable();
     //
     var program = new ProgramBlock();
     program.Name = "New Macro";
     program.Address = masterControlProgram.GeneratePid();
     program.Type = "Wizard";
     foreach (var migCommand in macroCommands)
     {
         var command = new ProgramCommand();
         command.Domain = migCommand.Domain;
         command.Target = migCommand.NodeId;
         command.CommandString = migCommand.Command;
         command.CommandArguments = "";
         if (!string.IsNullOrEmpty(migCommand.GetOption(0)) && migCommand.GetOption(0) != "null")
         {
             //TODO: should we pass entire command option string? migCmd.OptionsString
             command.CommandArguments = migCommand.GetOption(0) + (options != "" && options != "null" ? "/" + options : "");
         }
         program.Commands.Add(command);
     }
     masterControlProgram.ProgramAdd(program);
     //
     return program;
 }
Beispiel #3
0
        private List <ProgramError> CompileArduino(ProgramBlock program)
        {
            List <ProgramError> errors = new List <ProgramError>();

            // Generate, compile and upload Arduino Sketch
            string sketchFileName = ArduinoAppFactory.GetSketchFile(program.Address.ToString());

            if (!Directory.Exists(Path.GetDirectoryName(sketchFileName)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(sketchFileName));
            }
            string sketchMakefile = Path.Combine(Path.GetDirectoryName(sketchFileName), "Makefile");

            try
            {
                // .ino source is stored in the ScriptSource property
                File.WriteAllText(sketchFileName, program.ScriptSource);
                // Makefile source is stored in the ScriptCondition property
                File.WriteAllText(sketchMakefile, program.ScriptCondition);
                errors = ArduinoAppFactory.CompileSketch(sketchFileName, sketchMakefile);
            }
            catch (Exception e)
            {
                errors.Add(new ProgramError()
                {
                    Line         = 0,
                    Column       = 0,
                    ErrorMessage = "General failure: is 'arduino-mk' package installed?\n\n" + e.Message,
                    ErrorNumber  = "500",
                    CodeBlock    = "CR"
                });
            }

            return(errors);
        }
Beispiel #4
0
        public System.CodeDom.Compiler.CompilerResults CompileScript(ProgramBlock pb)
        {
            if (!Directory.Exists(Path.GetDirectoryName(pb.AssemblyFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(pb.AssemblyFile));
            }
            // DO NOT CHANGE THE FOLLOWING LINES OF CODE
            // it is a lil' trick for mono compatibility
            // since it was caching the assembly when using the same name
            string tmpfile = Guid.NewGuid().ToString() + ".dll";

            System.CodeDom.Compiler.CompilerResults cres = _scriptinghost.CompileScript(pb.ScriptCondition, pb.ScriptSource, tmpfile);
            // delete old assembly
            try
            {
                if (File.Exists(pb.AssemblyFile))
                {
                    // delete old assebly
                    File.Delete(pb.AssemblyFile);
                }
                // move newly compiled assembly to programs folder
                if (cres.Errors.Count == 0)
                {
                    // submitting new assembly
                    File.Move(tmpfile, pb.AssemblyFile);
                }
            }
            catch (Exception ex)
            {
                // report errors during post-compilation process
                //pb.ScriptErrors = ex.Message + "\n" + ex.StackTrace;
                cres.Errors.Add(new System.CodeDom.Compiler.CompilerError(pb.Name, 0, 0, "0", ex.Message + "\n" + ex.StackTrace));
            }
            return(cres);
        }
Beispiel #5
0
        public ProgramBlock SaveMacro(string options)
        {
            RecordingDisable();
            //
            ProgramBlock pb = new ProgramBlock();

            pb.Name    = "New Macro";
            pb.Address = _mastercontrolprogram.GeneratePid();
            pb.Type    = "Wizard";
            foreach (MIGInterfaceCommand mc in _macrocommands)
            {
                ProgramCommand pc = new ProgramCommand();
                pc.Domain           = mc.domain;
                pc.Target           = mc.nodeid;
                pc.CommandString    = mc.command;
                pc.CommandArguments = "";
                if (!string.IsNullOrEmpty(mc.GetOption(0)) && mc.GetOption(0) != "null")
                {
                    //TODO: should we pass entire command option string? migCmd.OptionsString
                    pc.CommandArguments = mc.GetOption(0) + (options != "" && options != "null" ? "/" + options : "");
                }
                pb.Commands.Add(pc);
            }
            _mastercontrolprogram.ProgramAdd(pb);
            //
            return(pb);
        }
Beispiel #6
0
 private void StartProgramScheduler(ProgramBlock program)
 {
     StopProgramScheduler(program);
     RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Idle");
     program.Engine.StartupThread = new Thread(CheckProgramSchedule);
     program.Engine.StartupThread.Start(program);
 }
Beispiel #7
0
        public ProgramBlock SaveMacro(string options)
        {
            RecordingDisable();
            //
            var program = new ProgramBlock();

            program.Name    = "New Macro";
            program.Address = masterControlProgram.GeneratePid();
            program.Type    = "Wizard";
            WizardEngine.WizardScript wizardScript = ((WizardEngine)program.Engine).Script;
            foreach (var migCommand in macroCommands)
            {
                var command = new Engines.WizardScript.ScriptCommand();
                command.Domain           = migCommand.Domain;
                command.Target           = migCommand.Address;
                command.CommandString    = migCommand.Command;
                command.CommandArguments = "";
                if (!string.IsNullOrEmpty(migCommand.GetOption(0)) && migCommand.GetOption(0) != "null")
                {
                    //TODO: should we pass entire command option string? migCmd.OptionsString
                    command.CommandArguments = migCommand.GetOption(0) + (options != "" && options != "null" ? "/" + options : "");
                }
                wizardScript.Commands.Add(command);
            }
            // serialize WizardScript to program.ScriptSource property
            program.ScriptSource = JsonConvert.SerializeObject(wizardScript);
            masterControlProgram.ProgramAdd(program);
            //
            return(program);
        }
Beispiel #8
0
        public void ProgramRemove(ProgramBlock program)
        {
            program.IsEnabled = false;
            program.Stop();
            automationPrograms.Remove(program);
            // delete program files
            string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs");

            // remove csharp assembly
            try
            {
                File.Delete(Path.Combine(file, program.Address + ".dll"));
            }
            catch
            {
            }
            // remove arduino folder files
            try
            {
                Directory.Delete(Path.Combine(file, "arduino", program.Address.ToString()), true);
            }
            catch
            {
            }
        }
Beispiel #9
0
        public List <ProgramError> CompileScript(ProgramBlock program)
        {
            List <ProgramError> errors = new List <ProgramError>();

            switch (program.Type.ToLower())
            {
            case "csharp":
                errors = CompileCsharp(program);
                break;

            case "ruby":
            case "python":
                errors = CompileIronScript(program);
                break;

            case "javascript":
                errors = CompileJavascript(program);
                break;

            case "arduino":
                errors = CompileArduino(program);
                break;
            }
            return(errors);
        }
Beispiel #10
0
 public void ProgramRemove(ProgramBlock pb)
 {
     pb.Stop();
     pb.IsEnabled = false;
     lock (_programblocks)
     {
         _programblocks.Remove(pb);
     }
 }
Beispiel #11
0
        private List <ProgramError> CompileJavascript(ProgramBlock program)
        {
            List <ProgramError> errors = new List <ProgramError>();

            Jint.Parser.JavaScriptParser jp = new Jint.Parser.JavaScriptParser(false);
            //Jint.Parser.ParserOptions po = new Jint.Parser.ParserOptions();
            try
            {
                jp.Parse(program.ScriptCondition);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error   = e.Message.Split(':');
                    string   message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[1]);
                        errors.Add(new ProgramError()
                        {
                            Line         = line,
                            ErrorMessage = message,
                            CodeBlock    = "TC"
                        });
                    }
                }
            }
            //
            try
            {
                jp.Parse(program.ScriptSource);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error   = e.Message.Split(':');
                    string   message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[1]);
                        errors.Add(new ProgramError()
                        {
                            Line         = line,
                            ErrorMessage = message,
                            CodeBlock    = "CR"
                        });
                    }
                }
            }

            return(errors);
        }
Beispiel #12
0
        internal void RaiseProgramModuleEvent(ProgramBlock program, string property, string value)
        {
            var programModule = hgService.Modules.Find(m => m.Domain == Domains.HomeAutomation_HomeGenie_Automation && m.Address == program.Address.ToString());

            if (programModule != null)
            {
                Utility.ModuleParameterSet(programModule, property, value);
                hgService.RaiseEvent(program.Address, programModule.Domain, programModule.Address, "Automation Program", property, value);
            }
        }
Beispiel #13
0
        // TODO: find a better solution to this...
        public void ExecuteWizardScript(ProgramBlock pb)
        {
            int repeatstartline = 0;
            int repeatcount     = 0;

            for (int x = 0; x < pb.Commands.Count; x++)
            {
                if (pb.Commands[x].Domain == Domains.HomeAutomation_HomeGenie)
                {
                    switch (pb.Commands[x].Target)
                    {
                    case "Automation":
                        //
                        string cs = pb.Commands[x].CommandString;
                        switch (cs)
                        {
                        case "Program.Pause":
                            Thread.Sleep((int)(double.Parse(pb.Commands[x].CommandArguments, System.Globalization.CultureInfo.InvariantCulture) * 1000));
                            break;

                        case "Program.Repeat":
                            // TODO: implement check for contiguous repeat statements
                            if (repeatcount <= 0)
                            {
                                repeatcount = (int)(double.Parse(pb.Commands[x].CommandArguments, System.Globalization.CultureInfo.InvariantCulture));
                            }
                            if (--repeatcount == 0)
                            {
                                repeatstartline = x + 1;
                            }
                            else
                            {
                                x = repeatstartline - 1;
                            }
                            break;

                        default:
                            ProgramCommand c        = pb.Commands[x];
                            string         wrequest = c.Domain + "/" + c.Target + "/" + c.CommandString + "/" + c.CommandArguments;
                            _homegenie.ExecuteAutomationRequest(new MIGInterfaceCommand(wrequest));
                            break;
                        }
                        //
                        break;
                    }
                }
                else
                {
                    _mcp_executeCommand(pb.Commands[x]);
                }
                //
                Thread.Sleep(10);
            }
        }
Beispiel #14
0
 public void ProgramAdd(ProgramBlock program)
 {
     automationPrograms.Add(program);
     program.EnabledStateChanged += program_EnabledStateChanged;
     program.Engine.SetHost(homegenie);
     RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Added");
     if (isEngineEnabled && program.IsEnabled)
     {
         program.Engine.StartScheduler();
     }
 }
Beispiel #15
0
 public void ProgramAdd(ProgramBlock program)
 {
     automationPrograms.Add(program);
     program.EnabledStateChanged += program_EnabledStateChanged;
     program.Engine.SetHost(homegenie);
     // Initialize state
     RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Idle");
     if (program.IsEnabled)
     {
         StartProgramEvaluator(program);
     }
 }
Beispiel #16
0
 public CSharpEngine(ProgramBlock pb) : base(pb) 
 {
     // TODO: SetShadowCopyPath/SetShadowCopyFiles methods are deprecated... 
     // TODO: create own AppDomain for "programDomain" instead of using CurrentDomain
     // TODO: and use AppDomainSetup to set shadow copy for each app domain
     // TODO: !!! verify AppDomain compatibility with mono !!!
     if (!isShadowCopySet)
     {
         isShadowCopySet = true;
         var domain = AppDomain.CurrentDomain;
         domain.SetShadowCopyPath(Path.Combine(domain.BaseDirectory, "programs"));
         domain.SetShadowCopyFiles();
     }
 }
Beispiel #17
0
 public void ProgramAdd(ProgramBlock pb)
 {
     lock (_programblocks)
     {
         _programblocks.Add(pb);
     }
     EvaluateProgramConditionAsync(pb, (ProgramBlock p, bool conditionsatisfied) =>
     {
         if (conditionsatisfied && p.IsEnabled)
         {
             Run(p, null); // that goes async too
         }
     });
 }
Beispiel #18
0
 private void StopProgramScheduler(ProgramBlock program)
 {
     if (program.Engine.StartupThread != null)
     {
         try
         {
             program.Engine.RoutedEventAck.Set();
             if (!program.Engine.StartupThread.Join(1000))
             {
                 program.Engine.StartupThread.Abort();
             }
         } catch { }
         program.Engine.StartupThread = null;
     }
 }
Beispiel #19
0
        internal void RaiseProgramModuleEvent(ProgramBlock program, string property, string value)
        {
            var programModule = homegenie.Modules.Find(m => m.Domain == Domains.HomeAutomation_HomeGenie_Automation && m.Address == program.Address.ToString());

            if (programModule != null)
            {
                var actionEvent = new MIG.InterfacePropertyChangedAction();
                actionEvent.Domain     = programModule.Domain;
                actionEvent.Path       = property;
                actionEvent.Value      = value;
                actionEvent.SourceId   = programModule.Address;
                actionEvent.SourceType = "Automation Program";
                Utility.ModuleParameterSet(programModule, property, value);
                homegenie.SignalModulePropertyChange(this, programModule, actionEvent);
            }
        }
Beispiel #20
0
        private List <ProgramError> CompileIronScript(ProgramBlock program)
        {
            List <ProgramError> errors = new List <ProgramError>();

            ScriptSource       source        = (program.scriptEngine as ScriptEngine).CreateScriptSourceFromString(program.ScriptCondition);
            ScriptEngineErrors errorListener = new ScriptEngineErrors("TC");

            source.Compile(errorListener);
            errors.AddRange(errorListener.Errors);
            errorListener = new ScriptEngineErrors("CR");
            source        = (program.scriptEngine as ScriptEngine).CreateScriptSourceFromString(program.ScriptSource);
            source.Compile(errorListener);
            errors.AddRange(errorListener.Errors);

            return(errors);
        }
Beispiel #21
0
        private void StartProgramEvaluator(ProgramBlock program)
        {
            EvaluateProgramConditionArgs evalArgs = new EvaluateProgramConditionArgs()
            {
                Program  = program,
                Callback = (ProgramBlock p, bool conditionsatisfied) =>
                {
                    if (conditionsatisfied && p.IsEnabled)
                    {
                        Run(p, null); // that goes async too
                    }
                }
            };

            ThreadPool.QueueUserWorkItem(new WaitCallback(EvaluateProgramCondition), evalArgs);
        }
Beispiel #22
0
 public void ProgramAdd(ProgramBlock program)
 {
     program.SetHost(homegenie);
     automationPrograms.Add(program);
     program.EnabledStateChanged += program_EnabledStateChanged;
     //
     // in case of c# script preload assembly from generated .dll
     if (program.Type.ToLower() == "csharp" && !program.AssemblyLoad())
     {
         program.ScriptErrors = "Program update is required.";
     }
     //
     // Initialize state
     RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Idle");
     if (program.IsEnabled)
     {
         StartProgramEvaluator(program);
     }
 }
Beispiel #23
0
        // this will ensure that the StartupCode is run at least every minute for checking scheduler conditions if any
        private void CheckProgramSchedule(object p)
        {
            ProgramBlock program = (ProgramBlock)p;

            // set initial state to signaled
            program.Engine.RoutedEventAck.Set();
            while (isEngineEnabled && program.IsEnabled)
            {
                program.Engine.RoutedEventAck.WaitOne((60 - DateTime.Now.Second) * 1000);
                // the startup code is not evaluated while the program is running
                if (program.IsRunning || !program.IsEnabled || !isEngineEnabled)
                {
                    continue;
                }
                else if (WillProgramRun(program))
                {
                    Run(program, null);
                }
            }
        }
Beispiel #24
0
        public ProgramBlock ProgramClone(int pid)
        {
            var program = ProgramGet(pid);
            var copy    = new ProgramBlock
            {
                Address            = GeneratePid(),
                Domain             = program.Domain,
                Type               = program.Type,
                Group              = program.Group,
                Name               = "Copy of " + program.Name,
                Description        = program.Description,
                ScriptSetup        = program.ScriptSetup,
                ScriptSource       = program.ScriptSource,
                AutoRestartEnabled = program.AutoRestartEnabled
            };

            ProgramAdd(copy);
            ProgramCompile(copy);
            return(copy);
        }
Beispiel #25
0
        private void program_EnabledStateChanged(object sender, bool isEnabled)
        {
            ProgramBlock program = (ProgramBlock)sender;

            if (isEnabled)
            {
                homegenie.modules_RefreshPrograms();
                homegenie.modules_RefreshVirtualModules();
                RaiseProgramModuleEvent(program, "Program.Status", "Enabled");
                // TODO: CRITICAL
                // TODO: we should ensure to dispose previous Evaluator Thread before starting the new one
                StartProgramEvaluator(program);
            }
            else
            {
                RaiseProgramModuleEvent(program, "Program.Status", "Disabled");
                homegenie.modules_RefreshPrograms();
                homegenie.modules_RefreshVirtualModules();
            }
            homegenie.modules_Sort();
        }
Beispiel #26
0
        public ProgramBlock ProgramClone(int pid, string newName = null)
        {
            var program = ProgramGet(pid);
            var copy    = new ProgramBlock
            {
                Address            = GeneratePid(),
                PackageInfo        = program.PackageInfo,
                Domain             = program.Domain,
                Type               = program.Type,
                Group              = program.Group,
                Name               = String.IsNullOrEmpty(newName) ? "Copy of " + program.Name : newName,
                Description        = program.Description,
                ScriptSetup        = program.ScriptSetup,
                ScriptSource       = program.ScriptSource,
                AutoRestartEnabled = program.AutoRestartEnabled
            };

            ProgramAdd(copy);
            ProgramCompile(copy);
            return(copy);
        }
Beispiel #27
0
        private void program_EnabledStateChanged(object sender, bool isEnabled)
        {
            ProgramBlock program = (ProgramBlock)sender;

            if (isEnabled)
            {
                program.ScriptErrors = "";
                homegenie.modules_RefreshPrograms();
                homegenie.modules_RefreshVirtualModules();
                RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Enabled");
                program.Engine.StartScheduler();
            }
            else
            {
                program.Engine.StopScheduler();
                RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Disabled");
                homegenie.modules_RefreshPrograms();
                homegenie.modules_RefreshVirtualModules();
            }
            homegenie.modules_Sort();
        }
Beispiel #28
0
        public void ProgramRemove(ProgramBlock program)
        {
            RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Removed");
            program.IsEnabled = false;
            automationPrograms.Remove(program);
            // delete program files
            // TODO: implement also deleting of data/programs/<pid> folder!
            string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs");

            // remove csharp assembly
            try
            {
                File.Delete(Path.Combine(file, program.Address + ".dll"));
            }
            catch
            {
            }
            // remove arduino folder files
            try
            {
                Directory.Delete(Path.Combine(file, "arduino", program.Address.ToString()), true);
            } catch { }
        }
Beispiel #29
0
        public void EvaluateProgramCondition(object evalArguments)
        {
            ProgramBlock program = (evalArguments as EvaluateProgramConditionArgs).Program;
            ConditionEvaluationCallback callback = (evalArguments as EvaluateProgramConditionArgs).Callback;
            //
            bool isConditionSatisfied = false;

            //
            while (isEngineRunning && program.IsEnabled)
            {
                if (program.IsRunning || !isEngineEnabled)
                {
                    Thread.Sleep(1000);
                    continue;
                }
                //
                program.RoutedEventAck.WaitOne(1000);
                //
                try
                {
                    isConditionSatisfied = false;
                    //
                    var result = program.EvaluateCondition();
                    if (result != null && result.Exception != null)
                    {
                        // runtime error occurred, script is being disabled
                        // so user can notice and fix it
                        List <ProgramError> error = new List <ProgramError>()
                        {
                            program.GetFormattedError(result.Exception, true)
                        };
                        program.ScriptErrors = JsonConvert.SerializeObject(error);
                        program.IsEnabled    = false;
                        RaiseProgramModuleEvent(program, Properties.RUNTIME_ERROR, "TC: " + result.Exception.Message.Replace('\n', ' ').Replace('\r', ' '));
                    }
                    else
                    {
                        isConditionSatisfied = (result != null ? (bool)result.ReturnValue : false);
                    }
                    //
                    bool lastResult = program.LastConditionEvaluationResult;
                    program.LastConditionEvaluationResult = isConditionSatisfied;
                    //
                    if (program.ConditionType == ConditionType.OnSwitchTrue)
                    {
                        isConditionSatisfied = (isConditionSatisfied == true && isConditionSatisfied != lastResult);
                    }
                    else if (program.ConditionType == ConditionType.OnSwitchFalse)
                    {
                        isConditionSatisfied = (isConditionSatisfied == false && isConditionSatisfied != lastResult);
                    }
                    else if (program.ConditionType == ConditionType.OnTrue || program.ConditionType == ConditionType.Once)
                    {
                        // noop
                    }
                    else if (program.ConditionType == ConditionType.OnFalse)
                    {
                        isConditionSatisfied = !isConditionSatisfied;
                    }
                }
                catch (Exception ex)
                {
                    // a runtime error occured
                    List <ProgramError> error = new List <ProgramError>()
                    {
                        program.GetFormattedError(ex, true)
                    };
                    program.ScriptErrors = JsonConvert.SerializeObject(error);
                    program.IsEnabled    = false;
                    RaiseProgramModuleEvent(program, Properties.RUNTIME_ERROR, "TC: " + ex.Message.Replace('\n', ' ').Replace('\r', ' '));
                }
                //
                callback(program, isConditionSatisfied);
                //
                program.RoutedEventAck.Reset();
            }
        }
 // TODO: v1.1 !!!IMPORTANT!!! move thread allocation and starting to ProgramEngineBase.cs class
 public void Run(ProgramBlock program, string options)
 {
     program.Engine.StartProgram(options);
 }
Beispiel #31
0
 public void ProgramRemove(ProgramBlock program)
 {
     program.IsEnabled = false;
     program.Stop();
     automationPrograms.Remove(program);
 }
Beispiel #32
0
        private List<ProgramError> CompileCsharp(ProgramBlock program)
        {
            List<ProgramError> errors = new List<ProgramError>();

            // check for output directory
            if (!Directory.Exists(Path.GetDirectoryName(program.AssemblyFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(program.AssemblyFile));
            }

            // dispose assembly and interrupt current task (if any)
            program.AppAssembly = null;
            program.IsEnabled = false;

            // DO NOT CHANGE THE FOLLOWING LINES OF CODE
            // it is a lil' trick for mono compatibility
            // since it will be caching the assembly when using the same name
            // and use the old one instead of the new one
            string tmpfile = Path.Combine("programs", Guid.NewGuid().ToString() + ".dll");
            System.CodeDom.Compiler.CompilerResults result = new System.CodeDom.Compiler.CompilerResults(null);
            try
            {
                result = CSharpAppFactory.CompileScript(program.ScriptCondition, program.ScriptSource, tmpfile);
            }
            catch (Exception ex)
            {
                // report errors during post-compilation process
                result.Errors.Add(new System.CodeDom.Compiler.CompilerError(program.Name, 0, 0, "-1", ex.Message));
            }

            if (result.Errors.Count > 0)
            {
                int sourceLines = program.ScriptSource.Split('\n').Length;
                foreach (System.CodeDom.Compiler.CompilerError error in result.Errors)
                {
                    int errorRow = (error.Line - CSharpAppFactory.PROGRAM_CODE_OFFSET);
                    string blockType = "CR";
                    if (errorRow >= sourceLines + CSharpAppFactory.CONDITION_CODE_OFFSET)
                    {
                        errorRow -= (sourceLines + CSharpAppFactory.CONDITION_CODE_OFFSET);
                        blockType = "TC";
                    }
                    if (!error.IsWarning)
                    {
                        errors.Add(new ProgramError() {
                            Line = errorRow,
                            Column = error.Column,
                            ErrorMessage = error.ErrorText,
                            ErrorNumber = error.ErrorNumber,
                            CodeBlock = blockType
                        });
                    }
                    else
                    {
                        var warning = String.Format("{0},{1},{2}: {3}", blockType, errorRow, error.Column, error.ErrorText);
                        RaiseProgramModuleEvent(program, Properties.COMPILER_WARNING, warning);
                    }
                }
            }
            if (errors.Count == 0)
            {
                program.AppAssembly = result.CompiledAssembly;
            }

            return errors;
        }
 public void ProgramRemove(ProgramBlock program)
 {
     RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Removed");
     program.IsEnabled = false;
     automationPrograms.Remove(program);
     // delete program files
     string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs");
     // remove csharp assembly
     try
     {
         File.Delete(Path.Combine(file, program.Address + ".dll"));
     }
     catch
     {
     }
     // remove arduino folder files 
     try
     {
         Directory.Delete(Path.Combine(file, "arduino", program.Address.ToString()), true);
     } catch { }
 }
Beispiel #34
0
        public void ProcessRequest(MIGClientRequest request, MIGInterfaceCommand migCommand)
        {
            string streamcontent = "";
            ProgramBlock currentProgram;
            ProgramBlock newProgram;
            //
            homegenie.ExecuteAutomationRequest(migCommand);
            if (migCommand.Command.StartsWith("Macro."))
            {
                switch (migCommand.Command)
                {
                    case "Macro.Record":
                        homegenie.ProgramEngine.MacroRecorder.RecordingEnable();
                        break;
                    case "Macro.Save":
                        newProgram = homegenie.ProgramEngine.MacroRecorder.SaveMacro(migCommand.GetOption(1));
                        migCommand.Response = newProgram.Address.ToString();
                        break;
                    case "Macro.Discard":
                        homegenie.ProgramEngine.MacroRecorder.RecordingDisable();
                        break;
                    case "Macro.SetDelay":
                        switch (migCommand.GetOption(0).ToLower())
                        {
                            case "none":
                                homegenie.ProgramEngine.MacroRecorder.DelayType = MacroDelayType.None;
                                break;

                            case "mimic":
                                homegenie.ProgramEngine.MacroRecorder.DelayType = MacroDelayType.Mimic;
                                break;

                            case "fixed":
                                double secs = double.Parse(migCommand.GetOption(1), System.Globalization.CultureInfo.InvariantCulture);
                                homegenie.ProgramEngine.MacroRecorder.DelayType = MacroDelayType.Fixed;
                                homegenie.ProgramEngine.MacroRecorder.DelaySeconds = secs;
                                break;
                        }
                        break;
                    case "Macro.GetDelay":
                        migCommand.Response = "[{ DelayType : '" + homegenie.ProgramEngine.MacroRecorder.DelayType + "', DelayOptions : '" + homegenie.ProgramEngine.MacroRecorder.DelaySeconds + "' }]";
                        break;
                }
            }
            else if (migCommand.Command.StartsWith("Scheduling."))
            {
                switch (migCommand.Command)
                {
                    case "Scheduling.Add":
                    case "Scheduling.Update":
                        var item = homegenie.ProgramEngine.SchedulerService.AddOrUpdate(migCommand.GetOption(0), migCommand.GetOption(1).Replace("|", "/"));
                        item.ProgramId = migCommand.GetOption(2);
                        homegenie.UpdateSchedulerDatabase();
                        break;
                    case "Scheduling.Delete":
                        homegenie.ProgramEngine.SchedulerService.Remove(migCommand.GetOption(0));
                        homegenie.UpdateSchedulerDatabase();
                        break;
                    case "Scheduling.Enable":
                        homegenie.ProgramEngine.SchedulerService.Enable(migCommand.GetOption(0));
                        homegenie.UpdateSchedulerDatabase();
                        break;
                    case "Scheduling.Disable":
                        homegenie.ProgramEngine.SchedulerService.Disable(migCommand.GetOption(0));
                        homegenie.UpdateSchedulerDatabase();
                        break;
                    case "Scheduling.Get":
                        migCommand.Response = JsonConvert.SerializeObject(homegenie.ProgramEngine.SchedulerService.Get(migCommand.GetOption(0)));
                        break;
                    case "Scheduling.List":
                        homegenie.ProgramEngine.SchedulerService.Items.Sort((SchedulerItem s1, SchedulerItem s2) =>
                        {
                            return s1.Name.CompareTo(s2.Name);
                        });
                        migCommand.Response = JsonConvert.SerializeObject(homegenie.ProgramEngine.SchedulerService.Items);
                        break;
                }
            }
            else if (migCommand.Command.StartsWith("Programs."))
            {
                if (migCommand.Command != "Programs.Import")
                {
                    streamcontent = new StreamReader(request.InputStream).ReadToEnd();
                }
                //
                switch (migCommand.Command)
                {
                    case "Programs.Import":
                        string archiveName = "homegenie_program_import.hgx";
                        if (File.Exists(archiveName)) File.Delete(archiveName);
                        //
                        var encoding = (request.Context as HttpListenerContext).Request.ContentEncoding;
                        string boundary = MIG.Gateways.WebServiceUtility.GetBoundary((request.Context as HttpListenerContext).Request.ContentType);
                        MIG.Gateways.WebServiceUtility.SaveFile(encoding, boundary, request.InputStream, archiveName);
                        //
                        var serializer = new XmlSerializer(typeof(ProgramBlock));
                        var reader = new StreamReader(archiveName);
                        newProgram = (ProgramBlock)serializer.Deserialize(reader);
                        reader.Close();
                        //
                        newProgram.Address = homegenie.ProgramEngine.GeneratePid();
                        newProgram.Group = migCommand.GetOption(0);
                        homegenie.ProgramEngine.ProgramAdd(newProgram);
                        //
                        newProgram.IsEnabled = false;
                        newProgram.ScriptErrors = "";
                        newProgram.AppAssembly = null;
                        //
                        homegenie.ProgramEngine.CompileScript(newProgram);
                        //
                        homegenie.UpdateProgramsDatabase();
                        //migCommand.response = JsonHelper.GetSimpleResponse(programblock.Address);
                        migCommand.Response = newProgram.Address.ToString();
                        break;

                    case "Programs.Export":
                        currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                        var writerSettings = new System.Xml.XmlWriterSettings();
                        writerSettings.Indent = true;
                        var programSerializer = new System.Xml.Serialization.XmlSerializer(typeof(ProgramBlock));
                        var builder = new StringBuilder();
                        var writer = System.Xml.XmlWriter.Create(builder, writerSettings);
                        programSerializer.Serialize(writer, currentProgram);
                        writer.Close();
                        migCommand.Response = builder.ToString();
                        //
                        (request.Context as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment; filename=\"" + currentProgram.Address + "-" + currentProgram.Name.Replace(" ", "_") + ".hgx\"");
                        break;

                    case "Programs.List":
                        var programList = new List<ProgramBlock>(homegenie.ProgramEngine.Programs);
                        programList.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                        {
                            string c1 = p1.Name + " " + p1.Address;
                            string c2 = p2.Name + " " + p2.Address;
                            return c1.CompareTo(c2);
                        });
                        migCommand.Response = JsonConvert.SerializeObject(programList);
                        break;

                    case "Programs.Add":
                        newProgram = new ProgramBlock() { Group = migCommand.GetOption(0), Name = streamcontent, Type = "Wizard", ScriptCondition = "// A \"return true;\" statement at any point of this code block, will cause the program to run.\n// For manually activated program, just leave a \"return false\" statement here.\n\nreturn false;\n" };
                        newProgram.Address = homegenie.ProgramEngine.GeneratePid();
                        homegenie.ProgramEngine.ProgramAdd(newProgram);
                        homegenie.UpdateProgramsDatabase();
                        migCommand.Response = JsonHelper.GetSimpleResponse(newProgram.Address.ToString());
                        break;

                    case "Programs.Delete":
                        currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                        if (currentProgram != null)
                        {
                            //TODO: remove groups associations as well
                            currentProgram.IsEnabled = false;
                            homegenie.ProgramEngine.ProgramRemove(currentProgram);
                            homegenie.UpdateProgramsDatabase();
                            // remove associated module entry
                            homegenie.Modules.RemoveAll(m => m.Domain == Domains.HomeAutomation_HomeGenie_Automation && m.Address == currentProgram.Address.ToString());
                            homegenie.UpdateModulesDatabase();
                        }
                        break;

                    case "Programs.Compile":
                    case "Programs.Update":
                        newProgram = JsonConvert.DeserializeObject<ProgramBlock>(streamcontent);
                        currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == newProgram.Address);
                        //
                        if (currentProgram == null)
                        {
                            newProgram.Address = homegenie.ProgramEngine.GeneratePid();
                            homegenie.ProgramEngine.ProgramAdd(newProgram);
                        }
                        else
                        {
                            if (currentProgram.Type.ToLower() != newProgram.Type.ToLower())
                            {
                                currentProgram.AppAssembly = null; // dispose assembly and interrupt current task
                            }
                            currentProgram.Type = newProgram.Type;
                            currentProgram.Group = newProgram.Group;
                            currentProgram.Name = newProgram.Name;
                            currentProgram.Description = newProgram.Description;
                            currentProgram.IsEnabled = newProgram.IsEnabled;
                            currentProgram.ScriptCondition = newProgram.ScriptCondition;
                            currentProgram.ScriptSource = newProgram.ScriptSource;
                            currentProgram.Commands = newProgram.Commands;
                            currentProgram.Conditions = newProgram.Conditions;
                            currentProgram.ConditionType = newProgram.ConditionType;
                            // reset last condition evaluation status
                            currentProgram.LastConditionEvaluationResult = false;
                        }
                        //
                        if (migCommand.Command == "Programs.Compile")
                        {
                            // reset previous error status
                            currentProgram.IsEnabled = false;
                            currentProgram.Stop();
                            currentProgram.ScriptErrors = "";
                            //
                            List<ProgramError> errors = homegenie.ProgramEngine.CompileScript(currentProgram);
                            //
                            currentProgram.IsEnabled = newProgram.IsEnabled;
                            currentProgram.ScriptErrors = JsonConvert.SerializeObject(errors);
                            migCommand.Response = currentProgram.ScriptErrors;
                        }
                        //
                        homegenie.UpdateProgramsDatabase();
                        //
                        homegenie.modules_RefreshPrograms();
                        homegenie.modules_RefreshVirtualModules();
                        homegenie.modules_Sort();
                        break;

                    case "Programs.Run":
                        currentProgram = ProgramRun(migCommand.GetOption(0), migCommand.GetOption(1));
                        break;

                    case "Programs.Toggle":
                        currentProgram = ProgramToggle(migCommand.GetOption(0), migCommand.GetOption(1));
                        break;

                    case "Programs.Break":
                        currentProgram = ProgramBreak(migCommand.GetOption(0));
                        break;

                    case "Programs.Restart":
                        currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                        if (currentProgram != null)
                        {
                            currentProgram.IsEnabled = false;
                            try
                            {
                                currentProgram.Stop();
                            }
                            catch { }
                            currentProgram.IsEnabled = true;
                            homegenie.UpdateProgramsDatabase();
                        }
                        break;

                    case "Programs.Enable":
                        currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                        if (currentProgram != null)
                        {
                            currentProgram.IsEnabled = true;
                            homegenie.UpdateProgramsDatabase();
                        }
                        break;

                    case "Programs.Disable":
                        currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                        if (currentProgram != null)
                        {
                            currentProgram.IsEnabled = false;
                            try
                            {
                                currentProgram.Stop();
                            }
                            catch { }
                            homegenie.UpdateProgramsDatabase();
                        }
                        break;
                }

            }
        }
Beispiel #35
0
 public List<ProgramError> CompileScript(ProgramBlock program)
 {
     List<ProgramError> errors = new List<ProgramError>();
     switch (program.Type.ToLower())
     {
     case "csharp":
         errors = CompileCsharp(program);
         break;
     case "ruby":
     case "python":
         errors = CompileIronScript(program);
         break;
     case "javascript":
         errors = CompileJavascript(program);
         break;
     case "arduino":
         errors = CompileArduino(program);
         break;
     }
     return errors;
 }
Beispiel #36
0
 public void ProgramAdd(ProgramBlock program)
 {
     program.SetHost(homegenie);
     automationPrograms.Add(program);
     program.EnabledStateChanged += program_EnabledStateChanged;
     //
     // Initialize state
     RaiseProgramModuleEvent(program, "Program.Status", "Idle");
     if (program.IsEnabled)
     {
         StartProgramEvaluator(program);
     }
 }
Beispiel #37
0
        // TODO: v1.1 !!!IMPORTANT!!! possibly move this inside ProgramEngineBase.cs class and rename to EvaluateStartupCode
        public void EvaluateProgramCondition(object evalArguments)
        {
            ProgramBlock program = (evalArguments as EvaluateProgramConditionArgs).Program;
            ConditionEvaluationCallback callback = (evalArguments as EvaluateProgramConditionArgs).Callback;
            //
            bool isConditionSatisfied = false;

            //
            while (isEngineRunning && program.IsEnabled)
            {
                // the startup code is not evaluated while the program is running
                if (program.IsRunning || !isEngineEnabled)
                {
                    Thread.Sleep(1000);
                    continue;
                }
                // wait 1 second or a new event
                program.Engine.RoutedEventAck.WaitOne(1000);
                // check if the program is still allowed to run
                if (program.IsRunning || !program.IsEnabled)
                {
                    program.Engine.RoutedEventAck.Reset();
                    continue;
                }
                // evaluate and get result from the code
                try
                {
                    isConditionSatisfied = false;
                    program.WillRun      = false;
                    //
                    var result = program.EvaluateCondition();
                    if (result != null && result.Exception != null)
                    {
                        // runtime error occurred, script is being disabled
                        // so user can notice and fix it
                        List <ProgramError> error = new List <ProgramError>()
                        {
                            program.GetFormattedError(result.Exception, true)
                        };
                        program.ScriptErrors = JsonConvert.SerializeObject(error);
                        program.IsEnabled    = false;
                        RaiseProgramModuleEvent(program, Properties.RuntimeError, "TC: " + result.Exception.Message.Replace('\n', ' ').Replace('\r', ' '));
                    }
                    else
                    {
                        isConditionSatisfied = (result != null ? (bool)result.ReturnValue : false);
                    }
                    //
                    bool lastResult = program.LastConditionEvaluationResult;
                    program.LastConditionEvaluationResult = isConditionSatisfied;
                    //
                    if (program.ConditionType == ConditionType.OnSwitchTrue)
                    {
                        isConditionSatisfied = (isConditionSatisfied == true && isConditionSatisfied != lastResult);
                    }
                    else if (program.ConditionType == ConditionType.OnSwitchFalse)
                    {
                        isConditionSatisfied = (isConditionSatisfied == false && isConditionSatisfied != lastResult);
                    }
                    else if (program.ConditionType == ConditionType.OnTrue || program.ConditionType == ConditionType.Once)
                    {
                        // noop
                    }
                    else if (program.ConditionType == ConditionType.OnFalse)
                    {
                        isConditionSatisfied = !isConditionSatisfied;
                    }
                }
                catch (Exception ex)
                {
                    // a runtime error occured
                    if (!ex.GetType().Equals(typeof(System.Reflection.TargetException)))
                    {
                        List <ProgramError> error = new List <ProgramError>()
                        {
                            program.GetFormattedError(ex, true)
                        };
                        program.ScriptErrors = JsonConvert.SerializeObject(error);
                        program.IsEnabled    = false;
                        RaiseProgramModuleEvent(program, Properties.RuntimeError, "TC: " + ex.Message.Replace('\n', ' ').Replace('\r', ' '));
                    }
                }
                //
                callback(program, isConditionSatisfied);
                //
                program.Engine.RoutedEventAck.Reset();
            }
        }
Beispiel #38
0
 internal void RaiseProgramModuleEvent(ProgramBlock program, string property, string value)
 {
     var programModule = homegenie.Modules.Find(m => m.Domain == Domains.HomeAutomation_HomeGenie_Automation && m.Address == program.Address.ToString());
     if (programModule != null)
     {
         var actionEvent = new MIG.InterfacePropertyChangedAction();
         actionEvent.Domain = programModule.Domain;
         actionEvent.Path = property;
         actionEvent.Value = value;
         actionEvent.SourceId = programModule.Address;
         actionEvent.SourceType = "Automation Program";
         Utility.ModuleParameterSet(programModule, property, value);
         homegenie.SignalModulePropertyChange(this, programModule, actionEvent);
     }
 }
Beispiel #39
0
 // TODO: find a better solution to this...
 public void ExecuteWizardScript(ProgramBlock program)
 {
     int repeatStartLine = 0;
     int repeatCount = 0;
     for (int x = 0; x < program.Commands.Count; x++)
     {
         if (program.Commands[x].Domain == Domains.HomeAutomation_HomeGenie)
         {
             switch (program.Commands[x].Target)
             {
             case "Automation":
                     //
                 string cs = program.Commands[x].CommandString;
                 switch (cs)
                 {
                 case "Program.Run":
                     string programId = program.Commands[x].CommandArguments;
                     var programToRun = homegenie.ProgramEngine.Programs.Find(p => p.Address.ToString() == programId || p.Name == programId);
                     if (programToRun != null && programToRun.Address != program.Address && !programToRun.IsRunning)
                     {
                         Run(programToRun, "");
                     }
                     break;
                 case "Program.Pause":
                     Thread.Sleep((int)(double.Parse(
                         program.Commands[x].CommandArguments,
                         System.Globalization.CultureInfo.InvariantCulture
                     ) * 1000));
                     break;
                 case "Program.Repeat":
                             // TODO: implement check for contiguous repeat statements
                     if (repeatCount <= 0)
                     {
                         repeatCount = (int)(double.Parse(
                             program.Commands[x].CommandArguments,
                             System.Globalization.CultureInfo.InvariantCulture
                         ));
                     }
                     if (--repeatCount == 0)
                     {
                         repeatStartLine = x + 1;
                     }
                     else
                     {
                         x = repeatStartLine - 1;
                     }
                     break;
                 default:
                     var programCommand = program.Commands[x];
                     string wrequest = programCommand.Domain + "/" + programCommand.Target + "/" + programCommand.CommandString + "/" + programCommand.CommandArguments;
                     homegenie.ExecuteAutomationRequest(new MIGInterfaceCommand(wrequest));
                     break;
                 }
                     //
                 break;
             }
         }
         else
         {
             ExecuteProgramCommand(program.Commands[x]);
         }
         //
         Thread.Sleep(10);
     }
 }
Beispiel #40
0
        private List<ProgramError> CompileIronScript(ProgramBlock program)
        {
            List<ProgramError> errors = new List<ProgramError>();

            ScriptSource source = (program.scriptEngine as ScriptEngine).CreateScriptSourceFromString(program.ScriptCondition);
            ScriptEngineErrors errorListener = new ScriptEngineErrors("TC");
            source.Compile(errorListener);
            errors.AddRange(errorListener.Errors);
            errorListener = new ScriptEngineErrors("CR");
            source = (program.scriptEngine as ScriptEngine).CreateScriptSourceFromString(program.ScriptSource);
            source.Compile(errorListener);
            errors.AddRange(errorListener.Errors);

            return errors;
        }
Beispiel #41
0
        private List<ProgramError> CompileJavascript(ProgramBlock program)
        {
            List<ProgramError> errors = new List<ProgramError>();

            Jint.Parser.JavaScriptParser jp = new Jint.Parser.JavaScriptParser(false);
            //Jint.Parser.ParserOptions po = new Jint.Parser.ParserOptions();
            try
            {
                jp.Parse(program.ScriptCondition);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error = e.Message.Split(':');
                    string message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[0]);
                        errors.Add(new ProgramError() {
                            Line = line,
                            ErrorMessage = message,
                            CodeBlock = "TC"
                        });
                    }
                }
            }
            //
            try
            {
                jp.Parse(program.ScriptSource);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error = e.Message.Split(':');
                    string message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[0]);
                        errors.Add(new ProgramError() {
                            Line = line,
                            ErrorMessage = message,
                            CodeBlock = "CR"
                        });
                    }
                }
            }

            return errors;
        }
Beispiel #42
0
        private List<ProgramError> CompileCsharp(ProgramBlock program)
        {
            List<ProgramError> errors = new List<ProgramError>();

            // dispose assembly and interrupt current task
            program.AppAssembly = null;
            program.IsEnabled = false;

            if (!Directory.Exists(Path.GetDirectoryName(program.AssemblyFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(program.AssemblyFile));
            }
            // DO NOT CHANGE THE FOLLOWING LINES OF CODE
            // it is a lil' trick for mono compatibility
            // since it was caching the assembly when using the same name
            string tmpfile = Guid.NewGuid().ToString() + ".dll";
            // delete old assembly
            System.CodeDom.Compiler.CompilerResults result = new System.CodeDom.Compiler.CompilerResults(null);
            try
            {
                result = CSharpAppFactory.CompileScript(program.ScriptCondition, program.ScriptSource, tmpfile);
                if (File.Exists(program.AssemblyFile))
                {
                    // delete old assebly
                    File.Delete(program.AssemblyFile);
                }
                // move newly compiled assembly to programs folder
                if (result.Errors.Count == 0)
                {
                    // submitting new assembly
                    File.Move(tmpfile, program.AssemblyFile);
                }
            }
            catch (Exception ex)
            {
                // report errors during post-compilation process
                result.Errors.Add(new System.CodeDom.Compiler.CompilerError(program.Name, 0, 0, "-1", ex.Message));
            }

            int startCodeLine = 19;
            int conditionCodeOffset = 7;
            //
            if (result.Errors.Count == 0)
            {
                program.AppAssembly = result.CompiledAssembly;
            }
            else
            {
                int sourceLines = program.ScriptSource.Split('\n').Length;
                foreach (System.CodeDom.Compiler.CompilerError error in result.Errors)
                {
                    //if (!ce.IsWarning)
                    {
                        int errorRow = (error.Line - startCodeLine);
                        string blockType = "CR";
                        if (errorRow >= sourceLines + conditionCodeOffset)
                        {
                            errorRow -= (sourceLines + conditionCodeOffset);
                            blockType = "TC";
                        }
                        errors.Add(new ProgramError() {
                            Line = errorRow,
                            Column = error.Column,
                            ErrorMessage = error.ErrorText,
                            ErrorNumber = error.ErrorNumber,
                            CodeBlock = blockType
                        });
                    }
                }
            }

            return errors;
        }
Beispiel #43
0
 private void StartProgramEvaluator(ProgramBlock program)
 {
     EvaluateProgramConditionArgs evalArgs = new EvaluateProgramConditionArgs() {
         Program = program,
         Callback = (ProgramBlock p, bool conditionsatisfied) =>
         {
             if (conditionsatisfied && p.IsEnabled)
             {
                 Run(p, null); // that goes async too
             }
         }
     };
     ThreadPool.QueueUserWorkItem(new WaitCallback(EvaluateProgramCondition), evalArgs);
 }
Beispiel #44
0
        public void ProcessRequest(MigClientRequest request)
        {
            var migCommand = request.Command;

            string response = "";
            switch (migCommand.Command)
            {
            case "Interfaces.List":
                response = "[ ";
                foreach (var migInterface in homegenie.Interfaces)
                {
                    var ifaceConfig = homegenie.SystemConfiguration.MigService.GetInterface(migInterface.GetDomain());
                    if (ifaceConfig == null || !ifaceConfig.IsEnabled)
                    {
                        continue;
                    }
                    response += "{ \"Domain\" : \"" + migInterface.GetDomain() + "\", \"IsConnected\" : \"" + migInterface.IsConnected + "\" },";
                }
                if (homegenie.UpdateChecker != null && homegenie.UpdateChecker.IsUpdateAvailable)
                {
                    response += "{ \"Domain\" : \"" + Domains.HomeGenie_UpdateChecker + "\", \"IsConnected\" : \"True\" }";
                    response += " ]";
                }
                else
                {
                    response = response.Substring(0, response.Length - 1) + " ]";
                }
                request.ResponseData = response;
                break;

            case "Interfaces.ListConfig":
                response = "[ ";
                foreach (var migInterface in homegenie.Interfaces)
                {
                    var ifaceConfig = homegenie.SystemConfiguration.MigService.GetInterface(migInterface.GetDomain());
                    if (ifaceConfig == null)
                        continue;
                    response += JsonConvert.SerializeObject(ifaceConfig) + ",";
                }
                response = response.Substring(0, response.Length - 1) + " ]";
                request.ResponseData = response;
                break;

            //TODO: should this be moved somewhere to MIG?
            case "Interfaces.Configure":
                switch (migCommand.GetOption(0))
                {
                case "Hardware.SerialPorts":
                    if (Environment.OSVersion.Platform == PlatformID.Unix)
                    {
                        var serialPorts = System.IO.Ports.SerialPort.GetPortNames();
                        var portList = new List<string>();
                        for (int p = serialPorts.Length - 1; p >= 0; p--)
                        {
                            if (serialPorts[p].Contains("/ttyS") 
                                || serialPorts[p].Contains("/ttyUSB") 
                                || serialPorts[p].Contains("/ttyAMA")   // RaZberry
                                || serialPorts[p].Contains("/ttyACM"))  // ZME_UZB1
                            {
                                portList.Add(serialPorts[p]);
                            }
                        }
                        request.ResponseData = portList;
                    }
                    else
                    {
                        var portNames = System.IO.Ports.SerialPort.GetPortNames();
                        request.ResponseData = portNames;
                    }
                    break;

                }
                break;

            case "Interface.Import":
                string downloadUrl = migCommand.GetOption(0);
                response = "";
                string ifaceFileName = Path.Combine(tempFolderPath, "mig_interface_import.zip");
                string outputFolder = Path.Combine(tempFolderPath, "mig");
                Utility.FolderCleanUp(outputFolder);

                try
                {
                    if (String.IsNullOrWhiteSpace(downloadUrl))
                    {
                        // file uploaded by user
                        MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, ifaceFileName);
                    }
                    else
                    {
                        // download file from url
                        using (var client = new WebClient())
                        {
                            client.DownloadFile(downloadUrl, ifaceFileName);
                            client.Dispose();
                        }
                    }
                }
                catch
                { 
                    // TODO: report exception
                }

                try
                {
                    if (!Directory.Exists(outputFolder))
                    {
                        Directory.CreateDirectory(outputFolder);
                    }
                    Utility.UncompressZip(ifaceFileName, outputFolder);
                    File.Delete(ifaceFileName);

                    var migInt = GetInterfaceConfig(Path.Combine(outputFolder, "configuration.xml"));
                    if (migInt != null)
                    {
                        response = String.Format("{0} ({1})\n{2}\n", migInt.Domain, migInt.AssemblyName, migInt.Description);
                        // Check for README notes and append them to the response
                        var readmeFile = Path.Combine(outputFolder, "README.TXT");
                        if (File.Exists(readmeFile))
                        {
                            response += File.ReadAllText(readmeFile);
                        }
                        request.ResponseData = new ResponseText(response);
                    }
                    else
                    {
                        request.ResponseData = new ResponseText("NOT A VALID ADD-ON PACKAGE");
                    }
                }
                catch
                {
                    // TODO: report exception
                }
                break;

            case "Interface.Install":
                // install the interface package from the unpacked archive folder
                if (InterfaceInstall(Path.Combine(tempFolderPath, "mig")))
                    request.ResponseData = new ResponseText("OK");
                else
                    request.ResponseData = new ResponseText("NOT A VALID ADD-ON PACKAGE");
                break;

            case "System.GetVersion":
                request.ResponseData = homegenie.UpdateChecker.GetCurrentRelease();
                break;

            case "System.Configure":
                if (migCommand.GetOption(0) == "Service.Restart")
                {
                    Program.Quit(true);
                    request.ResponseData = new ResponseText("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.UpdatesList")
                {
                    request.ResponseData = homegenie.UpdateChecker.RemoteUpdates;
                }
                else if (migCommand.GetOption(0) == "UpdateManager.Check")
                {
                    homegenie.UpdateChecker.Check();
                    request.ResponseData = new ResponseText("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.DownloadUpdate")
                {
                    var resultMessage = "ERROR";
                    bool success = homegenie.UpdateChecker.DownloadUpdateFiles();
                    if (success)
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                        }
                        else
                        {
                            resultMessage = "OK";
                        }
                    }
                    request.ResponseData = new ResponseText(resultMessage);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.InstallUpdate") //UpdateManager.InstallProgramsCommit")
                {
                    string resultMessage = "OK";
                    homegenie.SaveData();
                    if (!homegenie.UpdateChecker.InstallFiles())
                    {
                        resultMessage = "ERROR";
                    }
                    else
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                            Utility.RunAsyncTask(() =>
                            {
                                Thread.Sleep(2000);
                                Program.Quit(true);
                            });
                        }
                        else
                        {
                            homegenie.LoadConfiguration();
                            homegenie.UpdateChecker.Check();
                        }
                    }
                    request.ResponseData = new ResponseText(resultMessage);
                }
                else if (migCommand.GetOption(0) == "Statistics.GetStatisticsDatabaseMaximumSize")
                {
                    request.ResponseData = new ResponseText(homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes.ToString());
                }
                else if (migCommand.GetOption(0) == "Statistics.SetStatisticsDatabaseMaximumSize")
                {
                    try
                    {
                        int sizeLimit = int.Parse(migCommand.GetOption(1));
                        homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes = sizeLimit;
                        homegenie.SystemConfiguration.Update();
                        homegenie.Statistics.SizeLimit = sizeLimit * 1024 * 1024;
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "SystemLogging.DownloadCsv")
                {
                    string csvlog = "";
                    string logpath = Path.Combine("log", "homegenie.log");
                    if (migCommand.GetOption(1) == "1")
                    {
                        logpath = Path.Combine("log", "homegenie.log.bak");
                    }
                    if (File.Exists(logpath))
                    {
                        using (var fs = new FileStream(logpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (var sr = new StreamReader(fs, Encoding.Default))
                        {
                            csvlog = sr.ReadToEnd();
                        }
                    }
                    (request.Context.Data as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment;filename=homegenie_log_" + migCommand.GetOption(1) + ".csv");
                    request.ResponseData = csvlog;
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Enable")
                {
                    SystemLogger.Instance.OpenLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "true";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Disable")
                {
                    SystemLogger.Instance.CloseLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "false";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.IsEnabled")
                {
                    request.ResponseData = new ResponseText((homegenie.SystemConfiguration.HomeGenie.EnableLogFile.ToLower().Equals("true") ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "Security.SetPassword")
                {
                    // password only for now, with fixed user login 'admin'
                    string pass = migCommand.GetOption(1) == "" ? "" : MIG.Utility.Encryption.SHA1.GenerateHashString(migCommand.GetOption(1));
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Password", pass);
                    homegenie.SaveData();
                }
                else if (migCommand.GetOption(0) == "Security.ClearPassword")
                {
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Password", "");
                    homegenie.SaveData();
                }
                else if (migCommand.GetOption(0) == "Security.HasPassword")
                {
                    var webGateway = homegenie.MigService.GetGateway("WebServiceGateway");
                    var password = webGateway.GetOption("Password");
                    request.ResponseData = new ResponseText((password == null || String.IsNullOrEmpty(password.Value) ? "0" : "1"));
                }
                else if (migCommand.GetOption(0) == "HttpService.SetWebCacheEnabled")
                {
                    if (migCommand.GetOption(1) == "1")
                    {
                        homegenie.MigService.GetGateway("WebServiceGateway").SetOption("EnableFileCaching", "true");
                    }
                    else
                    {
                        homegenie.MigService.GetGateway("WebServiceGateway").SetOption("EnableFileCaching", "false");
                    }
                    homegenie.SystemConfiguration.Update();
                    request.ResponseData = new ResponseText("OK");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetWebCacheEnabled")
                {
                    var fileCaching = homegenie.MigService.GetGateway("WebServiceGateway").GetOption("EnableFileCaching");
                    request.ResponseData = new ResponseText(fileCaching != null ? fileCaching.Value : "false");  
                }
                else if (migCommand.GetOption(0) == "HttpService.GetPort")
                {
                    var port = homegenie.MigService.GetGateway("WebServiceGateway").GetOption("Port");
                    request.ResponseData = new ResponseText(port != null ? port.Value : "8080");
                }
                else if (migCommand.GetOption(0) == "HttpService.SetPort")
                {
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Port", migCommand.GetOption(1));
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "HttpService.GetHostHeader")
                {
                    var host = homegenie.MigService.GetGateway("WebServiceGateway").GetOption("Host");
                    request.ResponseData = new ResponseText(host != null ? host.Value : "*");
                }
                else if (migCommand.GetOption(0) == "HttpService.SetHostHeader")
                {
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Host", migCommand.GetOption(1));
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestore")
                {
                    // file uploaded by user
                    string archivename = Path.Combine(tempFolderPath, "homegenie_restore_config.zip");
                    Utility.FolderCleanUp(Utility.GetTmpFolder());
                    try
                    {
                        MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, archivename);
                        Utility.UncompressZip(archivename, tempFolderPath);
                        File.Delete(archivename);
                        request.ResponseData = new ResponseStatus(Status.Ok);
                    }
                    catch
                    {
                        request.ResponseData = new ResponseStatus(Status.Error);
                    }
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS1")
                {
                    var serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    var reader = new StreamReader(Path.Combine(tempFolderPath, "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    var newProgramList = new List<ProgramBlock>();
                    foreach (ProgramBlock program in newProgramsData)
                    {
                        if (program.Address >= ProgramManager.USER_SPACE_PROGRAMS_START)
                        {
                            ProgramBlock p = new ProgramBlock();
                            p.Address = program.Address;
                            p.Name = program.Name;
                            p.Description = program.Description;
                            newProgramList.Add(p);
                        }
                    }
                    newProgramList.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                    {
                        string c1 = p1.Address.ToString();
                        string c2 = p2.Address.ToString();
                        return c1.CompareTo(c2);
                    });
                    request.ResponseData = newProgramList;
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS2")
                {
                    // Import automation groups
                    var serializer = new XmlSerializer(typeof(List<Group>));
                    var reader = new StreamReader(Path.Combine(tempFolderPath, "automationgroups.xml"));
                    var automationGroups = (List<Group>)serializer.Deserialize(reader);
                    reader.Close();
                    foreach (var automationGroup in automationGroups)
                    {
                        if (homegenie.AutomationGroups.Find(g => g.Name == automationGroup.Name) == null)
                        {
                            homegenie.AutomationGroups.Add(automationGroup);
                        }
                    }
                    homegenie.UpdateGroupsDatabase("Automation");
                    // Copy system configuration files
                    File.Copy(Path.Combine(tempFolderPath, "groups.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "groups.xml"), true);
                    File.Copy(Path.Combine(tempFolderPath, "modules.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modules.xml"), true);
                    File.Copy(Path.Combine(tempFolderPath, "scheduler.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scheduler.xml"), true);
                    // TODO: add backward compatibility for systemconfig.xml from HG 1.0 < r494
                    UpdateSystemConfig();
                    // Copy MIG configuration files if present (from folder lib/mig/*.xml)
                    string migLibFolder = Path.Combine(tempFolderPath, "lib", "mig");
                    if (Directory.Exists(migLibFolder))
                    {
                        foreach (string f in Directory.GetFiles(migLibFolder, "*.xml"))
                        {
                            File.Copy(f, Path.Combine("lib", "mig", Path.GetFileName(f)), true);
                        }
                    }
                    homegenie.SoftReload();
                    // Restore automation programs
                    string selectedPrograms = migCommand.GetOption(1);
                    serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    reader = new StreamReader(Path.Combine(tempFolderPath, "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    foreach (var program in newProgramsData)
                    {
                        var currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == program.Address);
                        program.IsRunning = false;
                        // Only restore user space programs
                        if (selectedPrograms.Contains("," + program.Address.ToString() + ",") && program.Address >= ProgramManager.USER_SPACE_PROGRAMS_START)
                        {
                            int oldPid = program.Address;
                            if (currentProgram == null)
                            {
                                var newPid = ((currentProgram != null && currentProgram.Address == program.Address) ? homegenie.ProgramManager.GeneratePid() : program.Address);
                                try
                                {
                                    File.Copy(Path.Combine(tempFolderPath, "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", newPid + ".dll"), true);
                                }
                                catch
                                {
                                }
                                program.Address = newPid;
                                homegenie.ProgramManager.ProgramAdd(program);
                            }
                            else if (currentProgram != null)
                            {
                                homegenie.ProgramManager.ProgramRemove(currentProgram);
                                try
                                {
                                    File.Copy(Path.Combine(tempFolderPath, "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", program.Address + ".dll"), true);
                                }
                                catch
                                {
                                }
                                homegenie.ProgramManager.ProgramAdd(program);
                            }
                            // Restore Arduino program folder ...
                            // TODO: this is untested yet...
                            if (program.Type.ToLower() == "arduino")
                            {
                                string sourceFolder = Path.Combine(tempFolderPath, "programs", "arduino", oldPid.ToString());
                                string arduinoFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", "arduino", program.Address.ToString());
                                if (Directory.Exists(arduinoFolder))
                                    Directory.Delete(arduinoFolder, true);
                                Directory.CreateDirectory(arduinoFolder);
                                foreach (string newPath in Directory.GetFiles(sourceFolder))
                                {
                                    File.Copy(newPath, newPath.Replace(sourceFolder, arduinoFolder), true);
                                }
                            }
                        }
                        else if (currentProgram != null && program.Address < ProgramManager.USER_SPACE_PROGRAMS_START)
                        {
                            // Only restore Enabled/Disabled status of system programs
                            currentProgram.IsEnabled = program.IsEnabled;
                        }
                    }
                    homegenie.UpdateProgramsDatabase();
                    homegenie.SaveData();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationReset")
                {
                    homegenie.RestoreFactorySettings();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationBackup")
                {
                    homegenie.BackupCurrentSettings();
                    (request.Context.Data as HttpListenerContext).Response.Redirect("/hg/html/homegenie_backup_config.zip");
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationLoad")
                {
                    homegenie.SoftReload();
                }
                break;

            case "Modules.Get":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    request.ResponseData = Utility.Module2Json(module, false);
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.ParameterGet":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    var parameter = Utility.ModuleParameterGet(module, migCommand.GetOption(2));
                    if (parameter != null)
                        request.ResponseData = JsonConvert.SerializeObject(parameter, Formatting.Indented);
                    else
                        request.ResponseData = new ResponseText("ERROR: Unknown parameter '" + migCommand.GetOption(2) + "'");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.ParameterSet":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    var parameter = Utility.ModuleParameterSet(module, migCommand.GetOption(2), migCommand.GetOption(3));
                    request.ResponseData = new ResponseText("OK");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.StatisticsGet":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    var parameter = Utility.ModuleParameterGet(module, migCommand.GetOption(2));
                    if (parameter != null)
                        request.ResponseData = JsonConvert.SerializeObject(parameter.Statistics, Formatting.Indented);
                    else
                        request.ResponseData = new ResponseText("ERROR: Unknown parameter '" + migCommand.GetOption(2) + "'");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.List":
                try
                {
                    homegenie.modules_Sort();
                    request.ResponseData = homegenie.GetJsonSerializedModules(migCommand.GetOption(0).ToLower() == "short");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.RoutingReset":
                try
                {
                    for (int m = 0; m < homegenie.Modules.Count; m++)
                    {
                        homegenie.Modules[m].RoutingNode = "";
                    }
                    request.ResponseData = new ResponseText("OK");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.Save":
                string body = request.RequestText;
                var newModules = JsonConvert.DeserializeObject(body) as JArray;
                for (int i = 0; i < newModules.Count; i++)
                {
                    try
                    {
                        var module = homegenie.Modules.Find(m => m.Address == newModules[i]["Address"].ToString() && m.Domain == newModules[i]["Domain"].ToString());
                        module.Name = newModules[i]["Name"].ToString();
                        //
                        try
                        {
                            module.DeviceType = (MIG.ModuleTypes)Enum.Parse(typeof(MIG.ModuleTypes), newModules[i]["DeviceType"].ToString(), true);
                        }
                        catch
                        {
                            // TODO: check what's wrong here...
                        }
                        //
                        var moduleProperties = newModules[i]["Properties"] as JArray;
                        for (int p = 0; p < moduleProperties.Count; p++)
                        {
                            string propertyName = moduleProperties[p]["Name"].ToString();
                            string propertyValue = moduleProperties[p]["Value"].ToString();
                            ModuleParameter parameter = null;
                            parameter = module.Properties.Find(delegate(ModuleParameter mp)
                            {
                                return mp.Name == propertyName;
                            });
                            //
                            if (propertyName == Properties.VirtualMeterWatts)
                            {
                                try
                                {
                                    propertyValue = double.Parse(propertyValue.Replace(",", "."), System.Globalization.CultureInfo.InvariantCulture).ToString();
                                }
                                catch
                                {
                                    propertyValue = "0";
                                }
                            }
                            //
                            if (parameter == null)
                            {
                                module.Properties.Add(new ModuleParameter() {
                                    Name = propertyName,
                                    Value = propertyValue
                                });
                            }
                            else
                            {
                                if (moduleProperties[p]["NeedsUpdate"] != null && moduleProperties[p]["NeedsUpdate"].ToString() == "true")
                                {
                                    parameter.Value = propertyValue;
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //TODO: notify exception?
                    }
                }
                homegenie.UpdateModulesDatabase();//write modules
                break;

            case "Modules.Update":
                string streamContent = request.RequestText;
                var newModule = JsonConvert.DeserializeObject<Module>(streamContent);
                var currentModule = homegenie.Modules.Find(p => p.Domain == newModule.Domain && p.Address == newModule.Address);
                //
                if (currentModule == null)
                {
                    homegenie.Modules.Add(newModule);
                }
                else
                {
                    currentModule.Name = newModule.Name;
                    currentModule.Description = newModule.Description;
                    currentModule.DeviceType = newModule.DeviceType;
                    foreach (var newParameter in newModule.Properties)
                    {
                        var currentParameter = currentModule.Properties.Find(mp => mp.Name == newParameter.Name);
                        if (currentParameter == null)
                        {
                            currentModule.Properties.Add(newParameter);
                        }
                        else if (newParameter.NeedsUpdate)
                        {
                            // reset current reporting Watts if VMWatts field is set to 0
                            if (newParameter.Name == Properties.VirtualMeterWatts && newParameter.DecimalValue == 0 && currentParameter.DecimalValue != 0)
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    currentModule.Domain,
                                    currentModule.Address,
                                    currentModule.Description,
                                    Properties.MeterWatts,
                                    "0.0"
                                );
                            }
                            currentParameter.Value = newParameter.Value;
                        }
                    }
                    // look for deleted properties
                    var deletedParameters = new List<ModuleParameter>();
                    foreach (var parameter in currentModule.Properties)
                    {
                        var currentParameter = newModule.Properties.Find(mp => mp.Name == parameter.Name);
                        if (currentParameter == null)
                        {
                            deletedParameters.Add(parameter);
                        }
                    }
                    foreach (var parameter in deletedParameters)
                    {
                        currentModule.Properties.Remove(parameter);
                    }
                    deletedParameters.Clear();
                }
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Modules.Delete":
                var deletedModule = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                if (deletedModule != null)
                {
                    homegenie.Modules.Remove(deletedModule);
                }
                request.ResponseData = new ResponseText("OK");
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Stores.List":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        //module.Stores
                        response = "[";
                        for (int s = 0; s < module.Stores.Count; s++)
                        {
                            response += "{ \"Name\": \"" + Utility.XmlEncode(module.Stores[s].Name) + "\", \"Description\": \"" + Utility.XmlEncode(module.Stores[s].Description) + "\" },";
                        }
                        response = response.TrimEnd(',') + "]";
                        request.ResponseData = response;
                    }

                }
                break;

            case "Stores.Delete":
                break;

            case "Stores.ItemList":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        response = "[";
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        for (int p = 0; p < store.List.Count; p++)
                        {
                            response += "{ \"Name\": \"" + Utility.XmlEncode(store.List[p].Name) + "\", \"Description\": \"" + Utility.XmlEncode(store.List[p].Description) + "\" },";
                        }
                        response = response.TrimEnd(',') + "]";
                        request.ResponseData = response;
                    }
                }
                break;

            case "Stores.ItemDelete":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var name = migCommand.GetOption(3);
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.List.RemoveAll(i => i.Name == name);
                    }
                }
                break;

            case "Stores.ItemGet":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        request.ResponseData = store.Get(migCommand.GetOption(3));
                    }
                }
                break;

            case "Stores.ItemSet":
                {
                    // value is the POST body
                    string itemData = request.RequestText;
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.Get(migCommand.GetOption(3)).Value = itemData;
                    }
                }
                break;

            case "Groups.ModulesList":
                var theGroup = homegenie.Groups.Find(z => z.Name.ToLower() == migCommand.GetOption(0).Trim().ToLower());
                if (theGroup != null)
                {
                    string jsonmodules = "[";
                    for (int m = 0; m < theGroup.Modules.Count; m++)
                    {
                        var groupModule = homegenie.Modules.Find(mm => mm.Domain == theGroup.Modules[m].Domain && mm.Address == theGroup.Modules[m].Address);
                        if (groupModule != null)
                        {
                            jsonmodules += Utility.Module2Json(groupModule, false) + ",\n";
                        }
                    }
                    jsonmodules = jsonmodules.TrimEnd(',', '\n');
                    jsonmodules += "]";
                    request.ResponseData = jsonmodules;
                }
                break;
            case "Groups.List":
                try
                {
                    request.ResponseData = homegenie.GetGroups(migCommand.GetOption(0));
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Rename":
                string oldName = migCommand.GetOption(1);
                string newName = request.RequestText;
                var currentGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == oldName);
                var newGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == newName);
                // ensure that the new group name is not already defined
                if (newGroup == null && currentGroup != null)
                {
                    currentGroup.Name = newName;
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    //cmd.response = JsonHelper.GetSimpleResponse("OK");
                }
                else
                {
                    request.ResponseData = new ResponseText("New name already in use.");
                }
                break;

            case "Groups.Sort":
                {
                    var newGroupList = new List<Group>();
                    string[] newPositionOrder = request.RequestText.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < newPositionOrder.Length; i++)
                    {
                        newGroupList.Add(homegenie.GetGroups(migCommand.GetOption(0))[int.Parse(newPositionOrder[i])]);
                    }
                    homegenie.GetGroups(migCommand.GetOption(0)).Clear();
                    homegenie.GetGroups(migCommand.GetOption(0)).RemoveAll(g => true);
                    homegenie.GetGroups(migCommand.GetOption(0)).AddRange(newGroupList);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                }
                try
                {
                    request.ResponseData = homegenie.GetGroups(migCommand.GetOption(0));
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.SortModules":
                {
                    string groupName = migCommand.GetOption(1);
                    Group sortGroup = null;
                    sortGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == groupName);
                    if (sortGroup != null)
                    {
                        var newModulesReference = new List<ModuleReference>();
                        string[] newPositionOrder = request.RequestText.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < newPositionOrder.Length; i++)
                        {
                            newModulesReference.Add(sortGroup.Modules[int.Parse(newPositionOrder[i])]);
                        }
                        sortGroup.Modules.Clear();
                        sortGroup.Modules = newModulesReference;
                        homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    }
                }
                try
                {
                    request.ResponseData = homegenie.GetGroups(migCommand.GetOption(0));
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Add":
                string newGroupName = request.RequestText;
                homegenie.GetGroups(migCommand.GetOption(0)).Add(new Group() { Name = newGroupName });
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.Delete":
                string deletedGroupName = request.RequestText;
                Group deletedGroup = null;
                try
                {
                    deletedGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == deletedGroupName);
                }
                catch
                {
                }
                //
                if (deletedGroup != null)
                {
                    homegenie.GetGroups(migCommand.GetOption(0)).Remove(deletedGroup);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                    if (migCommand.GetOption(0).ToLower() == "automation")
                    {
                        var groupPrograms = homegenie.ProgramManager.Programs.FindAll(p => p.Group.ToLower() == deletedGroup.Name.ToLower());
                        if (groupPrograms != null)
                        {
                            // delete group association from programs
                            foreach (ProgramBlock program in groupPrograms)
                            {
                                program.Group = "";
                            }
                        }
                    }
                }
                break;

            case "Groups.Save":
                string jsonGroups = request.RequestText;
                var newGroups = JsonConvert.DeserializeObject<List<Group>>(jsonGroups);
                for (int i = 0; i < newGroups.Count; i++)
                {
                    try
                    {
                        var group = homegenie.Groups.Find(z => z.Name == newGroups[i].Name);
                        group.Modules.Clear();
                        group.Modules = newGroups[i].Modules;
                    }
                    catch
                    {
                    }
                }
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.WallpaperList":
                List<string> wallpaperList = new List<string>();
                var images = Directory.GetFiles(groupWallpapersPath);
                for (int i = 0; i < images.Length; i++)
                {
                    wallpaperList.Add(Path.GetFileName(images[i]));
                }
                request.ResponseData = wallpaperList;

                break;

            case "Groups.WallpaperAdd":
                {
                    string wallpaperFile = "";
                    try
                    {
                        wallpaperFile = MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, groupWallpapersPath);
                    }
                    catch
                    {
                    }
                    request.ResponseData = new ResponseText(Path.GetFileName(wallpaperFile));
                }
                break;

            case "Groups.WallpaperSet":
                {
                    string wpGroupName = migCommand.GetOption(0);
                    var wpGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == wpGroupName);
                    if (wpGroup != null)
                    {
                        wpGroup.Wallpaper = migCommand.GetOption(1);
                        homegenie.UpdateGroupsDatabase("Control");
                    }
                }
                break;

            case "Groups.WallpaperDelete":
                {
                    string wallpaperFile = migCommand.GetOption(0);
                    wallpaperFile = Path.Combine(groupWallpapersPath, Path.GetFileName(wallpaperFile));
                    if (File.Exists(wallpaperFile))
                    {
                        File.Delete(wallpaperFile);
                    }
                    request.ResponseData = new ResponseText("OK");
                }
                break;

            case "Widgets.List":
                List<string> widgetsList = new List<string>();
                var groups = Directory.GetDirectories(widgetBasePath);
                for (int d = 0; d < groups.Length; d++)
                {
                    var categories = Directory.GetDirectories(groups[d]);
                    for (int c = 0; c < categories.Length; c++)
                    {
                        var widgets = Directory.GetFiles(categories[c], "*.js");
                        var group = groups[d].Replace(widgetBasePath, "").Substring(1);
                        var category = categories[c].Replace(groups[d], "").Substring(1);
                        for (int w = 0; w < widgets.Length; w++)
                        {
                            widgetsList.Add(group + "/" + category + "/" + Path.GetFileNameWithoutExtension(widgets[w]));
                        }
                    }
                }
                request.ResponseData = widgetsList;
                break;

            case "Widgets.Add":
                {
                    var status = Status.Error;
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    widgetParts[0] = new String(widgetParts[0].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[1] = new String(widgetParts[1].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[2] = new String(widgetParts[2].Where(Char.IsLetter).ToArray()).ToLower();
                    if (!String.IsNullOrWhiteSpace(widgetParts[0]) && !String.IsNullOrWhiteSpace(widgetParts[1]) && !String.IsNullOrWhiteSpace(widgetParts[2]))
                    {
                        string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                        if (!Directory.Exists(filePath))
                        {
                            Directory.CreateDirectory(filePath);
                        }
                        // copy widget template into the new widget
                        var htmlFile = Path.Combine(filePath, widgetParts[2] + ".html");
                        var jsFile = Path.Combine(filePath, widgetParts[2] + ".js");
                        if (!File.Exists(htmlFile) && !File.Exists(jsFile))
                        {
                            File.Copy(Path.Combine(widgetBasePath, "template.html"), htmlFile);
                            File.Copy(Path.Combine(widgetBasePath, "template.js"), jsFile);
                            status = Status.Ok;
                        }
                    }
                    request.ResponseData = new ResponseStatus(status);
                }
                break;

            case "Widgets.Save":
                {
                    var status = Status.Error;
                    string widgetData = request.RequestText;
                    string fileType = migCommand.GetOption(0);
                    string widgetPath = migCommand.GetOption(1); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    switch (fileType)
                    {
                    // html/javascript source
                    case "html":
                    case "js":
                        using (TextWriter widgetWriter = new StreamWriter(Path.Combine(filePath, widgetParts[2] + "." + fileType)))
                        {
                            widgetWriter.Write(widgetData);
                        }
                        status = Status.Ok;
                        break;
                    // style sheet file
                    case "css":
                        break;
                    // locale file
                    case "json":
                        break;
                    // image file
                    case "jpg":
                    case "png":
                    case "gif":
                        break;
                    }
                    request.ResponseData = new ResponseStatus(status);
                }
                break;

            case "Widgets.Delete":
                {
                    var status = Status.Error;
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1], widgetParts[2] + ".");
                    if (File.Exists(filePath + "html"))
                    {
                        File.Delete(filePath + "html");
                        status = Status.Ok;
                    }
                    if (File.Exists(filePath + "js"))
                    {
                        File.Delete(filePath + "js");
                        status = Status.Ok;
                    }
                    request.ResponseData = new ResponseStatus(status);
                }
                break;

            case "Widgets.Export":
                {
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string widgetBundle = Path.Combine(tempFolderPath, "export", widgetPath.Replace('/', '_') + ".zip");
                    if (File.Exists(widgetBundle))
                    {
                        File.Delete(widgetBundle);
                    }
                    else if (!Directory.Exists(Path.GetDirectoryName(widgetBundle)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(widgetBundle));
                    }
                    string inputPath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    string outputPath = Path.Combine(widgetParts[0], widgetParts[1]);
                    string infoFilePath = Path.Combine(inputPath, "widget.info");
                    File.WriteAllText(infoFilePath, "HomeGenie exported widget.");
                    Utility.AddFileToZip(widgetBundle, infoFilePath, "widget.info");
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".html"), Path.Combine(outputPath, widgetParts[2] + ".html"));
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".js"), Path.Combine(outputPath, widgetParts[2] + ".js"));
                    //
                    byte[] bundleData = File.ReadAllBytes(widgetBundle);
                    (request.Context.Data as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment; filename=\"" + widgetPath.Replace('/', '_') + ".zip\"");
                    (request.Context.Data as HttpListenerContext).Response.OutputStream.Write(bundleData, 0, bundleData.Length);
                }
                break;
                
            case "Widgets.Import":
                {
                    string archiveFile = Path.Combine(tempFolderPath, "import_widget.zip");
                    string importPath = Path.Combine(tempFolderPath, "import");
                    if (Directory.Exists(importPath))
                        Directory.Delete(importPath, true);
                    MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, archiveFile);
                    if (WidgetImport(archiveFile, importPath))
                    {
                        request.ResponseData = new ResponseText("OK");
                    }
                    else
                    {
                        request.ResponseData = new ResponseText("ERROR");
                    }
                }
                break;

            case "Widgets.Parse":
                {
                    string widgetData = request.RequestText;
                    var parser = new JavaScriptParser();
                    try
                    {
                        request.ResponseData = new ResponseText("OK");
                        parser.Parse(widgetData);
                    }
                    catch (Jint.Parser.ParserException e)
                    {
                        request.ResponseData = new ResponseText("ERROR (" + e.LineNumber + "," + e.Column + "): " + e.Description);
                    }
                }
                break;

            case "Package.Install":
                {
                    string pkgBaseUrl = migCommand.GetOption(0);
                    string installFolder = Path.Combine(tempFolderPath, "pkg");
                    dynamic pkgData = null;
                    bool success = true;
                    // Download package specs
                    homegenie.RaiseEvent(
                        Domains.HomeGenie_System,
                        Domains.HomeGenie_PackageInstaller,
                        SourceModule.Master,
                        "HomeGenie Package Installer",
                        Properties.InstallProgressMessage,
                        "= Downloading: package.json"
                    );
                    using (var client = new WebClient())
                    {
                        try
                        {
                            string pkgJson = "[" + client.DownloadString(pkgBaseUrl + "/package.json") + "]";
                            pkgData = (JsonConvert.DeserializeObject(pkgJson) as JArray)[0];
                        }
                        catch
                        {
                            success = false;
                        }
                        client.Dispose();
                    }
                    // Download and install package files
                    if (success && pkgData != null)
                    {
                        // Import Automation Programs in package
                        foreach (var program in pkgData.programs)
                        {
                            homegenie.RaiseEvent(
                                Domains.HomeGenie_System,
                                Domains.HomeGenie_PackageInstaller,
                                SourceModule.Master,
                                "HomeGenie Package Installer",
                                Properties.InstallProgressMessage,
                                "= Downloading: " + program.file.ToString()
                            );
                            Utility.FolderCleanUp(installFolder);
                            string programFile = Path.Combine(installFolder, program.file.ToString());
                            if (File.Exists(programFile))
                                File.Delete(programFile);
                            using (var client = new WebClient())
                            {
                                try
                                {
                                    client.DownloadFile(pkgBaseUrl + "/" + program.file.ToString(), programFile);
                                }
                                catch
                                {
                                    success = false;
                                }
                                client.Dispose();
                            }
                            if (success)
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    Domains.HomeGenie_PackageInstaller,
                                    SourceModule.Master,
                                    "HomeGenie Package Installer",
                                    Properties.InstallProgressMessage,
                                    "= Installing: " + program.name.ToString()
                                );
                                int pid = int.Parse(program.uid.ToString());
                                var oldProgram = homegenie.ProgramManager.ProgramGet(pid);
                                if (oldProgram != null)
                                {
                                    homegenie.RaiseEvent(
                                        Domains.HomeGenie_System,
                                        Domains.HomeGenie_PackageInstaller,
                                        SourceModule.Master,
                                        "HomeGenie Package Installer",
                                        Properties.InstallProgressMessage,
                                        "= Replacing: '" + oldProgram.Name + "' with pid " + pid
                                    );
                                    homegenie.ProgramManager.ProgramRemove(oldProgram);
                                }
                                var programBlock = ProgramImport(homegenie, pid, programFile, program.group.ToString());
                                if (programBlock != null)
                                {
                                    programBlock.IsEnabled = true;
                                    homegenie.RaiseEvent(
                                        Domains.HomeGenie_System,
                                        Domains.HomeGenie_PackageInstaller,
                                        SourceModule.Master,
                                        "HomeGenie Package Installer",
                                        Properties.InstallProgressMessage,
                                        "= Installed: '" + program.name.ToString() + "' as pid " + pid
                                    );
                                }
                                else
                                {
                                    // TODO: report error and stop the package install procedure
                                    success = false;
                                }
                            }
                        }
                        // Import Widgets in package
                        foreach (var widget in pkgData.widgets)
                        {
                            homegenie.RaiseEvent(
                                Domains.HomeGenie_System,
                                Domains.HomeGenie_PackageInstaller,
                                SourceModule.Master,
                                "HomeGenie Package Installer",
                                Properties.InstallProgressMessage,
                                "= Downloading: " + widget.file.ToString()
                            );
                            Utility.FolderCleanUp(installFolder);
                            string widgetFile = Path.Combine(installFolder, widget.file.ToString());
                            if (File.Exists(widgetFile))
                                File.Delete(widgetFile);
                            using (var client = new WebClient())
                            {
                                try
                                {
                                    client.DownloadFile(pkgBaseUrl + "/" + widget.file.ToString(), widgetFile);
                                }
                                catch
                                {
                                    success = false;
                                }
                                client.Dispose();
                            }
                            if (success && WidgetImport(widgetFile, installFolder))
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    Domains.HomeGenie_PackageInstaller,
                                    SourceModule.Master,
                                    "HomeGenie Package Installer",
                                    Properties.InstallProgressMessage,
                                    "= Installed: '" + widget.name.ToString() + "'"
                                );
                            }
                            else
                            {
                                // TODO: report error and stop the package install procedure
                                success = false;
                            }
                        }
                        // Import MIG Interfaces in package
                        foreach (var migface in pkgData.interfaces)
                        {
                            homegenie.RaiseEvent(
                                Domains.HomeGenie_System,
                                Domains.HomeGenie_PackageInstaller,
                                SourceModule.Master,
                                "HomeGenie Package Installer",
                                Properties.InstallProgressMessage,
                                "= Downloading: " + migface.file.ToString()
                            );
                            Utility.FolderCleanUp(installFolder);
                            string migfaceFile = Path.Combine(installFolder, migface.file.ToString());
                            if (File.Exists(migfaceFile))
                                File.Delete(migfaceFile);
                            using (var client = new WebClient())
                            {
                                try
                                {
                                    client.DownloadFile(pkgBaseUrl + "/" + migface.file.ToString(), migfaceFile);
                                    Utility.UncompressZip(migfaceFile, installFolder);
                                    File.Delete(migfaceFile);
                                }
                                catch
                                {
                                    success = false;
                                }
                                client.Dispose();
                            }
                            if (success && InterfaceInstall(installFolder))
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    Domains.HomeGenie_PackageInstaller,
                                    SourceModule.Master,
                                    "HomeGenie Package Installer",
                                    Properties.InstallProgressMessage,
                                    "= Installed: '" + migface.name.ToString() + "'"
                                );
                            }
                            else
                            {
                                // TODO: report error and stop the package install procedure
                                success = false;
                            }
                        }
                    }
                    else
                    {
                        success = false;
                    }
                    if (success)
                    {
                        // TODO: add package info to the list of installed packages
                        // TODO: this package file must be included in the backup file also
                        // TODO: and the restore process should also download and install
                        // TODO: all packages included in it
                        homegenie.RaiseEvent(
                            Domains.HomeGenie_System,
                            Domains.HomeGenie_PackageInstaller,
                            SourceModule.Master,
                            "HomeGenie Package Installer",
                            Properties.InstallProgressMessage,
                            "= Status: Package Install Successful"
                        );
                    }
                    else
                    {
                        homegenie.RaiseEvent(
                            Domains.HomeGenie_System,
                            Domains.HomeGenie_PackageInstaller,
                            SourceModule.Master,
                            "HomeGenie Package Installer",
                            Properties.InstallProgressMessage,
                            "= Status: Package Install Error"
                        );
                    }
                    request.ResponseData = new ResponseText(success ? "OK" : "ERROR");
                }
                break;
            }
        }
Beispiel #45
0
        public void ProcessRequest(MIGClientRequest request, MIGInterfaceCommand migCommand)
        {

            switch (migCommand.Command)
            {
            case "Interfaces.List":
                migCommand.Response = "[ ";
                foreach (var kv in homegenie.Interfaces)
                {
                    var migInterface = kv.Value;
                    var ifaceConfig = homegenie.SystemConfiguration.MIGService.GetInterface(migInterface.Domain);
                    if (ifaceConfig == null || !ifaceConfig.IsEnabled)
                    {
                        continue;
                    }
                    migCommand.Response += "{ \"Domain\" : \"" + migInterface.Domain + "\", \"IsConnected\" : \"" + migInterface.IsConnected + "\" },";
                }
                if (homegenie.UpdateChecker != null && homegenie.UpdateChecker.IsUpdateAvailable)
                {
                    migCommand.Response += "{ \"Domain\" : \"HomeGenie.UpdateChecker\", \"IsConnected\" : \"True\" }";
                    migCommand.Response += " ]";
                }
                else
                {
                    migCommand.Response = migCommand.Response.Substring(0, migCommand.Response.Length - 1) + " ]";
                }
                    //
                break;

            //TODO: should this be moved somewhere to MIG?
            case "Interfaces.Configure":
                switch (migCommand.GetOption(0))
                {
                case "Hardware.SerialPorts":
                    if (Environment.OSVersion.Platform == PlatformID.Unix)
                    {
                        var serialPorts = System.IO.Ports.SerialPort.GetPortNames();
                        var portList = new List<string>();
                        for (int p = serialPorts.Length - 1; p >= 0; p--)
                        {
                            if (serialPorts[p].Contains("/ttyS") || serialPorts[p].Contains("/ttyUSB"))
                            {
                                portList.Add(serialPorts[p]);
                            }
                        }
                        if (Raspberry.Board.Current.IsRaspberryPi && !portList.Contains("/dev/ttyAMA0"))
                        {
                            portList.Add("/dev/ttyAMA0");
                        }
                        migCommand.Response = JsonHelper.GetSimpleResponse(JsonConvert.SerializeObject(portList));
                    }
                    else
                    {
                        var portNames = System.IO.Ports.SerialPort.GetPortNames();
                        migCommand.Response = JsonHelper.GetSimpleResponse(JsonConvert.SerializeObject(portNames));
                    }
                    break;

                }
                break;

            case "System.Configure":
                if (migCommand.GetOption(0) == "Service.Restart")
                {
                    Program.Quit(true);
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.UpdatesList")
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.UpdateChecker.RemoteUpdates);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.Check")
                {
                    homegenie.UpdateChecker.Check();
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.DownloadUpdate")
                {
                    var resultMessage = "ERROR";
                    bool success = homegenie.UpdateChecker.DownloadUpdateFiles();
                    if (success)
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                        }
                        else
                        {
                            resultMessage = "OK";
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(resultMessage);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.InstallUpdate") //UpdateManager.InstallProgramsCommit")
                {
                    string resultMessage = "OK";
                    if (!homegenie.UpdateChecker.InstallFiles())
                    {
                        resultMessage = "ERROR";
                    }
                    else
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                            Utility.RunAsyncTask(() =>
                            {
                                Thread.Sleep(2000);
                                Program.Quit(true);
                            });
                        }
                        else
                        {
                            homegenie.LoadConfiguration();
                            homegenie.MigService.ClearWebCache();
                            homegenie.UpdateChecker.Check();
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(resultMessage);
                }
                else if (migCommand.GetOption(0) == "HttpService.SetWebCacheEnabled")
                {
                    if (migCommand.GetOption(1) == "1")
                    {
                        homegenie.MigService.IsWebCacheEnabled = true;
                        homegenie.SystemConfiguration.MIGService.EnableWebCache = "true";
                    }
                    else
                    {
                        homegenie.MigService.IsWebCacheEnabled = false;
                        homegenie.SystemConfiguration.MIGService.EnableWebCache = "false";
                    }
                    homegenie.SystemConfiguration.Update();
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetWebCacheEnabled")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.MigService.IsWebCacheEnabled ? "1" : "0");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetPort")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.SystemConfiguration.HomeGenie.ServicePort.ToString());
                }
                else if (migCommand.GetOption(0) == "HttpService.SetPort")
                {
                    try
                    {
                        homegenie.SystemConfiguration.HomeGenie.ServicePort = int.Parse(migCommand.GetOption(1));
                        homegenie.SystemConfiguration.Update();
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "SystemLogging.DownloadCsv")
                {
                    string csvlog = "";
                    string logpath = Path.Combine("log", "homegenie.log");
                    if (migCommand.GetOption(1) == "1")
                    {
                        logpath = Path.Combine("log", "homegenie.log.bak");
                    }
                    if (File.Exists(logpath))
                    {
                        using (var fs = new FileStream(logpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (var sr = new StreamReader(fs, Encoding.Default))
                        {
                            csvlog = sr.ReadToEnd();
                        }
                    }
                    (request.Context as HttpListenerContext).Response.AddHeader(
                        "Content-Disposition",
                        "attachment;filename=homegenie_log_" + migCommand.GetOption(1) + ".csv"
                    );
                    migCommand.Response = csvlog;
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Enable")
                {
                    SystemLogger.Instance.OpenLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "true";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Disable")
                {
                    SystemLogger.Instance.CloseLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "false";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.IsEnabled")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse((homegenie.SystemConfiguration.HomeGenie.EnableLogFile.ToLower().Equals("true") ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "Security.SetPassword")
                {
                    // password only for now, with fixed user login 'admin'
                    string pass = migCommand.GetOption(1) == "" ? "" : MIG.Utility.Encryption.SHA1.GenerateHashString(migCommand.GetOption(1));
                    homegenie.MigService.SetWebServicePassword(pass);
                    homegenie.SystemConfiguration.HomeGenie.UserPassword = pass;
                    // regenerate encrypted files
                    homegenie.SystemConfiguration.Update();
                    homegenie.UpdateModulesDatabase();
                }
                else if (migCommand.GetOption(0) == "Security.ClearPassword")
                {
                    homegenie.MigService.SetWebServicePassword("");
                    homegenie.SystemConfiguration.HomeGenie.UserPassword = "";
                    // regenerate encrypted files
                    homegenie.SystemConfiguration.Update();
                    homegenie.UpdateModulesDatabase();
                }
                else if (migCommand.GetOption(0) == "Security.HasPassword")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse((homegenie.SystemConfiguration.HomeGenie.UserPassword != "" ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestore")
                {
                    // file uploaded by user
                    string archivename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                      "tmp",
                                                      "homegenie_restore_config.zip");
                    if (!Directory.Exists("tmp"))
                    {
                        Directory.CreateDirectory("tmp");
                    }
                    try
                    {
                        var downloadedMessageInfo = new DirectoryInfo("tmp");
                        foreach (var file in downloadedMessageInfo.GetFiles())
                        {
                            file.Delete();
                        }
                        foreach (DirectoryInfo directory in downloadedMessageInfo.GetDirectories())
                        {
                            directory.Delete(true);
                        }
                    }
                    catch
                    {
                    }
                    //
                    try
                    {
                        var encoding = (request.Context as HttpListenerContext).Request.ContentEncoding;
                        string boundary = MIG.Gateways.WebServiceUtility.GetBoundary((request.Context as HttpListenerContext).Request.ContentType);
                        MIG.Gateways.WebServiceUtility.SaveFile(encoding,
                                                                boundary,
                                                                request.InputStream,
                                                                archivename);
                        homegenie.UnarchiveConfiguration(archivename,
                                                         Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                                          "tmp"));
                        File.Delete(archivename);
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS1")
                {
                    var serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    var reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                               "tmp",
                                                               "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    var newProgramList = new List<ProgramBlock>();
                    foreach (ProgramBlock program in newProgramsData)
                    {
                        if (program.Address >= ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            ProgramBlock p = new ProgramBlock();
                            p.Address = program.Address;
                            p.Name = program.Name;
                            p.Description = program.Description;
                            newProgramList.Add(p);
                        }
                    }
                    newProgramList.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                    {
                        string c1 = p1.Address.ToString();
                        string c2 = p2.Address.ToString();
                        return c1.CompareTo(c2);
                    });
                    migCommand.Response = JsonConvert.SerializeObject(newProgramList);
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS2")
                {
                    //
                    var serializer = new XmlSerializer(typeof(List<Group>));
                    var reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                           "tmp",
                                                           "automationgroups.xml"));
                    var automationGroups = (List<Group>)serializer.Deserialize(reader);
                    reader.Close();
                    //
                    foreach (var automationGroup in automationGroups)
                    {
                        if (homegenie.AutomationGroups.Find(g => g.Name == automationGroup.Name) == null)
                        {
                            homegenie.AutomationGroups.Add(automationGroup);
                        }
                    }
                    //
                    homegenie.UpdateGroupsDatabase("Automation");
                    //
                    //File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp", "automationgroups.xml"), "./automationgroups.xml", true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp", "groups.xml"),
                              Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "groups.xml"),
                              true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp", "lircconfig.xml"),
                              Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "lircconfig.xml"),
                              true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp", "modules.xml"),
                              Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modules.xml"),
                              true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp", "systemconfig.xml"),
                              Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "systemconfig.xml"),
                              true);
                    //
                    homegenie.LoadConfiguration();
                    //
                    // Restore automation programs
                    string selectedPrograms = migCommand.GetOption(1);
                    serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                               "tmp",
                                                               "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    foreach (var program in newProgramsData)
                    {
                        var currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == program.Address);
                        // Only restore user space programs
                        if (selectedPrograms.Contains("," + program.Address.ToString() + ",") && program.Address >= ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            int oldPid = program.Address;
                            if (currentProgram == null)
                            {
                                var newPid = ((currentProgram != null && currentProgram.Address == program.Address) ? homegenie.ProgramEngine.GeneratePid() : program.Address);
                                try
                                {
                                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                           "tmp",
                                                           "programs",
                                                           program.Address + ".dll"),
                                              Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                 "programs",
                                                 newPid + ".dll"),
                                              true);
                                }
                                catch
                                {
                                }
                                program.Address = newPid;
                                homegenie.ProgramEngine.ProgramAdd(program);
                            }
                            else if (currentProgram != null)
                            {
                                homegenie.ProgramEngine.ProgramRemove(currentProgram);
                                try
                                {
                                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                           "tmp",
                                                           "programs",
                                                           program.Address + ".dll"),
                                              Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                 "programs",
                                                 program.Address + ".dll"),
                                              true);
                                }
                                catch
                                {
                                }
                                homegenie.ProgramEngine.ProgramAdd(program);
                            }
                            // Restore Arduino program folder ...
                            // TODO: this is untested yet...
                            if (program.Type.ToLower() == "arduino")
                            {
                                string sourceFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                                   "tmp",
                                                                   "programs",
                                                                   "arduino",
                                                                   oldPid.ToString());
                                string arduinoFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                                    "programs",
                                                                    "arduino",
                                                                    program.Address.ToString());
                                if (Directory.Exists(arduinoFolder)) Directory.Delete(arduinoFolder, true);
                                Directory.CreateDirectory(arduinoFolder);
                                foreach (string newPath in Directory.GetFiles(sourceFolder))
                                {
                                    File.Copy(newPath, newPath.Replace(sourceFolder, arduinoFolder), true);
                                }
                            }
                        }
                        else if (currentProgram != null && program.Address < ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            // Only restore Enabled/Disabled status of system programs
                            currentProgram.IsEnabled = program.IsEnabled;
                        }
                    }
                    //
                    homegenie.UpdateProgramsDatabase();
                    //
                    // regenerate encrypted files
                    homegenie.UpdateModulesDatabase();
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationReset")
                {
                    homegenie.RestoreFactorySettings();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationBackup")
                {
                    homegenie.BackupCurrentSettings();
                    (request.Context as HttpListenerContext).Response.Redirect("/hg/html/homegenie_backup_config.zip");
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationLoad")
                {
                    homegenie.LoadConfiguration();
                }
                break;

            case "Modules.Get":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    migCommand.Response = Utility.Module2Json(module, false);
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.List":
                try
                {
                    homegenie.modules_Sort();
                    migCommand.Response = homegenie.GetJsonSerializedModules(migCommand.GetOption(0).ToLower() == "short");
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.RoutingReset":
                try
                {
                    for (int m = 0; m < homegenie.Modules.Count; m++)
                    {
                        homegenie.Modules[m].RoutingNode = "";
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.Save":
                string body = new StreamReader(request.InputStream).ReadToEnd();
                var newModules = JsonConvert.DeserializeObject(body) as JArray;
                for (int i = 0; i < newModules.Count; i++)
                {
                    try
                    {
                        var module = homegenie.Modules.Find(m => m.Address == newModules[i]["Address"].ToString() && m.Domain == newModules[i]["Domain"].ToString());
                        module.Name = newModules[i]["Name"].ToString();
                        //
                        try
                        {
                            module.DeviceType = (MIG.ModuleTypes)Enum.Parse(typeof(MIG.ModuleTypes),
                                                                            newModules[i]["DeviceType"].ToString(),
                                                                            true);
                        }
                        catch
                        {
                            // TODO: check what's wrong here...
                        }
                        //
                        var moduleProperties = newModules[i]["Properties"] as JArray;
                        for (int p = 0; p < moduleProperties.Count; p++)
                        {
                            string propertyName = moduleProperties[p]["Name"].ToString();
                            string propertyValue = moduleProperties[p]["Value"].ToString();
                            ModuleParameter parameter = null;
                            parameter = module.Properties.Find(delegate(ModuleParameter mp)
                            {
                                return mp.Name == propertyName;
                            });
                            //
                            if (propertyName == ModuleParameters.MODPAR_VIRTUALMETER_WATTS)
                            {
                                try
                                {
                                    propertyValue = double.Parse(propertyValue.Replace(",", "."),
                                                                 System.Globalization.CultureInfo.InvariantCulture).ToString();
                                }
                                catch
                                {
                                    propertyValue = "0";
                                }
                            }
                            //
                            if (parameter == null)
                            {
                                module.Properties.Add(new ModuleParameter() {
                                    Name = propertyName,
                                    Value = propertyValue
                                });
                            }
                            else //if (true)
                            {
                                if (moduleProperties[p]["NeedsUpdate"] != null && moduleProperties[p]["NeedsUpdate"].ToString() == "true")
                                {
                                    parameter.Value = propertyValue;
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //TODO: notify exception?
                    }
                }
                homegenie.UpdateModulesDatabase();//write modules
                break;

            case "Modules.Update":
                string streamContent = new StreamReader(request.InputStream).ReadToEnd();
                var newModule = JsonConvert.DeserializeObject<Module>(streamContent);
                var currentModule = homegenie.Modules.Find(p => p.Domain == newModule.Domain && p.Address == newModule.Address);
                    //
                if (currentModule == null)
                {
                    homegenie.Modules.Add(newModule);
                }
                else
                {
                    currentModule.Name = newModule.Name;
                    currentModule.Description = newModule.Description;
                    currentModule.DeviceType = newModule.DeviceType;
                    //cm.Properties = mod.Properties;

                    foreach (var newParameter in newModule.Properties)
                    {
                        var currentParameter = currentModule.Properties.Find(mp => mp.Name == newParameter.Name);
                        if (currentParameter == null)
                        {
                            currentModule.Properties.Add(newParameter);
                        }
                        else if (newParameter.NeedsUpdate)
                        {
                            currentParameter.Value = newParameter.Value;
                        }
                    }
                    // look for deleted properties
                    var deletedParameters = new List<ModuleParameter>();
                    foreach (var parameter in currentModule.Properties)
                    {
                        var currentParameter = newModule.Properties.Find(mp => mp.Name == parameter.Name);
                        if (currentParameter == null)
                        {
                            deletedParameters.Add(parameter);
                        }
                    }
                    foreach (var parameter in deletedParameters)
                    {
                        currentModule.Properties.Remove(parameter);
                    }
                    deletedParameters.Clear();
                }
                    //
                homegenie.UpdateModulesDatabase();
                break;

            case "Modules.Delete":
                var deletedModule = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                if (deletedModule != null)
                {
                    homegenie.Modules.Remove(deletedModule);
                }
                migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                    //
                homegenie.UpdateModulesDatabase();
                break;

            case "Groups.ModulesList":
                var theGroup = homegenie.Groups.Find(z => z.Name.ToLower() == migCommand.GetOption(0).Trim().ToLower());
                if (theGroup != null)
                {
                    string jsonmodules = "[";
                    for (int m = 0; m < theGroup.Modules.Count; m++)
                    {
                        var groupModule = homegenie.Modules.Find(mm => mm.Domain == theGroup.Modules[m].Domain && mm.Address == theGroup.Modules[m].Address);
                        if (groupModule != null)
                        {
                            jsonmodules += Utility.Module2Json(groupModule, false) + ",\n";
                        }

                    }
                    jsonmodules = jsonmodules.TrimEnd(',', '\n');
                    jsonmodules += "]";
                    migCommand.Response = jsonmodules;
                }
                break;
            case "Groups.List":
                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Rename":
                string oldName = migCommand.GetOption(1);
                string newName = new StreamReader(request.InputStream).ReadToEnd();
                var currentGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == oldName);
                var newGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == newName);
                    // ensure that the new group name is not already defined
                if (newGroup == null && currentGroup != null)
                {
                    currentGroup.Name = newName;
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    //cmd.response = JsonHelper.GetSimpleResponse("OK");
                }
                else
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("New name already in use.");
                }
                break;

            case "Groups.Sort":
                using (var reader = new StreamReader(request.InputStream))
                {
                    var newGroupList = new List<Group>();
                    string[] newPositionOrder = reader.ReadToEnd().Split(new[] { ';' },
                                                                         StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < newPositionOrder.Length; i++)
                    {
                        newGroupList.Add(homegenie.GetGroups(migCommand.GetOption(0))[int.Parse(newPositionOrder[i])]);
                    }
                    homegenie.GetGroups(migCommand.GetOption(0)).Clear();
                    homegenie.GetGroups(migCommand.GetOption(0)).RemoveAll(g => true);
                    homegenie.GetGroups(migCommand.GetOption(0)).AddRange(newGroupList);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                }
                    //
                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.SortModules":
                using (var reader = new StreamReader(request.InputStream))
                {
                    string groupName = migCommand.GetOption(1);
                    Group sortGroup = null;
                    try
                    {
                        sortGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == groupName);
                    }
                    catch
                    {
                    }
                    //
                    if (sortGroup != null)
                    {
                        var newModulesReference = new List<ModuleReference>();
                        string[] newPositionOrder = reader.ReadToEnd().Split(new[] { ';' },
                                                                             StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < newPositionOrder.Length; i++)
                        {
                            newModulesReference.Add(sortGroup.Modules[int.Parse(newPositionOrder[i])]);
                        }
                        sortGroup.Modules.Clear();
                        sortGroup.Modules = newModulesReference;
                        homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    }
                }

                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Add":
                string newGroupName = new StreamReader(request.InputStream).ReadToEnd();
                homegenie.GetGroups(migCommand.GetOption(0)).Add(new Group() { Name = newGroupName });
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.Delete":
                string deletedGroupName = new StreamReader(request.InputStream).ReadToEnd();
                Group deletedGroup = null;
                try
                {
                    deletedGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == deletedGroupName);
                }
                catch
                {
                }
                    //
                if (deletedGroup != null)
                {
                    homegenie.GetGroups(migCommand.GetOption(0)).Remove(deletedGroup);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                    if (migCommand.GetOption(0).ToLower() == "automation")
                    {
                        var groupPrograms = homegenie.ProgramEngine.Programs.FindAll(p => p.Group.ToLower() == deletedGroup.Name.ToLower());
                        if (groupPrograms != null)
                        {
                            // delete group association from programs
                            foreach (ProgramBlock program in groupPrograms)
                            {
                                program.Group = "";
                            }
                        }
                    }
                }
                break;

            case "Groups.Save":
                string jsonGroups = new StreamReader(request.InputStream).ReadToEnd();
                var newGroups = JsonConvert.DeserializeObject<List<Group>>(jsonGroups);
                for (int i = 0; i < newGroups.Count; i++)
                {
                    try
                    {
                        var group = homegenie.Groups.Find(z => z.Name == newGroups[i].Name);
                        group.Modules.Clear();
                        group.Modules = newGroups[i].Modules;
                    }
                    catch
                    {
                    }
                }
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;
            }

        }
Beispiel #46
0
        public void ProcessRequest(MIGClientRequest request, MIGInterfaceCommand migCommand)
        {
            string response = "";
            switch (migCommand.Command)
            {
            case "Interfaces.List":
                migCommand.Response = "[ ";
                foreach (var kv in homegenie.Interfaces)
                {
                    var migInterface = kv.Value;
                    var ifaceConfig = homegenie.SystemConfiguration.MIGService.GetInterface(migInterface.Domain);
                    if (ifaceConfig == null || !ifaceConfig.IsEnabled)
                    {
                        continue;
                    }
                    migCommand.Response += "{ \"Domain\" : \"" + migInterface.Domain + "\", \"IsConnected\" : \"" + migInterface.IsConnected + "\" },";
                }
                if (homegenie.UpdateChecker != null && homegenie.UpdateChecker.IsUpdateAvailable)
                {
                    migCommand.Response += "{ \"Domain\" : \"" + Domains.HomeGenie_UpdateChecker + "\", \"IsConnected\" : \"True\" }";
                    migCommand.Response += " ]";
                }
                else
                {
                    migCommand.Response = migCommand.Response.Substring(0, migCommand.Response.Length - 1) + " ]";
                }
                break;

            case "Interfaces.ListConfig":
                migCommand.Response = "[ ";
                foreach (var kv in homegenie.Interfaces)
                {
                    var migInterface = kv.Value;
                    var ifaceConfig = homegenie.SystemConfiguration.MIGService.GetInterface(migInterface.Domain);
                    if (ifaceConfig == null)
                        continue;
                    migCommand.Response += JsonConvert.SerializeObject(ifaceConfig) + ",";
                }
                migCommand.Response = migCommand.Response.Substring(0, migCommand.Response.Length - 1) + " ]";
                break;

            //TODO: should this be moved somewhere to MIG?
            case "Interfaces.Configure":
                switch (migCommand.GetOption(0))
                {
                case "Hardware.SerialPorts":
                    if (Environment.OSVersion.Platform == PlatformID.Unix)
                    {
                        var serialPorts = System.IO.Ports.SerialPort.GetPortNames();
                        var portList = new List<string>();
                        for (int p = serialPorts.Length - 1; p >= 0; p--)
                        {
                            if (serialPorts[p].Contains("/ttyS") || serialPorts[p].Contains("/ttyUSB"))
                            {
                                portList.Add(serialPorts[p]);
                            }
                        }
                        if (Raspberry.Board.Current.IsRaspberryPi)
                        {
                            if (!portList.Contains("/dev/ttyAMA0"))
                                portList.Add("/dev/ttyAMA0"); // RaZberry
                            if (!portList.Contains("/dev/ttyACM0"))
                                portList.Add("/dev/ttyACM0"); // ZME_UZB1
                        }
                        migCommand.Response = JsonHelper.GetSimpleResponse(JsonConvert.SerializeObject(portList));
                    }
                    else
                    {
                        var portNames = System.IO.Ports.SerialPort.GetPortNames();
                        migCommand.Response = JsonHelper.GetSimpleResponse(JsonConvert.SerializeObject(portNames));
                    }
                    break;

                }
                break;

            case "Interface.Import":
                string downloadUrl = migCommand.GetOption(0);
                response = "";
                string ifaceFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "mig_interface_import.zip");
                string outputFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "mig");
                Utility.FolderCleanUp(outputFolder);

                try
                {
                    if (String.IsNullOrWhiteSpace(downloadUrl))
                    {
                        // file uploaded by user
                        MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, ifaceFileName);
                    }
                    else
                    {
                        // download file from url
                        var client = new WebClient();
                        client.DownloadFile(downloadUrl, ifaceFileName);
                        client.Dispose();
                    }
                }
                catch
                {
                    // TODO: report exception
                }

                try
                {
                    if (!Directory.Exists(outputFolder))
                    {
                        Directory.CreateDirectory(outputFolder);
                    }
                    Utility.UncompressZip(ifaceFileName, outputFolder);
                    File.Delete(ifaceFileName);

                    var migInt = GetInterfaceConfig(Path.Combine(outputFolder, "configuration.xml"));
                    if (migInt != null)
                    {
                        response = String.Format("{0} ({1})\n{2}\n", migInt.Domain, migInt.AssemblyName, migInt.Description);
                        // Check for README notes and append them to the response
                        var readmeFile = Path.Combine(outputFolder, "README.TXT");
                        if (File.Exists(readmeFile))
                        {
                            response += File.ReadAllText(readmeFile);
                        }
                        migCommand.Response = JsonHelper.GetSimpleResponse(response);
                    }
                    else
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("NOT A VALID ADD-ON PACKAGE");
                    }
                }
                catch
                {
                }
                break;

            case "Interface.Install":

                // install the interface package
                string outFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "mig");
                string configFile = Path.Combine(outFolder, "configuration.xml");
                var iface = GetInterfaceConfig(configFile);
                if (iface != null)
                {
                    File.Delete(configFile);
                    //
                    homegenie.MigService.RemoveInterface(iface.Domain);
                    //
                    string configletName = iface.Domain.Substring(iface.Domain.LastIndexOf(".") + 1).ToLower();
                    string configletPath = Path.Combine("html", "pages", "configure", "interfaces", "configlet", configletName + ".html");
                    if (File.Exists(configletPath))
                    {
                        File.Delete(configletPath);
                    }
                    File.Move(Path.Combine(outFolder, "configlet.html"), configletPath);
                    //
                    string logoPath = Path.Combine("html", "images", "interfaces", configletName + ".png");
                    if (File.Exists(logoPath))
                    {
                        File.Delete(logoPath);
                    }
                    File.Move(Path.Combine(outFolder, "logo.png"), logoPath);
                    // copy other interface files to mig folder (dll and dependencies)
                    string migFolder = "mig";
                    Utility.FolderCleanUp(migFolder);
                    DirectoryInfo dir = new DirectoryInfo(outFolder);
                    foreach (var f in dir.GetFiles())
                    {
                        string destFile = Path.Combine(migFolder, Path.GetFileName(f.FullName));
                        if (File.Exists(destFile))
                        {
                            File.Move(destFile, Path.Combine(destFile, ".old"));
                            File.Delete(Path.Combine(destFile, ".old"));
                        }
                        File.Move(f.FullName, destFile);
                    }
                    //
                    homegenie.SystemConfiguration.MIGService.Interfaces.RemoveAll(i => i.Domain == iface.Domain);
                    homegenie.SystemConfiguration.MIGService.Interfaces.Add(iface);
                    homegenie.SystemConfiguration.Update();
                    homegenie.MigService.AddInterface(iface.Domain, iface.AssemblyName);

                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("NOT A VALID ADD-ON PACKAGE");
                }
                break;

            case "System.Configure":
                if (migCommand.GetOption(0) == "Service.Restart")
                {
                    Program.Quit(true);
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.UpdatesList")
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.UpdateChecker.RemoteUpdates);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.Check")
                {
                    homegenie.UpdateChecker.Check();
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.DownloadUpdate")
                {
                    var resultMessage = "ERROR";
                    bool success = homegenie.UpdateChecker.DownloadUpdateFiles();
                    if (success)
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                        }
                        else
                        {
                            resultMessage = "OK";
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(resultMessage);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.InstallUpdate") //UpdateManager.InstallProgramsCommit")
                {
                    string resultMessage = "OK";
                    if (!homegenie.UpdateChecker.InstallFiles())
                    {
                        resultMessage = "ERROR";
                    }
                    else
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                            Utility.RunAsyncTask(() =>
                            {
                                Thread.Sleep(2000);
                                Program.Quit(true);
                            });
                        }
                        else
                        {
                            homegenie.LoadConfiguration();
                            homegenie.MigService.ClearWebCache();
                            homegenie.UpdateChecker.Check();
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(resultMessage);
                }
                else if (migCommand.GetOption(0) == "HttpService.SetWebCacheEnabled")
                {
                    if (migCommand.GetOption(1) == "1")
                    {
                        homegenie.MigService.IsWebCacheEnabled = true;
                        homegenie.SystemConfiguration.MIGService.EnableWebCache = "true";
                    }
                    else
                    {
                        homegenie.MigService.IsWebCacheEnabled = false;
                        homegenie.SystemConfiguration.MIGService.EnableWebCache = "false";
                    }
                    homegenie.SystemConfiguration.Update();
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetWebCacheEnabled")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.MigService.IsWebCacheEnabled ? "1" : "0");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetPort")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.SystemConfiguration.HomeGenie.ServicePort.ToString());
                }
                else if (migCommand.GetOption(0) == "HttpService.SetPort")
                {
                    try
                    {
                        homegenie.SystemConfiguration.HomeGenie.ServicePort = int.Parse(migCommand.GetOption(1));
                        homegenie.SystemConfiguration.Update();
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "HttpService.GetHostHeader")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.SystemConfiguration.HomeGenie.ServiceHost.ToString());
                }
                else if (migCommand.GetOption(0) == "HttpService.SetHostHeader")
                {
                    try
                    {
                        homegenie.SystemConfiguration.HomeGenie.ServiceHost = migCommand.GetOption(1);
                        homegenie.SystemConfiguration.Update();
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "Statistics.GetStatisticsDatabaseMaximumSize")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes.ToString());
                }
                else if (migCommand.GetOption(0) == "Statistics.SetStatisticsDatabaseMaximumSize")
                {
                    try
                    {
                        homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes = int.Parse(migCommand.GetOption(1));
                        homegenie.SystemConfiguration.Update();
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "SystemLogging.DownloadCsv")
                {
                    string csvlog = "";
                    string logpath = Path.Combine("log", "homegenie.log");
                    if (migCommand.GetOption(1) == "1")
                    {
                        logpath = Path.Combine("log", "homegenie.log.bak");
                    }
                    if (File.Exists(logpath))
                    {
                        using (var fs = new FileStream(logpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (var sr = new StreamReader(fs, Encoding.Default))
                        {
                            csvlog = sr.ReadToEnd();
                        }
                    }
                    (request.Context as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment;filename=homegenie_log_" + migCommand.GetOption(1) + ".csv");
                    migCommand.Response = csvlog;
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Enable")
                {
                    SystemLogger.Instance.OpenLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "true";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Disable")
                {
                    SystemLogger.Instance.CloseLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "false";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.IsEnabled")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse((homegenie.SystemConfiguration.HomeGenie.EnableLogFile.ToLower().Equals("true") ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "Security.SetPassword")
                {
                    // password only for now, with fixed user login 'admin'
                    string pass = migCommand.GetOption(1) == "" ? "" : MIG.Utility.Encryption.SHA1.GenerateHashString(migCommand.GetOption(1));
                    homegenie.MigService.SetWebServicePassword(pass);
                    homegenie.SystemConfiguration.HomeGenie.UserPassword = pass;
                    // regenerate encrypted files
                    homegenie.SystemConfiguration.Update();
                    homegenie.UpdateModulesDatabase();
                }
                else if (migCommand.GetOption(0) == "Security.ClearPassword")
                {
                    homegenie.MigService.SetWebServicePassword("");
                    homegenie.SystemConfiguration.HomeGenie.UserPassword = "";
                    // regenerate encrypted files
                    homegenie.SystemConfiguration.Update();
                    homegenie.UpdateModulesDatabase();
                }
                else if (migCommand.GetOption(0) == "Security.HasPassword")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse((homegenie.SystemConfiguration.HomeGenie.UserPassword != "" ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestore")
                {
                    // file uploaded by user
                    string archivename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "homegenie_restore_config.zip");
                    Utility.FolderCleanUp(Utility.GetTmpFolder());
                    try
                    {
                        MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, archivename);
                        Utility.UncompressZip(archivename, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder()));
                        File.Delete(archivename);
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS1")
                {
                    var serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    var reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    var newProgramList = new List<ProgramBlock>();
                    foreach (ProgramBlock program in newProgramsData)
                    {
                        if (program.Address >= ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            ProgramBlock p = new ProgramBlock();
                            p.Address = program.Address;
                            p.Name = program.Name;
                            p.Description = program.Description;
                            newProgramList.Add(p);
                        }
                    }
                    newProgramList.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                    {
                        string c1 = p1.Address.ToString();
                        string c2 = p2.Address.ToString();
                        return c1.CompareTo(c2);
                    });
                    migCommand.Response = JsonConvert.SerializeObject(newProgramList);
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS2")
                {
                    var serializer = new XmlSerializer(typeof(List<Group>));
                    var reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "automationgroups.xml"));
                    var automationGroups = (List<Group>)serializer.Deserialize(reader);
                    reader.Close();
                    //
                    foreach (var automationGroup in automationGroups)
                    {
                        if (homegenie.AutomationGroups.Find(g => g.Name == automationGroup.Name) == null)
                        {
                            homegenie.AutomationGroups.Add(automationGroup);
                        }
                    }
                    //
                    homegenie.UpdateGroupsDatabase("Automation");
                    //
                    //File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp", "automationgroups.xml"), "./automationgroups.xml", true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "groups.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "groups.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "lircconfig.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "lircconfig.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "modules.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modules.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "scheduler.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scheduler.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "systemconfig.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "systemconfig.xml"), true);
                    //
                    homegenie.LoadConfiguration();
                    //
                    // Restore automation programs
                    string selectedPrograms = migCommand.GetOption(1);
                    serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    foreach (var program in newProgramsData)
                    {
                        var currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == program.Address);
                        program.IsRunning = false;
                        // Only restore user space programs
                        if (selectedPrograms.Contains("," + program.Address.ToString() + ",") && program.Address >= ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            int oldPid = program.Address;
                            if (currentProgram == null)
                            {
                                var newPid = ((currentProgram != null && currentProgram.Address == program.Address) ? homegenie.ProgramEngine.GeneratePid() : program.Address);
                                try
                                {
                                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", newPid + ".dll"), true);
                                }
                                catch
                                {
                                }
                                program.Address = newPid;
                                homegenie.ProgramEngine.ProgramAdd(program);
                            }
                            else if (currentProgram != null)
                            {
                                homegenie.ProgramEngine.ProgramRemove(currentProgram);
                                try
                                {
                                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", program.Address + ".dll"), true);
                                }
                                catch
                                {
                                }
                                homegenie.ProgramEngine.ProgramAdd(program);
                            }
                            // Restore Arduino program folder ...
                            // TODO: this is untested yet...
                            if (program.Type.ToLower() == "arduino")
                            {
                                string sourceFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs", "arduino", oldPid.ToString());
                                string arduinoFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", "arduino", program.Address.ToString());
                                if (Directory.Exists(arduinoFolder))
                                    Directory.Delete(arduinoFolder, true);
                                Directory.CreateDirectory(arduinoFolder);
                                foreach (string newPath in Directory.GetFiles(sourceFolder))
                                {
                                    File.Copy(newPath, newPath.Replace(sourceFolder, arduinoFolder), true);
                                }
                            }
                        }
                        else if (currentProgram != null && program.Address < ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            // Only restore Enabled/Disabled status of system programs
                            currentProgram.IsEnabled = program.IsEnabled;
                        }
                    }
                    //
                    homegenie.UpdateProgramsDatabase();
                    //
                    // regenerate encrypted files
                    homegenie.UpdateModulesDatabase();
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationReset")
                {
                    homegenie.RestoreFactorySettings();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationBackup")
                {
                    homegenie.BackupCurrentSettings();
                    (request.Context as HttpListenerContext).Response.Redirect("/hg/html/homegenie_backup_config.zip");
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationLoad")
                {
                    homegenie.LoadConfiguration();
                }
                break;

            case "Modules.Get":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    migCommand.Response = Utility.Module2Json(module, false);
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.List":
                try
                {
                    homegenie.modules_Sort();
                    migCommand.Response = homegenie.GetJsonSerializedModules(migCommand.GetOption(0).ToLower() == "short");
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.RoutingReset":
                try
                {
                    for (int m = 0; m < homegenie.Modules.Count; m++)
                    {
                        homegenie.Modules[m].RoutingNode = "";
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.Save":
                string body = new StreamReader(request.InputStream).ReadToEnd();
                var newModules = JsonConvert.DeserializeObject(body) as JArray;
                for (int i = 0; i < newModules.Count; i++)
                {
                    try
                    {
                        var module = homegenie.Modules.Find(m => m.Address == newModules[i]["Address"].ToString() && m.Domain == newModules[i]["Domain"].ToString());
                        module.Name = newModules[i]["Name"].ToString();
                        //
                        try
                        {
                            module.DeviceType = (MIG.ModuleTypes)Enum.Parse(typeof(MIG.ModuleTypes), newModules[i]["DeviceType"].ToString(), true);
                        }
                        catch
                        {
                            // TODO: check what's wrong here...
                        }
                        //
                        var moduleProperties = newModules[i]["Properties"] as JArray;
                        for (int p = 0; p < moduleProperties.Count; p++)
                        {
                            string propertyName = moduleProperties[p]["Name"].ToString();
                            string propertyValue = moduleProperties[p]["Value"].ToString();
                            ModuleParameter parameter = null;
                            parameter = module.Properties.Find(delegate(ModuleParameter mp)
                            {
                                return mp.Name == propertyName;
                            });
                            //
                            if (propertyName == ModuleParameters.MODPAR_VIRTUALMETER_WATTS)
                            {
                                try
                                {
                                    propertyValue = double.Parse(propertyValue.Replace(",", "."), System.Globalization.CultureInfo.InvariantCulture).ToString();
                                }
                                catch
                                {
                                    propertyValue = "0";
                                }
                            }
                            //
                            if (parameter == null)
                            {
                                module.Properties.Add(new ModuleParameter() {
                                    Name = propertyName,
                                    Value = propertyValue
                                });
                            }
                            else
                            {
                                if (moduleProperties[p]["NeedsUpdate"] != null && moduleProperties[p]["NeedsUpdate"].ToString() == "true")
                                {
                                    parameter.Value = propertyValue;
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //TODO: notify exception?
                    }
                }
                homegenie.UpdateModulesDatabase();//write modules
                break;

            case "Modules.Update":
                string streamContent = new StreamReader(request.InputStream).ReadToEnd();
                var newModule = JsonConvert.DeserializeObject<Module>(streamContent);
                var currentModule = homegenie.Modules.Find(p => p.Domain == newModule.Domain && p.Address == newModule.Address);
                //
                if (currentModule == null)
                {
                    homegenie.Modules.Add(newModule);
                }
                else
                {
                    currentModule.Name = newModule.Name;
                    currentModule.Description = newModule.Description;
                    currentModule.DeviceType = newModule.DeviceType;
                    foreach (var newParameter in newModule.Properties)
                    {
                        var currentParameter = currentModule.Properties.Find(mp => mp.Name == newParameter.Name);
                        if (currentParameter == null)
                        {
                            currentModule.Properties.Add(newParameter);
                        }
                        else if (newParameter.NeedsUpdate)
                        {
                            // reset current reporting Watts if VMWatts field is set to 0
                            if (newParameter.Name == ModuleParameters.MODPAR_VIRTUALMETER_WATTS && newParameter.DecimalValue == 0 && currentParameter.DecimalValue != 0)
                            {
                                homegenie.migService_InterfacePropertyChanged(new InterfacePropertyChangedAction() {
                                    Domain = currentModule.Domain,
                                    SourceId = currentModule.Address,
                                    SourceType = currentModule.Description,
                                    Path = ModuleParameters.MODPAR_METER_WATTS,
                                    Value = "0.0"
                                });
                            }
                            currentParameter.Value = newParameter.Value;
                        }
                    }
                    // look for deleted properties
                    var deletedParameters = new List<ModuleParameter>();
                    foreach (var parameter in currentModule.Properties)
                    {
                        var currentParameter = newModule.Properties.Find(mp => mp.Name == parameter.Name);
                        if (currentParameter == null)
                        {
                            deletedParameters.Add(parameter);
                        }
                    }
                    foreach (var parameter in deletedParameters)
                    {
                        currentModule.Properties.Remove(parameter);
                    }
                    deletedParameters.Clear();
                }
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Modules.Delete":
                var deletedModule = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                if (deletedModule != null)
                {
                    homegenie.Modules.Remove(deletedModule);
                }
                migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Stores.List":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        //module.Stores
                        migCommand.Response = "[";
                        for (int s = 0; s < module.Stores.Count; s++)
                        {
                            migCommand.Response += "{ \"Name\": \"" + Utility.XmlEncode(module.Stores[s].Name) + "\", \"Description\": \"" + Utility.XmlEncode(module.Stores[s].Description) + "\" },";
                        }
                        migCommand.Response = migCommand.Response.TrimEnd(',') + "]";
                    }

                }
                break;

            case "Stores.Delete":
                break;

            case "Stores.ItemList":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        migCommand.Response = "[";
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        for (int p = 0; p < store.List.Count; p++)
                        {
                            migCommand.Response += "{ \"Name\": \"" + Utility.XmlEncode(store.List[p].Name) + "\", \"Description\": \"" + Utility.XmlEncode(store.List[p].Description) + "\" },";
                        }
                        migCommand.Response = migCommand.Response.TrimEnd(',') + "]";
                    }
                }
                break;

            case "Stores.ItemDelete":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var name = migCommand.GetOption(3);
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.List.RemoveAll(i => i.Name == name);
                    }
                }
                break;

            case "Stores.ItemGet":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        migCommand.Response += JsonConvert.SerializeObject(store.Get(migCommand.GetOption(3)));
                    }
                }
                break;

            case "Stores.ItemSet":
                {
                    // value is the POST body
                    string itemData = new StreamReader(request.InputStream).ReadToEnd();
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.Get(migCommand.GetOption(3)).Value = itemData;
                    }
                }
                break;

            case "Groups.ModulesList":
                var theGroup = homegenie.Groups.Find(z => z.Name.ToLower() == migCommand.GetOption(0).Trim().ToLower());
                if (theGroup != null)
                {
                    string jsonmodules = "[";
                    for (int m = 0; m < theGroup.Modules.Count; m++)
                    {
                        var groupModule = homegenie.Modules.Find(mm => mm.Domain == theGroup.Modules[m].Domain && mm.Address == theGroup.Modules[m].Address);
                        if (groupModule != null)
                        {
                            jsonmodules += Utility.Module2Json(groupModule, false) + ",\n";
                        }
                    }
                    jsonmodules = jsonmodules.TrimEnd(',', '\n');
                    jsonmodules += "]";
                    migCommand.Response = jsonmodules;
                }
                break;
            case "Groups.List":
                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Rename":
                string oldName = migCommand.GetOption(1);
                string newName = new StreamReader(request.InputStream).ReadToEnd();
                var currentGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == oldName);
                var newGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == newName);
                // ensure that the new group name is not already defined
                if (newGroup == null && currentGroup != null)
                {
                    currentGroup.Name = newName;
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    //cmd.response = JsonHelper.GetSimpleResponse("OK");
                }
                else
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("New name already in use.");
                }
                break;

            case "Groups.Sort":
                using (var reader = new StreamReader(request.InputStream))
                {
                    var newGroupList = new List<Group>();
                    string[] newPositionOrder = reader.ReadToEnd().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < newPositionOrder.Length; i++)
                    {
                        newGroupList.Add(homegenie.GetGroups(migCommand.GetOption(0))[int.Parse(newPositionOrder[i])]);
                    }
                    homegenie.GetGroups(migCommand.GetOption(0)).Clear();
                    homegenie.GetGroups(migCommand.GetOption(0)).RemoveAll(g => true);
                    homegenie.GetGroups(migCommand.GetOption(0)).AddRange(newGroupList);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                }
                //
                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.SortModules":
                using (var reader = new StreamReader(request.InputStream))
                {
                    string groupName = migCommand.GetOption(1);
                    Group sortGroup = null;
                    try
                    {
                        sortGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == groupName);
                    }
                    catch
                    {
                    }
                    //
                    if (sortGroup != null)
                    {
                        var newModulesReference = new List<ModuleReference>();
                        string[] newPositionOrder = reader.ReadToEnd().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < newPositionOrder.Length; i++)
                        {
                            newModulesReference.Add(sortGroup.Modules[int.Parse(newPositionOrder[i])]);
                        }
                        sortGroup.Modules.Clear();
                        sortGroup.Modules = newModulesReference;
                        homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    }
                }

                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Add":
                string newGroupName = new StreamReader(request.InputStream).ReadToEnd();
                homegenie.GetGroups(migCommand.GetOption(0)).Add(new Group() { Name = newGroupName });
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.Delete":
                string deletedGroupName = new StreamReader(request.InputStream).ReadToEnd();
                Group deletedGroup = null;
                try
                {
                    deletedGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == deletedGroupName);
                }
                catch
                {
                }
                //
                if (deletedGroup != null)
                {
                    homegenie.GetGroups(migCommand.GetOption(0)).Remove(deletedGroup);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                    if (migCommand.GetOption(0).ToLower() == "automation")
                    {
                        var groupPrograms = homegenie.ProgramEngine.Programs.FindAll(p => p.Group.ToLower() == deletedGroup.Name.ToLower());
                        if (groupPrograms != null)
                        {
                            // delete group association from programs
                            foreach (ProgramBlock program in groupPrograms)
                            {
                                program.Group = "";
                            }
                        }
                    }
                }
                break;

            case "Groups.Save":
                string jsonGroups = new StreamReader(request.InputStream).ReadToEnd();
                var newGroups = JsonConvert.DeserializeObject<List<Group>>(jsonGroups);
                for (int i = 0; i < newGroups.Count; i++)
                {
                    try
                    {
                        var group = homegenie.Groups.Find(z => z.Name == newGroups[i].Name);
                        group.Modules.Clear();
                        group.Modules = newGroups[i].Modules;
                    }
                    catch
                    {
                    }
                }
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.WallpaperList":
                List<string> wallpaperList = new List<string>();
                var images = Directory.GetFiles(groupWallpapersPath);
                for (int i = 0; i < images.Length; i++)
                {
                    wallpaperList.Add(Path.GetFileName(images[i]));
                }
                migCommand.Response = JsonConvert.SerializeObject(wallpaperList);

                break;

            case "Groups.WallpaperAdd":
                {
                    string wallpaperFile = "";
                    try
                    {
                        wallpaperFile = MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, groupWallpapersPath);
                    }
                    catch
                    {
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(Path.GetFileName(wallpaperFile));
                }
                break;

            case "Groups.WallpaperSet":
                {
                    string wpGroupName = migCommand.GetOption(0);
                    var wpGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == wpGroupName);
                    if (wpGroup != null)
                    {
                        wpGroup.Wallpaper = migCommand.GetOption(1);
                        homegenie.UpdateGroupsDatabase("Control");
                    }
                }
                break;

            case "Groups.WallpaperDelete":
                {
                    string wallpaperFile = migCommand.GetOption(0);
                    wallpaperFile = Path.Combine(groupWallpapersPath, Path.GetFileName(wallpaperFile));
                    if (File.Exists(wallpaperFile))
                    {
                        File.Delete(wallpaperFile);
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                break;

            case "Widgets.List":
                List<string> widgetsList = new List<string>();
                var groups = Directory.GetDirectories(widgetBasePath);
                for (int d = 0; d < groups.Length; d++)
                {
                    var categories = Directory.GetDirectories(groups[d]);
                    for (int c = 0; c < categories.Length; c++)
                    {
                        var widgets = Directory.GetFiles(categories[c], "*.js");
                        var group = groups[d].Replace(widgetBasePath, "").Substring(1);
                        var category = categories[c].Replace(groups[d], "").Substring(1);
                        for (int w = 0; w < widgets.Length; w++)
                        {
                            widgetsList.Add(group + "/" + category + "/" + Path.GetFileNameWithoutExtension(widgets[w]));
                        }
                    }
                }
                migCommand.Response = JsonConvert.SerializeObject(widgetsList);
                break;

            case "Widgets.Add":
                {
                    response = "ERROR";
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    widgetParts[0] = new String(widgetParts[0].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[1] = new String(widgetParts[1].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[2] = new String(widgetParts[2].Where(Char.IsLetter).ToArray()).ToLower();
                    if (!String.IsNullOrWhiteSpace(widgetParts[0]) && !String.IsNullOrWhiteSpace(widgetParts[1]) && !String.IsNullOrWhiteSpace(widgetParts[2]))
                    {
                        string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                        if (!Directory.Exists(filePath))
                        {
                            Directory.CreateDirectory(filePath);
                        }
                        // copy widget template into the new widget
                        var htmlFile = Path.Combine(filePath, widgetParts[2] + ".html");
                        var jsFile = Path.Combine(filePath, widgetParts[2] + ".js");
                        if (!File.Exists(htmlFile) && !File.Exists(jsFile))
                        {
                            File.Copy(Path.Combine(widgetBasePath, "template.html"), htmlFile);
                            File.Copy(Path.Combine(widgetBasePath, "template.js"), jsFile);
                            response = "OK";
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(response);
                }
                break;

            case "Widgets.Save":
                {
                    response = "ERROR";
                    string widgetData = new StreamReader(request.InputStream).ReadToEnd();
                    string fileType = migCommand.GetOption(0);
                    string widgetPath = migCommand.GetOption(1); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    switch (fileType)
                    {
                    // html/javascript source
                    case "html":
                    case "js":
                        using (TextWriter widgetWriter = new StreamWriter(Path.Combine(filePath, widgetParts[2] + "." + fileType)))
                        {
                            widgetWriter.Write(widgetData);
                        }
                        response = "OK";
                        break;
                    // style sheet file
                    case "css":
                        break;
                    // locale file
                    case "json":
                        break;
                    // image file
                    case "jpg":
                    case "png":
                    case "gif":
                        break;
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(response);
                }
                break;

            case "Widgets.Delete":
                {
                    response = "ERROR";
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1], widgetParts[2] + ".");
                    if (File.Exists(filePath + "html"))
                    {
                        File.Delete(filePath + "html");
                        response = "OK";
                    }
                    if (File.Exists(filePath + "js"))
                    {
                        File.Delete(filePath + "js");
                        response = "OK";
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(response);
                }
                break;

            case "Widgets.Export":
                {
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string widgetBundle = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "export", widgetPath.Replace('/', '_') + ".zip");
                    if (File.Exists(widgetBundle))
                    {
                        File.Delete(widgetBundle);
                    }
                    else if (!Directory.Exists(Path.GetDirectoryName(widgetBundle)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(widgetBundle));
                    }
                    string inputPath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    string outputPath = Path.Combine(widgetParts[0], widgetParts[1]);
                    string infoFilePath = Path.Combine(inputPath, "widget.info");
                    File.WriteAllText(infoFilePath, "HomeGenie exported widget.");
                    Utility.AddFileToZip(widgetBundle, infoFilePath, "widget.info");
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".html"), Path.Combine(outputPath, widgetParts[2] + ".html"));
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".js"), Path.Combine(outputPath, widgetParts[2] + ".js"));
                    //
                    byte[] bundleData = File.ReadAllBytes(widgetBundle);
                    (request.Context as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment; filename=\"" + widgetPath.Replace('/', '_') + ".zip\"");
                    (request.Context as HttpListenerContext).Response.OutputStream.Write(bundleData, 0, bundleData.Length);
                }
                break;

            case "Widgets.Import":
                {
                    string archiveFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "import_widget.zip");
                    string importPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "import");
                    if (Directory.Exists(importPath))
                        Directory.Delete(importPath, true);
                    MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, archiveFile);
                    if (WidgetImport(archiveFile, importPath))
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                    }
                    else
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("ERROR");
                    }
                }
                break;

            case "Widgets.Parse":
                {
                    string widgetData = new StreamReader(request.InputStream).ReadToEnd();
                    var parser = new JavaScriptParser();
                    try
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                        parser.Parse(widgetData);
                    }
                    catch (Jint.Parser.ParserException e)
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("ERROR (" + e.LineNumber + "," + e.Column + "): " + e.Description);
                    }
                }
                break;
            }
        }
Beispiel #47
0
 public void Run(ProgramBlock program, string options)
 {
     if (program.IsRunning) return;
     //
     if (program.ProgramThread != null)
     {
         program.Stop();
         program.IsRunning = false;
     }
     //
     program.IsRunning = true;
     RaiseProgramModuleEvent(program, "Program.Status", "Running");
     //
     if (program.Type.ToLower() != "wizard")
     {
         if (program.Type.ToLower() == "csharp" && program.AppAssembly == null)
         {
             program.IsRunning = false;
         }
         else
         {
             program.TriggerTime = DateTime.UtcNow;
             program.ProgramThread = new Thread(() =>
             {
                 MethodRunResult result = null;
                 try
                 {
                     result = program.Run(options);
                 } catch (Exception ex) {
                     result = new MethodRunResult();
                     result.Exception = ex;
                 }
                 //
                 if (result != null && result.Exception != null)
                 {
                     // runtime error occurred, script is being disabled
                     // so user can notice and fix it
                     List<ProgramError> error = new List<ProgramError>() { new ProgramError() {
                             CodeBlock = "CR",
                             Column = 0,
                             Line = 0,
                             ErrorNumber = "-1",
                             ErrorMessage = result.Exception.Message
                         }
                     };
                     program.ScriptErrors = JsonConvert.SerializeObject(error);
                     program.IsEnabled = false;
                     RaiseProgramModuleEvent(
                         program,
                         "Runtime.Error",
                         "CR: " + result.Exception.Message.Replace(
                             '\n',
                             ' '
                         )
                     );
                 }
                 program.IsRunning = false;
                 program.ProgramThread = null;
                 RaiseProgramModuleEvent(program, "Program.Status", "Idle");
             });
             //
             try
             {
                 program.ProgramThread.Start();
             }
             catch
             {
                 program.Stop();
                 program.IsRunning = false;
                 RaiseProgramModuleEvent(program, "Program.Status", "Idle");
             }
         }
     }
     else
     {
         program.TriggerTime = DateTime.UtcNow;
         if (program.ConditionType == ConditionType.Once)
         {
             program.IsEnabled = false;
         }
         //
         program.ProgramThread = new Thread(() =>
         {
             try
             {
                 ExecuteWizardScript(program);
             }
             catch (ThreadAbortException)
             {
                 program.IsRunning = false;
             }
             finally
             {
                 program.IsRunning = false;
             }
             RaiseProgramModuleEvent(program, "Program.Status", "Idle");
         });
         //
         program.ProgramThread.Start();
     }
     //
     Thread.Sleep(100);
 }
Beispiel #48
0
 public List<ProgramError> CompileScript(ProgramBlock program)
 {
     return program.Compile();
 }
Beispiel #49
0
 public void Run(ProgramBlock program, string options)
 {
     if (program.IsRunning)
     {
         return;
     }
     //
     if (program.ProgramThread != null)
     {
         program.Stop();
         program.IsRunning = false;
     }
     //
     program.IsRunning = true;
     RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Running");
     //
     program.TriggerTime   = DateTime.UtcNow;
     program.ProgramThread = new Thread(() =>
     {
         MethodRunResult result = null;
         try
         {
             result = program.Run(options);
         }
         catch (Exception ex)
         {
             result           = new MethodRunResult();
             result.Exception = ex;
         }
         //
         if (result != null && result.Exception != null)
         {
             // runtime error occurred, script is being disabled
             // so user can notice and fix it
             List <ProgramError> error = new List <ProgramError>()
             {
                 program.GetFormattedError(result.Exception, false)
             };
             program.ScriptErrors = JsonConvert.SerializeObject(error);
             program.IsEnabled    = false;
             RaiseProgramModuleEvent(program, Properties.RUNTIME_ERROR, "CR: " + result.Exception.Message.Replace('\n', ' ').Replace('\r', ' '));
         }
         program.IsRunning     = false;
         program.ProgramThread = null;
         RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Idle");
     });
     //
     if (program.ConditionType == ConditionType.Once)
     {
         program.IsEnabled = false;
     }
     //
     try
     {
         program.ProgramThread.Start();
     }
     catch
     {
         program.Stop();
         program.IsRunning = false;
         RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Idle");
     }
     //
     //Thread.Sleep(100);
 }
Beispiel #50
0
 public void ProgramAdd(ProgramBlock program)
 {
     automationPrograms.Add(program);
     program.EnabledStateChanged += program_EnabledStateChanged;
     program.Engine.SetHost(homegenie);
     // Initialize state
     RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Idle");
     if (program.IsEnabled)
     {
         StartProgramEvaluator(program);
     }
 }
Beispiel #51
0
 public void ProgramAdd(ProgramBlock program)
 {
     program.SetHost(homegenie);
     automationPrograms.Add(program);
     program.EnabledStateChanged += program_EnabledStateChanged;
     //
     // in case of c# script preload assembly from generated .dll
     if (program.Type.ToLower() == "csharp" && !program.AssemblyLoad())
     {
         program.ScriptErrors = "Program update is required.";
     }
     //
     // Initialize state
     RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Idle");
     if (program.IsEnabled)
     {
         StartProgramEvaluator(program);
     }
 }
Beispiel #52
0
 public void ProgramRemove(ProgramBlock program)
 {
     program.IsEnabled = false;
     program.Engine.Stop();
     automationPrograms.Remove(program);
     // delete program files
     string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs");
     // remove csharp assembly
     try
     {
         File.Delete(Path.Combine(file, program.Address + ".dll"));
     }
     catch
     {
     }
     // remove arduino folder files
     try
     {
         Directory.Delete(Path.Combine(file, "arduino", program.Address.ToString()), true);
     } catch { }
 }
 public void ProgramAdd(ProgramBlock program)
 {
     automationPrograms.Add(program);
     program.EnabledStateChanged += program_EnabledStateChanged;
     program.Engine.SetHost(homegenie);
     RaiseProgramModuleEvent(program, Properties.ProgramStatus, "Added");
     if (isEngineEnabled && program.IsEnabled)
     {
         program.Engine.StartScheduler();
     }
 }
Beispiel #54
0
        // TODO: v1.1 !!!IMPORTANT!!! move thread allocation and starting to ProgramEngineBase.cs class
        public void Run(ProgramBlock program, string options)
        {
            if (program.IsRunning)
                return;

            if (program.Engine.ProgramThread != null)
            {
                program.Engine.Stop();
                program.IsRunning = false;
            }

            program.IsRunning = true;
            RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Running");

            program.TriggerTime = DateTime.UtcNow;

            program.Engine.ProgramThread = new Thread(() =>
            {
                MethodRunResult result = null;
                try
                {
                    result = program.Run(options);
                }
                catch (Exception ex)
                {
                    result = new MethodRunResult();
                    result.Exception = ex;
                }
                //
                if (result != null && result.Exception != null && !result.Exception.GetType().Equals(typeof(System.Reflection.TargetException)))
                {
                    // runtime error occurred, script is being disabled
                    // so user can notice and fix it
                    List<ProgramError> error = new List<ProgramError>() { program.GetFormattedError(result.Exception, false) };
                    program.ScriptErrors = JsonConvert.SerializeObject(error);
                    program.IsEnabled = false;
                    RaiseProgramModuleEvent(program, Properties.RUNTIME_ERROR, "CR: " + result.Exception.Message.Replace('\n', ' ').Replace('\r', ' '));
                }
                program.IsRunning = false;
                program.Engine.ProgramThread = null;
                RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Idle");
            });
            //
            if (program.ConditionType == ConditionType.Once)
            {
                program.IsEnabled = false;
            }
            //
            try
            {
                program.Engine.ProgramThread.Start();
            }
            catch
            {
                program.Engine.Stop();
                program.IsRunning = false;
                RaiseProgramModuleEvent(program, Properties.PROGRAM_STATUS, "Idle");
            }
            //
            //Thread.Sleep(100);
        }
Beispiel #55
0
        private List <ProgramError> CompileCsharp(ProgramBlock program)
        {
            List <ProgramError> errors = new List <ProgramError>();

            // dispose assembly and interrupt current task
            program.AppAssembly = null;
            program.IsEnabled   = false;
            // clean up old assembly files
            if (!Directory.Exists(Path.GetDirectoryName(program.AssemblyFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(program.AssemblyFile));
            }
            if (File.Exists(program.AssemblyFile))
            {
                File.Delete(program.AssemblyFile);
            }
            if (File.Exists(program.AssemblyFile + ".mdb"))
            {
                File.Delete(program.AssemblyFile + ".mdb");
            }
            if (File.Exists(program.AssemblyFile + ".pdb"))
            {
                File.Delete(program.AssemblyFile + ".pdb");
            }

            // DO NOT CHANGE THE FOLLOWING LINES OF CODE
            // it is a lil' trick for mono compatibility
            // since it will be caching the assembly when using the same name
            // and use the old one instead of the new one
            string tmpfile = Path.Combine("programs", Guid.NewGuid().ToString() + ".dll");

            System.CodeDom.Compiler.CompilerResults result = new System.CodeDom.Compiler.CompilerResults(null);
            try
            {
                result = CSharpAppFactory.CompileScript(program.ScriptCondition, program.ScriptSource, tmpfile);
            }
            catch (Exception ex)
            {
                // report errors during post-compilation process
                result.Errors.Add(new System.CodeDom.Compiler.CompilerError(program.Name, 0, 0, "-1", ex.Message));
            }

            if (result.Errors.Count == 0)
            {
                program.AppAssembly = result.CompiledAssembly;
                File.Move(tmpfile, program.AssemblyFile);
                if (File.Exists(tmpfile + ".mdb"))
                {
                    File.Move(tmpfile + ".mdb", program.AssemblyFile + ".mdb");
                }
                if (File.Exists(tmpfile + ".pdb"))
                {
                    File.Move(tmpfile + ".pdb", program.AssemblyFile + ".pdb");
                }
            }
            else
            {
                int sourceLines = program.ScriptSource.Split('\n').Length;
                foreach (System.CodeDom.Compiler.CompilerError error in result.Errors)
                {
                    //if (!ce.IsWarning)
                    {
                        int    errorRow  = (error.Line - CSharpAppFactory.PROGRAM_CODE_OFFSET);
                        string blockType = "CR";
                        if (errorRow >= sourceLines + CSharpAppFactory.CONDITION_CODE_OFFSET)
                        {
                            errorRow -= (sourceLines + CSharpAppFactory.CONDITION_CODE_OFFSET);
                            blockType = "TC";
                        }
                        errors.Add(new ProgramError()
                        {
                            Line         = errorRow,
                            Column       = error.Column,
                            ErrorMessage = error.ErrorText,
                            ErrorNumber  = error.ErrorNumber,
                            CodeBlock    = blockType
                        });
                    }
                }
            }

            return(errors);
        }
Beispiel #56
0
 internal void RaiseProgramModuleEvent(ProgramBlock program, string property, string value)
 {
     var programModule = homegenie.Modules.Find(m => m.Domain == Domains.HomeAutomation_HomeGenie_Automation && m.Address == program.Address.ToString());
     if (programModule != null)
     {
         Utility.ModuleParameterSet(programModule, property, value);
         homegenie.RaiseEvent(programModule.Domain, programModule.Address, "Automation Program", property, value);
         //homegenie.MigService.RaiseEvent(actionEvent);
         //homegenie.SignalModulePropertyChange(this, programModule, actionEvent);
     }
 }
Beispiel #57
0
 public CSharpEngine(ProgramBlock pb)
     : base(pb)
 {
 }
Beispiel #58
0
        private List<ProgramError> CompileArduino(ProgramBlock program)
        {
            List<ProgramError> errors = new List<ProgramError>();

            // Generate, compile and upload Arduino Sketch
            string sketchFileName = ArduinoAppFactory.GetSketchFile(program.Address.ToString());
            if (!Directory.Exists(Path.GetDirectoryName(sketchFileName)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(sketchFileName));
            }
            string sketchMakefile = Path.Combine(Path.GetDirectoryName(sketchFileName), "Makefile");

            try
            {
                // .ino source is stored in the ScriptSource property
                File.WriteAllText(sketchFileName, program.ScriptSource);
                // Makefile source is stored in the ScriptCondition property
                File.WriteAllText(sketchMakefile, program.ScriptCondition);
                errors = ArduinoAppFactory.CompileSketch(sketchFileName, sketchMakefile);
            }
            catch (Exception e)
            { 
                errors.Add(new ProgramError() {
                    Line = 0,
                    Column = 0,
                    ErrorMessage = "General failure: is 'arduino-mk' package installed?\n\n" + e.Message,
                    ErrorNumber = "500",
                    CodeBlock = "CR"
                });
            }

            return errors;
        }
Beispiel #59
0
        public void ProcessRequest(MigClientRequest request)
        {
            var migCommand = request.Command;
            string streamContent = "";
            ProgramBlock currentProgram;
            ProgramBlock newProgram;
            string sketchFile = "", sketchFolder = "";
            //
            homegenie.ExecuteAutomationRequest(migCommand);
            if (migCommand.Command.StartsWith("Macro."))
            {
                switch (migCommand.Command)
                {
                case "Macro.Record":
                    homegenie.ProgramManager.MacroRecorder.RecordingEnable();
                    break;
                case "Macro.Save":
                    newProgram = homegenie.ProgramManager.MacroRecorder.SaveMacro(migCommand.GetOption(1));
                    request.ResponseData = newProgram.Address.ToString();
                    break;
                case "Macro.Discard":
                    homegenie.ProgramManager.MacroRecorder.RecordingDisable();
                    break;
                case "Macro.SetDelay":
                    switch (migCommand.GetOption(0).ToLower())
                    {
                    case "none":
                        homegenie.ProgramManager.MacroRecorder.DelayType = MacroDelayType.None;
                        break;

                    case "mimic":
                        homegenie.ProgramManager.MacroRecorder.DelayType = MacroDelayType.Mimic;
                        break;

                    case "fixed":
                        double secs = double.Parse(
                            migCommand.GetOption(1),
                            System.Globalization.CultureInfo.InvariantCulture
                        );
                        homegenie.ProgramManager.MacroRecorder.DelayType = MacroDelayType.Fixed;
                        homegenie.ProgramManager.MacroRecorder.DelaySeconds = secs;
                        break;
                    }
                    break;
                case "Macro.GetDelay":
                    request.ResponseData = "{ \"DelayType\" : \"" + homegenie.ProgramManager.MacroRecorder.DelayType + "\", \"DelayOptions\" : \"" + homegenie.ProgramManager.MacroRecorder.DelaySeconds + "\" }";
                    break;
                }
            }
            else if (migCommand.Command.StartsWith("Scheduling."))
            {
                switch (migCommand.Command)
                {
                case "Scheduling.Add":
                case "Scheduling.Update":
                    var item = homegenie.ProgramManager.SchedulerService.AddOrUpdate(
                        migCommand.GetOption(0),
                        migCommand.GetOption(1).Replace(
                            "|",
                            "/"
                        )
                    );
                    item.ProgramId = migCommand.GetOption(2);
                    homegenie.UpdateSchedulerDatabase();
                    break;
                case "Scheduling.Delete":
                    homegenie.ProgramManager.SchedulerService.Remove(migCommand.GetOption(0));
                    homegenie.UpdateSchedulerDatabase();
                    break;
                case "Scheduling.Enable":
                    homegenie.ProgramManager.SchedulerService.Enable(migCommand.GetOption(0));
                    homegenie.UpdateSchedulerDatabase();
                    break;
                case "Scheduling.Disable":
                    homegenie.ProgramManager.SchedulerService.Disable(migCommand.GetOption(0));
                    homegenie.UpdateSchedulerDatabase();
                    break;
                case "Scheduling.Get":
                    request.ResponseData = homegenie.ProgramManager.SchedulerService.Get(migCommand.GetOption(0));
                    break;
                case "Scheduling.List":
                    homegenie.ProgramManager.SchedulerService.Items.Sort((SchedulerItem s1, SchedulerItem s2) =>
                    {
                        return s1.Name.CompareTo(s2.Name);
                    });
                    request.ResponseData = homegenie.ProgramManager.SchedulerService.Items;
                    break;
                case "Scheduling.Describe":
                    var cronDescription = "";
                    try {
                        cronDescription = ExpressionDescriptor.GetDescription(migCommand.GetOption(0));
                        cronDescription = Char.ToLowerInvariant(cronDescription[0]) + cronDescription.Substring(1);
                    } catch { }
                    request.ResponseData = new ResponseText(cronDescription);
                    break;
                }
            }
            else if (migCommand.Command.StartsWith("Programs."))
            {
                if (migCommand.Command != "Programs.Import")
                {
                    streamContent = request.RequestText;
                }
                //
                switch (migCommand.Command)
                {
                case "Programs.Import":
                    string archiveName = "homegenie_program_import.hgx";
                    if (File.Exists(archiveName))
                        File.Delete(archiveName);
                    //
                    MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, archiveName);
                    //
                    int newPid = homegenie.ProgramManager.GeneratePid();
                    var reader = new StreamReader(archiveName);
                    char[] signature = new char[2];
                    reader.Read(signature, 0, 2);
                    reader.Close();
                    if (signature[0] == 'P' && signature[1] == 'K')
                    {
                        // Read and uncompress zip file content (arduino program bundle)
                        string zipFileName = archiveName.Replace(".hgx", ".zip");
                        if (File.Exists(zipFileName))
                            File.Delete(zipFileName);
                        File.Move(archiveName, zipFileName);
                        string destFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "import");
                        if (Directory.Exists(destFolder))
                            Directory.Delete(destFolder, true);
                        Utility.UncompressZip(zipFileName, destFolder);
                        string bundleFolder = Path.Combine("programs", "arduino", newPid.ToString());
                        if (Directory.Exists(bundleFolder))
                            Directory.Delete(bundleFolder, true);
                        if (!Directory.Exists(Path.Combine("programs", "arduino")))
                            Directory.CreateDirectory(Path.Combine("programs", "arduino"));
                        Directory.Move(Path.Combine(destFolder, "src"), bundleFolder);
                        reader = new StreamReader(Path.Combine(destFolder, "program.hgx"));
                    }
                    else
                    {
                        reader = new StreamReader(archiveName);
                    }
                    var serializer = new XmlSerializer(typeof(ProgramBlock));
                    newProgram = (ProgramBlock)serializer.Deserialize(reader);
                    reader.Close();
                    //
                    newProgram.Address = newPid;
                    newProgram.Group = migCommand.GetOption(0);
                    homegenie.ProgramManager.ProgramAdd(newProgram);
                    //
                    newProgram.IsEnabled = false;
                    newProgram.ScriptErrors = "";
                    newProgram.Engine.SetHost(homegenie);
                    //
                    if (newProgram.Type.ToLower() != "arduino")
                    {
                        homegenie.ProgramManager.CompileScript(newProgram);
                    }
                    //
                    homegenie.UpdateProgramsDatabase();
                    //migCommand.response = JsonHelper.GetSimpleResponse(programblock.Address);
                    request.ResponseData = newProgram.Address.ToString();
                    break;

                case "Programs.Export":
                    currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                    string filename = currentProgram.Address + "-" + currentProgram.Name.Replace(" ", "_");
                    //
                    var writerSettings = new System.Xml.XmlWriterSettings();
                    writerSettings.Indent = true;
                    var programSerializer = new System.Xml.Serialization.XmlSerializer(typeof(ProgramBlock));
                    var builder = new StringBuilder();
                    var writer = System.Xml.XmlWriter.Create(builder, writerSettings);
                    programSerializer.Serialize(writer, currentProgram);
                    writer.Close();
                    //
                    if (currentProgram.Type.ToLower() == "arduino")
                    {
                        string arduinoBundle = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                                            Utility.GetTmpFolder(),
                                                           "export",
                                                            filename + ".zip");
                        if (File.Exists(arduinoBundle))
                        {
                            File.Delete(arduinoBundle);
                        }
                        else if (!Directory.Exists(Path.GetDirectoryName(arduinoBundle)))
                        {
                            Directory.CreateDirectory(Path.GetDirectoryName(arduinoBundle));
                        }
                        string mainProgramFile = Path.Combine(Path.GetDirectoryName(arduinoBundle), "program.hgx");
                        File.WriteAllText(
                            mainProgramFile,
                            builder.ToString()
                        );
                        Utility.AddFileToZip(arduinoBundle, mainProgramFile, "program.hgx");
                        sketchFolder = Path.Combine("programs", "arduino", currentProgram.Address.ToString());
                        foreach (string f in Directory.GetFiles(sketchFolder))
                        {
                            if (!Path.GetFileName(f).StartsWith("sketch_"))
                            {
                                Utility.AddFileToZip(
                                    arduinoBundle,
                                    Path.Combine(sketchFolder, Path.GetFileName(f)),
                                    Path.Combine(
                                        "src",
                                        Path.GetFileName(f)
                                    )
                                );
                            }
                        }
                        //
                        byte[] bundleData = File.ReadAllBytes(arduinoBundle);
                        (request.Context.Data as HttpListenerContext).Response.AddHeader(
                            "Content-Disposition",
                            "attachment; filename=\"" + filename + ".zip\""
                            );
                        (request.Context.Data as HttpListenerContext).Response.OutputStream.Write(bundleData, 0, bundleData.Length);
                    }
                    else
                    {
                        (request.Context.Data as HttpListenerContext).Response.AddHeader(
                            "Content-Disposition",
                            "attachment; filename=\"" + filename + ".hgx\""
                        );
                        request.ResponseData = builder.ToString();
                    }
                    break;

                case "Programs.List":
                    var programList = new List<ProgramBlock>(homegenie.ProgramManager.Programs);
                    programList.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                    {
                        string c1 = p1.Name + " " + p1.Address;
                        string c2 = p2.Name + " " + p2.Address;
                        return c1.CompareTo(c2);
                    });
                    request.ResponseData = programList;
                    break;

                case "Programs.Add":
                    newProgram = new ProgramBlock() {
                        Group = migCommand.GetOption(0),
                        Name = streamContent,
                        Type = "Wizard"
                    };
                    newProgram.Address = homegenie.ProgramManager.GeneratePid();
                    homegenie.ProgramManager.ProgramAdd(newProgram);
                    homegenie.UpdateProgramsDatabase();
                    request.ResponseData = new ResponseText(newProgram.Address.ToString());
                    break;

                case "Programs.Delete":
                    currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                    if (currentProgram != null)
                    {
                        //TODO: remove groups associations as well
                        homegenie.ProgramManager.ProgramRemove(currentProgram);
                        homegenie.UpdateProgramsDatabase();
                        // remove associated module entry
                        homegenie.Modules.RemoveAll(m => m.Domain == Domains.HomeAutomation_HomeGenie_Automation && m.Address == currentProgram.Address.ToString());
                        homegenie.UpdateModulesDatabase();
                    }
                    break;

                case "Programs.Compile":
                case "Programs.Update":
                    newProgram = JsonConvert.DeserializeObject<ProgramBlock>(streamContent);
                    currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == newProgram.Address);
                        //
                    if (currentProgram == null)
                    {
                        newProgram.Address = homegenie.ProgramManager.GeneratePid();
                        homegenie.ProgramManager.ProgramAdd(newProgram);
                    }
                    else
                    {
                        bool typeChanged = (currentProgram.Type.ToLower() != newProgram.Type.ToLower());
                        currentProgram.Type = newProgram.Type;
                        currentProgram.Group = newProgram.Group;
                        currentProgram.Name = newProgram.Name;
                        currentProgram.Description = newProgram.Description;
                        if (typeChanged)
                            currentProgram.Engine.SetHost(homegenie);
                        currentProgram.IsEnabled = newProgram.IsEnabled;
                        currentProgram.ScriptCondition = newProgram.ScriptCondition;
                        currentProgram.ScriptSource = newProgram.ScriptSource;
                        currentProgram.Commands = newProgram.Commands;
                        currentProgram.Conditions = newProgram.Conditions;
                        currentProgram.ConditionType = newProgram.ConditionType;
                        // reset last condition evaluation status
                        currentProgram.LastConditionEvaluationResult = false;
                    }
                        //
                    if (migCommand.Command == "Programs.Compile")
                    {
                        // reset previous error status
                        currentProgram.IsEnabled = false;
                        currentProgram.Engine.Stop();
                        currentProgram.ScriptErrors = "";
                        //
                        List<ProgramError> errors = homegenie.ProgramManager.CompileScript(currentProgram);
                        //
                        currentProgram.IsEnabled = newProgram.IsEnabled && errors.Count == 0;
                        currentProgram.ScriptErrors = JsonConvert.SerializeObject(errors);
                        request.ResponseData = currentProgram.ScriptErrors;
                    }
                        //
                    homegenie.UpdateProgramsDatabase();
                        //
                    homegenie.modules_RefreshPrograms();
                    homegenie.modules_RefreshVirtualModules();
                    homegenie.modules_Sort();
                    break;

                case "Programs.Arduino.FileLoad":
                    sketchFolder = Path.GetDirectoryName(ArduinoAppFactory.GetSketchFile(migCommand.GetOption(0)));
                    sketchFile = migCommand.GetOption(1);
                    if (sketchFile == "main")
                    {
                        // "main" is a special keyword to indicate the main program sketch file
                        sketchFile = ArduinoAppFactory.GetSketchFile(migCommand.GetOption(0));
                    }
                    sketchFile = Path.Combine(sketchFolder, Path.GetFileName(sketchFile));
                    request.ResponseData = new ResponseText(File.ReadAllText(sketchFile));
                    break;

                case "Programs.Arduino.FileSave":
                    sketchFolder = Path.GetDirectoryName(ArduinoAppFactory.GetSketchFile(migCommand.GetOption(0)));
                    sketchFile = Path.Combine(sketchFolder, Path.GetFileName(migCommand.GetOption(1)));
                    File.WriteAllText(sketchFile, streamContent);
                    break;

                case "Programs.Arduino.FileAdd":
                    sketchFolder = Path.GetDirectoryName(ArduinoAppFactory.GetSketchFile(migCommand.GetOption(0)));
                    if (!Directory.Exists(sketchFolder))
                        Directory.CreateDirectory(sketchFolder);
                    sketchFile = Path.Combine(sketchFolder, Path.GetFileName(migCommand.GetOption(1)));
                    if (File.Exists(sketchFile))
                    {
                        request.ResponseData = new ResponseText("EXISTS");
                    }
                    else if (!ArduinoAppFactory.IsValidProjectFile(sketchFile))
                    {
                        request.ResponseData = new ResponseText("INVALID_NAME");
                    }
                    else
                    {
                        StreamWriter sw = File.CreateText(sketchFile);
                        sw.Close();
                        sw.Dispose();
                        sw = null;
                        request.ResponseData = new ResponseText("OK");
                    }
                    break;

                case "Programs.Arduino.FileDelete":
                    sketchFolder = Path.GetDirectoryName(ArduinoAppFactory.GetSketchFile(migCommand.GetOption(0)));
                    sketchFile = Path.Combine(sketchFolder, Path.GetFileName(migCommand.GetOption(1)));
                    if (!File.Exists(sketchFile))
                    {
                        request.ResponseData = new ResponseText("NOT_FOUND");
                    }
                    else
                    {
                        File.Delete(sketchFile);
                        request.ResponseData = new ResponseText("OK");
                    }
                    break;

                case "Programs.Arduino.FileList":
                    sketchFolder = Path.GetDirectoryName(ArduinoAppFactory.GetSketchFile(migCommand.GetOption(0)));
                    List<string> files = new List<string>();
                    foreach (string f in Directory.GetFiles(sketchFolder))
                    {
                        if (ArduinoAppFactory.IsValidProjectFile(f))
                        {
                            files.Add(Path.GetFileName(f));
                        }
                    }
                    request.ResponseData = files;
                    break;

                case "Programs.Run":
                    currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                    if (currentProgram != null)
                    {
                        // clear any runtime errors before running
                        currentProgram.ScriptErrors = "";
                        homegenie.ProgramManager.RaiseProgramModuleEvent(
                            currentProgram,
                            Properties.RUNTIME_ERROR,
                            ""
                        );
                        currentProgram.IsEnabled = true;
                        ProgramRun(migCommand.GetOption(0), migCommand.GetOption(1));
                    }
                    break;

                case "Programs.Toggle":
                    currentProgram = ProgramToggle(migCommand.GetOption(0), migCommand.GetOption(1));
                    break;

                case "Programs.Break":
                    currentProgram = ProgramBreak(migCommand.GetOption(0));
                    break;

                case "Programs.Restart":
                    currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                    if (currentProgram != null)
                    {
                        currentProgram.IsEnabled = false;
                        try
                        {
                            currentProgram.Engine.Stop();
                        }
                        catch
                        {
                        }
                        currentProgram.IsEnabled = true;
                        homegenie.UpdateProgramsDatabase();
                    }
                    break;

                case "Programs.Enable":
                    currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                    if (currentProgram != null)
                    {
                        currentProgram.IsEnabled = true;
                        homegenie.UpdateProgramsDatabase();
                    }
                    break;

                case "Programs.Disable":
                    currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                    if (currentProgram != null)
                    {
                        currentProgram.IsEnabled = false;
                        try
                        {
                            currentProgram.Engine.Stop();
                        }
                        catch
                        {
                        }
                        homegenie.UpdateProgramsDatabase();
                    }
                    break;
                }

            }
        }
Beispiel #60
0
 private bool ProgramsDiff(ProgramBlock oldProgram, ProgramBlock newProgram)
 {
     bool unchanged = (JsonConvert.SerializeObject(oldProgram.ConditionType) == JsonConvert.SerializeObject(newProgram.ConditionType)) &&
     (JsonConvert.SerializeObject(oldProgram.Conditions) == JsonConvert.SerializeObject(newProgram.Conditions)) &&
     (JsonConvert.SerializeObject(oldProgram.Commands) == JsonConvert.SerializeObject(newProgram.Commands)) &&
     (oldProgram.ScriptCondition == newProgram.ScriptCondition) &&
     (oldProgram.ScriptSource == newProgram.ScriptSource) &&
     (oldProgram.Name == newProgram.Name) &&
     (oldProgram.Description == newProgram.Description) &&
     (oldProgram.Group == newProgram.Group) &&
     (oldProgram.Type == newProgram.Type);
     return !unchanged;
 }