Exemple #1
0
        internal static void GrafanaSettings(out string power, out string temperature, out string length, out string language, out string URL_Admin)
        {
            TimeSpan ts = DateTime.UtcNow - lastGrafanaSettings;

            if (ts.TotalMinutes < 10)
            {
                power       = _power;
                temperature = _temperature;
                length      = _length;
                language    = _language;
                URL_Admin   = _URL_Admin;
                return;
            }

            power       = "hp";
            temperature = "celsius";
            length      = "km";
            language    = "de";
            URL_Admin   = "";

            try
            {
                string filePath = FileManager.GetFilePath(TLFilename.SettingsFilename);

                if (!File.Exists(filePath))
                {
                    lastGrafanaSettings = DateTime.UtcNow;
                    return;
                }

                string  json = File.ReadAllText(filePath);
                dynamic j    = new JavaScriptSerializer().DeserializeObject(json);

                if (IsPropertyExist(j, "Power"))
                {
                    power = j["Power"];
                }

                if (IsPropertyExist(j, "Temperature"))
                {
                    temperature = j["Temperature"];
                }

                if (IsPropertyExist(j, "Length"))
                {
                    length = j["Length"];
                }

                if (IsPropertyExist(j, "Language"))
                {
                    language = j["Language"];
                }

                if (IsPropertyExist(j, "URL_Admin"))
                {
                    if (j["URL_Admin"].ToString().Length > 0)
                    {
                        URL_Admin = j["URL_Admin"];
                    }
                }

                _power       = power;
                _temperature = temperature;
                _length      = length;
                _language    = language;
                _URL_Admin   = URL_Admin;

                lastGrafanaSettings = DateTime.UtcNow;
            }
            catch (Exception ex)
            {
                Logfile.Log(ex.ToString());
            }
        }
