Example #1
0
        public bool UpdateScheduler(string file)
        {
            var success = true;

            //
            // add new scheduler items
            //
            try
            {
                var serializer     = new XmlSerializer(typeof(List <SchedulerItem>));
                var reader         = new StreamReader(file);
                var schedulerItems = (List <SchedulerItem>)serializer.Deserialize(reader);
                reader.Close();
                //
                var configChanged = false;
                foreach (var item in schedulerItems)
                {
                    // it will only import the new ones
                    if (_homegenieService.ProgramManager.SchedulerService.Get(item.Name) == null)
                    {
                        LogMessage("+ Adding Scheduler Item: " + item.Name);
                        _homegenieService.ProgramManager.SchedulerService.AddOrUpdate(item.Name, item.CronExpression, item.Data, item.Description, item.Script);
                        if (!configChanged)
                        {
                            configChanged = true;
                        }
                    }
                }
                //
                if (configChanged)
                {
                    _homegenieService.UpdateSchedulerDatabase();
                }
            }
            catch
            {
                success = false;
            }
            if (!success)
            {
                LogMessage("! ERROR updating Scheduler Items");
            }
            return(success);
        }
Example #2
0
        private bool UpdateScheduler(string file)
        {
            bool success = true;

            //
            // add new scheduler items
            //
            try
            {
                var serializer     = new XmlSerializer(typeof(List <SchedulerItem>));
                var reader         = new StreamReader(file);
                var schedulerItems = (List <SchedulerItem>)serializer.Deserialize(reader);
                reader.Close();
                //
                bool configChanged = false;
                foreach (var item in schedulerItems)
                {
                    if (homegenie.ProgramManager.SchedulerService.Get(item.Name) == null)
                    {
                        LogMessage("+ Adding Scheduler Item: " + item.Name);
                        homegenie.ProgramManager.SchedulerService.AddOrUpdate(item.Name, item.CronExpression);
                        if (!configChanged)
                        {
                            configChanged = true;
                        }
                    }
                }
                //
                if (configChanged)
                {
                    homegenie.UpdateSchedulerDatabase();
                }
            }
            catch
            {
                success = false;
            }
            if (!success)
            {
                LogMessage("! ERROR updating Scheduler Items");
            }
            return(success);
        }
Example #3
0
        public void ProcessRequest(MIGClientRequest request, MIGInterfaceCommand migCommand)
        {
            string       streamContent = "";
            ProgramBlock currentProgram;
            ProgramBlock newProgram;
            string       sketchFile = "", sketchFolder = "";

            //
            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);
                    //
                    int    newPid    = homegenie.ProgramEngine.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.ProgramEngine.ProgramAdd(newProgram);
                    //
                    newProgram.IsEnabled    = false;
                    newProgram.ScriptErrors = "";
                    newProgram.AppAssembly  = null;
                    //
                    if (newProgram.Type.ToLower() != "arduino")
                    {
                        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)));
                    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 as HttpListenerContext).Response.AddHeader(
                            "Content-Disposition",
                            "attachment; filename=\"" + filename + ".zip\""
                            );
                        (request.Context as HttpListenerContext).Response.OutputStream.Write(bundleData, 0, bundleData.Length);
                    }
                    else
                    {
                        (request.Context as HttpListenerContext).Response.AddHeader(
                            "Content-Disposition",
                            "attachment; filename=\"" + filename + ".hgx\""
                            );
                        migCommand.Response = builder.ToString();
                    }
                    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"
                    };
                    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.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));
                    migCommand.Response = JsonHelper.GetSimpleResponse(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))
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("EXISTS");
                    }
                    else if (!ArduinoAppFactory.IsValidProjectFile(sketchFile))
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("INVALID_NAME");
                    }
                    else
                    {
                        StreamWriter sw = File.CreateText(sketchFile);
                        sw.Close();
                        sw.Dispose();
                        sw = null;
                        migCommand.Response = JsonHelper.GetSimpleResponse("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))
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("NOT_FOUND");
                    }
                    else
                    {
                        File.Delete(sketchFile);
                        migCommand.Response = JsonHelper.GetSimpleResponse("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));
                        }
                    }
                    migCommand.Response = JsonConvert.SerializeObject(files);
                    break;

                case "Programs.Run":
                    currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                    if (currentProgram != null)
                    {
                        // clear any runtime errors before running
                        currentProgram.ScriptErrors = "";
                        homegenie.ProgramEngine.RaiseProgramModuleEvent(
                            currentProgram,
                            Properties.RUNTIME_ERROR,
                            ""
                            );
                        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;
                }
            }
        }
Example #4
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;
                }
            }
        }
