diff --git a/CHANGELOG.md b/CHANGELOG.md index ff52c8d..da136a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,24 @@ # Changelog All notable changes to this project will be documented in this file. +## Release 1.0.0 + +### New features +- Supports FlowConfig to forward encoder data to other modules +- Forward encoder data on serial port +- Check if persistent data to load provides all relevant parameters. Otherwise add default values +- Provide version of module via 'OnNewStatusModuleVersion' +- Function 'getParameters' to provide PersistentData parameters +- Check if features of module can be used on device and provide this via 'OnNewStatusModuleIsActive' event / 'getStatusModuleActive' function + +### Improvements +- Now compatible with CSK_Module_DigitalIOManager version >= 3.7.0 (if using DigitalIn port as encoder interface) +- New UI design available (e.g. selectable via CSK_Module_PersistentData v4.1.0 or higher), see 'OnNewStatusCSKStyle' +- 'loadParameters' returns its success +- 'sendParameters' can control if sent data should be saved directly by CSK_Module_PersistentData +- Added UI icon +- Changed log level of some messages from 'info' to 'fine' + ## Release 0.2.0 ### Improvements diff --git a/CSK_Module_Encoder/pages/assets/CSK_Module_Encoder/UI_sample.png b/CSK_Module_Encoder/pages/assets/CSK_Module_Encoder/UI_sample.png new file mode 100644 index 0000000..8b2701e Binary files /dev/null and b/CSK_Module_Encoder/pages/assets/CSK_Module_Encoder/UI_sample.png differ diff --git a/CSK_Module_Encoder/pages/assets/legacy/settings.json b/CSK_Module_Encoder/pages/assets/legacy/settings.json index 939ec2a..a845df1 100644 --- a/CSK_Module_Encoder/pages/assets/legacy/settings.json +++ b/CSK_Module_Encoder/pages/assets/legacy/settings.json @@ -1,3 +1,9 @@ { -"showLoginButton": false + "canChangeLanguage": true, + "showLoginButton": false, + "defaultLanguage": "en", + "disableEditMode": true, + "showPageHistory": true, + "compactMode": false, + "canChangeCompactMode": false } \ No newline at end of file diff --git a/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.css b/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.css index 56a9b40..5676390 100644 --- a/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.css +++ b/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.css @@ -1,9 +1,81 @@ +.myCustomSpacerVert10_CSK_Module_Encoder { + min-height: 10px; +} + +.myCustomSpacerVert20_CSK_Module_Encoder { + min-height: 20px; +} + +.myCustomFrameNoColor_CSK_Module_Encoder { + margin: 6px; + border-radius: 10px; + border-style: solid; + border-width: 0px; + border-color: 007CC1; + background-color: white; +} + .myCustomFrame_CSK_Module_Encoder { + margin: 6px; + border-radius: 10px; border-style: solid; border-width: 1px; - border-color: grey; - margin: 6px; + border-color: #007CC1; + background-color: white; +} + +.myCustomLabel_CSK_Module_Encoder { + font-size:30px; + color: grey; + margin-top: 10px; +} + +.myCustomFrameLabel_CSK_Module_Encoder { + background: white; + position:relative; + top: calc(-1.2rem); + left: calc(1rem); + font-size: medium; +} + +.myCustomPersistentDataMargin_CSK_Module_Encoder { + margin-top: -53px; + margin-left: 130px; +} + +.myCustomPersistentDataMarginBack_CSK_Module_Encoder { + margin-left: -127px; +} + +.myCustomBorderLeft_CSK_Module_Encoder { + border-left: 1px solid lightgray; +} + +.myCustomMarginFirstRow_CSK_Module_Encoder { + margin-top: -49px; +} + +.myCustomBorderBottom_CSK_Module_Encoder { + border-bottom: 1px solid lightgray; + margin-inline: calc(1rem); +} + +.myCustomMarginTop7PX_CSK_Module_Encoder { + margin-top: 7px; +} + +.myCustomBackground_CSK_Module_Encoder { +} + +.myCustomButton_CSK_Module_Encoder { + border-radius: 30px; + padding: 11px; +} + +.myCustomMarginInline1Rem_CSK_Module_Encoder { + margin-inline: calc(1rem); } -.myCustomCssClass_CSK_Module_Encoder { +.myMinWidht100p_CSK_Module_Encoder { + min-width: 100%; } diff --git a/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.html b/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.html index a2d5d62..333c37c 100644 --- a/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.html +++ b/CSK_Module_Encoder/pages/pages/CSK_Module_Encoder/CSK_Module_Encoder.html @@ -1,493 +1,834 @@ - - + + + + + + + +

+ Encoder +

