~aleteoryx/muditaos

b8239928370663155dc8556354b3715dd387fc5a — Jakub Pyszczak 4 years ago 7ffccab
[EGD-6655] Screen light when active

Added enabling screen light if there was any key pressed
and screen light controler is in the automatic mode.
Added screen light disabling after 5 seconds of timeout
without any key being pressed.
M module-apps/application-settings-new/ApplicationSettings.cpp => module-apps/application-settings-new/ApplicationSettings.cpp +4 -4
@@ 600,8 600,8 @@ namespace app
    void ApplicationSettingsNew::setBrightness(bsp::eink_frontlight::BrightnessPercentage value)
    {
        screen_light_control::Parameters parameters{value};
        bus.sendUnicast(std::make_shared<sevm::ScreenLightControlMessage>(
                            screen_light_control::Action::setManualModeBrightness, parameters),
        bus.sendUnicast(std::make_shared<sevm::ScreenLightSetParameters>(
                            screen_light_control::ParameterizedAction::setManualModeBrightness, parameters),
                        service::name::evt_manager);
    }



@@ 625,8 625,8 @@ namespace app
        screen_light_control::Parameters parameters;
        parameters.functionPoints =
            screen_light_control::functions::BrightnessFunction({{0.0f, 0.0f}, {1000.0f, 100.0f}});
        bus.sendUnicast(std::make_shared<sevm::ScreenLightControlMessage>(
                            screen_light_control::Action::setAutomaticModeParameters, parameters),
        bus.sendUnicast(std::make_shared<sevm::ScreenLightSetParameters>(
                            screen_light_control::ParameterizedAction::setAutomaticModeParameters, parameters),
                        service::name::evt_manager);
    }


M module-apps/application-settings-new/windows/DisplayLightWindow.cpp => module-apps/application-settings-new/windows/DisplayLightWindow.cpp +0 -1
@@ 52,7 52,6 @@ namespace gui
    void DisplayLightWindow::switchHandler(bool &onOffSwitch)
    {
        onOffSwitch = !onOffSwitch;

        screenLightSettings->setStatus(isDisplayLightSwitchOn);
        screenLightSettings->setMode(isAutoLightSwitchOn);


M module-services/service-db/agents/settings/Settings.cpp => module-services/service-db/agents/settings/Settings.cpp +1 -1
@@ 197,7 197,7 @@ namespace settings
        cache->setValue(path, variableValue);
    }

    std::string Settings::getValue(const std::string &variableName, SettingsScope scope)
    std::string Settings::getValue(const std::string &variableName, SettingsScope scope) const
    {
        EntryPath path;
        path.variable = variableName;

M module-services/service-db/service-db/Settings.hpp => module-services/service-db/service-db/Settings.hpp +1 -1
@@ 45,7 45,7 @@ namespace settings
        void unregisterValueChange(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);
        /// unregisters all registered variables (both global and local)
        void unregisterValueChange();
        std::string getValue(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal);
        std::string getValue(const std::string &variableName, SettingsScope scope = SettingsScope::AppLocal) const;

        void getAllProfiles(OnAllProfilesRetrievedCallback cb);
        void setCurrentProfile(const std::string &profile);

M module-services/service-evtmgr/CMakeLists.txt => module-services/service-evtmgr/CMakeLists.txt +1 -0
@@ 6,6 6,7 @@ set(SOURCES
        WorkerEvent.cpp
        api/EventManagerServiceAPI.cpp
        battery-level-check/BatteryLevelCheck.cpp
        backlight-handler/BacklightHandler.cpp
        screen-light-control/ControlFunctions.cpp
        screen-light-control/ScreenLightControl.cpp
        vibra/Vibra.cpp

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +18 -83
@@ 40,8 40,6 @@
#include <fstream>
#include <filesystem>
#include <list>
#include <tuple>
#include <vector>
#include <module-apps/messages/AppMessage.hpp>
#include <SystemManager/messages/CpuFrequencyMessage.hpp>
#include <common_data/EventStore.hpp>


@@ 61,8 59,7 @@ EventManager::EventManager(const std::string &name)
                                                                loggerTimerName,
                                                                std::chrono::milliseconds{loggerDelayMs},
                                                                [this](sys::Timer & /*timer*/) { dumpLogsToFile(); })},
      screenLightControl(std::make_unique<screen_light_control::ScreenLightControl>(settings, this)),
      Vibra(std::make_unique<vibra_handle::Vibra>(this))
      Vibra(std::make_unique<vibra_handle::Vibra>(this)), backlightHandler(settings, this)
{
    LOG_INFO("[%s] Initializing", name.c_str());
    alarmTimestamp = 0;


@@ 125,10 122,7 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
                const auto mode = sys::SystemManager::translateSliderState(message->key);
                bus.sendUnicast(std::make_shared<sys::PhoneModeRequest>(mode), service::name::system_manager);
            }
            if (keypadLightState == bsp::keypad_backlight::State::activeMode && !isKeypadLightInCallMode) {
                bsp::keypad_backlight::turnOnAll();
                startKeypadLightTimer();
            }
            backlightHandler.handleKeyPressed();
        }

        // send key to focused application


@@ 173,7 167,7 @@ sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sy
        if (auto msg = dynamic_cast<sevm::StatusStateMessage *>(msgl)) {
            auto message   = std::make_shared<sevm::StatusStateMessage>(MessageType::EVMModemStatus);
            message->state = msg->state;
            bus.sendUnicast(message, "ServiceCellular");
            bus.sendUnicast(message, ServiceCellular::serviceName);
        }
        handled = true;
    }