Example #5
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 newSchedule = JsonConvert.DeserializeObject <SchedulerItem>(request.RequestText);
                    var item        = homegenie.ProgramManager.SchedulerService.AddOrUpdate(
                        newSchedule.Name,
                        newSchedule.CronExpression,
                        newSchedule.Data,
                        newSchedule.Description,
                        newSchedule.Script
                        );
                    if (newSchedule.BoundDevices != null)
                    {
                        item.BoundDevices = newSchedule.BoundDevices;
                    }
                    if (newSchedule.BoundModules != null)
                    {
                        item.BoundModules = newSchedule.BoundModules;
                    }
                    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.ListOccurrences":
                    int hours = 24;
                    int.TryParse(migCommand.GetOption(0), out hours);
                    DateTime dateStart = DateTime.Today.ToUniversalTime();
                    string   startFrom = migCommand.GetOption(1);
                    if (!String.IsNullOrWhiteSpace(startFrom))
                    {
                        dateStart = Utility.JavascriptToDate(long.Parse(startFrom));
                    }
                    List <dynamic> nextList = new List <dynamic>();
                    foreach (var ce in homegenie.ProgramManager.SchedulerService.Items)
                    {
                        if (!ce.IsEnabled)
                        {
                            continue;
                        }
                        var evt     = new { Name = ce.Name, Description = ce.Description, RunScript = !String.IsNullOrWhiteSpace(ce.Script), Occurrences = new List <double>() };
                        var d       = dateStart;
                        var dateEnd = dateStart.AddHours(hours);
                        var occurs  = homegenie.ProgramManager.SchedulerService.GetScheduling(dateStart, dateEnd, ce.CronExpression);
                        occurs.Sort();
                        foreach (var dt in occurs)
                        {
                            evt.Occurrences.Add(Utility.DateToJavascript(dt.ToUniversalTime()));
                        }
                        if (evt.Occurrences.Count > 0)
                        {
                            nextList.Add(evt);
                        }
                    }
                    request.ResponseData = nextList;
                    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).Trim());
                        cronDescription = Char.ToLowerInvariant(cronDescription[0]) + cronDescription.Substring(1);
                    } catch { }
                    request.ResponseData = new ResponseText(cronDescription);
                    break;

                case "Scheduling.SolarTimes":
                    var solarTimes = new SolarTimes(DateTime.Now, homegenie.ProgramManager.SchedulerService.Location["latitude"].Value, homegenie.ProgramManager.SchedulerService.Location["longitude"].Value);
                    request.ResponseData = solarTimes;
                    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();
                    newProgram = homegenie.PackageManager.ProgramImport(newPid, archiveName, migCommand.GetOption(0));

                    /*
                     * 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;
                    writerSettings.Encoding = Encoding.UTF8;
                    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.Get":
                    try
                    {
                        var prg      = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                        var settings = new JsonSerializerSettings {
                            Formatting = Formatting.Indented
                        };
                        request.ResponseData = JsonConvert.SerializeObject(prg, settings);
                    }
                    catch (Exception ex)
                    {
                        request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                    }
                    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.StopProgram();
                        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.RuntimeError,
                            ""
                            );
                        currentProgram.IsEnabled = true;
                        System.Threading.Thread.Sleep(500);
                        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.StopProgram();
                        }
                        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.StopProgram();
                        }
                        catch
                        {
                        }
                        homegenie.UpdateProgramsDatabase();
                    }
                    break;
                }
            }
        }
Example #6
0
        public void ProcessRequest(MigClientRequest request)
        {
            var          migCommand    = request.Command;
            string       streamContent = "";
            ProgramBlock currentProgram;
            ProgramBlock newProgram;
            string       sketchFile = "", sketchFolder = "";

            //
            request.ResponseData = new ResponseStatus(Status.Ok);
            if (homegenie.ExecuteAutomationRequest(migCommand))
            {
                // TODO: should it just return if the request has been already processed?
            }
            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;

                    default:
                        request.ResponseData = new ResponseStatus(Status.Error);
                        break;
                    }
                    break;

                case "Macro.GetDelay":
                    request.ResponseData = "{ \"DelayType\" : \"" + homegenie.ProgramManager.MacroRecorder.DelayType + "\", \"DelayOptions\" : \"" + homegenie.ProgramManager.MacroRecorder.DelaySeconds + "\" }";
                    break;

                default:
                    request.ResponseData = new ResponseStatus(Status.Error);
                    break;
                }
            }
            else if (migCommand.Command.StartsWith("Scheduling."))
            {
                switch (migCommand.Command)
                {
                case "Scheduling.Add":
                case "Scheduling.Update":
                    var newSchedule = JsonConvert.DeserializeObject <SchedulerItem>(request.RequestText);
                    var item        = homegenie.ProgramManager.SchedulerService.AddOrUpdate(
                        newSchedule.Name,
                        newSchedule.CronExpression,
                        newSchedule.Data,
                        newSchedule.Description,
                        newSchedule.Script
                        );
                    if (newSchedule.BoundDevices != null)
                    {
                        item.BoundDevices = newSchedule.BoundDevices;
                    }
                    if (newSchedule.BoundModules != null)
                    {
                        item.BoundModules = newSchedule.BoundModules;
                    }
                    homegenie.UpdateSchedulerDatabase();
                    break;

                case "Scheduling.ModuleUpdate":
                    var mod = homegenie.Modules.Find((m) =>
                                                     m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (mod == null)
                    {
                        break;
                    }
                    var scheduling = JsonConvert.DeserializeObject <dynamic>(request.RequestText);
                    for (int i = 0; i < scheduling.include.Count; i++)
                    {
                        string name          = scheduling.include[i].Value.ToString();
                        var    schedulerItem = homegenie.ProgramManager.SchedulerService.Get(name);
                        if (schedulerItem != null)
                        {
                            schedulerItem.BoundModules.RemoveAll((mr) =>
                                                                 mr.Domain == mod.Domain && mr.Address == mod.Address);
                            schedulerItem.BoundModules.Add(new ModuleReference()
                            {
                                Domain  = mod.Domain,
                                Address = mod.Address
                            });
                        }
                    }
                    for (int i = 0; i < scheduling.exclude.Count; i++)
                    {
                        string name          = scheduling.exclude[i].Value.ToString();
                        var    schedulerItem = homegenie.ProgramManager.SchedulerService.Get(name);
                        if (schedulerItem != null)
                        {
                            schedulerItem.BoundModules.RemoveAll((mr) =>
                                                                 mr.Domain == mod.Domain && mr.Address == mod.Address);
                        }
                    }
                    homegenie.UpdateSchedulerDatabase();
                    break;

                case "Scheduling.Get":
                    request.ResponseData = homegenie.ProgramManager.SchedulerService.Get(migCommand.GetOption(0));
                    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.Delete":
                    homegenie.ProgramManager.SchedulerService.Remove(migCommand.GetOption(0));
                    homegenie.UpdateSchedulerDatabase();
                    break;

                case "Scheduling.ListOccurrences":
                    int hours = 24;
                    int.TryParse(migCommand.GetOption(0), out hours);
                    DateTime dateStart = DateTime.Today.ToUniversalTime();
                    string   startFrom = migCommand.GetOption(1);
                    if (!String.IsNullOrWhiteSpace(startFrom))
                    {
                        dateStart = Utility.JavascriptToDate(long.Parse(startFrom));
                    }
                    string         cronExpression = migCommand.GetOption(2);
                    List <dynamic> nextList       = new List <dynamic>();
                    if (!String.IsNullOrEmpty(cronExpression))
                    {
                        var evt = new
                        {
                            CronExpression = cronExpression,
                            Occurrences    = new List <double>()
                        };
                        var d       = dateStart;
                        var dateEnd = dateStart.AddHours(hours);
                        var occurs  = homegenie.ProgramManager.SchedulerService.GetScheduling(dateStart, dateEnd, cronExpression);
                        occurs.Sort();
                        foreach (var dt in occurs)
                        {
                            evt.Occurrences.Add(Utility.DateToJavascript(dt.ToUniversalTime()));
                        }
                        if (evt.Occurrences.Count > 0)
                        {
                            nextList.Add(evt);
                        }
                    }
                    else
                    {
                        for (int s = 0; s < homegenie.ProgramManager.SchedulerService.Items.Count; s++)
                        {
                            var ce = homegenie.ProgramManager.SchedulerService.Items[s];
                            if (!ce.IsEnabled)
                            {
                                continue;
                            }
                            var evt     = new { ce.Name, ce.Description, RunScript = !String.IsNullOrWhiteSpace(ce.Script), Occurrences = new List <double>() };
                            var d       = dateStart;
                            var dateEnd = dateStart.AddHours(hours);
                            var occurs  = homegenie.ProgramManager.SchedulerService.GetScheduling(dateStart, dateEnd, ce.CronExpression);
                            occurs.Sort();
                            foreach (var dt in occurs)
                            {
                                evt.Occurrences.Add(Utility.DateToJavascript(dt.ToUniversalTime()));
                            }
                            if (evt.Occurrences.Count > 0)
                            {
                                nextList.Add(evt);
                            }
                        }
                    }
                    request.ResponseData = nextList;
                    break;

                case "Scheduling.List":
                    homegenie.ProgramManager.SchedulerService
                    .Items.Sort((s1, s2) => String.Compare(s1.Name, s2.Name, StringComparison.Ordinal));
                    request.ResponseData = homegenie.ProgramManager.SchedulerService.Items;
                    break;

                case "Scheduling.Describe":
                    var cronDescription = "";
                    try {
                        cronDescription = ExpressionDescriptor.GetDescription(migCommand.GetOption(0).Trim());
                        cronDescription = Char.ToLowerInvariant(cronDescription[0]) + cronDescription.Substring(1);
                    } catch { }
                    request.ResponseData = new ResponseText(cronDescription);
                    break;

                case "Scheduling.SolarTimes":
                    var solarTimes = new SolarTimes(DateTime.Now, homegenie.ProgramManager.SchedulerService.Location["latitude"].Value, homegenie.ProgramManager.SchedulerService.Location["longitude"].Value);
                    request.ResponseData = solarTimes;
                    break;

                default:
                    request.ResponseData = new ResponseStatus(Status.Error);
                    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();
                    newProgram = homegenie.PackageManager.ProgramImport(newPid, archiveName, migCommand.GetOption(0));
                    homegenie.UpdateProgramsDatabase();
                    request.ResponseData = new ResponseText(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;
                    writerSettings.Encoding = Encoding.UTF8;
                    var programSerializer = new XmlSerializer(typeof(ProgramBlock));
                    var builder           = new StringBuilder();
                    var writer            = System.Xml.XmlWriter.Create(builder, writerSettings);
                    programSerializer.Serialize(writer, currentProgram);
                    writer.Close();
                    //
                    (request.Context.Data as HttpListenerContext).Response.AddHeader(
                        "Content-Type", "application/octet-stream; charset=utf-8"
                        );
                    //
                    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.Get":
                    try
                    {
                        var prg      = homegenie.ProgramManager.Programs.Find(p => p.Address == int.Parse(migCommand.GetOption(0)));
                        var settings = new JsonSerializerSettings {
                            Formatting = Formatting.Indented
                        };
                        request.ResponseData = JsonConvert.SerializeObject(prg, settings);
                    }
                    catch (Exception ex)
                    {
                        request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                    }
                    break;

                case "Programs.Add":
                    try
                    {
                        // This works with HG > 1.4.x
                        newProgram = JsonConvert.DeserializeObject <ProgramBlock>(streamContent);
                    }
                    catch (Exception e)
                    {
                        // this is for backward compatibility with HG v1.3.x
                        newProgram = new ProgramBlock()
                        {
                            Group = migCommand.GetOption(0),
                            Name  = streamContent,
                            Type  = "CSharp"
                        };
                    }
                    newProgram.Address = homegenie.ProgramManager.GeneratePid();
                    homegenie.ProgramManager.ProgramAdd(newProgram);
                    homegenie.UpdateProgramsDatabase();
                    request.ResponseData = new ResponseText(newProgram.Address.ToString());
                    break;

                case "Programs.Clone":
                    var copy = homegenie.ProgramManager
                               .ProgramClone(int.Parse(migCommand.GetOption(0)), migCommand.GetOption(1));
                    homegenie.UpdateProgramsDatabase();
                    request.ResponseData = new ResponseText(copy.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);
                        currentProgram = newProgram;
                    }
                    else
                    {
                        bool typeChanged = !string.Equals(currentProgram.Type, newProgram.Type, StringComparison.CurrentCultureIgnoreCase);
                        currentProgram.Type               = newProgram.Type;
                        currentProgram.Group              = newProgram.Group;
                        currentProgram.Name               = newProgram.Name;
                        currentProgram.Description        = newProgram.Description;
                        currentProgram.AutoRestartEnabled = newProgram.AutoRestartEnabled;
                        currentProgram.Cloneable          = newProgram.Cloneable;
                        if (typeChanged)
                        {
                            currentProgram.Engine.SetHost(homegenie);
                        }
                        currentProgram.IsEnabled    = newProgram.IsEnabled;
                        currentProgram.ScriptSetup  = newProgram.ScriptSetup;
                        currentProgram.ScriptSource = newProgram.ScriptSource;
                    }
                    //
                    if (migCommand.Command == "Programs.Compile")
                    {
                        // reset previous error status
                        currentProgram.IsEnabled = false;
                        currentProgram.Engine.StopProgram();
                        currentProgram.ScriptErrors = "";
                        homegenie.ProgramManager.RaiseProgramModuleEvent(
                            currentProgram,
                            Properties.RuntimeError,
                            ""
                            );
                        //
                        List <ProgramError> errors = homegenie.ProgramManager
                                                     .ProgramCompile(currentProgram);
                        currentProgram.IsEnabled    = newProgram.IsEnabled && errors.Count == 0;
                        currentProgram.ScriptErrors = JsonConvert.SerializeObject(errors);
                        request.ResponseData        = currentProgram.ScriptErrors;
                    }
                    else
                    {
                        request.ResponseData = new ResponseStatus(Status.Ok);
                    }
                    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.RuntimeError,
                            ""
                            );
                        currentProgram.IsEnabled = true;
                        System.Threading.Thread.Sleep(500);
                        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.StopProgram();
                        }
                        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.StopProgram();
                        }
                        catch
                        {
                        }
                        homegenie.UpdateProgramsDatabase();
                    }
                    break;

                case "Programs.OptionsGet":
                    var programModule = homegenie.Modules.Find(m =>
                                                               m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (programModule != null)
                    {
                        var options        = new List <OptionField>();
                        var programOptions = new ModuleOptions()
                        {
                            id          = programModule.Address,
                            name        = programModule.Name,
                            description = programModule.Description,
                            items       = options
                        };
                        programModule.Properties.ForEach((o) =>
                        {
                            if (o.Name.StartsWith("ConfigureOptions."))
                            {
                                var fieldType = o.FieldType.Split(':');
                                options.Add(new OptionField()
                                {
                                    pid  = programModule.Address,
                                    type = new OptionFieldType()
                                    {
                                        id      = fieldType[0],
                                        options = fieldType.Skip(1).ToList <object>()
                                    },
                                    name        = o.Name,
                                    description = o.Description,
                                    field       = new ModuleField()
                                    {
                                        key       = o.Name,
                                        value     = o.Value,
                                        timestamp = o.UpdateTime.ToString("o")
                                    }
                                });
                            }
                        });
                        options.Sort((o1, o2) => (o1.description).CompareTo(o2.description));
                        request.ResponseData = JsonConvert.SerializeObject(programOptions);
                    }
                    break;

                default:
                    request.ResponseData = new ResponseStatus(Status.Error);
                    break;
                }
            }
            else
            {
                request.ResponseData = new ResponseStatus(Status.Error);
            }
        }
Example #7
0
        public void ProcessRequest(MIGClientRequest request, MIGInterfaceCommand migcmd)
        {
            string streamcontent = "";

            //
            _hg.ExecuteAutomationRequest(migcmd);
            //
            if (migcmd.command.StartsWith("Macro."))
            {
                switch (migcmd.command)
                {
                case "Macro.Record":
                    _hg.ProgramEngine.MacroRecorder.RecordingEnable();
                    break;

                case "Macro.Save":
                    ProgramBlock pb = _hg.ProgramEngine.MacroRecorder.SaveMacro(migcmd.GetOption(1));
                    migcmd.response = pb.Address.ToString();
                    break;

                case "Macro.Discard":
                    _hg.ProgramEngine.MacroRecorder.RecordingDisable();
                    break;

                case "Macro.SetDelay":
                    switch (migcmd.GetOption(0).ToLower())
                    {
                    case "none":
                        _hg.ProgramEngine.MacroRecorder.DelayType = MacroDelayType.None;
                        break;

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

                    case "fixed":
                        double secs = double.Parse(migcmd.GetOption(1), System.Globalization.CultureInfo.InvariantCulture);
                        _hg.ProgramEngine.MacroRecorder.DelayType    = MacroDelayType.Fixed;
                        _hg.ProgramEngine.MacroRecorder.DelaySeconds = secs;
                        break;
                    }
                    break;

                case "Macro.GetDelay":
                    migcmd.response = "[{ DelayType : '" + _hg.ProgramEngine.MacroRecorder.DelayType + "', DelayOptions : '" + _hg.ProgramEngine.MacroRecorder.DelaySeconds + "' }]";
                    break;
                }
            }
            else if (migcmd.command.StartsWith("Scheduling."))
            {
                switch (migcmd.command)
                {
                case "Scheduling.Add":
                case "Scheduling.Update":
                    SchedulerItem item = _hg.ProgramEngine.SchedulerService.AddOrUpdate(migcmd.GetOption(0), migcmd.GetOption(1).Replace("|", "/"));
                    item.ProgramId = migcmd.GetOption(2);
                    _hg.UpdateSchedulerDatabase();
                    break;

                case "Scheduling.Delete":
                    _hg.ProgramEngine.SchedulerService.Remove(migcmd.GetOption(0));
                    _hg.UpdateSchedulerDatabase();
                    break;

                case "Scheduling.Enable":
                    _hg.ProgramEngine.SchedulerService.Enable(migcmd.GetOption(0));
                    _hg.UpdateSchedulerDatabase();
                    break;

                case "Scheduling.Disable":
                    _hg.ProgramEngine.SchedulerService.Disable(migcmd.GetOption(0));
                    _hg.UpdateSchedulerDatabase();
                    break;

                case "Scheduling.Get":
                    migcmd.response = JsonConvert.SerializeObject(_hg.ProgramEngine.SchedulerService.Get(migcmd.GetOption(0)));
                    break;

                case "Scheduling.List":
                    migcmd.response = JsonConvert.SerializeObject(_hg.ProgramEngine.SchedulerService.Items);
                    break;
                }
            }
            else if (migcmd.command.StartsWith("Programs."))
            {
                if (migcmd.command != "Programs.Import")
                {
                    streamcontent = new StreamReader(request.InputStream).ReadToEnd();
                }
                //
                ProgramBlock cp = null;
                //
                switch (migcmd.command)
                {
                case "Programs.Import":
                    string archivename = "homegenie_program_import.hgx";
                    if (File.Exists(archivename))
                    {
                        File.Delete(archivename);
                    }
                    //
                    Encoding enc      = (request.Context as HttpListenerContext).Request.ContentEncoding;
                    string   boundary = MIG.Gateways.WebServiceUtility.GetBoundary((request.Context as HttpListenerContext).Request.ContentType);
                    MIG.Gateways.WebServiceUtility.SaveFile(enc, boundary, request.InputStream, archivename);
                    //
                    XmlSerializer mserializer  = new XmlSerializer(typeof(ProgramBlock));
                    StreamReader  mreader      = new StreamReader(archivename);
                    ProgramBlock  programblock = (ProgramBlock)mserializer.Deserialize(mreader);
                    mreader.Close();
                    //
                    programblock.Address = _hg.ProgramEngine.GeneratePid();
                    programblock.Group   = migcmd.GetOption(0);
                    _hg.ProgramEngine.ProgramAdd(programblock);
                    //
                    //TODO: move program compilation into an method of ProgramEngine and also apply to Programs.Update
                    programblock.IsEnabled      = false;
                    programblock.ScriptErrors   = "";
                    programblock.ScriptAssembly = null;
                    //
                    // DISABLED IN FLAVOUR OF USER ASSISTED ENABLING, to prevent malicious scripts to start automatically
                    // in case of c# script type, we have to recompile it

                    /*
                     * if (programblock.Type.ToLower() == "csharp" && programblock.IsEnabled)
                     * {
                     *  System.CodeDom.Compiler.CompilerResults res = _mastercontrolprogram.CompileScript(programblock);
                     *  //
                     *  if (res.Errors.Count == 0)
                     *  {
                     *      programblock.ScriptAssembly = res.CompiledAssembly;
                     *  }
                     *  else
                     *  {
                     *      int sourcelines = programblock.ScriptSource.Split('\n').Length;
                     *      foreach (System.CodeDom.Compiler.CompilerError ce in res.Errors)
                     *      {
                     *          //if (!ce.IsWarning)
                     *          {
                     *              int errline = (ce.Line - 16);
                     *              string blocktype = "Code";
                     *              if (errline >= sourcelines + 7)
                     *              {
                     *                  errline -= (sourcelines + 7);
                     *                  blocktype = "Condition";
                     *              }
                     *              string errmsg = "Line " + errline + ", Column " + ce.Column + " " + ce.ErrorText + " (" + ce.ErrorNumber + ")";
                     *              programblock.ScriptErrors += errmsg + " (" + blocktype + ")" + "\n";
                     *          }
                     *      }
                     *  }
                     * }
                     * //
                     * cmd.response = programblock.ScriptErrors;
                     */
                    //
                    _hg.UpdateProgramsDatabase();
                    //cmd.response = JsonHelper.GetSimpleResponse(programblock.Address);
                    migcmd.response = programblock.Address.ToString();
                    break;

                case "Programs.Export":
                    cp = _hg.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migcmd.GetOption(0)));
                    System.Xml.XmlWriterSettings ws = new System.Xml.XmlWriterSettings();
                    ws.Indent = true;
                    System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(ProgramBlock));
                    StringBuilder        sb  = new StringBuilder();
                    System.Xml.XmlWriter wri = System.Xml.XmlWriter.Create(sb, ws);
                    x.Serialize(wri, cp);
                    wri.Close();
                    migcmd.response = sb.ToString();
                    //
                    (request.Context as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment; filename=\"" + cp.Address + "-" + cp.Name.Replace(" ", "_") + ".hgx\"");
                    break;

                case "Programs.List":
                    List <ProgramBlock> prgs = new List <ProgramBlock>(_hg.ProgramEngine.Programs);
                    prgs.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                    {
                        string c1 = p1.Name + " " + p1.Address;
                        string c2 = p2.Name + " " + p2.Address;
                        return(c1.CompareTo(c2));
                    });
                    migcmd.response = JsonConvert.SerializeObject(prgs);
                    break;

                case "Programs.Add":
                    ProgramBlock pb = new ProgramBlock()
                    {
                        Group = migcmd.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"
                    };
                    pb.Address = _hg.ProgramEngine.GeneratePid();
                    _hg.ProgramEngine.ProgramAdd(pb);
                    _hg.UpdateProgramsDatabase();
                    migcmd.response = JsonHelper.GetSimpleResponse(pb.Address.ToString());
                    break;

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

                case "Programs.Compile":
                case "Programs.Update":
                    programblock = JsonConvert.DeserializeObject <ProgramBlock>(streamcontent);
                    cp           = _hg.ProgramEngine.Programs.Find(p => p.Address == programblock.Address);
                    //
                    if (cp == null)
                    {
                        programblock.Address = _hg.ProgramEngine.GeneratePid();
                        _hg.ProgramEngine.ProgramAdd(programblock);
                    }
                    else
                    {
                        if (cp.Type.ToLower() != programblock.Type.ToLower())
                        {
                            cp.ScriptAssembly = null;     // dispose assembly and interrupt current task
                        }
                        cp.Type            = programblock.Type;
                        cp.Group           = programblock.Group;
                        cp.Name            = programblock.Name;
                        cp.Description     = programblock.Description;
                        cp.IsEnabled       = programblock.IsEnabled;
                        cp.ScriptCondition = programblock.ScriptCondition;
                        cp.ScriptSource    = programblock.ScriptSource;
                        cp.Commands        = programblock.Commands;
                        cp.Conditions      = programblock.Conditions;
                        cp.ConditionType   = programblock.ConditionType;
                        // reset last condition evaluation status
                        cp.LastConditionEvaluationResult = false;
                    }

                    if (migcmd.command == "Programs.Compile" && cp.Type.ToLower() == "csharp") // && programblock.IsEnabled)
                    {
                        cp.ScriptAssembly = null;                                              // dispose assembly and interrupt current task
                        cp.IsEnabled      = false;
                        cp.ScriptErrors   = "";
                        //
                        System.CodeDom.Compiler.CompilerResults res = _hg.ProgramEngine.CompileScript(cp);
                        //
                        if (res.Errors.Count == 0)
                        {
                            cp.ScriptAssembly = res.CompiledAssembly;
                        }
                        else
                        {
                            int sourcelines = cp.ScriptSource.Split('\n').Length;
                            foreach (System.CodeDom.Compiler.CompilerError ce in res.Errors)
                            {
                                //if (!ce.IsWarning)
                                {
                                    int    errline   = (ce.Line - 16);
                                    string blocktype = "Code";
                                    if (errline >= sourcelines + 7)
                                    {
                                        errline  -= (sourcelines + 7);
                                        blocktype = "Condition";
                                    }
                                    string errmsg = "Line " + errline + ", Column " + ce.Column + " " + ce.ErrorText + " (" + ce.ErrorNumber + ")";
                                    cp.ScriptErrors += errmsg + " (" + blocktype + ")" + "\n";
                                }
                            }
                        }
                        //
                        cp.IsEnabled = programblock.IsEnabled;
                        //
                        migcmd.response = cp.ScriptErrors;
                    }

                    _hg.UpdateProgramsDatabase();
                    //
                    _hg._modules_refresh_virtualmods();
                    _hg._modules_sort();
                    break;

                case "Programs.Run":
                    cp = _hg.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migcmd.GetOption(0)));
                    if (cp != null)
                    {
                        _hg.ProgramEngine.Run(cp, migcmd.GetOption(1));
                    }
                    break;

                case "Programs.Break":
                    cp = _hg.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migcmd.GetOption(0)));
                    if (cp != null)
                    {
                        cp.Stop();
                        _hg.UpdateProgramsDatabase();
                    }
                    break;

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

                case "Programs.Disable":
                    cp = _hg.ProgramEngine.Programs.Find(p => p.Address == int.Parse(migcmd.GetOption(0)));
                    if (cp != null)
                    {
                        cp.IsEnabled = false;
                        try
                        {
                            cp.Stop();
                        }
                        catch { }
                        _hg.UpdateProgramsDatabase();
                    }
                    break;
                }
            }
        }
