/// <summary>
        /// Creates an installation package for a plugin.
        /// </summary>
        /// <param name="tInfo">Meta information about the plug-in. (can be null, but then tPlace has to be specified)</param>
        /// <param name="tPlace">Additional information about the plug-in's presence in a market place (can be null, but then tInfo has to be specified)</param>
        /// <param name="outputDirectory">Path to a directory that will be used for temporary files as well as the generated installation package</param>
        /// <param name="bForce">Overwrites output files if they already exists.</param>
        /// <param name="packageFilePath">Path to the installation package within the outputDirectory.</param>
        /// <returns>null or empty string if successful. Error information on failure.</returns>
        public static string CreatePluginPackage(ThePluginInfo tInfo, TheServicesMarketPlace tPlace, string outputDirectory, bool bForce, out string packageFilePath)
        {
            packageFilePath = null;
            string tMetaFile = "";

            if (tInfo != null)
            {
                if (tInfo.Capabilities != null && tInfo.Capabilities.Contains(eThingCaps.Internal))
                {
                    return($"{tInfo.ServiceName} Is Internal Only");
                }
                if (String.IsNullOrEmpty(outputDirectory))
                {
                    tMetaFile = TheCommonUtils.cdeFixupFileName($"store\\{tInfo.cdeMID}\\{tInfo.Platform}\\");
                }
                else
                {
                    tMetaFile = $"{outputDirectory}\\store\\{tInfo.cdeMID}\\{tInfo.Platform}\\";
                }
                if (!Directory.Exists(tMetaFile))
                {
                    TheCommonUtils.CreateDirectories(tMetaFile);
                }
                WriteServiceInfo(tInfo, outputDirectory);

                string tgr = tMetaFile + "new\\";
                if (TheCommonUtils.IsOnLinux())
                {
                    tgr = tgr.Replace('\\', '/');
                }
                if (Directory.Exists(tgr))
                {
                    Directory.Delete(tgr, true);
                }

                if (tInfo.FilesManifest != null && tInfo.FilesManifest.Count > 0)
                {
                    foreach (string tFile in tInfo.FilesManifest)
                    {
                        if (tFile == null)
                        {
                            continue;
                        }
                        string tFinalFile = tFile;
                        try
                        {
                            if (tFile.StartsWith("@"))  //If a Manifest file starts with @ this function expects this syntax: "@<platform>@<FileName>"
                            {
                                var tC = tFile.Split('@');
                                if (tC.Length < 3)
                                {
                                    continue;
                                }
                                switch (tC[1])
                                {
                                case "net35":
                                    if (tInfo.Platform != cdePlatform.X32_V3)
                                    {
                                        continue;
                                    }
                                    break;

                                case "net40":
                                    if (tInfo.Platform != cdePlatform.NETV4_32 && tInfo.Platform != cdePlatform.NETV4_64)
                                    {
                                        continue;
                                    }
                                    break;

                                case "net45":
                                    if (tInfo.Platform != cdePlatform.X64_V3 && tInfo.Platform != cdePlatform.X32_V4)
                                    {
                                        continue;
                                    }
                                    break;

                                case "netstandard2.0":
                                    break;

                                default:
                                    if ((TheCommonUtils.CInt(tC[1]) > 0 && TheCommonUtils.CInt(tC[1]) != TheCommonUtils.CInt(tInfo.Platform)))
                                    {
                                        continue;
                                    }
                                    break;
                                }
                                tFinalFile = tC[2];
                            }
                            string src = TheBaseAssets.MyServiceHostInfo.BaseDirectory;
                            if (TheBaseAssets.MyServiceHostInfo.cdeHostingType == cdeHostType.IIS)
                            {
                                src += "bin\\";
                            }
                            src += tFinalFile;
                            if (TheCommonUtils.IsOnLinux())
                            {
                                src = src.Replace('\\', '/');
                            }
                            tgr = tMetaFile + "new\\" + tFinalFile;
                            if (TheCommonUtils.IsOnLinux())
                            {
                                tgr = tgr.Replace('\\', '/');
                            }
                            TheCommonUtils.CreateDirectories(tgr);
                            File.Copy(src, tgr, true);
                        }
                        catch (Exception e)
                        {
                            return(string.Format("Manifest File {0} could not be copied: {1}", tFile, e.ToString()));
                            //TheBaseAssets.MySYSLOG.WriteToLog(2, new TSM("ISMManager", string.Format("Manifest Filer {0} could not be copied.", tFile), eMsgLevel.l1_Error, e.ToString())); //Log Entry that service has been started
                        }
                    }
                }
            }
            else
            {
                tMetaFile = TheCommonUtils.cdeFixupFileName(string.Format("store\\{0}\\{1}\\", tPlace.PluginID, tPlace.Platform));  //now PluginID which contains ThePluginInfo.cdeMID
            }

            if (tPlace != null && File.Exists(tMetaFile + "META.CDEM"))
            {
                TheServicesMarketPlace tPl = null;
                using (StreamReader sr = new StreamReader(tMetaFile + "META.CDEM"))
                {
                    String line = sr.ReadToEnd();
                    tPl = TheCommonUtils.DeserializeJSONStringToObject <TheServicesMarketPlace>(line);
                }
                if ((tInfo != null && tInfo.CurrentVersion <= tPl.CurrentVersion) || (tPl != null && tPlace.CurrentVersion <= tPl.CurrentVersion))
                {
                    return($"{tPlace?.ServiceName} has existing Version in Store: PInfo:{tInfo?.CurrentVersion} vs Meta:{tPl?.CurrentVersion} vs Place:{tPlace?.CurrentVersion}");
                }
            }
            if (tPlace == null)
            {
                tPlace = new TheServicesMarketPlace();
                tPlace.Capabilities    = tInfo.Capabilities;
                tPlace.Categories      = tInfo.Categories;
                tPlace.PluginID        = tInfo.cdeMID; //PluginID now contains ThePluginInfo.cdeMID
                tPlace.CurrentVersion  = tInfo.CurrentVersion;
                tPlace.LongDescription = tInfo.LongDescription;
                tPlace.Developer       = tInfo.Developer;
                tPlace.DeveloperUrl    = tInfo.DeveloperUrl;
                tPlace.HomeUrl         = tInfo.HomeUrl;
                tPlace.Platform        = tInfo.Platform;
                tPlace.Price           = tInfo.Price;
                tPlace.ServiceName     = tInfo.ServiceName;
                tPlace.AvailableSince  = DateTime.Now;
                tPlace.RaterCount      = new List <int>()
                {
                    0, 0, 0, 0, 0
                };
                tPlace.Rating             = 0;
                tPlace.DownloadCounter    = 0;
                tPlace.ServiceDescription = string.IsNullOrEmpty(tInfo.ServiceDescription) ? tInfo.ServiceName : tInfo.ServiceDescription;
                if (TheBaseAssets.MyServiceHostInfo != null)
                {
                    if (string.IsNullOrEmpty(tPlace.HomeUrl))
                    {
                        tPlace.HomeUrl = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false) + "/%PluginID%";
                    }
                    tPlace.IconUrl = tInfo.IconUrl;
                    if (string.IsNullOrEmpty(tPlace.IconUrl) || tPlace.IconUrl == "toplogo-150.png")
                    {
                        tPlace.IconUrl = "<i class=\"cl-font cl-Logo cl-4x\"></i>"; // TheBaseAssets.MyServiceHostInfo.UPnPIcon;
                    }
                    if (tPlace.IconUrl.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || tPlace.IconUrl.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase))
                    {
                        tPlace.IconUrl = $"<img src='{tPlace.IconUrl}' class='Blocked' width='78' height='78'></img>";
                    }
                    else if (tPlace.IconUrl.StartsWith("FA"))
                    {
                        tPlace.IconUrl = "<i class='fa faIcon " + (tPlace.IconUrl.Substring(3, 1) == "S" ? "fa-spin " : "") + "fa-" + tPlace.IconUrl.Substring(2, 1) + "x'>&#x" + tPlace.IconUrl.Substring(4, tPlace.IconUrl.Length - 4) + ";</i>";
                    }
                }
                if (Directory.Exists(tMetaFile + "new"))
                {
                    var res = CreateCDEX(tPlace, tMetaFile, true, out packageFilePath);
                    if (res != null)
                    {
                        return(res);
                    }
                    //Directory.Move(tMetaFile + "new", tMetaFile + "DONE_" + TheCommonUtils.GetTimeStamp());
                }
                else
                {
                    return("Error: Output directory does not exists");
                }
            }
            else
            {
                if (tInfo.CurrentVersion > tPlace.CurrentVersion)
                {
                    tPlace.CurrentVersion = tInfo.CurrentVersion;
                }
                var res = CreateCDEX(tPlace, tMetaFile, bForce, out packageFilePath);
                if (res != null)
                {
                    return(res);
                }
            }
            tPlace.LastUpdate = DateTime.Now;
            using (StreamWriter sr = new StreamWriter(tMetaFile + "META.CDEM"))
                sr.Write(TheCommonUtils.SerializeObjectToJSONString <TheServicesMarketPlace>(tPlace));
            return("");
        }
