private static void RunWorkplace(Workplace workplace)
        {
            var outputPath = CreateLogFileIfNotExists(workplace.Oid + "-" + workplace.Name + ".txt");

            using (var factory = CreateLogger(outputPath, out var logger)) {
                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Started running", logger);
                var timer = Stopwatch.StartNew();
                var defaultProductIsInDatabase = workplace.CheckForDefaultProduct(logger);
                var defaultOrderIsInDatabase   = workplace.CheckForDefaultOrder(logger);
                if (!defaultProductIsInDatabase)
                {
                    workplace.CreateDefaultProduct(logger);
                }

                if (!defaultOrderIsInDatabase)
                {
                    workplace.CreateDefaultOrder(logger);
                }

                workplace.CheckForDefaultProduct(logger);
                workplace.CheckForDefaultOrder(logger);
                workplace.PreviousWorkshiftId = workplace.GetActualWorkShiftIdFor(logger);

                while (_databaseIsOnline && _loopCanRun && _systemIsActivated)
                {
                    LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Inside loop started for " + workplace.Name, logger);
                    workplace.AddProductionPort(logger);
                    workplace.AddCountPort(logger);
                    workplace.AddFailPort(logger);
                    workplace.ActualWorkshiftId = workplace.GetActualWorkShiftIdFor(logger);
                    LogDeviceInfo($"[ {workplace.Name} ] --INF-- Actual Workshift before: {workplace.ActualWorkshiftId}, latest: {workplace.PreviousWorkshiftId} ", logger);
                    workplace.UpdateActualStateForWorkplace(logger);
                    LogDeviceInfo($"[ {workplace.Name} ] --INF-- Actual Workshift after: {workplace.ActualWorkshiftId}, latest: {workplace.PreviousWorkshiftId} ", logger);

                    if (workplace.ActualStateType == StateType.Running)
                    {
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace in production", logger);
                        var workplaceHasActiveIdle    = workplace.CheckIfWorkplaceHasActivedIdle(logger);
                        var workplaceHasActiveOrder   = workplace.CheckIfWorkplaceHasActiveOrder(logger);
                        var lastOrderWasClosedOffline = workplace.CheckIfLastOrderWasClosedOffline(logger);
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace has active order: " + workplaceHasActiveOrder, logger);
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace has active idle: " + workplaceHasActiveIdle, logger);
                        if (!workplaceHasActiveOrder && lastOrderWasClosedOffline)
                        {
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Creating order from last poweroff closed order", logger);
                            workplace.CreatePoweroffOrderForWorkplace(logger);
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_order created", logger);
                        }
                        else if (!workplaceHasActiveOrder)
                        {
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Creating order", logger);
                            workplace.CreateOrderForWorkplace(logger);
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_order created", logger);
                        }
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Active order: " + workplaceHasActiveOrder, logger);
                        if (workplaceHasActiveOrder)
                        {
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Updating data for order", logger);
                            workplace.UpdateOrderData(logger);
                        }
                    }
                    else if (workplace.ActualStateType == StateType.Idle)
                    {
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace in idle", logger);
                        var workplaceHasActiveIdle    = workplace.CheckIfWorkplaceHasActivedIdle(logger);
                        var workplaceHasActiveOrder   = workplace.CheckIfWorkplaceHasActiveOrder(logger);
                        var lastOrderWasClosedOffline = workplace.CheckIfLastOrderWasClosedOffline(logger);
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace has active order: " + workplaceHasActiveOrder, logger);
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace has active idle: " + workplaceHasActiveIdle, logger);
                        if (!workplaceHasActiveOrder && lastOrderWasClosedOffline)
                        {
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Creating order from last poweroff closed order", logger);
                            workplace.CreatePoweroffOrderForWorkplace(logger);
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_order created", logger);
                        }
                        else if (workplaceHasActiveOrder)
                        {
                            if (!workplaceHasActiveIdle)
                            {
                                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- State is idle, but no open terminal idle, checking for last idle DTE", logger);
                                var workplaceIdleTime = workplace.GetWorkplaceIdleTime(logger);
                                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace idle time in seconds: " + workplaceIdleTime, logger);
                                var timeFromLastIdle = workplace.GetSecondsFromLastIdle(logger);
                                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Seconds from last idle DTE: " + timeFromLastIdle, logger);
                                if (timeFromLastIdle > workplaceIdleTime)
                                {
                                    LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Seconds from last idle are more than workplace idle time, checking last idle DTE", logger);
                                    var lastIdleTime = workplace.GetLastIdleTimeForWorkplace(logger);
                                    if (lastIdleTime > workplace.LastStateDateTime)
                                    {
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Idle DTE is newer than state DTE", logger);
                                        workplace.CreateIdleForWorkplace(logger, true, lastIdleTime);
                                        workplace.UpdateOrderIdleTable(logger);
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_idle created", logger);
                                    }
                                    else
                                    {
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- State DTE is newer than idle DTE", logger);
                                        workplace.CreateIdleForWorkplace(logger, true, workplace.LastStateDateTime);
                                        workplace.UpdateOrderIdleTable(logger);
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_idle created", logger);
                                    }
                                }
                                else
                                {
                                    LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Seconds from last idle are less than workplace idle time", logger);
                                }

                                workplace.UpdateOrderData(logger);
                            }
                            else
                            {
                                workplace.UpdateOrderData(logger);
                            }
                        }
                        else
                        {
                            if (!workplaceHasActiveIdle)
                            {
                                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- State is idle, but no open terminal idle, checking for last idle DTE", logger);
                                var workplaceIdleTime = workplace.GetWorkplaceIdleTime(logger);
                                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace idle time in seconds: " + workplaceIdleTime, logger);
                                var timeFromLastIdle = workplace.GetSecondsFromLastIdle(logger);
                                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Seconds from last idle DTE: " + timeFromLastIdle, logger);
                                if (timeFromLastIdle > workplaceIdleTime)
                                {
                                    LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Seconds from last idle are more than workplace idle time, checking last idle DTE", logger);
                                    var lastIdleTime = workplace.GetLastIdleTimeForWorkplace(logger);
                                    if (lastIdleTime > workplace.LastStateDateTime)
                                    {
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Idle DTE is newer than state DTE", logger);
                                        workplace.CreateIdleForWorkplace(logger, false, lastIdleTime);
                                        workplace.UpdateOrderIdleTable(logger);
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_idle created", logger);
                                    }
                                    else
                                    {
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- State DTE is newer than idle DTE", logger);
                                        workplace.CreateIdleForWorkplace(logger, false, workplace.LastStateDateTime);
                                        workplace.UpdateOrderIdleTable(logger);
                                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_idle created", logger);
                                    }
                                }
                                else
                                {
                                    LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Seconds from last idle are less than workplace idle time", logger);
                                }
                            }
                        }
                    }
                    else if (workplace.ActualStateType == StateType.PowerOff)
                    {
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Workplace offline", logger);
                        var workplaceHasActiveOrder = workplace.CheckIfWorkplaceHasActiveOrder(logger);
                        var workplaceHasActiveIdle  = workplace.CheckIfWorkplaceHasActivedIdle(logger);
                        if (workplaceHasActiveOrder)
                        {
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Closing order", logger);
                            var actualDate = DateTime.Now;
                            workplace.CloseOrderForWorkplace(actualDate, true, logger);
                            workplace.UpdateWorkplaceIdleTime(logger);
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_order closed", logger);
                        }

                        if (workplaceHasActiveIdle)
                        {
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Closing idle", logger);
                            var actualDate = DateTime.Now;
                            workplace.CloseIdleForWorkplace(actualDate, logger);
                            LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Terminal_input_idle closed", logger);
                        }
                    }

                    var sleepTime = Convert.ToDouble(_downloadEvery);
                    var waitTime  = sleepTime - timer.ElapsedMilliseconds;
                    if ((waitTime) > 0)
                    {
                        LogDeviceInfo($"[ {workplace.Name} ] --INF-- Sleeping for {waitTime} ms", logger);
                        Thread.Sleep((int)(waitTime));
                    }
                    else
                    {
                        LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Processing takes more than" + _downloadEvery + " ms", logger);
                    }

                    timer.Restart();
                }

                factory.Dispose();
                LogDeviceInfo("[ " + workplace.Name + " ] --INF-- Process ended.", logger);
                _numberOfRunningWorkplaces--;
            }
        }