Exemple #2
0
        // if car is driving, switch state and return
        // else if car is charging, switch state and return
        // else if KeepOnlineMinAfterUsage is reached, sleep SuspendAPIMinutes minutes
        // else sleep 5000
        private static void HandleState_Online()
        {
            {
                if (webhelper.IsDriving() && DBHelper.currentJSON.current_speed > 0)
                {
                    webhelper.ResetLastChargingState();
                    lastCarUsed         = DateTime.Now;
                    lastOdometerChanged = DateTime.Now;

                    if (webhelper.scanMyTesla != null)
                    {
                        webhelper.scanMyTesla.FastMode(true);
                    }

                    double missingOdometer = DBHelper.currentJSON.current_odometer - odometerLastTrip;

                    if (odometerLastTrip != 0)
                    {
                        if (missingOdometer > 5)
                        {
                            Logfile.Log($"Missing: {missingOdometer} km! - Check: https://teslalogger.de/faq-1.php");
                            WriteMissingFile(missingOdometer);
                        }
                        else
                        {
                            Logfile.Log($"Missing: {missingOdometer} km");
                        }
                    }

                    SetCurrentState(TeslaState.Drive);
                    webhelper.StartStreamThread(); // für altitude
                    DBHelper.StartDriveState();

                    Task.Run(() => webhelper.DeleteWakeupFile());
                    return;
                }
                else if (webhelper.IsCharging(true))
                {
                    lastCarUsed = DateTime.Now;
                    Logfile.Log("Charging");
                    if (webhelper.scanMyTesla != null)
                    {
                        webhelper.scanMyTesla.FastMode(true);
                    }

                    webhelper.IsDriving(true);
                    DBHelper.StartChargingState(webhelper);
                    SetCurrentState(TeslaState.Charge);

                    webhelper.DeleteWakeupFile();
                }
                else
                {
                    RefreshToken();

                    Tools.StartSleeping(out int startSleepHour, out int startSleepMinute);
                    bool doSleep = true;

                    if (FileManager.CheckCmdGoSleepFile())
                    {
                        Logfile.Log("STOP communication with Tesla Server to enter sleep Mode! (Sleep Button)  https://teslalogger.de/faq-1.php");
                        SetCurrentState(TeslaState.GoSleep);
                        goSleepWithWakeup = false;
                    }
                    else if (DateTime.Now.Hour == startSleepHour && DateTime.Now.Minute == startSleepMinute)
                    {
                        Logfile.Log("STOP communication with Tesla Server to enter sleep Mode! (Timespan Sleep Mode)  https://teslalogger.de/faq-1.php");
                        SetCurrentState(TeslaState.GoSleep);
                        goSleepWithWakeup = true;
                    }
                    else
                    {
                        // wenn er 15 min online war und nicht geladen oder gefahren ist, dann muss man ihn die möglichkeit geben offline zu gehen
                        TimeSpan ts = DateTime.Now - lastCarUsed;
                        if (ts.TotalMinutes > ApplicationSettings.Default.KeepOnlineMinAfterUsage)
                        {
                            SetCurrentState(TeslaState.Start);

                            webhelper.IsDriving(true); // kurz bevor er schlafen geht, eine Positionsmeldung speichern und schauen ob standheizung / standklima / sentry läuft.
                            if (DBHelper.currentJSON.current_is_preconditioning)
                            {
                                Logfile.Log("preconditioning prevents car to get sleep");
                                lastCarUsed = DateTime.Now;
                            }
                            else if (webhelper.is_sentry_mode)
                            {
                                Logfile.Log("sentry_mode prevents car to get sleep");
                                lastCarUsed = DateTime.Now;
                            }
                            else
                            {
                                try
                                {
                                    Logfile.Log("STOP communication with Tesla Server to enter sleep Mode! https://teslalogger.de/faq-1.php");
                                    DBHelper.currentJSON.current_falling_asleep = true;
                                    DBHelper.currentJSON.CreateCurrentJSON();

                                    for (int x = 0; x < ApplicationSettings.Default.SuspendAPIMinutes * 10; x++)
                                    {
                                        TimeSpan tsSMT = DateTime.Now - DBHelper.currentJSON.lastScanMyTeslaReceived;
                                        if (DBHelper.currentJSON.SMTSpeed > 5 &&
                                            DBHelper.currentJSON.SMTSpeed < 260 &&
                                            DBHelper.currentJSON.SMTBatteryPower > 2 &&
                                            tsSMT.TotalMinutes < 5)
                                        {
                                            Logfile.Log("ScanMyTesla prevents car to get sleep. Speed: " + DBHelper.currentJSON.SMTSpeed);
                                            lastCarUsed = DateTime.Now;
                                            string wakeup = webhelper.Wakeup().Result;
                                            doSleep = false;
                                            break;
                                        }

                                        if (webhelper.ExistsWakeupFile)
                                        {
                                            Logfile.Log("Wakeupfile prevents car to get sleep");
                                            lastCarUsed = DateTime.Now;
                                            webhelper.DeleteWakeupFile();
                                            string wakeup = webhelper.Wakeup().Result;
                                            doSleep = false;
                                            break;
                                        }

                                        if (x % 10 == 0)
                                        {
                                            Logfile.Log("Waiting for car to go to sleep " + (x / 10).ToString());

                                            Tools.StartSleeping(out startSleepHour, out startSleepMinute);
                                            if (DateTime.Now.Hour == startSleepHour && DateTime.Now.Minute == startSleepMinute)
                                            {
                                                Logfile.Log("STOP communication with Tesla Server to enter sleep Mode! (Timespan Sleep Mode)  https://teslalogger.de/faq-1.php");
                                                SetCurrentState(TeslaState.GoSleep);
                                                goSleepWithWakeup = true;
                                                break;
                                            }
                                        }

                                        Thread.Sleep(1000 * 6);
                                    }
                                }
                                finally
                                {
                                    if (!goSleepWithWakeup)
                                    {
                                        Logfile.Log("Restart communication with Tesla Server! 2");
                                        DBHelper.currentJSON.current_falling_asleep = false;
                                        DBHelper.currentJSON.CreateCurrentJSON();
                                    }
                                }
                            }
                        }
                    }

                    DBHelper.currentJSON.CheckCreateCurrentJSON();

                    if (doSleep)
                    {
                        Thread.Sleep(5000);
                    }
                    else
                    {
                        return;
                    }
                }
            }
        }