Example #2
0
        public override bool CreateUX()
        {
            if (mIsUXInitCalled)
            {
                return(false);
            }
            mIsUXInitCalled = true;

            MyPCVitalsDashboard = TheNMIEngine.AddDashboard(MyBaseThing, new TheDashboardInfo(MyBaseEngine, "Node Vitals")
            {
                PropertyBag = new ThePropertyBag()
                {
                    "Category=Diagnostics", "Caption=Node Vitals", "Thumbnail=FA5:f108",
                }
            });

            TheFormInfo tMyConfForm = new TheFormInfo(TheThing.GetSafeThingGuid(MyBaseThing, "Config"), eEngineName.NMIService, "Setting", string.Format("TheThing;:;0;:;True;:;cdeMID={0}", MyBaseThing.cdeMID))
            {
                DefaultView = eDefaultView.Form, PropertyBag = new ThePropertyBag {
                    "TileWidth=6"
                }
            };

            TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyConfForm, "CMyForm", "Settings", 1, 9, 0xC0, TheNMIEngine.GetNodeForCategory(), null, null);

            TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.SingleCheck, 1, 2, 0xC0, "Disable Collection", "IsHealthCollectionOff");
            //TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.SingleCheck, 2, 2, 0xC0, "Enable OHM", "EnableOHM");
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 10, 2, 0xC0, "Health Collection Cycle", "HealthCollectionCycle");
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 11, 2, 0xC0, "Sensor Delay", "SensorDelay");
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 12, 2, 0xC0, "Sensor Deadband", "SensorAccelDeadband");
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 13, 2, 0xC0, "Chart Values", "ChartValues", new nmiCtrlNumber {
                MinValue = 10
            });
            TheNMIEngine.AddSmartControl(MyBaseThing, tMyConfForm, eFieldType.Number, 14, 2, 0xC0, "Default Chart TileWidth", "ChartSize", new nmiCtrlNumber {
                MinValue = 6, MaxValue = 30
            });

            if (!TheCommonUtils.IsHostADevice())
            {
                TheFormInfo tMyForm = new TheFormInfo()
                {
                    cdeMID = new Guid("{A3765D29-8EFF-4F09-B5BC-E5CE4C7DEA6F}"), FormTitle = "CPU Details", defDataSource = "TheThing;:;0;:;True;:;DeviceType=CPUInfo"
                };
                TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyForm, "CMyTable", "CPUs", 2, 3, 0, "Live Tables", null, null);

                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 5, FldWidth = 4, Flags = 2, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Friendly Name", DataItem = "MyPropertyBag.FriendlyName.Value"
                });
                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 6, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "HostURL", DataItem = "MyPropertyBag.HostUrl.Value"
                });

                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 11, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Speed", DataItem = "MyPropertyBag.MaxClockSpeed.Value"
                });
                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 12, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Cores", DataItem = "MyPropertyBag.NumberOfCores.Value"
                });
                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 13, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Manufacturer", DataItem = "MyPropertyBag.Manufacturer.Value"
                });
                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 14, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Architecture", DataItem = "MyPropertyBag.AddressWidth.Value"
                });
                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 15, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Rev", DataItem = "MyPropertyBag.Revision.Value"
                });
                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 16, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "L2 Cache", DataItem = "MyPropertyBag.L2CacheSize.Value"
                });
                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 17, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Version", DataItem = "MyPropertyBag.Version.Value"
                });

                TheNMIEngine.AddField(tMyForm, new TheFieldInfo()
                {
                    FldOrder = 80, FldWidth = 2, cdeA = 0xFF, Type = eFieldType.DateTime, Header = "Last Update", DataItem = "MyPropertyBag.LastUpdate.Value"
                });


                TheFormInfo tMyHForm = new TheFormInfo()
                {
                    cdeMID = new Guid("{33170B1F-CA19-4DC6-A18F-15B5F7669E0A}"), FormTitle = "PC Health Details", defDataSource = "TheThing;:;0;:;True;:;DeviceType=PC-Health"
                };
                TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyHForm, "CMyTable", "PC Health", 3, 3, 0, "Live Tables", null, null);

                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 5, FldWidth = 3, Flags = 2, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Friendly Name", DataItem = "MyPropertyBag.FriendlyName.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 6, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "HostAddress", DataItem = "MyPropertyBag.HostAddress.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 7, FldWidth = 3, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Host Version", DataItem = "MyPropertyBag.HostVersion.Value"
                });
                //TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 8, Flags = 0, cdeA = 0xC0, Type = eFieldType.SingleEnded, Header = "Station Roles", DataItem = "MyPropertyBag.StationRoles.Value" });

                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 11, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "CPU Load", DataItem = "MyPropertyBag.CPULoad.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 13, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "CPU Temp", DataItem = "MyPropertyBag.CPUTemp.Value"
                });
                //TheNMIEngine.AddField(tMyHForm, new TheFieldInfo() { FldOrder = 14, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Core Temps", DataItem = "MyPropertyBag.CoreTemps.Value" });

                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 21, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "RAM Available", DataItem = "MyPropertyBag.RAMAvailable.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 22, FldWidth = 2, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "PC Uptime", DataItem = "MyPropertyBag.PCUptime.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 23, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "Watts", DataItem = "MyPropertyBag.StationWatts.Value"
                });

                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 31, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeUptime", DataItem = "MyPropertyBag.cdeUptime.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 32, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeHandles", DataItem = "MyPropertyBag.cdeHandles.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 33, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeWorkingSetSize", DataItem = "MyPropertyBag.cdeWorkingSetSize.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 34, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "cdeThreadCount", DataItem = "MyPropertyBag.cdeThreadCount.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 35, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "EventTimeOuts", DataItem = "MyPropertyBag.TotalEventTimeouts.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 36, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "QSenders", DataItem = "MyPropertyBag.QSenders.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 37, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "TSM Inserts", DataItem = "MyPropertyBag.QSInserted.Value"
                });
                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 38, Flags = 0, cdeA = 0x0, Type = eFieldType.SingleEnded, Header = "TSM Sents", DataItem = "MyPropertyBag.QSSent.Value"
                });

                TheNMIEngine.AddField(tMyHForm, new TheFieldInfo()
                {
                    FldOrder = 80, FldWidth = 2, cdeA = 0xFF, Type = eFieldType.DateTime, Header = "Last Update", DataItem = "MyPropertyBag.LastUpdate.Value"
                });
            }

            if (!TheBaseAssets.MyServiceHostInfo.IsCloudService)
            {
                int tBS = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ChartValues");
                if (tBS < 10)
                {
                    tBS = 10;
                }
                if (tBS > 10000)
                {
                    tBS = 10000;
                }

                int tCS = (int)TheThing.GetSafePropertyNumber(MyBaseThing, "ChartSize");
                if (tCS < 6)
                {
                    tCS = 6;
                }

                TheNMIEngine.AddChartScreen(MyBaseThing, new TheChartDefinition(TheThing.GetSafeThingGuid(MyBaseThing, "CPUState"), "Computer CPU State", tBS, "TheHealthHistory", true, "", "PB.HostAddress", "PB.CPULoad;PB.CPUTemp;PB.RAMAvailable")
                {
                    GroupMode = 0, IntervalInMS = 0
                }, 2, 3, 0, TheNMIEngine.GetNodeForCategory(), false, new ThePropertyBag()
                {
                    ".TileHeight=8", ".NoTE=true", $".TileWidth={tCS}", $"Header={TheNMIEngine.GetNodeForCategory()}"
                });
                TheNMIEngine.AddChartScreen(MyBaseThing, new TheChartDefinition(TheThing.GetSafeThingGuid(MyBaseThing, "CDERes"), "CDE Resources", tBS, "TheHealthHistory", true, "", "PB.HostAddress", "PB.cdeHandles;PB.cdeWorkingSetSize")
                {
                    GroupMode = 0, IntervalInMS = 0
                }, 5, 3, 0, TheNMIEngine.GetNodeForCategory(), false, new ThePropertyBag()
                {
                    ".TileHeight=8", ".NoTE=true", $".TileWidth={tCS}", $"Header={TheNMIEngine.GetNodeForCategory()}"
                });
                TheNMIEngine.AddChartScreen(MyBaseThing, new TheChartDefinition(TheThing.GetSafeThingGuid(MyBaseThing, "CDEKPIs"), "CDE KPIs", tBS, "TheHealthHistory", true, "", "PB.HostAddress", "PB.QSenders;PB.QSLocalProcessed;PB.QSSent;PB.QKBSent;PB.QKBReceived;PB.QSInserted;PB.EventTimeouts;PB.TotalEventTimeouts;PB.CCTSMsRelayed;PB.CCTSMsReceived;PB.CCTSMsEvaluated;PB.HTCallbacks;PB.KPI1;PB.KPI2;PB.KPI3;PB.KPI4;PB.KPI5;PB.KPI10")
                {
                    GroupMode = 0, IntervalInMS = 0
                }, 5, 3, 0, TheNMIEngine.GetNodeForCategory(), false, new ThePropertyBag()
                {
                    ".TileHeight=8", ".NoTE=true", $".TileWidth={tCS}", $"Header={TheNMIEngine.GetNodeForCategory()}"
                });

                if (!TheCommonUtils.IsOnLinux())
                {
                    var tMyLiveForm = TheNMIEngine.AddStandardForm(MyBaseThing, "Live CPU Chart", 18, "CPULoad", null, 0, TheNMIEngine.GetNodeForCategory());
                    (tMyLiveForm["Header"] as TheFieldInfo).Header = $"{TheNMIEngine.GetNodeForCategory()} CPU Chart";
                    var tc = TheNMIEngine.AddSmartControl(MyBaseThing, tMyLiveForm["Form"] as TheFormInfo, eFieldType.UserControl, 22, 0, 0, "CPU Load", "LoadBucket", new ThePropertyBag()
                    {
                        "ParentFld=1",
                        "ControlType=Line Chart", "Title=CPU Load", "SubTitle=" + GetProperty("HostAddress", true),
                        "SeriesNames=[{ \"name\":\"CPU-Load\", \"lineColor\":\"rgba(0,255,0,0.39)\"}, { \"name\":\"CDE-Load\", \"lineColor\":\"rgba(0,0,255,0.39)\"}]",
                        "TileHeight=4", "Speed=800", "Delay=0", "Background=rgba(0,0,0,0.01)", "MaxValue=100", "NoTE=true"
                    });
                    tc.AddOrUpdatePlatformBag(eWebPlatform.Any, new nmiPlatBag {
                        TileWidth = 18
                    });
                    tc.AddOrUpdatePlatformBag(eWebPlatform.Mobile, new nmiPlatBag {
                        TileWidth = 6
                    });
                    tc.AddOrUpdatePlatformBag(eWebPlatform.HoloLens, new nmiPlatBag {
                        TileWidth = 12
                    });
                }
            }

            if (TheCommonUtils.CBool(TheBaseAssets.MySettings.GetSetting("PCVitalsMaster")))
            {
                TheFormInfo tMyFormUp = TheNMIEngine.AddForm(new TheFormInfo(MyBaseThing)
                {
                    cdeMID = TheThing.GetSafeThingGuid(MyBaseThing, "THHUPLOAD"), FormTitle = "PC Vitals Uploader", DefaultView = eDefaultView.Form
                });
                TheNMIEngine.AddFormToThingUX(MyBaseThing, tMyFormUp, "CMyForm", "PC Vitals Uploader", 3, 13, 0x80, TheNMIEngine.GetNodeForCategory(), null, new nmiDashboardTile {
                    TileThumbnail = "FA3:f093",
                });
                TheNMIEngine.AddSmartControl(MyBaseThing, tMyFormUp, eFieldType.DropUploader, 3, 2, 128, "Drop a TheHealthHistory-file here", null,
                                             new nmiCtrlDropUploader {
                    TileHeight = 6, NoTE = true, TileWidth = 6, EngineName = MyBaseEngine.GetEngineName(), MaxFileSize = 10000000
                });
                FindTHHFiles();
            }


            TheNMIEngine.AddPageDefinitions(new List <ThePageDefinition>
            {
                { new ThePageDefinition(new Guid("{7FED3369-AF7C-451F-9ED1-71131BB993F4}"), "/PCHEALTH", "Health Info", "", Guid.Empty)
                  {
                      WPID = 10, IncludeCDE = true, RequireLogin = false, PortalGuid = MyBaseEngine.GetDashboardGuid(), StartScreen = MyBaseEngine.GetDashboardGuid()
                  } },
            });
            TheNMIEngine.AddAboutButton(MyBaseThing);
            TheNMIEngine.RegisterEngine(MyBaseEngine);

            mIsUXInitialized = true;
            return(true);
        }