Example #8
0
        private void HandleScheduling(MigInterfaceCommand migCommand, MigClientRequest request)
        {
            switch (migCommand.Command)
            {
            case "Scheduling.Add":
            case "Scheduling.Update":
                var newSchedule = JsonConvert.DeserializeObject <SchedulerItem>(request.RequestText);
                var item        = homegenie.ProgramManager.SchedulerService.AddOrUpdate(
                    newSchedule.Name,
                    newSchedule.CronExpression,
                    newSchedule.Data,
                    newSchedule.Description,
                    newSchedule.Script
                    );
                if (newSchedule.BoundDevices != null)
                {
                    item.BoundDevices = newSchedule.BoundDevices;
                }
                if (newSchedule.BoundModules != null)
                {
                    item.BoundModules = newSchedule.BoundModules;
                }
                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.ListOccurrences":
                var hours = 24;
                int.TryParse(migCommand.GetOption(0), out hours);
                var dateStart = DateTime.Today.ToUniversalTime();
                var startFrom = migCommand.GetOption(1);
                if (!string.IsNullOrWhiteSpace(startFrom))
                {
                    dateStart = Utility.JavascriptToDate(long.Parse(startFrom));
                }

                var nextList = new List <dynamic>();
                foreach (var schedulerItem in homegenie.ProgramManager.SchedulerService.Items)
                {
                    if (!schedulerItem.IsEnabled)
                    {
                        continue;
                    }

                    var evt = new
                    {
                        Name        = schedulerItem.Name, Description = schedulerItem.Description,
                        RunScript   = !string.IsNullOrWhiteSpace(schedulerItem.Script),
                        Occurrences = new List <double>()
                    };

                    var dateEnd = dateStart.AddHours(hours);
                    var occurs  = homegenie.ProgramManager.SchedulerService.GetScheduling(
                        dateStart, dateEnd, schedulerItem.CronExpression);
                    occurs.Sort();
                    foreach (var dt in occurs)
                    {
                        evt.Occurrences.Add(Utility.DateToJavascript(dt.ToUniversalTime()));
                    }

                    if (evt.Occurrences.Count > 0)
                    {
                        nextList.Add(evt);
                    }
                }

                request.ResponseData = nextList;
                break;

            case "Scheduling.List":
                homegenie.ProgramManager.SchedulerService.Items.Sort((s1, s2) => s1.Name.CompareTo(s2.Name));
                request.ResponseData = homegenie.ProgramManager.SchedulerService.Items;
                break;

            case "Scheduling.Describe":
                var cronDescription = "";
                try
                {
                    cronDescription = ExpressionDescriptor.GetDescription(migCommand.GetOption(0).Trim());
                    cronDescription = char.ToLowerInvariant(cronDescription[0]) + cronDescription.Substring(1);
                }
                catch
                {
                }

                request.ResponseData = new ResponseText(cronDescription);
                break;

            case "Scheduling.SolarTimes":
                var solarTimes = new SolarTimes(DateTime.Now,
                                                homegenie.ProgramManager.SchedulerService.Location["latitude"].Value,
                                                homegenie.ProgramManager.SchedulerService.Location["longitude"].Value);
                request.ResponseData = solarTimes;
                break;
            }
        }