@@ 237,26 231,32 @@ sys::ReturnCodes EventManager::InitHandler()
    connect(sevm::KeypadBacklightMessage(bsp::keypad_backlight::Action::turnOff), [&](sys::Message *msgl) {
        auto request      = static_cast<sevm::KeypadBacklightMessage *>(msgl);
        auto response     = std::make_shared<sevm::KeypadBacklightResponseMessage>();
        response->success = processKeypadBacklightRequest(request->action);
        response->success = backlightHandler.processKeypadRequest(request->action);
        return response;
    });

    connect(sevm::BatterySetCriticalLevel(0), [&](sys::Message *msgl) {
        auto request = static_cast<sevm::BatterySetCriticalLevel *>(msgl);
        battery_level_check::setBatteryCriticalLevel(request->criticalLevel);
        return std::make_shared<sys::ResponseMessage>();
        return sys::msgHandled();
    });

    connect(sevm::ScreenLightControlMessage(), [&](sys::Message *msgl) {
    connect(typeid(sevm::ScreenLightControlMessage), [&](sys::Message *msgl) {
        auto *m = dynamic_cast<sevm::ScreenLightControlMessage *>(msgl);
        screenLightControl->processRequest(m->action, m->parameters);
        return std::make_shared<sys::ResponseMessage>();
        backlightHandler.processScreenRequest(m->action);
        return sys::msgHandled();
    });

    connect(typeid(sevm::ScreenLightSetParameters), [&](sys::Message *msgl) {
        auto *m = dynamic_cast<sevm::ScreenLightSetParameters *>(msgl);
        backlightHandler.processScreenRequest(m->action, std::move(m->parameters));
        return sys::msgHandled();
    });

    connect(sevm::ScreenLightControlRequestParameters(), [&](sys::Message *msgl) {
        screen_light_control::Parameters params = {screenLightControl->getBrightnessValue()};
        screen_light_control::Parameters params = {backlightHandler.getScreenBrightnessValue()};
        auto msg                                = std::make_shared<sevm::ScreenLightControlParametersResponse>(
            screenLightControl->getLightState(), screenLightControl->getAutoModeState(), params);
            backlightHandler.getScreenLightState(), backlightHandler.getScreenAutoModeState(), params);
        return msg;
    });
    connect(sevm::RtcUpdateTimeMessage(0), [&](sys::Message *msgl) {


@@ 281,13 281,13 @@ sys::ReturnCodes EventManager::InitHandler()
                bus.sendUnicast(std::make_shared<sevm::BatteryStatusChangeMessage>(), targetApplication);
            }
        }
        return std::make_shared<sys::ResponseMessage>();
        return sys::msgHandled();
    });

    connect(sevm::VibraMessage(bsp::vibrator::Action::stop), [&](sys::Message *msgl) {
        auto request = static_cast<sevm::VibraMessage *>(msgl);
        processVibraRequest(request->action, request->repetitionTime);
        return std::make_shared<sys::ResponseMessage>();
        return sys::msgHandled();
    });

    connect(sevm::ToggleTorchOnOffMessage(), [&]([[maybe_unused]] sys::Message *msg) {


@@ 383,71 383,6 @@ void EventManager::handleMinuteUpdate(time_t timestamp)
    }
}

bool EventManager::processKeypadBacklightRequest(bsp::keypad_backlight::Action action)
{
    bool response = false;
    switch (action) {
    case bsp::keypad_backlight::Action::turnOn:
        if (keypadLightState == bsp::keypad_backlight::State::activeMode) {
            keypadLightTimer.stop();
        }
        keypadLightState = bsp::keypad_backlight::State::on;
        response         = bsp::keypad_backlight::turnOnAll();
        break;
    case bsp::keypad_backlight::Action::turnOff:
        if (keypadLightState == bsp::keypad_backlight::State::activeMode) {
            keypadLightTimer.stop();
        }
        keypadLightState = bsp::keypad_backlight::State::off;
        response         = bsp::keypad_backlight::shutdown();
        break;
    case bsp::keypad_backlight::Action::checkState:
        response = bsp::keypad_backlight::checkState();
        break;
    case bsp::keypad_backlight::Action::turnOnActiveMode:
        keypadLightState = bsp::keypad_backlight::State::activeMode;
        response         = bsp::keypad_backlight::turnOnAll();
        startKeypadLightTimer();
        break;
    case bsp::keypad_backlight::Action::turnOnCallMode:
        if (keypadLightTimer.isActive()) {
            keypadLightTimer.stop();
        }
        isKeypadLightInCallMode = true;
        response                = bsp::keypad_backlight::turnOnFunctionKeysBacklight();
        break;
    case bsp::keypad_backlight::Action::turnOffCallMode:
        isKeypadLightInCallMode = false;
        restoreKeypadLightState();
        break;
    }
    return response;
}

void EventManager::restoreKeypadLightState()
{
    switch (keypadLightState) {
    case bsp::keypad_backlight::State::off:
        processKeypadBacklightRequest(bsp::keypad_backlight::Action::turnOff);
        break;
    case bsp::keypad_backlight::State::on:
        processKeypadBacklightRequest(bsp::keypad_backlight::Action::turnOn);
        break;
    case bsp::keypad_backlight::State::activeMode:
        processKeypadBacklightRequest(bsp::keypad_backlight::Action::turnOnActiveMode);
        break;
    }
}

void EventManager::startKeypadLightTimer()
{
    keypadLightTimer = sys::TimerFactory::createSingleShotTimer(
        this, keypadLightTimerName, keypadLightTimerTimeout, [this](sys::Timer &) {
            bsp::keypad_backlight::shutdown();
        });
    keypadLightTimer.start();
}