Exemple #3
0
        private static void HandleState_GoSleep()
        {
            webhelper.ResetLastChargingState();
            bool KeepSleeping = true;
            int  round        = 0;

            try
            {
                while (KeepSleeping)
                {
                    round++;
                    Thread.Sleep(1000);
                    if (File.Exists(FileManager.GetFilePath(TLFilename.WakeupFilename)))
                    {
                        if (webhelper.DeleteWakeupFile())
                        {
                            string wakeup = webhelper.Wakeup().Result;
                        }

                        KeepSleeping = false;
                        SetCurrentState(TeslaState.Start);
                        break;
                    }
                    else if (round > 10)
                    {
                        round = 0;

                        if (webhelper.TaskerWakeupfile())
                        {
                            if (webhelper.DeleteWakeupFile())
                            {
                                string wakeup = webhelper.Wakeup().Result;
                            }

                            KeepSleeping = false;
                            SetCurrentState(TeslaState.Start);
                            break;
                        }
                    }

                    if (goSleepWithWakeup)
                    {
                        Tools.EndSleeping(out int stopSleepingHour, out int stopSleepingMinute);

                        if (DateTime.Now.Hour == stopSleepingHour && DateTime.Now.Minute == stopSleepingMinute)
                        {
                            Logfile.Log("Stop Sleeping Timespan reached!");

                            KeepSleeping = false;
                            SetCurrentState(TeslaState.Start);
                            break;
                        }
                    }
                }
            }
            finally
            {
                Logfile.Log("Restart communication with Tesla Server! 1");
                DBHelper.currentJSON.current_falling_asleep = false;
                DBHelper.currentJSON.CreateCurrentJSON();
            }
        }
        public void CreateCurrentJSON()
        {
            try
            {
                int    duration    = 0;
                double distance    = 0;
                double trip_kwh    = 0.0;
                double trip_avg_wh = 0.0;

                try
                {
                    if (current_trip_end == DateTime.MinValue)
                    {
                        duration = (int)((TimeSpan)(DateTime.Now - current_trip_start)).TotalSeconds;
                        distance = current_odometer - current_trip_km_start;
                        trip_kwh = (current_trip_start_range - current_ideal_battery_range_km) * Wh_TR;

                        if (distance > 0)
                        {
                            trip_avg_wh = trip_kwh / distance * 1000;
                        }
                    }
                    else
                    {
                        duration = (int)((TimeSpan)(current_trip_end - current_trip_start)).TotalSeconds;
                        distance = current_trip_km_end - current_trip_km_start;
                        trip_kwh = (current_trip_start_range - current_trip_end_range) * Wh_TR;

                        if (distance > 0)
                        {
                            trip_avg_wh = trip_kwh / distance * 1000;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logfile.Log(ex.ToString());
                    duration = 0;
                }
                if (duration < 0)
                {
                    duration = 0;
                }


                var values = new Dictionary <string, object>
                {
                    { "charging", current_charging },
                    { "driving", current_driving },
                    { "online", current_online },
                    { "sleeping", current_sleeping },
                    { "speed", current_speed },
                    { "power", current_power },
                    { "odometer", current_odometer },
                    { "ideal_battery_range_km", current_ideal_battery_range_km },
                    { "outside_temp", current_outside_temp },
                    { "battery_level", current_battery_level },
                    { "charger_voltage", current_charger_voltage },
                    { "charger_phases", current_charger_phases },
                    { "charger_actual_current", current_charger_actual_current },
                    { "charge_energy_added", current_charge_energy_added },
                    { "charger_power", current_charger_power },
                    { "car_version", current_car_version },
                    { "trip_start", current_trip_start.ToString("t", Tools.ciDeDE) },
                    { "trip_max_speed", current_trip_max_speed },
                    { "trip_max_power", current_trip_max_power },
                    { "trip_duration_sec", duration },
                    { "trip_kwh", trip_kwh },
                    { "trip_avg_kwh", trip_avg_wh },
                    { "trip_distance", distance },
                    { "ts", DateTime.Now.ToString("s") },
                    { "latitude", latitude },
                    { "longitude", longitude },
                    { "charge_limit_soc", charge_limit_soc },
                    { "inside_temperature", current_inside_temperature },
                    { "battery_heater", current_battery_heater },
                    { "is_preconditioning", current_is_preconditioning },
                    { "sentry_mode", current_is_sentry_mode }
                };

                TimeSpan ts = DateTime.Now - lastScanMyTeslaReceived;
                if (ts.TotalMinutes < 5)
                {
                    values.Add("SMTCellTempAvg", SMTCellTempAvg);
                    values.Add("SMTCellMinV", SMTCellMinV);
                    values.Add("SMTCellAvgV", SMTCellAvgV);
                    values.Add("SMTCellMaxV", SMTCellMaxV);
                    values.Add("SMTBMSmaxCharge", SMTBMSmaxCharge);
                    values.Add("SMTBMSmaxDischarge", SMTBMSmaxDischarge);
                }

                current_json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(values);

                FileManager.WriteCurrentJsonFile(current_json);
            }
            catch (Exception ex)
            {
                Logfile.Log(ex.ToString());
                current_json = "";
            }
        }
        private static Dictionary <string, string> GetLanguageDictionary(string language)
        {
            Dictionary <string, string> ht = new Dictionary <string, string>();

            string filename = Path.Combine(FileManager.GetExecutingPath(), "language-" + language + ".txt");
            string content  = null;

            if (File.Exists(filename))
            {
                try
                {
                    string[] lines = File.ReadAllLines(filename);
                    foreach (string line in lines)
                    {
                        content = line;

                        if (line.Length == 0)
                        {
                            continue;
                        }

                        if (line.StartsWith("#"))
                        {
                            continue;
                        }

                        if (!line.Contains("="))
                        {
                            continue;
                        }

                        int    pos   = line.IndexOf("=");
                        string key   = line.Substring(0, pos).Trim();
                        string value = line.Substring(pos + 1);

                        // Logfile.Log("Key insert: " + key);

                        if (ht.ContainsKey(key))
                        {
                            Logfile.Log($"Error Key '{key}' already in Dictionary!!!");
                            continue;
                        }

                        if (value.Trim().Length > 0)
                        {
                            ht.Add(key, value);
                        }
                        else
                        {
                            ht.Add(key, key + " xxx");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logfile.Log(ex.Message);
                    Logfile.ExceptionWriter(ex, content);
                }
            }

            return(ht);
        }
        public static void Start(WebHelper wh)
        {
            try
            {
                shareDataOnStartup = Tools.IsShareData();

                if (!DBHelper.ColumnExists("pos", "battery_level"))
                {
                    Logfile.Log("ALTER TABLE pos ADD COLUMN battery_level DOUBLE NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE pos ADD COLUMN battery_level DOUBLE NULL");
                }

                if (!DBHelper.ColumnExists("drivestate", "outside_temp_avg"))
                {
                    Logfile.Log("ALTER TABLE drivestate ADD COLUMN outside_temp_avg DOUBLE NULL, ADD COLUMN speed_max INT NULL, ADD COLUMN power_max INT NULL, ADD COLUMN power_min INT NULL, ADD COLUMN power_avg DOUBLE NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE drivestate ADD COLUMN outside_temp_avg DOUBLE NULL, ADD COLUMN speed_max INT NULL, ADD COLUMN power_max INT NULL, ADD COLUMN power_min INT NULL, ADD COLUMN power_avg DOUBLE NULL");

                    DBHelper.UpdateAllDrivestateData();
                }

                if (!DBHelper.ColumnExists("charging", "charger_pilot_current"))
                {
                    Logfile.Log("ALTER TABLE charging ADD COLUMN charger_pilot_current INT NULL, ADD COLUMN charge_current_request INT NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE charging ADD COLUMN charger_pilot_current INT NULL, ADD COLUMN charge_current_request INT NULL");
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.TableExists("car_version"))
                {
                    Logfile.Log("CREATE TABLE car_version (id int NOT NULL AUTO_INCREMENT, StartDate datetime NOT NULL, version varchar(50), PRIMARY KEY(id))");
                    DBHelper.ExecuteSQLQuery("CREATE TABLE car_version (id int NOT NULL AUTO_INCREMENT, StartDate datetime NOT NULL, version varchar(50), PRIMARY KEY(id))");
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.TableExists("can"))
                {
                    Logfile.Log("CREATE TABLE `can` (`datum` datetime NOT NULL, `id` mediumint NOT NULL, `val` double DEFAULT NULL, PRIMARY KEY(`datum`,`id`) ) ENGINE = InnoDB DEFAULT CHARSET = latin1;");
                    DBHelper.ExecuteSQLQuery("CREATE TABLE `can` (`datum` datetime NOT NULL, `id` mediumint NOT NULL, `val` double DEFAULT NULL, PRIMARY KEY(`datum`,`id`) ) ENGINE = InnoDB DEFAULT CHARSET = latin1;");
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("pos", "inside_temp"))
                {
                    Logfile.Log("ALTER TABLE pos ADD COLUMN inside_temp DOUBLE NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE pos ADD COLUMN inside_temp DOUBLE NULL", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("pos", "battery_heater"))
                {
                    Logfile.Log("ALTER TABLE pos ADD COLUMN battery_heater TINYINT(1) NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE pos ADD COLUMN battery_heater TINYINT(1) NULL", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("pos", "is_preconditioning"))
                {
                    Logfile.Log("ALTER TABLE pos ADD COLUMN is_preconditioning TINYINT(1) NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE pos ADD COLUMN is_preconditioning TINYINT(1) NULL", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("pos", "sentry_mode"))
                {
                    Logfile.Log("ALTER TABLE pos ADD COLUMN sentry_mode TINYINT(1) NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE pos ADD COLUMN sentry_mode TINYINT(1) NULL", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("chargingstate", "conn_charge_cable"))
                {
                    Logfile.Log("ALTER TABLE chargingstate ADD COLUMN conn_charge_cable varchar(50)");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE chargingstate ADD COLUMN conn_charge_cable varchar(50)", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("chargingstate", "fast_charger_brand"))
                {
                    Logfile.Log("ALTER TABLE chargingstate ADD COLUMN fast_charger_brand varchar(50)");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE chargingstate ADD COLUMN fast_charger_brand varchar(50)", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("chargingstate", "fast_charger_type"))
                {
                    Logfile.Log("ALTER TABLE chargingstate ADD COLUMN fast_charger_type varchar(50)");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE chargingstate ADD COLUMN fast_charger_type varchar(50)", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("chargingstate", "fast_charger_present"))
                {
                    Logfile.Log("ALTER TABLE chargingstate ADD COLUMN fast_charger_present TINYINT(1)");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE chargingstate ADD COLUMN fast_charger_present TINYINT(1)", 300);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("charging", "battery_heater"))
                {
                    Logfile.Log("ALTER TABLE charging ADD COLUMN battery_heater TINYINT(1) NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE charging ADD COLUMN battery_heater TINYINT(1) NULL", 600);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("chargingstate", "max_charger_power"))
                {
                    Logfile.Log("ALTER TABLE chargingstate ADD COLUMN max_charger_power int NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE chargingstate ADD COLUMN max_charger_power int NULL", 600);
                    Logfile.Log("ALTER TABLE OK");
                }

                if (!DBHelper.ColumnExists("trip", "outside_temp_avg"))
                {
                    UpdateDBView(wh);
                }

                if (!DBHelper.TableExists("mothership"))
                {
                    Logfile.Log("CREATE TABLE mothership (id int NOT NULL AUTO_INCREMENT, ts datetime NOT NULL, commandid int NOT NULL, duration DOUBLE NULL, PRIMARY KEY(id))");
                    DBHelper.ExecuteSQLQuery("CREATE TABLE mothership (id int NOT NULL AUTO_INCREMENT, ts datetime NOT NULL, commandid int NOT NULL, duration DOUBLE NULL, PRIMARY KEY(id))");
                    Logfile.Log("CREATE TABLE OK");
                }
                if (!DBHelper.TableExists("mothershipcommands"))
                {
                    Logfile.Log("CREATE TABLE mothershipcommands (id int NOT NULL AUTO_INCREMENT, command varchar(50) NOT NULL, PRIMARY KEY(id))");
                    DBHelper.ExecuteSQLQuery("CREATE TABLE mothershipcommands (id int NOT NULL AUTO_INCREMENT, command varchar(50) NOT NULL, PRIMARY KEY(id))");
                    Logfile.Log("CREATE TABLE OK");
                }
                if (!DBHelper.ColumnExists("mothership", "httpcode"))
                {
                    Logfile.Log("ALTER TABLE mothership ADD COLUMN httpcode int NULL");
                    DBHelper.ExecuteSQLQuery("ALTER TABLE mothership ADD COLUMN httpcode int NULL", 600);
                    Logfile.Log("ALTER TABLE OK");
                }
                if (!DBHelper.TableExists("httpcodes"))
                {
                    Logfile.Log("CREATE TABLE httpcodes (id int NOT NULL, text varchar(50) NOT NULL, PRIMARY KEY(id))");
                    DBHelper.ExecuteSQLQuery("CREATE TABLE httpcodes (id int NOT NULL, text varchar(50) NOT NULL, PRIMARY KEY(id))");
                    Logfile.Log("CREATE TABLE OK");
                }

                DBHelper.EnableMothership();

                CheckDBCharset();

                DBHelper.UpdateHTTPStatusCodes();

                timer = new System.Threading.Timer(FileChecker, wh, 10000, 5000);

                Chmod("/var/www/html/admin/wallpapers", 777);

                UpdatePHPini();

                try
                {
                    // create empty weather.ini file
                    string filepath = Path.Combine(FileManager.GetExecutingPath(), "weather.ini");
                    if (!File.Exists(filepath))
                    {
                        File.WriteAllText(filepath, "city = \"Berlin, de\"\r\nappid = \"12345678901234567890123456789012\"");
                    }

                    Chmod(filepath, 666, false);
                }
                catch (Exception)
                { }


                if (File.Exists("cmd_updated.txt"))
                {
                    Logfile.Log("Update skipped!");
                    return;
                }

                File.AppendAllText("cmd_updated.txt", DateTime.Now.ToLongTimeString());
                Logfile.Log("Start update");

                if (Tools.IsMono())
                {
                    Chmod("VERSION", 666);
                    Chmod("settings.json", 666);
                    Chmod("cmd_updated.txt", 666);
                    Chmod("MQTTClient.exe.config", 666);

                    if (!Exec_mono("git", "--version", false).Contains("git version"))
                    {
                        Exec_mono("apt-get", "-y install git");
                        Exec_mono("git", "--version");
                    }

                    Exec_mono("rm", "-rf /etc/teslalogger/git/*");

                    Exec_mono("rm", "-rf /etc/teslalogger/git");
                    Exec_mono("mkdir", "/etc/teslalogger/git");
                    Exec_mono("mozroots", "--import --sync --machine");
                    Exec_mono("git", "clone --progress https://github.com/bassmaster187/TeslaLogger /etc/teslalogger/git/", true, true);

                    Tools.CopyFilesRecursively(new DirectoryInfo("/etc/teslalogger/git/TeslaLogger/GrafanaPlugins"), new DirectoryInfo("/var/lib/grafana/plugins"));
                    Tools.CopyFilesRecursively(new DirectoryInfo("/etc/teslalogger/git/TeslaLogger/www"), new DirectoryInfo("/var/www/html"));
                    Tools.CopyFile("/etc/teslalogger/git/TeslaLogger/bin/geofence.csv", "/etc/teslalogger/geofence.csv");
                    Tools.CopyFile("/etc/teslalogger/git/TeslaLogger/GrafanaConfig/sample.yaml", "/etc/grafana/provisioning/dashboards/sample.yaml");

                    if (!Directory.Exists("/var/lib/grafana/dashboards"))
                    {
                        Directory.CreateDirectory("/var/lib/grafana/dashboards");
                    }

                    Tools.CopyFilesRecursively(new DirectoryInfo("/etc/teslalogger/git/TeslaLogger/bin"), new DirectoryInfo("/etc/teslalogger"));

                    try
                    {
                        if (!File.Exists("/etc/teslalogger/MQTTClient.exe.config"))
                        {
                            Logfile.Log("Copy empty MQTTClient.exe.config file");
                            Tools.CopyFile("/etc/teslalogger/git/MQTTClient/App.config", "/etc/teslalogger/MQTTClient.exe.config");
                        }
                    }
                    catch (Exception ex)
                    {
                        Logfile.Log(ex.ToString());
                    }
                }

                Logfile.Log("End update");

                Logfile.Log("Rebooting");

                Exec_mono("reboot", "");
            }
            catch (Exception ex)
            {
                Logfile.Log("Error in update: " + ex.ToString());
            }
        }