Example #9
0
        public bool InstallPackage(string packageFile)
        {
            var          packageData      = JsonConvert.DeserializeObject <PackageData>(File.ReadAllText(packageFile));
            string       repositoryFolder = Path.Combine(Utility.GetDataFolder(), "packages", packageData.Repository);
            string       programsDatabase = Path.Combine(repositoryFolder, packageData.Id, "programs.xml");
            ProgramBlock programToInstall;
            var          serializer = new XmlSerializer(typeof(List <ProgramBlock>));

            using (var reader = new StreamReader(programsDatabase))
            {
                var programs = (List <ProgramBlock>)serializer.Deserialize(reader);
                foreach (var item in packageData.Programs)
                {
                    if (item.Repository != packageData.Repository || item.PackageId != packageData.Id)
                    {
                        // external dependency
                        // TODO: external dependency are not automatically installed
                        // TODO: should report to user
                        continue;
                    }
                    programToInstall = programs.Find((p) => p.Address.ToString() == item.Hid);
                    var installedInstances = homegenie.ProgramManager.Programs
                                             .FindAll((p) => p.PackageInfo.Repository == item.Repository && p.PackageInfo.PackageId == item.PackageId && p.PackageInfo.Id == item.Id);
                    if (installedInstances.Count > 0)
                    {
                        Console.WriteLine("Installing program " + JsonConvert.SerializeObject(item) + item.Hid);
                        // update program code
                        var install = programToInstall;
                        installedInstances.ForEach((p) =>
                        {
                            p.Description          = install.Description;
                            p.ScriptSetup          = install.ScriptSetup;
                            p.ScriptSource         = install.ScriptSource;
                            p.PackageInfo.Checksum = item.Checksum;
                            homegenie.ProgramManager.ProgramCompile(p);
                        });
                    }
                    else if (programToInstall != null)
                    {
                        // add automation group if does not exist
                        if (!String.IsNullOrEmpty(programToInstall.Group))
                        {
                            bool programGroupExists = homegenie.AutomationGroups.Find((ag) => ag.Name == programToInstall.Group) != null;
                            if (!programGroupExists)
                            {
                                homegenie.AutomationGroups.Add(new Group()
                                {
                                    Name = programToInstall.Group
                                });
                                homegenie.UpdateGroupsDatabase("Automation");
                            }
                        }
                        // add the new programm
                        int newProgramId = int.Parse(item.Hid);
                        var prg          = homegenie.ProgramManager.ProgramGet(newProgramId);
                        if (prg != null)
                        {
                            // assign a new id if the standard id is already taken
                            newProgramId = homegenie.ProgramManager.GeneratePid();
                        }
                        // not installed, install it
                        programToInstall.Address = newProgramId;
                        homegenie.ProgramManager.ProgramAdd(programToInstall);
                        homegenie.ProgramManager.ProgramCompile(programToInstall);
                    }
                    else
                    {
                        // TODO: this should never happen, maybe add reporting
                    }
                }
                homegenie.UpdateProgramsDatabase();
            }
            string modulesDatabase = Path.Combine(repositoryFolder, packageData.Id, "modules.xml");

            if (File.Exists(modulesDatabase))
            {
                serializer = new XmlSerializer(typeof(List <Module>));
                using (var reader = new StreamReader(modulesDatabase))
                {
                    var modules = (List <Module>)serializer.Deserialize(reader);
                    foreach (var module in modules)
                    {
                        homegenie.Modules.RemoveAll((m) => m.Domain == module.Domain && module.Address == m.Address);
                        homegenie.Modules.Add(module);
                    }
                    homegenie.UpdateModulesDatabase();
                }
            }
            string groupsDatabase = Path.Combine(repositoryFolder, packageData.Id, "groups.xml");

            if (File.Exists(groupsDatabase))
            {
                serializer = new XmlSerializer(typeof(List <Group>));
                using (var reader = new StreamReader(groupsDatabase))
                {
                    var pkgGroups = (List <Group>)serializer.Deserialize(reader);
                    foreach (var group in pkgGroups)
                    {
                        bool exists = homegenie.Groups.Find((g) => g.Name == group.Name) != null;
                        if (!exists)
                        {
                            homegenie.Groups.Add(group);
                        }
                        // merge modules
                        var targetGroup = homegenie.Groups.Find((g) => g.Name == group.Name);
                        foreach (var mr in group.Modules)
                        {
                            exists = targetGroup.Modules.Find((tmr) =>
                                                              tmr.Domain == mr.Domain && tmr.Address == mr.Address) != null;
                            if (!exists)
                            {
                                targetGroup.Modules.Add(mr);
                            }
                        }
                    }
                    homegenie.UpdateGroupsDatabase("");
                }
            }
            string scheduleDatabase = Path.Combine(repositoryFolder, packageData.Id, "schedules.xml");

            if (File.Exists(scheduleDatabase))
            {
                serializer = new XmlSerializer(typeof(List <SchedulerItem>));
                using (var reader = new StreamReader(scheduleDatabase))
                {
                    var pkgSchedules = (List <SchedulerItem>)serializer.Deserialize(reader);
                    foreach (var schedule in pkgSchedules)
                    {
                        homegenie.ProgramManager.SchedulerService.Remove(schedule.Name);
                        homegenie.ProgramManager.SchedulerService.Items.Add(schedule);
                    }
                    homegenie.UpdateSchedulerDatabase();
                }
            }
            return(true);
        }