bool EventManager::processVibraRequest(bsp::vibrator::Action act, std::chrono::milliseconds RepetitionTime)
{
    switch (act) {

A module-services/service-evtmgr/backlight-handler/BacklightHandler.cpp => module-services/service-evtmgr/backlight-handler/BacklightHandler.cpp +210 -0
@@ 0,0 1,210 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BacklightHandler.hpp"
#include <service-db/agents/settings/SystemSettings.hpp>
#include <service-db/service-db/Settings.hpp>
#include <Timers/TimerFactory.hpp>

namespace backlight
{
    namespace timers
    {
        constexpr auto keypadLightTimerName    = "KeypadLightTimer";
        constexpr auto screenLightTimerName    = "ScreenLightTimer";
        constexpr auto keypadLightTimerTimeout = std::chrono::seconds(5);
        constexpr auto screenLightTimerTimeout = std::chrono::seconds(5);
    } // namespace timers

    Handler::Handler(std::shared_ptr<settings::Settings> settings, sys::Service *parent)
        : settings{settings}, screenLightControl{std::make_unique<screen_light_control::ScreenLightControl>(settings,
                                                                                                            parent)},
          keypadLightTimer{
              sys::TimerFactory::createSingleShotTimer(parent,
                                                       timers::keypadLightTimerName,
                                                       timers::keypadLightTimerTimeout,
                                                       [this](sys::Timer &) { bsp::keypad_backlight::shutdown(); })},
          screenLightTimer{sys::TimerFactory::createSingleShotTimer(
              parent, timers::screenLightTimerName, timers::keypadLightTimerTimeout, [this](sys::Timer &) {
                  if (utils::getNumericValue<bool>(getValue(settings::Brightness::state)) &&
                      utils::getNumericValue<bool>(getValue(settings::Brightness::autoMode)) &&
                      screenLightControl->getLightState()) {
                      screenLightControl->processRequest(screen_light_control::Action::turnOff);
                  }
              })}

    {}

    void Handler::processScreenRequest(screen_light_control::Action action)
    {
        if (action == screen_light_control::Action::enableAutomaticMode) {
            startScreenLightTimer();
        }
        handleScreenLightSettings(action);
        screenLightControl->processRequest(action);
    }

    void Handler::processScreenRequest(screen_light_control::ParameterizedAction action,
                                       screen_light_control::Parameters params)
    {
        handleScreenLightSettings(action, params);
        screenLightControl->processRequest(action, params);
    }

    void Handler::handleKeyPressed()
    {
        handleKeypadLightRefresh();
        handleScreenLightRefresh();
    }

    void Handler::stopKeypadTimer()
    {
        if (keypadLightState == bsp::keypad_backlight::State::activeMode) {
            keypadLightTimer.stop();
        }
    }

    void Handler::setKeypadLightInCallMode(bool value) noexcept
    {
        isKeypadLightInCallMode = value;
    }

    void Handler::setKeypadLightState(bsp::keypad_backlight::State value) noexcept
    {
        keypadLightState = value;
    }

    auto Handler::processKeypadRequest(bsp::keypad_backlight::Action action) -> bool
    {
        switch (action) {
        case bsp::keypad_backlight::Action::turnOn: {
            stopKeypadTimer();
            setKeypadLightState(bsp::keypad_backlight::State::on);
            return bsp::keypad_backlight::turnOnAll();
        }
        case bsp::keypad_backlight::Action::turnOff: {
            stopKeypadTimer();
            setKeypadLightState(bsp::keypad_backlight::State::off);
            return bsp::keypad_backlight::shutdown();
        }
        case bsp::keypad_backlight::Action::checkState: {
            return bsp::keypad_backlight::checkState();
        }
        case bsp::keypad_backlight::Action::turnOnActiveMode: {
            setKeypadLightState(bsp::keypad_backlight::State::activeMode);
            const auto response = bsp::keypad_backlight::turnOnAll();
            startKeypadLightTimer();
            return response;
        }
        case bsp::keypad_backlight::Action::turnOnCallMode: {
            if (keypadLightTimer.isActive()) {
                keypadLightTimer.stop();
            }
            return bsp::keypad_backlight::turnOnFunctionKeysBacklight();
        }
        case bsp::keypad_backlight::Action::turnOffCallMode: {
            setKeypadLightInCallMode(false);
            restoreKeypadLightState();
            return true;
        }
        }
        return false;
    }

    void Handler::restoreKeypadLightState()
    {
        switch (keypadLightState) {
        case bsp::keypad_backlight::State::off:
            processKeypadRequest(bsp::keypad_backlight::Action::turnOff);
            break;
        case bsp::keypad_backlight::State::on:
            processKeypadRequest(bsp::keypad_backlight::Action::turnOn);
            break;
        case bsp::keypad_backlight::State::activeMode:
            processKeypadRequest(bsp::keypad_backlight::Action::turnOnActiveMode);
            break;
        }
    }

    auto Handler::getValue(std::string path) const -> std::string
    {
        return settings->getValue(path);
    }

    void Handler::setValue(std::string path, std::string value)
    {
        settings->setValue(path, value);
    }

    void Handler::startKeypadLightTimer()
    {
        keypadLightTimer.start();
    }

    void Handler::startScreenLightTimer()
    {
        screenLightTimer.start();
    }

    auto Handler::getScreenLightState() const noexcept -> bool
    {
        return screenLightControl->getLightState();
    }

    auto Handler::getScreenAutoModeState() const noexcept -> screen_light_control::ScreenLightMode
    {
        return screenLightControl->getAutoModeState();
    }

    auto Handler::getScreenBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage
    {
        return screenLightControl->getBrightnessValue();
    }

    void Handler::handleKeypadLightRefresh()
    {
        if (keypadLightState == bsp::keypad_backlight::State::activeMode && !isKeypadLightInCallMode) {
            bsp::keypad_backlight::turnOnAll();
            startKeypadLightTimer();
        }
    }

    void Handler::handleScreenLightRefresh()
    {
        if (utils::getNumericValue<bool>(getValue(settings::Brightness::state)) &&
            utils::getNumericValue<bool>(getValue(settings::Brightness::autoMode))) {

            if (!screenLightControl->getLightState()) {
                screenLightControl->processRequest(screen_light_control::Action::turnOn);
            }
            startScreenLightTimer();
        }
    }

    void Handler::handleScreenLightSettings(screen_light_control::Action action)
    {
        switch (action) {
        case screen_light_control::Action::enableAutomaticMode:
            setValue(settings::Brightness::autoMode, utils::to_string(true));
            break;
        case screen_light_control::Action::disableAutomaticMode:
            setValue(settings::Brightness::autoMode, utils::to_string(false));
            screenLightControl->processRequest(screen_light_control::ParameterizedAction::setManualModeBrightness,
                                               screen_light_control::Parameters{utils::getNumericValue<float>(
                                                   getValue(settings::Brightness::brightnessLevel))});
            break;
        case screen_light_control::Action::turnOff:
            setValue(settings::Brightness::state, utils::to_string(false));
            break;
        case screen_light_control::Action::turnOn:
            setValue(settings::Brightness::state, utils::to_string(true));
            break;
        }
    }

    void Handler::handleScreenLightSettings(screen_light_control::ParameterizedAction action,
                                            screen_light_control::Parameters params)
    {
        setValue(settings::Brightness::brightnessLevel, utils::to_string(params.manualModeBrightness));
    }
} // namespace backlight

A module-services/service-evtmgr/backlight-handler/BacklightHandler.hpp => module-services/service-evtmgr/backlight-handler/BacklightHandler.hpp +79 -0
@@ 0,0 1,79 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <bsp/keypad_backlight/keypad_backlight.hpp>
#include <service-evtmgr/screen-light-control/ScreenLightControl.hpp>
#include <Timers/TimerHandle.hpp>

namespace settings
{
    class Settings;
} // namespace settings

namespace backlight
{
    class SettingsInterface
    {
      public:
        virtual ~SettingsInterface() = default;

      protected:
        virtual auto getValue(std::string path) const -> std::string = 0;
        virtual void setValue(std::string path, std::string value)   = 0;
    };

    /// @brief Backlight events handler
    class Handler : public SettingsInterface
    {
      public:
        Handler(std::shared_ptr<settings::Settings> settings, sys::Service *parent);

        /// Process request of the screen light control
        /// @screen_light_control::Action an action to perform
        void processScreenRequest(screen_light_control::Action action);

        /// Process request of the screen light control with specified parameters
        /// @screen_light_control::ParameterizedAction an action to perform
        /// @screen_light_control::Parameters parameters being set
        void processScreenRequest(screen_light_control::ParameterizedAction action,
                                  screen_light_control::Parameters params);

        void handleKeyPressed();
        /// Process request of the keypad light control
        /// @screen_light_control::ParameterizedAction an action to perform
        /// @return True if request was processed succesfully, false otherwise
        auto processKeypadRequest(bsp::keypad_backlight::Action action) -> bool;

        [[nodiscard]] auto getScreenLightState() const noexcept -> bool;
        [[nodiscard]] auto getScreenAutoModeState() const noexcept -> screen_light_control::ScreenLightMode;
        [[nodiscard]] auto getScreenBrightnessValue() const noexcept -> bsp::eink_frontlight::BrightnessPercentage;

      protected:
        [[nodiscard]] auto getValue(std::string path) const -> std::string override;
        void setValue(std::string path, std::string value) override;

      private:
        std::shared_ptr<settings::Settings> settings;
        std::unique_ptr<screen_light_control::ScreenLightControl> screenLightControl;
        /// Timer that keeps key backlight on for a certain time if there was key pressed
        sys::TimerHandle keypadLightTimer;
        /// Timer that keeps screen backlight on for a certain time if there was key pressed
        sys::TimerHandle screenLightTimer;
        bsp::keypad_backlight::State keypadLightState = bsp::keypad_backlight::State::off;
        bool isKeypadLightInCallMode                  = false;

        void startKeypadLightTimer();
        void startScreenLightTimer();
        void stopKeypadTimer();
        void setKeypadLightInCallMode(bool value) noexcept;
        void setKeypadLightState(bsp::keypad_backlight::State value) noexcept;
        void restoreKeypadLightState();
        void handleKeypadLightRefresh();
        void handleScreenLightRefresh();
        void handleScreenLightSettings(screen_light_control::Action action);
        void handleScreenLightSettings(screen_light_control::ParameterizedAction action,
                                       screen_light_control::Parameters params);
    };
} // namespace backlight

M module-services/service-evtmgr/doc/light_control_algorithm.puml => module-services/service-evtmgr/doc/light_control_algorithm.puml +9 -0
@@ 2,6 2,9 @@

hide footbox

participant "Key pressed" as kp
participant "Timer" as t

box "500ms" #LightBlue
participant "Light Measurement" as lm
participant "Brightness Function" as bc


@@ 13,9 16,15 @@ participant "Current ramp value \ncalculation with hysteresis" as rc
participant "Light driver duty cycle \nupdate with Gamma Correction" as ld
end box

kp -> lm : turn on backlight
lm -> bc : measurement
bc -> ru : brightness \nvalue
ru -> rc : ramp target
rc -> ld : current ramp \nvalue
kp -> t  : start timer

alt timeout
t -> t : turn off backlight
end

@enduml

M module-services/service-evtmgr/doc/light_control_algorithm.svg => module-services/service-evtmgr/doc/light_control_algorithm.svg +16 -4
@@ 1,8 1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="250px" preserveAspectRatio="none" style="width:900px;height:250px;" version="1.1" viewBox="0 0 900 250" width="900px" zoomAndPan="magnify"><defs><filter height="300%" id="f1mh8i95ojgk88" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#ADD8E6" height="231.5234" style="stroke:#A80036;stroke-width:1.0;" width="443" x="1" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="49" x="198" y="18.0669">500ms</text><rect fill="#90EE90" height="231.5234" style="stroke:#A80036;stroke-width:1.0;" width="448" x="446" y="6"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="40" x="650" y="18.0669">25ms</text><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="80" x2="80" y1="76.7266" y2="243.5234"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="244" x2="244" y1="76.7266" y2="243.5234"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="386" x2="386" y1="76.7266" y2="243.5234"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="549" x2="549" y1="76.7266" y2="243.5234"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="774" x2="774" y1="76.7266" y2="243.5234"/><rect fill="#FEFECE" filter="url(#f1mh8i95ojgk88)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="147" x="5" y="41.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="133" x="12" y="61.4248">Light Measurement</text><rect fill="#FEFECE" filter="url(#f1mh8i95ojgk88)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="153" x="166" y="41.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="139" x="173" y="61.4248">Brightness Function</text><rect fill="#FEFECE" filter="url(#f1mh8i95ojgk88)" height="46.5938" style="stroke:#A80036;stroke-width:1.5;" width="103" x="333" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="85" x="340" y="45.1279">Ramp target</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="89" x="340" y="61.4248">value update</text><rect fill="#FEFECE" filter="url(#f1mh8i95ojgk88)" height="46.5938" style="stroke:#A80036;stroke-width:1.5;" width="194" x="450" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="131" x="479.5" y="45.1279">Current ramp value</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="180" x="457" y="61.4248">calculation with hysteresis</text><rect fill="#FEFECE" filter="url(#f1mh8i95ojgk88)" height="46.5938" style="stroke:#A80036;stroke-width:1.5;" width="228" x="658" y="25.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="148" x="696" y="45.1279">Light driver duty cycle</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="214" x="665" y="61.4248">update with Gamma Correction</text><polygon fill="#A80036" points="232.5,103.8594,242.5,107.8594,232.5,111.8594,236.5,107.8594" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="80.5" x2="238.5" y1="107.8594" y2="107.8594"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="91" x="87.5" y="102.7935">measurement</text><polygon fill="#A80036" points="374.5,148.125,384.5,152.125,374.5,156.125,378.5,152.125" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="244.5" x2="380.5" y1="152.125" y2="152.125"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="67" x="251.5" y="131.9263">brightness</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="34" x="251.5" y="147.0591">value</text><polygon fill="#A80036" points="537,177.2578,547,181.2578,537,185.2578,541,181.2578" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="386.5" x2="543" y1="181.2578" y2="181.2578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="77" x="393.5" y="176.1919">ramp target</text><polygon fill="#A80036" points="762,221.5234,772,225.5234,762,229.5234,766,225.5234" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="549" x2="768" y1="225.5234" y2="225.5234"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="84" x="556" y="205.3247">current ramp</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="34" x="556" y="220.4575">value</text><!--MD5=[41ba1f1179bd1c783f736902b7001ce8]
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="385px" preserveAspectRatio="none" style="width:1097px;height:385px;" version="1.1" viewBox="0 0 1097 385" width="1097px" zoomAndPan="magnify"><defs><filter height="300%" id="f1he2whahaiyz0" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#ADD8E6" height="363.0547" style="stroke: #A80036; stroke-width: 1.0;" width="443" x="193.5" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="49" x="390.5" y="16.0669">500ms</text><rect fill="#90EE90" height="363.0547" style="stroke: #A80036; stroke-width: 1.0;" width="448" x="638.5" y="4"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="40" x="842.5" y="16.0669">25ms</text><rect fill="#FFFFFF" filter="url(#f1he2whahaiyz0)" height="59.2656" style="stroke: #000000; stroke-width: 2.0;" width="164.5" x="113.5" y="296.7891"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="60" x2="60" y1="74.7266" y2="373.0547"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="151.5" x2="151.5" y1="74.7266" y2="373.0547"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="272.5" x2="272.5" y1="74.7266" y2="373.0547"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="436.5" x2="436.5" y1="74.7266" y2="373.0547"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="578.5" x2="578.5" y1="74.7266" y2="373.0547"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="741.5" x2="741.5" y1="74.7266" y2="373.0547"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="966.5" x2="966.5" y1="74.7266" y2="373.0547"/><rect fill="#FEFECE" filter="url(#f1he2whahaiyz0)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="100" x="8" y="39.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="86" x="15" y="59.4248">Key pressed</text><rect fill="#FEFECE" filter="url(#f1he2whahaiyz0)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="53" x="123.5" y="39.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="39" x="130.5" y="59.4248">Timer</text><rect fill="#FEFECE" filter="url(#f1he2whahaiyz0)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="147" x="197.5" y="39.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="133" x="204.5" y="59.4248">Light Measurement</text><rect fill="#FEFECE" filter="url(#f1he2whahaiyz0)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="153" x="358.5" y="39.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="139" x="365.5" y="59.4248">Brightness Function</text><rect fill="#FEFECE" filter="url(#f1he2whahaiyz0)" height="46.5938" style="stroke: #A80036; stroke-width: 1.5;" width="103" x="525.5" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="85" x="532.5" y="43.1279">Ramp target</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="89" x="532.5" y="59.4248">value update</text><rect fill="#FEFECE" filter="url(#f1he2whahaiyz0)" height="46.5938" style="stroke: #A80036; stroke-width: 1.5;" width="194" x="642.5" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="131" x="672" y="43.1279">Current ramp value</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="180" x="649.5" y="59.4248">calculation with hysteresis</text><rect fill="#FEFECE" filter="url(#f1he2whahaiyz0)" height="46.5938" style="stroke: #A80036; stroke-width: 1.5;" width="228" x="850.5" y="23.1328"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="148" x="888.5" y="43.1279">Light driver duty cycle</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="214" x="857.5" y="59.4248">update with Gamma Correction</text><polygon fill="#A80036" points="261,101.8594,271,105.8594,261,109.8594,265,105.8594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="60" x2="267" y1="105.8594" y2="105.8594"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="107" x="67" y="100.7935">turn on backlight</text><polygon fill="#A80036" points="425,130.9922,435,134.9922,425,138.9922,429,134.9922" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="273" x2="431" y1="134.9922" y2="134.9922"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="91" x="280" y="129.9263">measurement</text><polygon fill="#A80036" points="567,175.2578,577,179.2578,567,183.2578,571,179.2578" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="437" x2="573" y1="179.2578" y2="179.2578"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="67" x="444" y="159.0591">brightness</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="34" x="444" y="174.1919">value</text><polygon fill="#A80036" points="729.5,204.3906,739.5,208.3906,729.5,212.3906,733.5,208.3906" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="579" x2="735.5" y1="208.3906" y2="208.3906"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="77" x="586" y="203.3247">ramp target</text><polygon fill="#A80036" points="954.5,248.6563,964.5,252.6563,954.5,256.6563,958.5,252.6563" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="741.5" x2="960.5" y1="252.6563" y2="252.6563"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="84" x="748.5" y="232.4575">current ramp</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="34" x="748.5" y="247.5903">value</text><polygon fill="#A80036" points="140,277.7891,150,281.7891,140,285.7891,144,281.7891" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="60" x2="146" y1="281.7891" y2="281.7891"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="68" x="67" y="276.7231">start timer</text><path d="M113.5,296.7891 L177.5,296.7891 L177.5,303.7891 L167.5,313.7891 L113.5,313.7891 L113.5,296.7891 " fill="#EEEEEE" style="stroke: #000000; stroke-width: 1.0;"/><rect fill="none" height="59.2656" style="stroke: #000000; stroke-width: 2.0;" width="164.5" x="113.5" y="296.7891"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="19" x="128.5" y="309.856">alt</text><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="59" x="192.5" y="308.9995">[timeout]</text><line style="stroke: #A80036; stroke-width: 1.0;" x1="152" x2="194" y1="335.0547" y2="335.0547"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="194" x2="194" y1="335.0547" y2="348.0547"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="153" x2="194" y1="348.0547" y2="348.0547"/><polygon fill="#A80036" points="163,344.0547,153,348.0547,163,352.0547,159,348.0547" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="107" x="159" y="329.9888">turn off backlight</text><!--
@startuml

hide footbox

participant "Key pressed" as kp
participant "Timer" as t

box "500ms" #LightBlue
participant "Light Measurement" as lm
participant "Brightness Function" as bc


@@ 14,18 17,27 @@ participant "Current ramp value \ncalculation with hysteresis" as rc
participant "Light driver duty cycle \nupdate with Gamma Correction" as ld
end box

kp -> lm : turn on backlight
lm -> bc : measurement
bc -> ru : brightness \nvalue
ru -> rc : ramp target
rc -> ld : current ramp \nvalue
kp -> t  : start timer

alt timeout
t -> t : turn off backlight
end

@enduml

PlantUML version 1.2020.22(Sun Dec 06 10:36:27 CET 2020)
PlantUML version 1.2018.13(Mon Nov 26 18:11:51 CET 2018)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Java Version: 11.0.11+9-Ubuntu-0ubuntu2.20.04
Operating System: Linux
OS Version: 5.8.0-50-generic
Default Encoding: UTF-8
Language: pl
Country: PL
Language: en
Country: US
--></g></svg>
\ No newline at end of file

M module-services/service-evtmgr/doc/light_control_message_flow.puml => module-services/service-evtmgr/doc/light_control_message_flow.puml +4 -0
@@ 1,5 1,9 @@
@startuml
alt control message without any parameters
Application -> "Event Manager" as evm : ScreenLightControlMessage
else contol message with parameters
Application -> "Event Manager" as evm : ScreenLightSetParameters
end
evm -> "ScreenLightControl" as slc: processRequest()
slc -> "Eink Frontlight" : request
slc -> "Light Sensor" : request

M module-services/service-evtmgr/doc/light_control_message_flow.svg => module-services/service-evtmgr/doc/light_control_message_flow.svg +11 -4
@@ 1,16 1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="220px" preserveAspectRatio="none" style="width:725px;height:220px;" version="1.1" viewBox="0 0 725 220" width="725px" zoomAndPan="magnify"><defs><filter height="300%" id="fywa74pnlo8ex" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="51" x2="51" y1="40.2969" y2="176.8281"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="254" x2="254" y1="40.2969" y2="176.8281"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="400" x2="400" y1="40.2969" y2="176.8281"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="543" x2="543" y1="40.2969" y2="176.8281"/><line style="stroke:#A80036;stroke-width:1.0;stroke-dasharray:5.0,5.0;" x1="663" x2="663" y1="40.2969" y2="176.8281"/><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="89" x="5" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="75" x="12" y="24.9951">Application</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="89" x="5" y="175.8281"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="75" x="12" y="195.8232">Application</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="117" x="194" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="103" x="201" y="24.9951">Event Manager</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="117" x="194" y="175.8281"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="103" x="201" y="195.8232">Event Manager</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="146" x="325" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="132" x="332" y="24.9951">ScreenLightControl</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="146" x="325" y="175.8281"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="132" x="332" y="195.8232">ScreenLightControl</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="112" x="485" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="98" x="492" y="24.9951">Eink Frontlight</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="112" x="485" y="175.8281"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="98" x="492" y="195.8232">Eink Frontlight</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="100" x="611" y="5"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="86" x="618" y="24.9951">Light Sensor</text><rect fill="#FEFECE" filter="url(#fywa74pnlo8ex)" height="30.2969" style="stroke:#A80036;stroke-width:1.5;" width="100" x="611" y="175.8281"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="86" x="618" y="195.8232">Light Sensor</text><polygon fill="#A80036" points="242.5,67.4297,252.5,71.4297,242.5,75.4297,246.5,71.4297" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="51.5" x2="248.5" y1="71.4297" y2="71.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="179" x="58.5" y="66.3638">ScreenLightControlMessage</text><polygon fill="#A80036" points="388,96.5625,398,100.5625,388,104.5625,392,100.5625" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="254.5" x2="394" y1="100.5625" y2="100.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="112" x="261.5" y="95.4966">processRequest()</text><polygon fill="#A80036" points="531,125.6953,541,129.6953,531,133.6953,535,129.6953" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="400" x2="537" y1="129.6953" y2="129.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="49" x="407" y="124.6294">request</text><polygon fill="#A80036" points="651,154.8281,661,158.8281,651,162.8281,655,158.8281" style="stroke:#A80036;stroke-width:1.0;"/><line style="stroke:#A80036;stroke-width:1.0;" x1="400" x2="657" y1="158.8281" y2="158.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="49" x="407" y="153.7622">request</text><!--MD5=[cffb76a7c8b7e9568ee4c32e1fb1e346]
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="290px" preserveAspectRatio="none" style="width:740px;height:290px;" version="1.1" viewBox="0 0 740 290" width="740px" zoomAndPan="magnify"><defs><filter height="300%" id="fa37k5x5er5rs" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#fa37k5x5er5rs)" height="90.2031" style="stroke: #000000; stroke-width: 2.0;" width="357" x="13" y="55.2969"/><rect fill="#FFFFFF" height="43.9375" style="stroke: none; stroke-width: 1.0;" width="357" x="13" y="101.5625"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="69" x2="69" y1="38.2969" y2="249.8984"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="272" x2="272" y1="38.2969" y2="249.8984"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="418" x2="418" y1="38.2969" y2="249.8984"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="561" x2="561" y1="38.2969" y2="249.8984"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="681" x2="681" y1="38.2969" y2="249.8984"/><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="89" x="23" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="75" x="30" y="22.9951">Application</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="89" x="23" y="248.8984"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="75" x="30" y="268.8936">Application</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="117" x="212" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="103" x="219" y="22.9951">Event Manager</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="117" x="212" y="248.8984"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="103" x="219" y="268.8936">Event Manager</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="146" x="343" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="132" x="350" y="22.9951">ScreenLightControl</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="146" x="343" y="248.8984"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="132" x="350" y="268.8936">ScreenLightControl</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="112" x="503" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="98" x="510" y="22.9951">Eink Frontlight</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="112" x="503" y="248.8984"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="98" x="510" y="268.8936">Eink Frontlight</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="100" x="629" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="86" x="636" y="22.9951">Light Sensor</text><rect fill="#FEFECE" filter="url(#fa37k5x5er5rs)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="100" x="629" y="248.8984"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="86" x="636" y="268.8936">Light Sensor</text><path d="M13,55.2969 L77,55.2969 L77,62.2969 L67,72.2969 L13,72.2969 L13,55.2969 " fill="#EEEEEE" style="stroke: #000000; stroke-width: 1.0;"/><rect fill="none" height="90.2031" style="stroke: #000000; stroke-width: 2.0;" width="357" x="13" y="55.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="19" x="28" y="68.3638">alt</text><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="273" x="92" y="67.5073">[control message without any parameters]</text><polygon fill="#A80036" points="260.5,89.5625,270.5,93.5625,260.5,97.5625,264.5,93.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="69.5" x2="266.5" y1="93.5625" y2="93.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="179" x="76.5" y="88.4966">ScreenLightControlMessage</text><line style="stroke: #000000; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="13" x2="370" y1="102.5625" y2="102.5625"/><text fill="#000000" font-family="sans-serif" font-size="11" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="220" x="18" y="112.7729">[contol message with parameters]</text><polygon fill="#A80036" points="260.5,133.5,270.5,137.5,260.5,141.5,264.5,137.5" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="69.5" x2="266.5" y1="137.5" y2="137.5"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="173" x="76.5" y="132.4341">ScreenLightSetParameters</text><polygon fill="#A80036" points="406,169.6328,416,173.6328,406,177.6328,410,173.6328" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="272.5" x2="412" y1="173.6328" y2="173.6328"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="112" x="279.5" y="168.5669">processRequest()</text><polygon fill="#A80036" points="549,198.7656,559,202.7656,549,206.7656,553,202.7656" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="418" x2="555" y1="202.7656" y2="202.7656"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="49" x="425" y="197.6997">request</text><polygon fill="#A80036" points="669,227.8984,679,231.8984,669,235.8984,673,231.8984" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="418" x2="675" y1="231.8984" y2="231.8984"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="49" x="425" y="226.8325">request</text><!--
@startuml
alt control message without any parameters
Application -> "Event Manager" as evm : ScreenLightControlMessage
else contol message with parameters
Application -> "Event Manager" as evm : ScreenLightSetParameters
end
evm -> "ScreenLightControl" as slc: processRequest()
slc -> "Eink Frontlight" : request
slc -> "Light Sensor" : request
@enduml

PlantUML version 1.2020.22(Sun Dec 06 10:36:27 CET 2020)
PlantUML version 1.2018.13(Mon Nov 26 18:11:51 CET 2018)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Java Version: 11.0.11+9-Ubuntu-0ubuntu2.20.04
Operating System: Linux
OS Version: 5.8.0-50-generic
Default Encoding: UTF-8
Language: pl
Country: PL
Language: en
Country: US
--></g></svg>
\ No newline at end of file

M module-services/service-evtmgr/doc/screen_light_control.md => module-services/service-evtmgr/doc/screen_light_control.md +4 -3
@@ 11,7 11,7 @@ screen_light_control module via messages in field `sevm::screen_light_control::P

### Automatic mode

In the automatic mode screen light is controlled using data from the ambient light sensor. This data is 
In the automatic mode screen light is on for a 5s from last key press and is controlled using data from the ambient light sensor. This data is 
then processed with brightness function mapping to obtain particular level of screen lighting. Control algoritm contains ramp, hysteresis and gamma correction calculation.

![](light_control_algorithm.svg "light control algorithm")


@@ 54,7 54,8 @@ Default value of &gamma; is 2.5 . For leds this factor could be in range 2.2-2.8

## Message API

`screen_light_control::ScreenLightControlMessage` is used to control the module. It takes action and data structure as parameters. Set of actions is described in `sevm::screen_light_control::Action`.
`screen_light_control::ScreenLightControlRequestParameters` us ised to request currently setup parameters for display light and sensor.
`screen_light_control::ScreenLightControlMessage` is used to control the module. It takes action as a parameter. Set of actions is described in `sevm::screen_light_control::Action`.
`screen_light_control::ScreenLightSetParameters` is used to control the module. It takes action and data structure as parameters. Set of actions is described in `sevm::screen_light_control::ParameterizedAction`.
`screen_light_control::ScreenLightControlRequestParameters` is used to request currently setup parameters for display light and sensor.

![](light_control_message_flow.svg "Message to light control")
\ No newline at end of file

M module-services/service-evtmgr/screen-light-control/ControlFunctions.hpp => module-services/service-evtmgr/screen-light-control/ControlFunctions.hpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 6,7 6,7 @@
#include <bsp/eink_frontlight/eink_frontlight.hpp>
#include <bsp/light_sensor/light_sensor.hpp>
#include <vector>
#include <memory>
#include <utility>

namespace screen_light_control::functions
{

M module-services/service-evtmgr/screen-light-control/ScreenLightControl.cpp => module-services/service-evtmgr/screen-light-control/ScreenLightControl.cpp +36 -49
@@ 3,10 3,12 @@

#include "ScreenLightControl.hpp"

#include <agents/settings/SystemSettings.hpp>
#include <module-sys/Timers/TimerFactory.hpp>
#include <Service/Message.hpp>
#include <Service/Service.hpp>
#include <module-sys/Timers/TimerFactory.hpp>
#include <agents/settings/SystemSettings.hpp>
#include <service-db/service-db/Settings.hpp>
#include <Utils.hpp>

namespace screen_light_control
{


@@ 32,63 34,54 @@ namespace screen_light_control

    void ScreenLightControl::initFromSettings()
    {
        settings->registerValueChange(
            settings::Brightness::brightnessLevel,
            [&](const std::string &value) { setBrightnessLevel(utils::getNumericValue<float>(value)); },
            settings::SettingsScope::Global);

        settings->registerValueChange(
            settings::Brightness::autoMode,
            [&](const std::string &value) {
                if (utils::getNumericValue<bool>(value)) {
                    enableAutomaticMode();
                }
                else {
                    disableAutomaticMode();
                }
            },
            settings::SettingsScope::Global);

        settings->registerValueChange(
            settings::Brightness::state,
            [&](const std::string &value) {
                if (utils::getNumericValue<bool>(value)) {
                    turnOn();
                }
                else {
                    turnOff();
                }
            },
            settings::SettingsScope::Global);
    }

    void ScreenLightControl::processRequest(Action action, const Parameters &params)
        settings->registerValueChange(settings::Brightness::brightnessLevel, [&](const std::string &value) {
            setBrightnessLevel(utils::getNumericValue<float>(value));
        });

        settings->registerValueChange(settings::Brightness::autoMode, [&](const std::string &value) {
            if (utils::getNumericValue<bool>(value)) {
                enableAutomaticMode();
            }
            else {
                disableAutomaticMode();
            }
        });

        settings->registerValueChange(settings::Brightness::state, [&](const std::string &value) {
            if (utils::getNumericValue<bool>(value)) {
                turnOn();
            }
            else {
                turnOff();
            }
        });
    }

    void ScreenLightControl::processRequest(Action action)
    {
        switch (action) {
        case Action::turnOff:
            turnOff();
            setScreenLightSettings(settings::Brightness::state, lightOn);
            break;
        case Action::turnOn:
            turnOn();
            setScreenLightSettings(settings::Brightness::state, lightOn);
            break;
        case Action::enableAutomaticMode:
            enableAutomaticMode();
            setScreenLightSettings(settings::Brightness::autoMode, automaticMode == ScreenLightMode::Automatic);
            break;
        case Action::disableAutomaticMode:
            disableAutomaticMode();
            setScreenLightSettings(settings::Brightness::autoMode, automaticMode == ScreenLightMode::Automatic);
            break;
        case Action::setManualModeBrightness:
        }
    }

    void ScreenLightControl::processRequest(ParameterizedAction action, Parameters params)
    {
        switch (action) {
        case ParameterizedAction::setManualModeBrightness:
            setBrightnessLevel(params.manualModeBrightness);
            setScreenLightSettings(settings::Brightness::brightnessLevel, params.manualModeBrightness);
            break;
        case Action::setGammaCorrectionFactor:
            setGammaFactor(params.gammaFactor);
            break;
        case Action::setAutomaticModeParameters:
        case ParameterizedAction::setAutomaticModeParameters:
            setAutomaticModeParameters(params);
            break;
        }


@@ 176,12 169,6 @@ namespace screen_light_control
        brightnessValue = brightnessPercentage;
    }

    void ScreenLightControl::setGammaFactor(float gammaFactor)
    {
        bsp::eink_frontlight::setGammaFactor(gammaFactor);
        setScreenLightSettings(settings::Brightness::gammaFactor, gammaFactor);
    }

    void ScreenLightControl::turnOff()
    {
        bsp::eink_frontlight::turnOff();

M module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp => module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp +25 -16
@@ 3,10 3,19 @@

#pragma once

#include <module-sys/Timers/TimerHandle.hpp>
#include <service-db/service-db/Settings.hpp>
#include "ControlFunctions.hpp"
#include <Utils.hpp>
#include <memory>
#include <module-sys/Timers/TimerHandle.hpp>

namespace settings
{
    class Settings;
} // namespace settings

namespace sys
{
    class Service;
} // namespace sys

/// Screen light control algorithm. Automatic/Manual mode of operation.
/// Processing of ambient light sensor input to screen brightness output.


@@ 22,13 31,17 @@ namespace screen_light_control
    /// Set of actions to control the screen light
    enum class Action
    {
        turnOff,                    ///< Turn off screen frontlight
        turnOn,                     ///< Turn on screen frontlight
        enableAutomaticMode,        ///< Enable automatic mode of screen frontlight
        disableAutomaticMode,       ///< Disable automatic mode of screen frontlight
        setManualModeBrightness,    ///< Set screen brightness in manual mode control
        setGammaCorrectionFactor,   ///< Set gamma factor for screen frontlight correction
        setAutomaticModeParameters, ///< Set parameters for automatic mode of screen frontlight
        turnOff,             ///< Turn off screen frontlight
        turnOn,              ///< Turn on screen frontlight
        enableAutomaticMode, ///< Enable automatic mode of screen frontlight
        disableAutomaticMode ///< Disable automatic mode of screen frontlight
    };

    /// Set of actions to control the screen light using specified parameters
    enum class ParameterizedAction
    {
        setManualModeBrightness,   ///< Set screen brightness in manual mode control
        setAutomaticModeParameters ///< Set parameters for automatic mode of screen frontlight
    };

    struct Parameters


@@ 55,7 68,8 @@ namespace screen_light_control
        explicit ScreenLightControl(std::shared_ptr<settings::Settings> settings, sys::Service *parent);
        ~ScreenLightControl();

        void processRequest(Action action, const Parameters &params);
        void processRequest(Action action);
        void processRequest(ParameterizedAction action, Parameters params);

        [[nodiscard]] auto getLightState() const noexcept -> bool;
        [[nodiscard]] auto getAutoModeState() const noexcept -> ScreenLightMode;


@@ 70,7 84,6 @@ namespace screen_light_control

        void setAutomaticModeParameters(const Parameters &params);
        void setBrightnessLevel(bsp::eink_frontlight::BrightnessPercentage brightnessPercentage);
        void setGammaFactor(float gammaFactor);

        void turnOff();
        void turnOn();


@@ 78,10 91,6 @@ namespace screen_light_control
        void enableAutomaticMode();
        void disableAutomaticMode();

        template <class T> void setScreenLightSettings(const std::string &varName, T value)
        {
            settings->setValue(varName, utils::to_string(value), settings::SettingsScope::Global);
        }
        void initFromSettings();

        static constexpr inline auto CONTROL_TIMER_MS = 25;

M module-services/service-evtmgr/service-evtmgr/EventManager.hpp => module-services/service-evtmgr/service-evtmgr/EventManager.hpp +8 -15
@@ 5,17 5,14 @@

#include "Constants.hpp"

#include <backlight-handler/BacklightHandler.hpp>
#include <bsp/vibrator/vibrator.hpp>
#include <MessageType.hpp>
#include <Service/Common.hpp>
#include <Service/Message.hpp>
#include <Service/Service.hpp>
#include <Timers/TimerHandle.hpp>
#include <Service/Worker.hpp>
#include <bsp/common.hpp>
#include <bsp/keyboard/key_codes.hpp>
#include <bsp/keypad_backlight/keypad_backlight.hpp>
#include <screen-light-control/ScreenLightControl.hpp>
#include <vibra/Vibra.hpp>
#include <service-db/DBServiceName.hpp>

#include <cstdint>


@@ 25,14 22,16 @@

class WorkerEvent;

namespace vibra_handle
{
    class Vibra;
} // namespace vibra_handle

class EventManager : public sys::Service
{
  private:
    static constexpr auto stackDepth = 4096;
    void handleMinuteUpdate(time_t timestamp);
    bool processKeypadBacklightRequest(bsp::keypad_backlight::Action action);
    void startKeypadLightTimer();
    void restoreKeypadLightState();
    bool processVibraRequest(bsp::vibrator::Action act,
                             std::chrono::milliseconds RepetitionTime = std::chrono::milliseconds{1000});
    void toggleTorchOnOff();


@@ 40,12 39,6 @@ class EventManager : public sys::Service

    std::shared_ptr<settings::Settings> settings;
    sys::TimerHandle loggerTimer;
    sys::TimerHandle keypadLightTimer;
    bsp::keypad_backlight::State keypadLightState{bsp::keypad_backlight::State::off};
    bool isKeypadLightInCallMode = false;

    static constexpr auto keypadLightTimerName    = "KeypadLightTimer";
    static constexpr auto keypadLightTimerTimeout = std::chrono::seconds(5);

  protected:
    std::unique_ptr<WorkerEvent> EventWorker;


@@ 61,8 54,8 @@ class EventManager : public sys::Service
    // flag set when there is alarm to handle
    bool alarmIsValid = false;

    std::unique_ptr<screen_light_control::ScreenLightControl> screenLightControl;
    std::unique_ptr<vibra_handle::Vibra> Vibra;
    backlight::Handler backlightHandler;

  public:
    explicit EventManager(const std::string &name = service::name::evt_manager);

M module-services/service-evtmgr/service-evtmgr/ScreenLightControlMessage.hpp => module-services/service-evtmgr/service-evtmgr/ScreenLightControlMessage.hpp +12 -8
@@ 1,9 1,6 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "module-services/service-evtmgr/screen-light-control/ScreenLightControl.hpp"


@@ 17,15 14,22 @@ namespace sevm
    class ScreenLightControlMessage : public sys::DataMessage
    {
      public:
        ScreenLightControlMessage() : sys::DataMessage(MessageType::ScreenLightControlAction)
        explicit ScreenLightControlMessage(screen_light_control::Action act)
            : sys::DataMessage(MessageType::ScreenLightControlAction), action(act)
        {}
        ScreenLightControlMessage(screen_light_control::Action act,
                                  screen_light_control::Parameters params = screen_light_control::Parameters())

        const screen_light_control::Action action;
    };

    class ScreenLightSetParameters : public sys::DataMessage
    {
      public:
        ScreenLightSetParameters(screen_light_control::ParameterizedAction act, screen_light_control::Parameters params)
            : sys::DataMessage(MessageType::ScreenLightControlAction), action(act), parameters(std::move(params))
        {}

        screen_light_control::Action action;
        screen_light_control::Parameters parameters;
        const screen_light_control::ParameterizedAction action;
        const screen_light_control::Parameters parameters;
    };

    class ScreenLightControlRequestParameters : public sys::DataMessage