+ + + + +
+
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BIDIRECTIONAL - - - POSITIVE_MOVEMENT - - - NEGATIVE_MOVEMENT - - - FORWARD_MOVEMENT - - - BACKWARD_MOVEMENT - - - - - - - - - - - - - - - - - - - - - - - SINGLE_PHASE - - - DUAL_PHASE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TICKS - - - DISTANCE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Load Config - - - - - - - - - Save Config - - - - - - - - - - - - - - - - Please login via CSK_UserManagement module (at least with user level "Operator" or higher). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BIDIRECTIONAL + + + POSITIVE_MOVEMENT + + + NEGATIVE_MOVEMENT + + + FORWARD_MOVEMENT + + + BACKWARD_MOVEMENT + + + + + + + + + + + + + + + + + + + + + + + + + + + SINGLE_PHASE + + + DUAL_PHASE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TICKS + + + DISTANCE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Please log in via CSK_UserManagement module (at least via user level "Operator") - - - - - - + + + + + + - - Module is not supported on this device... - - - - - - - - - -
- - - -
+ + + + Module is not supported on this device... + + UI sample + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/CSK_Module_Encoder/pages/src/converter.ts b/CSK_Module_Encoder/pages/src/converter.ts index 5556714..6a26810 100644 --- a/CSK_Module_Encoder/pages/src/converter.ts +++ b/CSK_Module_Encoder/pages/src/converter.ts @@ -1,3 +1,72 @@ export function convertToList(value) { return JSON.parse(value) +} + +export function changeStyle(theme) { + const style: HTMLStyleElement = document.createElement('style'); + style.id ='blub' + + const toggleSW = document.querySelectorAll("davinci-toggle-switch") + toggleSW.forEach((userItem) => { + const shadowToggle = userItem.shadowRoot + const finalToggleSW = shadowToggle?.querySelector('div') + finalToggleSW?.classList.add('hasIcon') + }); + + if (theme == 'CSK_Style'){ + var headerToolbar = `.sopasjs-ui-header-toolbar-wrapper { background-color: #FFFFFF; }` + var uiHeader = `.sopasjs-ui-header>.app-logo { margin-right:0px; }` + var appLogo = `.app-logo { background-color:#FFFFFF; background-image: url(data:image/png;base64,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) }` + var uiNavbar =`.sopasjs-ui-navbar-wrapper { background-color: #737F85; }` + var navbarMenuLiActive = `.sopasjs-navbar-menu>li.active { background-color: #283c45; }` + var navbarMenuLiActiveA = `.sopasjs-navbar-menu>li.active>a { background-color: #283c45; }` + var navbarMeluLi = `.sopasjs-navbar-menu>li { color: #FFFFFF; }` + var navbarMeluLiA = `.sopasjs-navbar-menu>li>a { color: #FFFFFF; }` + var headerToolbarButtonHighlight = `.sopasjs-ui-header-toolbar-button.sopasjs-ui-navigation-navbutton>a.highlight { background-color: #737F85; }` + var toolbarButton = `.sopasjs-ui-header-toolbar-button>a { color: #283c45; }` + + var customBackground = `.CSK_Module_Encoder .myCustomBackground_CSK_Module_Encoder { background-color: #737F8522; }` // font-family: "Open Sans"; }` + + style.innerHTML = headerToolbar; + style.innerHTML += uiHeader; + style.innerHTML += appLogo; + style.innerHTML += uiNavbar; + style.innerHTML += navbarMenuLiActive; + style.innerHTML += navbarMenuLiActiveA; + style.innerHTML += navbarMeluLi; + style.innerHTML += navbarMeluLiA; + style.innerHTML += headerToolbarButtonHighlight; + style.innerHTML += toolbarButton; + + style.innerHTML += customBackground; + } + else if (theme == 'None'){ + var headerToolbar = `.sopasjs-ui-header-toolbar-wrapper { background-color: #007fc3; }` + var uiHeader = `.sopasjs-ui-header>.app-logo { margin-right:10px; }` + var appLogo = `.app-logo { background-color:#007fc3; background-image: url('data:image/png;base64,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') }` + var uiNavbar =`.sopasjs-ui-navbar-wrapper { background-color: #f6f8f9; }` + var navbarMenuLiActive = `.sopasjs-navbar-menu>li.active { background-color: #007fc3; }` + var navbarMenuLiActiveA = `.sopasjs-navbar-menu>li.active>a { background-color: #007fc3; }` + var navbarMeluLi = `.sopasjs-navbar-menu>li { color: #697987; }` + var navbarMeluLiA = `.sopasjs-navbar-menu>li>a { color: #505f6b; }` + var headerToolbarButtonHighlight = `.sopasjs-ui-header-toolbar-button.sopasjs-ui-navigation-navbutton>a.highlight { background-color: #006093; }` + var toolbarButton = `.sopasjs-ui-header-toolbar-button>a { color: #cce5f3; }` + + var customBackground = `.CSK_Module_Encoder .myCustomBackground_CSK_Module_Encoder { background-color: #fff; }` // font-family: "sans-serif"; }` + + style.innerHTML = headerToolbar; + style.innerHTML += uiHeader; + style.innerHTML += appLogo; + style.innerHTML += uiNavbar; + style.innerHTML += navbarMenuLiActive; + style.innerHTML += navbarMenuLiActiveA; + style.innerHTML += navbarMeluLi; + style.innerHTML += navbarMeluLiA; + style.innerHTML += headerToolbarButtonHighlight; + style.innerHTML += toolbarButton; + + style.innerHTML += customBackground; + } + document.head.append(style); + return theme } \ No newline at end of file diff --git a/CSK_Module_Encoder/pages/src/index.ts b/CSK_Module_Encoder/pages/src/index.ts index e69de29..8db9768 100644 --- a/CSK_Module_Encoder/pages/src/index.ts +++ b/CSK_Module_Encoder/pages/src/index.ts @@ -0,0 +1,21 @@ +document.addEventListener('sopasjs-ready', () => { + const page_1 = document.querySelector('div.sopasjs-ui-navbar-wrapper > div > ul > li:nth-child(3) > a > i'); + page_1.classList.remove('fa-file'); + page_1.classList.add('fa-circle-o-notch'); + + const page_FirstLabel = document.querySelector('div.sopasjs-ui-navbar-wrapper > div > ul > li:nth-child(2)'); + const page_App = document.querySelector('div.sopasjs-ui-navbar-wrapper > div > ul > li:nth-child(4)'); + const page_Setup = document.querySelector('div.sopasjs-ui-navbar-wrapper > div > ul > li:nth-child(5) > a'); + + page_FirstLabel.remove(); + page_App.remove(); + page_Setup.remove(); + + setTimeout(() => { + const element = document.querySelector("div.sjs-wrapper > div > div.sjs-fullscreen-toggle") + if(element) { + element.parentElement.removeChild(element) + } + document.title = 'CSK_Module_Encoder' + }, 500); +}) \ No newline at end of file diff --git a/CSK_Module_Encoder/project.mf.xml b/CSK_Module_Encoder/project.mf.xml index 2c567fe..a3350d1 100644 --- a/CSK_Module_Encoder/project.mf.xml +++ b/CSK_Module_Encoder/project.mf.xml @@ -22,7 +22,7 @@ Activate encoder feature (setEncoderFeatureActive). + **2) Pulling encoder / conveyor data periodically** + It is possible to configure a timer to periodically pull encoder / conveyor data. + Set the cycle time via setTimerCycle and activate it via setTimerActive. + -If activated it will pull now the encoder / conveyor data and provide it via the OnNewEncoderInfo / OnNewConveyorInfo events. + +If activated it will pull now the encoder / conveyor data and provide it via the OnNewIncrementInfo / OnNewConveyorInfo events. + {empty} + ** 3) Use ConveyorTimeout** + It is possible to configure a ConveyorTimeout to receive an event if the conveyor moved for a defined amount of ticks or a distance. + @@ -181,16 +181,38 @@ You can make use of the mentioned features / events from other apps or you can d Notify if module can be used on device. + + Notify UI style to use for CSK modules. + + + + Notify version of module. + + + + Notify if FlowConfig should have priority for FlowConfig relevant configurations. + + + + Notify if encoder data should be forwarded. + + + + Notify interface to forward encoder data. + + + + Notify list of interfaces to forward encoder data. + + + + Notify status if forwarding encoder data of currently selected interface is possible. + + Function to set the name of the parameters if saved/loaded via the CSK_PersistentData module. - - Send parameters to CSK_PersistentData module if possible to save them. - - - Load parameters for this module from the CSK_PersistentData module if possible and use them. - Configure if this module should load its saved parameters at app/device boot up. @@ -275,133 +297,85 @@ You can make use of the mentioned features / events from other apps or you can d Function to set the prescaler value for the increment input. If greater than 1 all increment values are scaled with this factor. This can be used if the incoming values need a higher resolution than the increment should have. + + Load parameters for this module from the CSK_PersistentData module if possible and use them. + + + + Send parameters to CSK_PersistentData module if possible to save them. + + + + Function to get status if module is active. + + + + Function to clear FlowConfig relevant configurations. + + + released + Function to get all parameters of the client in JSON format. + + + + Function to reset main configuration of module. + + + Function to configure if FlowConfig should have priority for FlowConfig relevant configuration. + + + + Function to set status if received encoder data should be forwarded on another interface. + + + + Function to set interface to forward received encoder data. + + - - no description yet - - - - - - - no description yet - - - - - - - - - - - no description yet - - - - - - - - - - no description yet - - - - - - - - - no description yet - - - no description yet - - - - - - no description yet - - - - - - - no description yet - - - - - - - - - no description yet - - - - - - no description yet - - - - - - no description yet - - - - - - - - no description yet - - - - - - - - no description yet - - - - - - - - - - no description yet - - - - - - no description yet - - - no description yet - - - - + + released + Crown to provide CSK_FlowConfig relevant features. + + Mode to provide encoder / conveyor data. + ENCODER + CONVEYOR + TIMEOUT + HANDLE_ENCODER + HANDLE_TIMEOUT + + + + released + data-flow + Provide encoder / conveyor data. + + + data-flow + Provide encoder / conveyor data. + + + + + released + Internally used CSK_FlowConfig create function. + + + + + released + Internally used CSK_FlowConfig register function. + + + + + + - - no description yet - - - - SICK AG - 0.2.0 + 1.0.0 low false false diff --git a/CSK_Module_Encoder/scripts/CSK_Module_Encoder.lua b/CSK_Module_Encoder/scripts/CSK_Module_Encoder.lua index 19ca3c7..8bf7c65 100644 --- a/CSK_Module_Encoder/scripts/CSK_Module_Encoder.lua +++ b/CSK_Module_Encoder/scripts/CSK_Module_Encoder.lua @@ -43,6 +43,13 @@ _G.logHandle:applyConfig() -- Check this script regarding encoder_Model parameters and functions _G.encoder_Model = require('Sensors/Encoder/Encoder_Model') +-- If using FlowConfig activate following code line +require('Sensors/Encoder/FlowConfig/Encoder_FlowConfig') + +if _G.availableAPIs.default == false or _G.availableAPIs.specific == false then + _G.logger:warning("CSK_Encoder: Relevant CROWN(s) not available on device. Module is not supported...") +end + --************************************************************************** --**********************End Global Scope *********************************** --************************************************************************** diff --git a/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Controller.lua b/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Controller.lua index 7e9a2dc..e72e00e 100644 --- a/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Controller.lua +++ b/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Controller.lua @@ -20,6 +20,10 @@ local encoder_Model -- ************************ UI Events Start ******************************** +Script.serveEvent('CSK_Encoder.OnNewStatusModuleVersion', 'Encoder_OnNewStatusModuleVersion') +Script.serveEvent('CSK_Encoder.OnNewStatusCSKStyle', 'Encoder_OnNewStatusCSKStyle') +Script.serveEvent('CSK_Encoder.OnNewStatusModuleIsActive', 'Encoder_OnNewStatusModuleIsActive') + Script.serveEvent('CSK_Encoder.OnNewIncrementInfo', 'Encoder_OnNewIncrementInfo') Script.serveEvent('CSK_Encoder.OnNewConveyorInfo', 'Encoder_OnNewConveyorInfo') Script.serveEvent('CSK_Encoder.OnConveyorTimeout', 'Encoder_OnConveyorTimeout') @@ -27,6 +31,7 @@ Script.serveEvent('CSK_Encoder.OnConveyorTimeout', 'Encoder_OnConveyorTimeout') Script.serveEvent('CSK_Encoder.OnNewStatusEncoderFeatureActive', 'Encoder_OnNewStatusEncoderFeatureActive') Script.serveEvent('CSK_Encoder.OnNewEncoderInterfaceList', 'Encoder_OnNewEncoderInterfaceList') + Script.serveEvent('CSK_Encoder.OnNewStatusEncoderInterface', 'Encoder_OnNewStatusEncoderInterface') Script.serveEvent('CSK_Encoder.OnNewEncoderIncrementSourceList', 'Encoder_OnNewEncoderIncrementSourceList') @@ -52,7 +57,12 @@ Script.serveEvent('CSK_Encoder.OnNewStatusConveyorTimeoutActive', 'Encoder_OnNew Script.serveEvent('CSK_Encoder.OnNewStatusConveyorTimeoutMode', 'Encoder_OnNewStatusConveyorTimeoutMode') Script.serveEvent('CSK_Encoder.OnNewStatusConveyorTimeoutValue', 'Encoder_OnNewStatusConveyorTimeoutValue') -Script.serveEvent('CSK_Encoder.OnNewStatusModuleIsActive', 'Encoder_OnNewStatusModuleIsActive') +Script.serveEvent('CSK_Encoder.OnNewStatusForwardAvailable', 'Encoder_OnNewStatusForwardAvailable') +Script.serveEvent('CSK_Encoder.OnNewForwardInterfaceList', 'Encoder_OnNewForwardInterfaceList') +Script.serveEvent('CSK_Encoder.OnNewStatusForwardEncoder', 'Encoder_OnNewStatusForwardEncoder') +Script.serveEvent('CSK_Encoder.OnNewStatusForwardInterface', 'Encoder_OnNewStatusForwardInterface') + +Script.serveEvent('CSK_Encoder.OnNewStatusFlowConfigPriority', 'Encoder_OnNewStatusFlowConfigPriority') Script.serveEvent("CSK_Encoder.OnNewStatusLoadParameterOnReboot", "Encoder_OnNewStatusLoadParameterOnReboot") Script.serveEvent("CSK_Encoder.OnPersistentDataModuleAvailable", "Encoder_OnPersistentDataModuleAvailable") Script.serveEvent("CSK_Encoder.OnNewParameterName", "Encoder_OnNewParameterName") @@ -130,9 +140,11 @@ local function handleOnExpiredTmrEncoder() updateUserLevel() - Script.notifyEvent("Encoder_OnNewStatusModuleIsActive", encoder_Model.moduleActive) + Script.notifyEvent("Encoder_OnNewStatusModuleVersion", 'v' .. encoder_Model.version) + Script.notifyEvent("Encoder_OnNewStatusCSKStyle", encoder_Model.styleForUI) + Script.notifyEvent("Encoder_OnNewStatusModuleIsActive", _G.availableAPIs.default and _G.availableAPIs.specific) - if encoder_Model.moduleActive then + if _G.availableAPIs.default and _G.availableAPIs.specific then Script.notifyEvent("Encoder_OnNewStatusEncoderFeatureActive", encoder_Model.parameters.encoderActive) @@ -162,6 +174,12 @@ local function handleOnExpiredTmrEncoder() Script.notifyEvent("Encoder_OnNewStatusConveyorTimeoutMode", encoder_Model.parameters.conveyorTimeoutMode) Script.notifyEvent("Encoder_OnNewStatusConveyorTimeoutValue", encoder_Model.parameters.conveyorTimeoutValue) + Script.notifyEvent("Encoder_OnNewStatusForwardAvailable", encoder_Model.forwardAvailable) + Script.notifyEvent("Encoder_OnNewForwardInterfaceList", encoder_Model.helperFuncs.createStringListBySimpleTable(encoder_Model.availableForwardInterfaces)) + Script.notifyEvent("Encoder_OnNewStatusForwardEncoder", encoder_Model.parameters.forwardActive) + Script.notifyEvent("Encoder_OnNewStatusForwardInterface", encoder_Model.parameters.forwardInterface) + + Script.notifyEvent("Encoder_OnNewStatusFlowConfigPriority", encoder_Model.parameters.flowConfigPriority) Script.notifyEvent("Encoder_OnNewStatusLoadParameterOnReboot", encoder_Model.parameterLoadOnReboot) Script.notifyEvent("Encoder_OnPersistentDataModuleAvailable", encoder_Model.persistentModuleAvailable) Script.notifyEvent("Encoder_OnNewParameterName", encoder_Model.parametersName) @@ -172,7 +190,9 @@ Timer.register(tmrEncoder, "OnExpired", handleOnExpiredTmrEncoder) -- ********************* UI Setting / Submit Functions Start ******************** local function pageCalled() - updateUserLevel() -- try to hide user specific content asap + if _G.availableAPIs.default and _G.availableAPIs.specific then + updateUserLevel() -- try to hide user specific content asap + end tmrEncoder:start() return '' end @@ -188,7 +208,7 @@ end Script.serveFunction('CSK_Encoder.getEncoderHandle', getEncoderHandle) local function setEncoderFeatureActive(status) - _G.logger:info(nameOfModule .. ": Set encoder features status to " .. tostring(status)) + _G.logger:fine(nameOfModule .. ": Set encoder features status to " .. tostring(status)) encoder_Model.parameters.encoderActive = status if status == false then -- Check if digital input port needs to be freed for CSK_DigitalIOManager module @@ -200,16 +220,23 @@ end Script.serveFunction('CSK_Encoder.setEncoderFeatureActive', setEncoderFeatureActive) local function setEncoderInterface(interface) - _G.logger:info(nameOfModule .. ": Set encoder interface to " .. interface) + _G.logger:fine(nameOfModule .. ": Set encoder interface to " .. interface) encoder_Model.freeDigitalInPort() encoder_Model.parameters.encoderInterface = interface encoder_Model.setupEncoder() + + encoder_Model.forwardAvailable = false + for _, value in ipairs(encoder_Model.availableForwardInterfaces) do + if interface == value then + encoder_Model.forwardAvailable = true + end + end handleOnExpiredTmrEncoder() end Script.serveFunction('CSK_Encoder.setEncoderInterface', setEncoderInterface) local function setEncoderSource(source) - _G.logger:info(nameOfModule .. ": Set encoder source to " .. source) + _G.logger:fine(nameOfModule .. ": Set encoder source to " .. source) encoder_Model.parameters.encoderSource = source encoder_Model.setupEncoder() handleOnExpiredTmrEncoder() @@ -217,7 +244,7 @@ end Script.serveFunction('CSK_Encoder.setEncoderSource', setEncoderSource) local function setDecoderInstance(instance) - _G.logger:info(nameOfModule .. ": Set decoder instance to " .. instance) + _G.logger:fine(nameOfModule .. ": Set decoder instance to " .. instance) encoder_Model.parameters.decoderInstance = instance encoder_Model.setupEncoder() handleOnExpiredTmrEncoder() @@ -225,7 +252,7 @@ end Script.serveFunction('CSK_Encoder.setDecoderInstance', setDecoderInstance) local function setDecoderHighResoltuion(status) - _G.logger:info(nameOfModule .. ": Set decoder high resolution status to " .. tostring(status)) + _G.logger:fine(nameOfModule .. ": Set decoder high resolution status to " .. tostring(status)) encoder_Model.parameters.decoderHighResolution = status encoder_Model.setupEncoder() handleOnExpiredTmrEncoder() @@ -233,7 +260,7 @@ end Script.serveFunction('CSK_Encoder.setDecoderHighResoltuion', setDecoderHighResoltuion) local function setDecoderCountMode(mode) - _G.logger:info(nameOfModule .. ": Set decoder count mode to " .. mode) + _G.logger:fine(nameOfModule .. ": Set decoder count mode to " .. mode) encoder_Model.parameters.decoderCountMode = mode encoder_Model.setupEncoder() handleOnExpiredTmrEncoder() @@ -241,7 +268,7 @@ end Script.serveFunction('CSK_Encoder.setDecoderCountMode', setDecoderCountMode) local function setDecoderPrescaler(prescaler) - _G.logger:info(nameOfModule .. ": Set decoder prescaler to " .. tostring(prescaler)) + _G.logger:fine(nameOfModule .. ": Set decoder prescaler to " .. tostring(prescaler)) encoder_Model.parameters.decoderPrescaler = prescaler encoder_Model.setupEncoder() handleOnExpiredTmrEncoder() @@ -249,7 +276,7 @@ end Script.serveFunction('CSK_Encoder.setDecoderPrescaler', setDecoderPrescaler) local function setDecoderNumberOfPhases(phases) - _G.logger:info(nameOfModule .. ": Set decoder numberOfPhases to " .. phases) + _G.logger:fine(nameOfModule .. ": Set decoder numberOfPhases to " .. phases) encoder_Model.parameters.decoderNumberOfPhases = phases encoder_Model.setupEncoder() handleOnExpiredTmrEncoder() @@ -257,7 +284,7 @@ end Script.serveFunction('CSK_Encoder.setDecoderNumberOfPhases', setDecoderNumberOfPhases) local function setTimerActive(status) - _G.logger:info(nameOfModule .. ": Set cycle timer status to " .. tostring(status)) + _G.logger:fine(nameOfModule .. ": Set cycle timer status to " .. tostring(status)) encoder_Model.parameters.timerActive = status encoder_Model.setupTimer() handleOnExpiredTmrEncoder() @@ -265,7 +292,7 @@ end Script.serveFunction('CSK_Encoder.setTimerActive', setTimerActive) local function setTimerCycle(time) - _G.logger:info(nameOfModule .. ": Set cycle time to " .. tostring(time)) + _G.logger:fine(nameOfModule .. ": Set cycle time to " .. tostring(time)) encoder_Model.parameters.timerCycle = time encoder_Model.setupTimer() handleOnExpiredTmrEncoder() @@ -273,7 +300,7 @@ end Script.serveFunction('CSK_Encoder.setTimerCycle', setTimerCycle) local function setConveyorActive(status) - _G.logger:info(nameOfModule .. ": Set conveyor status to " .. tostring(status)) + _G.logger:fine(nameOfModule .. ": Set conveyor status to " .. tostring(status)) encoder_Model.parameters.conveyorActive = status encoder_Model.setupConveyor() handleOnExpiredTmrEncoder() @@ -281,7 +308,7 @@ end Script.serveFunction('CSK_Encoder.setConveyorActive', setConveyorActive) local function setConveyorSource(source) - _G.logger:info(nameOfModule .. ": Set conveyor source to " .. source) + _G.logger:fine(nameOfModule .. ": Set conveyor source to " .. source) encoder_Model.parameters.conveyorSource = source encoder_Model.setupConveyor() handleOnExpiredTmrEncoder() @@ -289,7 +316,7 @@ end Script.serveFunction('CSK_Encoder.setConveyorSource', setConveyorSource) local function setConveyorResolution(resolution) - _G.logger:info(nameOfModule .. ": Set conveyor resolution to " .. tostring(resolution)) + _G.logger:fine(nameOfModule .. ": Set conveyor resolution to " .. tostring(resolution)) encoder_Model.parameters.conveyorResolution = resolution encoder_Model.setupConveyor() handleOnExpiredTmrEncoder() @@ -297,7 +324,7 @@ end Script.serveFunction('CSK_Encoder.setConveyorResolution', setConveyorResolution) local function setConveyorPrescaler(prescaler) - _G.logger:info(nameOfModule .. ": Set conveyor prescaler to " .. tostring(prescaler)) + _G.logger:fine(nameOfModule .. ": Set conveyor prescaler to " .. tostring(prescaler)) encoder_Model.parameters.conveyorPrescaler = prescaler encoder_Model.setupConveyor() handleOnExpiredTmrEncoder() @@ -314,7 +341,7 @@ end Script.serveFunction('CSK_Encoder.getConveyorTimeoutHandle', getConveyorTimeoutHandle) local function setConveyorTimeoutActive(status) - _G.logger:info(nameOfModule .. ": Set conveyor timeout active status to " .. tostring(status)) + _G.logger:fine(nameOfModule .. ": Set conveyor timeout active status to " .. tostring(status)) encoder_Model.parameters.conveyorTimeoutActive = status encoder_Model.setupConveyorTimeout() handleOnExpiredTmrEncoder() @@ -322,7 +349,7 @@ end Script.serveFunction('CSK_Encoder.setConveyorTimeoutActive', setConveyorTimeoutActive) local function setConveyorTimeoutMode(mode) - _G.logger:info(nameOfModule .. ": Set conveyor timeout mode to " .. mode) + _G.logger:fine(nameOfModule .. ": Set conveyor timeout mode to " .. mode) encoder_Model.parameters.conveyorTimeoutMode = mode encoder_Model.setupConveyorTimeout() handleOnExpiredTmrEncoder() @@ -330,29 +357,61 @@ end Script.serveFunction('CSK_Encoder.setConveyorTimeoutMode', setConveyorTimeoutMode) local function setConveyorTimeoutValue(value) - _G.logger:info(nameOfModule .. ": Set conveyor timeout value to " .. tostring(value)) + _G.logger:fine(nameOfModule .. ": Set conveyor timeout value to " .. tostring(value)) encoder_Model.parameters.conveyorTimeoutValue = value encoder_Model.setupConveyorTimeout() handleOnExpiredTmrEncoder() end Script.serveFunction('CSK_Encoder.setConveyorTimeoutValue', setConveyorTimeoutValue) +local function setForwardActive(status) + _G.logger:fine(nameOfModule .. ": Set status to forward encoder data to " .. tostring(status)) + encoder_Model.parameters.forwardActive = status + Script.notifyEvent("Encoder_OnNewStatusForwardEncoder", status) +end +Script.serveFunction('CSK_Encoder.setForwardActive', setForwardActive) + +local function setForwardInterface(interface) + _G.logger:fine(nameOfModule .. ": Set interface to forward encoder data to " .. tostring(interface)) + encoder_Model.parameters.forwardInterface = interface +end +Script.serveFunction('CSK_Encoder.setForwardInterface', setForwardInterface) + +local function getStatusModuleActive() + return _G.availableAPIs.default and _G.availableAPIs.specific +end +Script.serveFunction('CSK_Encoder.getStatusModuleActive', getStatusModuleActive) + +local function clearFlowConfigRelevantConfiguration() + -- Insert code here to clear FlowConfig relevant actions + --TODO + --encoder_Model.deregisterFromEvent() +end +Script.serveFunction('CSK_Encoder.clearFlowConfigRelevantConfiguration', clearFlowConfigRelevantConfiguration) + +local function getParameters() + return encoder_Model.helperFuncs.json.encode(encoder_Model.parameters) +end +Script.serveFunction('CSK_Encoder.getParameters', getParameters) + -- ***************************************************************** -- Following function can be adapted for CSK_PersistentData module usage -- ***************************************************************** local function setParameterName(name) - _G.logger:info(nameOfModule .. ": Set parameter name: " .. tostring(name)) + _G.logger:fine(nameOfModule .. ": Set parameter name: " .. tostring(name)) encoder_Model.parametersName = name end Script.serveFunction("CSK_Encoder.setParameterName", setParameterName) -local function sendParameters() +local function sendParameters(noDataSave) if encoder_Model.persistentModuleAvailable then CSK_PersistentData.addParameter(encoder_Model.helperFuncs.convertTable2Container(encoder_Model.parameters), encoder_Model.parametersName) CSK_PersistentData.setModuleParameterName(nameOfModule, encoder_Model.parametersName, encoder_Model.parameterLoadOnReboot) - _G.logger:info(nameOfModule .. ": Send Encoder parameters with name '" .. encoder_Model.parametersName .. "' to CSK_PersistentData module.") - CSK_PersistentData.saveData() + _G.logger:fine(nameOfModule .. ": Send Encoder parameters with name '" .. encoder_Model.parametersName .. "' to CSK_PersistentData module.") + if not noDataSave then + CSK_PersistentData.saveData() + end else _G.logger:warning(nameOfModule .. ": CSK_PersistentData module not available.") end @@ -363,47 +422,64 @@ local function loadParameters() if encoder_Model.persistentModuleAvailable then local data = CSK_PersistentData.getParameter(encoder_Model.parametersName) if data then + clearFlowConfigRelevantConfiguration() _G.logger:info(nameOfModule .. ": Loaded parameters from CSK_PersistentData module.") encoder_Model.parameters = encoder_Model.helperFuncs.convertContainer2Table(data) + + encoder_Model.parameters = encoder_Model.helperFuncs.checkParameters(encoder_Model.parameters, encoder_Model.helperFuncs.defaultParameters.getParameters()) + encoder_Model.setupEncoder() CSK_Encoder.pageCalled() + return true else _G.logger:warning(nameOfModule .. ": Loading parameters from CSK_PersistentData module did not work.") + return false end else _G.logger:warning(nameOfModule .. ": CSK_PersistentData module not available.") + return false end end Script.serveFunction("CSK_Encoder.loadParameters", loadParameters) local function setLoadOnReboot(status) encoder_Model.parameterLoadOnReboot = status - _G.logger:info(nameOfModule .. ": Set new status to load setting on reboot: " .. tostring(status)) + _G.logger:fine(nameOfModule .. ": Set new status to load setting on reboot: " .. tostring(status)) + Script.notifyEvent("Encoder_OnNewStatusLoadParameterOnReboot", status) end Script.serveFunction("CSK_Encoder.setLoadOnReboot", setLoadOnReboot) +local function setFlowConfigPriority(status) + encoder_Model.parameters.flowConfigPriority = status + _G.logger:fine(nameOfModule .. ": Set new status of FlowConfig priority: " .. tostring(status)) + Script.notifyEvent("Encoder_OnNewStatusFlowConfigPriority", encoder_Model.parameters.flowConfigPriority) +end +Script.serveFunction('CSK_Encoder.setFlowConfigPriority', setFlowConfigPriority) + --- Function to react on initial load of persistent parameters local function handleOnInitialDataLoaded() - _G.logger:info(nameOfModule .. ': Try to initially load parameter from CSK_PersistentData module.') - if string.sub(CSK_PersistentData.getVersion(), 1, 1) == '1' then + if _G.availableAPIs.default and _G.availableAPIs.specific then + _G.logger:fine(nameOfModule .. ': Try to initially load parameter from CSK_PersistentData module.') + if string.sub(CSK_PersistentData.getVersion(), 1, 1) == '1' then - _G.logger:warning(nameOfModule .. ': CSK_PersistentData module is too old and will not work. Please update CSK_PersistentData module.') + _G.logger:warning(nameOfModule .. ': CSK_PersistentData module is too old and will not work. Please update CSK_PersistentData module.') - encoder_Model.persistentModuleAvailable = false - else + encoder_Model.persistentModuleAvailable = false + else - local parameterName, loadOnReboot = CSK_PersistentData.getModuleParameterName(nameOfModule) + local parameterName, loadOnReboot = CSK_PersistentData.getModuleParameterName(nameOfModule) - if parameterName then - encoder_Model.parametersName = parameterName - encoder_Model.parameterLoadOnReboot = loadOnReboot - end + if parameterName then + encoder_Model.parametersName = parameterName + encoder_Model.parameterLoadOnReboot = loadOnReboot + end - if encoder_Model.parameterLoadOnReboot then - loadParameters() + if encoder_Model.parameterLoadOnReboot then + loadParameters() + end + Script.notifyEvent('Encoder_OnDataLoadedOnReboot') end - Script.notifyEvent('Encoder_OnDataLoadedOnReboot') end end if CSK_DigitalIOManager then @@ -412,6 +488,15 @@ else Script.register("CSK_PersistentData.OnInitialDataLoaded", handleOnInitialDataLoaded) end +local function resetModule() + if _G.availableAPIs.default and _G.availableAPIs.specific then + clearFlowConfigRelevantConfiguration() + pageCalled() + end +end +Script.serveFunction('CSK_Encoder.resetModule', resetModule) +Script.register("CSK_PersistentData.OnResetAllModules", resetModule) + -- ************************************************* -- END of functions for CSK_PersistentData module usage -- ************************************************* diff --git a/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Model.lua b/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Model.lua index 758e519..73106fe 100644 --- a/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Model.lua +++ b/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Model.lua @@ -31,10 +31,12 @@ setEncoder_ModelHandle(encoder_Model) --Loading helper functions if needed encoder_Model.helperFuncs = require('Sensors/Encoder/helper/funcs') -encoder_Model.moduleActive = true -- Features provided by device (APIs available) - -- Create parameters / instances for this module +encoder_Model.styleForUI = 'None' -- Optional parameter to set UI style +encoder_Model.version = Engine.getCurrentAppVersion() -- Version of module encoder_Model.availableInterfaces = {} -- List of available connectors to connect the encoder +encoder_Model.availableForwardInterfaces = {} -- List of available interfaces to forward encoder data +encoder_Model.forwardAvailable = false -- Status if it is possible to forward encoder data on other interface (needs to be a SerialPort) -- Check if specific API was loaded via if _G.availableAPIs.specific then @@ -51,6 +53,7 @@ if _G.availableAPIs.specific then end for key, value in ipairs(serialPortList) do table.insert(encoder_Model.availableInterfaces, value) + table.insert(encoder_Model.availableForwardInterfaces, value) end encoder_Model.availableEncoderIncrementSources = Engine.getEnumValues('EncoderIncrementSources') -- Relevant to set encoder source @@ -71,34 +74,21 @@ if _G.availableAPIs.specific then -- Parameters to be saved permanently if wanted encoder_Model.parameters = {} - - encoder_Model.parameters.encoderActive = false -- Status if encoder features are active + encoder_Model.parameters = encoder_Model.helperFuncs.defaultParameters.getParameters() -- Load default parameters encoder_Model.parameters.encoderInterface = encoder_Model.availableInterfaces[1] -- Source of connected encoder (e.g. S4, INC, SER1) - encoder_Model.parameters.encoderSource = encoder_Model.availableEncoderIncrementSources[1] -- Devices identifier of the encoder (e.g. ENC1) - encoder_Model.parameters.decoderInstance = encoder_Model.availableDecoderInstances[1] or '' -- Instance of decoder to use - encoder_Model.parameters.decoderHighResolution = false -- Status if using high resolution or robust mode - encoder_Model.parameters.decoderCountMode = 'POSITIVE_MOVEMENT' -- Select how increments will be counted, 'BIDIRECTIONAL', 'POSITIVE_MOVEMENT', 'NEGATIVE_MOVEMENT', 'FORWARD_MOVEMENT', 'BACKWARD_MOVEMENT' - encoder_Model.parameters.decoderPrescaler = 1 -- Prescaler value for the increment input - encoder_Model.parameters.decoderNumberOfPhases = 'DUAL_PHASE' -- Select 'SINGLE_PHASE' (A_in) / 'DUAL_PHASE' (A_in and B_in) - - encoder_Model.parameters.timerActive = false -- Status if encoder data should be pulled periodically - encoder_Model.parameters.timerCycle = 1000 -- Cycle time to get increment values + -- Check if it is possible to forward the encoder data from the interface + for _, value in ipairs(encoder_Model.availableForwardInterfaces) do + if encoder_Model.parameters.encoderInterface == value then + encoder_Model.forwardAvailable = true + end + end - encoder_Model.parameters.conveyorActive = false -- Status if conveyor featues should be used + encoder_Model.parameters.forwardInterface = encoder_Model.availableForwardInterfaces[1] -- Interface to optionally forward encoder data + encoder_Model.parameters.encoderSource = encoder_Model.availableEncoderIncrementSources[1] -- Devices identifier of the encoder (e.g. ENC1) + encoder_Model.parameters.decoderInstance = encoder_Model.availableDecoderInstances[1] or '' -- Instance of decoder to use encoder_Model.parameters.conveyorSource = encoder_Model.availableIncrementSources[1] or '' -- Source of increment source to be used for updating the system increment - encoder_Model.parameters.conveyorResolution = 1 -- Resolution in micrometer/increment - encoder_Model.parameters.conveyorPrescaler = 1 -- Prescaler value for the increment input - - encoder_Model.parameters.conveyorTimeoutActive = false -- Status if conveyor timeout should be used - encoder_Model.parameters.conveyorTimeoutValue = 100 -- Can be ticks or mm - encoder_Model.parameters.conveyorTimeoutMode = 'TICKS' -- 'TICKS' or 'DISTANCE' - -else - encoder_Model.moduleActive = false - _G.logger:warning(nameOfModule .. ': Necessary CROWNs are not available on this device. Module is not supported...') - end --************************************************************************** @@ -107,6 +97,13 @@ end --**********************Start Function Scope ******************************* --************************************************************************** +--- Function to react on UI style change +local function handleOnStyleChanged(theme) + encoder_Model.styleForUI = theme + Script.notifyEvent("Encoder_OnNewStatusCSKStyle", encoder_Model.styleForUI) +end +Script.register('CSK_PersistentData.OnNewStatusCSKStyle', handleOnStyleChanged) + --- Function to periodically pull increment / conveyor information local function handleOnTimerExpired() local incr, timestamp = encoder_Model.encoder[encoder_Model.parameters.encoderSource]:getCurrentIncrement() @@ -149,7 +146,6 @@ end --- Function to notify when conveyor timeout expired and restart it local function handleOnConveyorTimerExpired() - print("Got trigger") --DEBUG restartConveyorTimeout() Script.notifyEvent('Encoder_OnConveyorTimeout', DateTime.getTimestamp()) end @@ -207,7 +203,6 @@ local function setupEncoder() encoder_Model.flow = Flow.create() encoder_Model.flow:setType('CFLOW') - if string.sub(encoder_Model.parameters.encoderInterface, 1, 2) == 'IN' then -- TTL encoder connected on INC port @@ -226,6 +221,18 @@ local function setupEncoder() encoder_Model.flow:addLink('IncIn:A_in', 'Encoder:A_in') encoder_Model.flow:addLink('IncIn:B_in', 'Encoder:B_in') + if encoder_Model.parameters.forwardActive == true then + if encoder_Model.parameters.forwardInterface ~= encoder_Model.parameters.encoderInterface then + encoder_Model.flow:addProviderBlock('Transmit', 'Connector.Serial.transmit') + encoder_Model.flow:setCreationParameter('Transmit', encoder_Model.parameters.forwardInterface) + + encoder_Model.flow:addLink('IncIn:A_in', 'Transmit:A_out') + encoder_Model.flow:addLink('IncIn:B_in', 'Transmit:B_out') + else + _G.logger:warning(nameOfModule .. ": Not possible to forward encoder data on this interface.") + end + end + encoder_Model.flow:start() elseif string.sub(encoder_Model.parameters.encoderInterface, 1, 2) == 'SE' then @@ -246,6 +253,18 @@ local function setupEncoder() encoder_Model.flow:addLink('SerIn:A_in', 'Encoder:A_in') encoder_Model.flow:addLink('SerIn:B_in', 'Encoder:B_in') + if encoder_Model.parameters.forwardActive == true then + if encoder_Model.parameters.forwardInterface ~= encoder_Model.parameters.encoderInterface then + encoder_Model.flow:addProviderBlock('Transmit', 'Connector.Increment.transmit') + encoder_Model.flow:setCreationParameter('Transmit', encoder_Model.parameters.forwardInterface) + + encoder_Model.flow:addLink('IncIn:A_in', 'Transmit:A_out') + encoder_Model.flow:addLink('IncIn:B_in', 'Transmit:B_out') + else + _G.logger:warning(nameOfModule .. ": Not possible to forward encoder data on this interface.") + end + end + encoder_Model.flow:start() elseif string.sub(encoder_Model.parameters.encoderInterface, 1, 1) == 'S' then diff --git a/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Parameters.lua b/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Parameters.lua new file mode 100644 index 0000000..04275c8 --- /dev/null +++ b/CSK_Module_Encoder/scripts/Sensors/Encoder/Encoder_Parameters.lua @@ -0,0 +1,45 @@ +---@diagnostic disable: redundant-parameter, undefined-global + +--*************************************************************** +-- Inside of this script, you will find the relevant parameters +-- for this module and its default values +--*************************************************************** + +local functions = {} + +local function getParameters() + + local encoderParameters = {} + + encoderParameters.flowConfigPriority = false -- Status if FlowConfig should have priority for FlowConfig relevant configurations + + encoderParameters.encoderActive = false -- Status if encoder features are active + encoderParameters.forwardActive = false -- Status if encoder data should be forwarded + + encoderParameters.decoderHighResolution = false -- Status if using high resolution or robust mode + encoderParameters.decoderCountMode = 'POSITIVE_MOVEMENT' -- Select how increments will be counted, 'BIDIRECTIONAL', 'POSITIVE_MOVEMENT', 'NEGATIVE_MOVEMENT', 'FORWARD_MOVEMENT', 'BACKWARD_MOVEMENT' + encoderParameters.decoderPrescaler = 1 -- Prescaler value for the increment input + encoderParameters.decoderNumberOfPhases = 'DUAL_PHASE' -- Select 'SINGLE_PHASE' (A_in) / 'DUAL_PHASE' (A_in and B_in) + + encoderParameters.timerActive = false -- Status if encoder data should be pulled periodically + encoderParameters.timerCycle = 1000 -- Cycle time to get increment values + + encoderParameters.conveyorActive = false -- Status if conveyor featues should be used + encoderParameters.conveyorResolution = 1 -- Resolution in micrometer/increment + encoderParameters.conveyorPrescaler = 1 -- Prescaler value for the increment input + + encoderParameters.conveyorTimeoutActive = false -- Status if conveyor timeout should be used + encoderParameters.conveyorTimeoutValue = 100 -- Can be ticks or mm + encoderParameters.conveyorTimeoutMode = 'TICKS' -- 'TICKS' or 'DISTANCE' + + encoderParameters.encoderInterface = '' -- Source of connected encoder (e.g. S4, INC, SER1) + encoderParameters.forwardInterface = '' -- Interace to forward received encoder data + encoderParameters.encoderSource = '' -- Devices identifier of the encoder (e.g. ENC1) + encoderParameters.decoderInstance = '' -- Instance of decoder to use + encoderParameters.conveyorSource = '' -- Source of increment source to be used for updating the system increment + + return encoderParameters +end +functions.getParameters = getParameters + +return functions \ No newline at end of file diff --git a/CSK_Module_Encoder/scripts/Sensors/Encoder/FlowConfig/Encoder_FlowConfig.lua b/CSK_Module_Encoder/scripts/Sensors/Encoder/FlowConfig/Encoder_FlowConfig.lua new file mode 100644 index 0000000..90c71f2 --- /dev/null +++ b/CSK_Module_Encoder/scripts/Sensors/Encoder/FlowConfig/Encoder_FlowConfig.lua @@ -0,0 +1,18 @@ +-- Include all relevant FlowConfig scripts + +--***************************************************************** +-- Here you will find all the required content to provide specific +-- features of this module via the 'CSK FlowConfig'. +--***************************************************************** + +require('Sensors.Encoder.FlowConfig.Encoder_OnNewData') + +--- Function to react if FlowConfig was updated +local function handleOnClearOldFlow() + if _G.availableAPIs.default and _G.availableAPIs.specific then + if encoder_Model.parameters.flowConfigPriority then + CSK_Encoder.clearFlowConfigRelevantConfiguration() + end + end +end +Script.register('CSK_FlowConfig.OnClearOldFlow', handleOnClearOldFlow) \ No newline at end of file diff --git a/CSK_Module_Encoder/scripts/Sensors/Encoder/FlowConfig/Encoder_OnNewData.lua b/CSK_Module_Encoder/scripts/Sensors/Encoder/FlowConfig/Encoder_OnNewData.lua new file mode 100644 index 0000000..589e5f4 --- /dev/null +++ b/CSK_Module_Encoder/scripts/Sensors/Encoder/FlowConfig/Encoder_OnNewData.lua @@ -0,0 +1,67 @@ +-- Block namespace +local BLOCK_NAMESPACE = "Encoder_FC.OnNewData" +local nameOfModule = 'CSK_Encoder' + +--************************************************************* +--************************************************************* + +-- Required to keep track of already allocated resource +local instanceTable = {} + +local function register(handle, _ , callback) + + Container.remove(handle, "CB_Function") + Container.add(handle, "CB_Function", callback) + + local mode = Container.get(handle, 'Mode') + + local function localCallback() + if callback ~= nil then + if mode == 'ENCODER' then + Script.callFunction(callback, 'CSK_Encoder.OnNewIncrementInfo') + elseif mode == 'CONVEYOR' then + Script.callFunction(callback, 'CSK_Encoder.OnNewConveyorInfo') + elseif mode == 'TIMEOUT' then + Script.callFunction(callback, 'CSK_Encoder.OnConveyorTimeout') + elseif mode == 'HANDLE_ENCODER' then + Script.callFunction(callback, 'HANDLE_ENC') + elseif mode == 'HANDLE_TIMEOUT' then + Script.callFunction(callback, 'HANDLE_TIM') + end + else + _G.logger:warning(nameOfModule .. ": " .. BLOCK_NAMESPACE .. ".CB_Function missing!") + end + end + Script.register('CSK_FlowConfig.OnNewFlowConfig', localCallback) + + return true +end +Script.serveFunction(BLOCK_NAMESPACE ..".register", register) + +--************************************************************* +--************************************************************* +local function create(mode) + + local instanceName = tostring(mode) + + -- Check if same instance is already configured + if instanceTable[instanceName] ~= nil then + _G.logger:warning(nameOfModule .. "Instance invalid or already in use, please choose another one") + return nil + else + -- Otherwise create handle and store the restriced resource + local handle = Container.create() + instanceTable[instanceName] = instanceTable + Container.add(handle, 'Mode', mode) + Container.add(handle, "CB_Function", "") + return handle + end +end +Script.serveFunction(BLOCK_NAMESPACE .. ".create", create) + +--- Function to reset instances if FlowConfig was cleared +local function handleOnClearOldFlow() + Script.releaseObject(instanceTable) + instanceTable = {} +end +Script.register('CSK_FlowConfig.OnClearOldFlow', handleOnClearOldFlow) \ No newline at end of file diff --git a/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/checkAPIs.lua b/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/checkAPIs.lua index 1a6e5a7..ef7f6a6 100644 --- a/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/checkAPIs.lua +++ b/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/checkAPIs.lua @@ -5,16 +5,16 @@ local availableAPIs = {} +-- Function to load all default APIs local function loadAPIs() CSK_Encoder = require 'API.CSK_Encoder' - Container = require 'API.Container' - DateTime = require 'API.DateTime' - Engine = require 'API.Engine' - Flow = require 'API.Flow' Log = require 'API.Log' Log.Handler = require 'API.Log.Handler' Log.SharedLogger = require 'API.Log.SharedLogger' + + Container = require 'API.Container' + Engine = require 'API.Engine' Object = require 'API.Object' Timer = require 'API.Timer' @@ -25,18 +25,23 @@ local function loadAPIs() CSK_PersistentData = require 'API.CSK_PersistentData' elseif appList[i] == 'CSK_Module_UserManagement' then CSK_UserManagement = require 'API.CSK_UserManagement' + elseif appList[i] == 'CSK_Module_FlowConfig' then + CSK_FlowConfig = require 'API.CSK_FlowConfig' end end end +-- Function to load specific APIs local function loadSpecificAPIs() -- If you want to check for specific APIs/functions supported on the device the module is running, place relevant APIs here - -- e.g.: + DateTime = require 'API.DateTime' + Flow = require 'API.Flow' Conveyor = require 'API.Conveyor' Conveyor.Timeout = require 'API.Conveyor.Timeout' Encoder = require 'API.Encoder' end +-- Function to load related APIs local function checkRelatedAPIs() CSK_DigitalIOManager = require 'API.CSK_DigitalIOManager' end diff --git a/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/funcs.lua b/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/funcs.lua index 5a1c284..a69b497 100644 --- a/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/funcs.lua +++ b/CSK_Module_Encoder/scripts/Sensors/Encoder/helper/funcs.lua @@ -7,9 +7,13 @@ --**********************Start Global Scope ********************************* --************************************************************************** +local nameOfModule = 'CSK_Encoder' + local funcs = {} -- Providing standard JSON functions funcs.json = require('Sensors/Encoder/helper/Json') +-- Default parameters for instances of module +funcs.defaultParameters = require('Sensors/Encoder/Encoder_Parameters') --************************************************************************** --********************** End Global Scope ********************************** @@ -142,6 +146,27 @@ local function createStringListBySimpleTable(content) end funcs.createStringListBySimpleTable = createStringListBySimpleTable +--- Function to compare table content. Optionally will fill missing values within content table with values of defaultTable +---@param content auto Data to check +---@param defaultTable auto Reference data +---@return auto[] content Update of data +local function checkParameters(content, defaultTable) + for key, value in pairs(defaultTable) do + if type(value) == 'table' then + if content[key] == nil then + _G.logger:info(nameOfModule .. ": Created missing parameters table '" .. tostring(key) .. "'") + content[key] = {} + end + content[key] = checkParameters(content[key], defaultTable[key]) + elseif content[key] == nil then + _G.logger:info(nameOfModule .. ": Missing parameter '" .. tostring(key) .. "'. Adding default value '" .. tostring(defaultTable[key]) .. "'") + content[key] = defaultTable[key] + end + end + return content +end +funcs.checkParameters = checkParameters + return funcs --************************************************************************** diff --git a/README.md b/README.md index a377e10..2e0c02a 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,25 @@ # CSK_Module_Encoder Module to provide Encoder / Conveyor functionality. - -![](https://github.com/SICKAppSpaceCodingStarterKit/CSK_Module_Encoder/blob/main/docu/media/UI_Screenshot.png) +![](./docu/media/UI_Screenshot.png) ## How to Run + The app includes an intuitive GUI to setup a connected encoder / conveyor to use. For further information check out the [documentation](https://raw.githack.com/SICKAppSpaceCodingStarterKit/CSK_Module_Encoder/main/docu/CSK_Module_Encoder.html) in the folder "docu". ## Information -Tested on: -1. SIM1012 - Firmware 2.2.0 +Tested on: +|Device|Firmware|Module version| +|--|--|--| +|SIM1012|V2.4.2|V1.0.0| -This application / module is part of the SICK AppSpace Coding Starter Kit developing approach. -It is programmed in an object oriented way. Some of the modules use kind of "classes" in Lua to make it possible to reuse code / classes in other projects. -In general it is not neccessary to code this way, but the architecture of this app can serve as a sample to be used especially for bigger projects and to make it easier to share code. +This module is part of the SICK AppSpace Coding Starter Kit developing approach. +It is programmed in an object-oriented way. Some of these modules use kind of "classes" in Lua to make it possible to reuse code / classes in other projects. +In general, it is not neccessary to code this way, but the architecture of this app can serve as a sample to be used especially for bigger projects and to make it easier to share code. Please check the [documentation](https://github.com/SICKAppSpaceCodingStarterKit/.github/blob/main/docu/SICKAppSpaceCodingStarterKit_Documentation.md) of CSK for further information. ## Topics -Coding Starter Kit, CSK, Module, SICK-AppSpace, Encoder, Conveyor, Inkrement +Coding Starter Kit, CSK, Module, SICK-AppSpace, Encoder, Conveyor, Increment diff --git a/docu/CSK_Module_Encoder.html b/docu/CSK_Module_Encoder.html index b2b01f8..8645914 100644 --- a/docu/CSK_Module_Encoder.html +++ b/docu/CSK_Module_Encoder.html @@ -6,7 +6,7 @@ -Documentation - CSK_Module_Encoder 0.2.0 +Documentation - CSK_Module_Encoder 1.0.0