Skip to main content

KanoaMES v1.9

Release Date - 2/1/25

Change Summary

This has been quite a big release for us with over 100 development tickets being addressed ranging from bug fixes, performance improvements, to brand new features that keep extending the Kanoa MES platform capabilities. We have to say this is our best release ever!

Of notable mention...

  • New date selector
  • New asset selector
  • New bread crumb selector
  • New Quality Check Details screen
  • Faster and combined getCalendarEvents() for shift and operations schedule
  • Refactored intelligent Scheduling and shift adherence
  • Auto install of projects
  • Operator Badge In/Out feature
  • Multi Item / Production Order support
  • Added new Item States and Scrap Reasons
  • Configurable Production Day start and end times
  • New widgets and user customizable operator Screen
  • Updates and fixes to Operations analytic screens

Implementation Guidance

Our kanoaMES module now handles the installation of the kanoa projects, reducing the number of installation steps. On a clean install, the module will install KANOA_SCRIPTS, kanoaAPP, kanoaMES and kanoaMarquee projects. On module updates to existing systems, only kanoaAPP will ever be updated. The kanoaMES module will create a backup of kanoaAPP.

This release package has been tested against Ignition 8.1.45.

  • kanoaMES_1_9_23.modl
  • ApexCharts-signed 1.0.17.modl
  • BIJC_Calendar_Component_v1.8.1.modl

A new widget was added called Manual State Selector which calls the customizable script kanoaScripts.custom.ops.asset.stateChange(). This script can be modified, in the default version the state of the line is set based on the state of the cells on the line. If this is a new install, this script will be installed. If this is an existing install, we do not over-write the KANOA_SCRIPTS project. You can add the script below instead to make the new widget operational.

def stateChange(paramsDict, userId):
'''
This function can be called whenever an assets state changes and can be customized however needed. In this example
we are assumng a cell on a line has changed state and the cells under the line drive the line state
Args:
paramsDict (dict)
- assetInfo (dict)
Returns:
None
Updated:
jfc - 2/5/25 7:30am Created
'''

log = system.util.getLogger("kanoaScripts")
debug = system.tag.read("[Kanoa]kanoa/debug/tags/debugStates").value
if debug: log.info("stateChange() called by %s with %s"%(userId, paramsDict))
assetInfo = paramsDict['assetInfo'] if paramsDict.has_key('assetInfo') else None
assetPath = assetInfo['assetPath'] if assetInfo.has_key('assetPath') else None

if assetPath:
#Now we'll check if we need to update the line
parentPath = "\\".join(assetPath.split("\\")[:-1])
assets = system.kanoa.utilities.convertDatasetToJSON(system.kanoa.asset.getAssets({'assetPath': parentPath + '\\%'}))
tagPathList = [asset['tagPath'] + '/Line/OEE/StateTypeName' for asset in assets]
tagPathValues = system.tag.readBlocking(tagPathList)
assetStateTypeList = list(set([tagValue.value for tagValue in tagPathValues]))

tagPathList = [asset['tagPath'] + '/Line/OEE/StateName' for asset in assets]
tagPathValues = system.tag.readBlocking(tagPathList)
assetStateList = list(set([tagValue.value for tagValue in tagPathValues]))

if 'Running' in assetStateTypeList: parentState = 'Running'
elif 'Unplanned Downtime' in assetStateTypeList:
if 'Idle' in assetStateList: assetStateList.pop(assetStateList.index('Idle'))
if 'Off Line' in assetStateList: assetStateList.pop(assetStateList.index('Off Line'))
parentState = 'Idle' if len(assetStateList) == 0 else 'Down'
elif 'Planned Downtime' in assetStateTypeList: parentState = 'Planned Down'
else: parentState = 'Idle'

parentTagPath = system.kanoa.asset.getAssetTagPath({'assetPath': parentPath})
currentStateName = system.tag.read(parentTagPath + '/Line/OEE/stateName').value

if currentStateName != parentState:
log.info("Setting %s to state %s"%(parentPath, parentState))

assetStateInfo = system.kanoa.utilities.convertDatasetRowToJSON(system.kanoa.asset.getAssetStates({'assetId': assetInfo['parentId'], 'stateName': parentState}),0)
if assetStateInfo['stateCode']:
stateInfo = {'assetId': assetInfo['parentId'], 'assetStateId': assetInfo['parentId'], 'stateCode': assetStateInfo['stateCode'], 'tStamp': system.date.now(), 'note': None}
log.info("addStateEvent() called with %s"%stateInfo)
stateEventId = system.kanoa.event.addStateEvent(stateInfo, userId)

#We'll update the OEE state values for display purposes
tagPath = '%s%s'%(parentTagPath, '/Line/OEE/')
tagPathList = [tagPath+'stateName', tagPath+'stateTypeName', tagPath+'stateTypeColor', tagPath+'stateColor', tagPath+'stateIconPath']
tagPathValues = [assetStateInfo['stateName'], assetStateInfo['stateTypeName'] or '', assetStateInfo['stateTypeColor'] or '', assetStateInfo['stateColor'] or assetStateInfo['stateTypeColor'] or '', assetStateInfo['iconPath'] or '']
system.tag.writeBlocking(tagPathList, tagPathValues)
else:
log.warn("Couldn't find a stateCode for assetId %s %s"%(values['parentId'], parentState))
return

Change Log

New Bread Crumb Selector

A new selector has been added that allows navigation by clicking on the 'breadcrumb'. The breadcrumb can be used alongside the treeSelector component to navigate through any type of hierarchy. We use it now for traversing assets, but it can just as easily be used for material hierarchies.

It can be found at kanoa/core/templates/selectors/breadcrumb/breadcrumb.

breadcrumb


Date Range Selector

A new dateSelector component has been added that combines a number of other date selectors all into one. It has been extended to return 'Current Run', 'Current Shift', 'Previous Shift' whe passed an assetPath. It has also been merged with the Live date range selector to add 'Last 24 hrs, 'Last 7 Days' and 'Last 14 Days'. When selected date range is set to include the current time, option to automatically refresh is provided. All options are configurable, so you can choose which ones are displayed.

It can be found at kanoa/core/templates/selectors/dateSelector.

dateSelector


Configurable Start and End Times for Production Day

The start and end time that is returned for an asset when selecting 'Today', 'Yesterday', 'Last Week' etc. can also now be customized by setting a custom asset attribute called '_ProductionDay'. This can be set at any level of the asset tree and assets below it will adhere to it. Different times can be set for different assets.

productionDay


Operator Badging In

We've added views that support capturing operator badging in and out. A record of who was working on what, where and when is stored using the dynamic attributes schema.

operatorBadgeIn


Scrap Reasons & Item States

We've also added item states that allows counts to be associated to configurable items states. This can be used by operators to code scrap reasons or connected directly to a plc to automatically set bottles kicked off a bottling line for say 'Low fill level' or 'Missing bottle cap'.

scrapReasons

Items States are configurable in the new kanoa/mes/config/itemStates/itemStateConfiguration view.


Multi Item and Production Order Support

Along with item states, we have extended the countEvent table to allow for counts to be associated directly to production orders or items. With this seemingly innocuous change, we are now able to capture and analyze data for assets that can be processing multiple production orders at the same time such as a manual work center.

It also allows us to support assets that may produce multiple parts at the same time such as a stamping press or a lumber mill where multiple products come out at the end of the line.


More Widgets and Customizable Operator Screens

Our Quality application leads the way in providing an interface where users can pretty much configure whatever they want without the need for developers to be in the designer configuring checks for them. We've taken that mantra a step further by utilizing the dashboard capability implemented in release 1.7 and using that so that users can build their own operator station screens. Users can now server themselves, you just need to build the widgets they want.

We've added customizable Info Panel and navigation Panel to the Operator screen. Custom asset attribute '_assetOpsInfoPanelViewPath' can be set for the left hand panel. Custom asset attribute '_assetOpsViewPath' can be set for the right hand panel.

In the image below, we are using 'kanoa/mes/asset/operation/assetInfoPanelWorkCell' for an asset that has a number of stations working on different items, and 'kanoa/mes/asset/operation/stationPanel' that uses the dashboard to set and view a custom operator dashboard.

operatorDashboard

To that end, we've added a few more widgets out of the box and we'll be adding more in future releases.

  • Asset State Selector
  • Asset Count Editor
  • Downtime Editor

Quality

  • Added limit check to system.kanoa.quality.analysis.getChkItemEventsByRow() to prevent it overloading the Quality Check Details screen. Analysis is now broken into pages.
  • Check Sheet details screen has been updated to add sparkline and tolerances to the column view.

columnView


Operations Analysis

  • Run Review opens downtime table to start date of modeEvent and not the selected runStart of the chosen period. This has been fixed.
  • Footer groups showed 'mixed units' on Run Review screen even though they were all the same units. This has been fixed.
  • Asset Operation Info panel was calling getPreviousModeEvent when that information is stored in the assetOEE tag. Removed to reduce the number of database calls.
  • Production Chart Data wasn't always returning the correct data for the different interval options. This has been fixed.
  • assetDowntimeBarChart view now uses state colors.
  • oeeBarChart changes. Overall OEE metrics were taken as mean from the interval data stored procedure. Am now calling new spGetOEEDataSummary() with corrected availability and performance. Also not all interval worked if any of the apq values were null, this is now fixed.
  • spGetOEEDataSummary calculations have been corrected. It was not calculating minutes or availability correctly.
  • system.kanoa.event.buildProductionBarChartByDay() has been updated to only return data for the given range rather than the start of the modeEvent. This is used by the Summary screen and utilization bar charts.

Shift & Operations Schedule Management

Big changes have been made to how shift and operations scheduling is handled. KanoaMES supports the creation of shift and scheduled events in multi-site time zones from clients in any time zone for databases and gateways that may be in different time zones. Although the recommendation has always been to have the database server set to UTC to avoid issues created by daylight savings for multi-time zone implementations,we still need to support installs where the database server is set in a specific time zone for single time zone implementations.

Changes to how we handle shifts and operation schedules is as follows..

  • start and end times are still stored as datetime objects in the database, however the calendar component and scheduling deals with date strings.
  • dates are converted to date strings using the time zone offset stored for the site.
  • scheduled events are always shown in the calendar at the time scheduled for the site.

We were continually applying site and client time zone offsets whenever we dealt with scheduled events. We now deal with them exclusively as date time objects and only apply offset when displaying in the calendar and saving to the database.

This has dramatically simplified the implementation and corrected issues we saw occasionally with offset being applied incorrectly for clients in certain time zones. We believe we have also fixed issues associated with scheduling events for an asset when the time zone offset at the time was different due to daylight savings.

Shift Inheritance has been tweaked as well. Assets inherit shifts set for their parents, however they would no longer inherit the minute a shift was created at that asset level. With this release, you can now add non-recurring shift events to an asset and still inherit from it's parents shift schedule. This allows for 'overtime' or special 'weekend' shifts to be configured.

  • Intelligent Scheduling has been extended in this release to apply when editing scheduled events not just when creating new events.
  • Scheduling events on calendar occasionally created duplicate ghost events. We now disable editing on the calendar when a event is being created or modified.
  • Added intelligent scheduling to edited events not just new events.
  • Selected asset is now saved when switching between shift and Scheduling Operations screen.
  • Operations calendar allowed for selection of invalid recurring options. This has been fixed.
  • Scheduled Operation start and end time do not match on Run Control screen. This has been fixed.

Styles

  • We realized a change we had made to the global.css file to set a default font size was preventing the ability to set custom font sizes on the dropdown and some other components. This has been fixed.
  • View containers backgroundColor defaulted to --kanoaPrimary (blue). Background color now defaults to --kcSurface

Database Schema

  • DB lock on modeEvent table: mes.vwProduction and vwAssetType didn't have NOLOCK keyword on table joins. This has been fixed.
  • Added enabled column to mes.counterType.
  • Added endAttributeEventId to [mes].[vwAttributeEvents]
  • Added mes.vwStateEvents
  • Added dbp.screenDashboards
  • Added dbp.vwScreenDashboards

Tags

  • [Kanoa]kanoa/timers/shiftEventTimer has been updated.
  • [Kanoa]kanoa/timers/checkAssetScheduleTimer has been updated.

System Functions

  • system.kanoa.event.checkforDuplicateModeEvents() has been modified to not delete duplicate events created by the schedule.
  • system.kanoa.utilities.secondsToText() has been updated to check for valid valid seconds being passed.
  • Added system.kanoa.config.getConfigType()
  • Added system.kanoa.config.saveConfig and deprecated system.kanoa.config.writeConfig()
  • Added system.kanoa.item.getItemStateClasses()
  • Added system.kanoa.item.addItemStateClass()
  • Added system.kanoa.item.updateItemStateClass()
  • Added system.kanoa.item.deleteItemStateClass()
  • Added system.kanoa.item.getItemStates()
  • Added system.kanoa.item.addItemState()
  • Added system.kanoa.item.updateItemState()
  • Added system.kanoa.item.deleteItemState()
  • Added system.kanoa.item.getItemStateLinks()
  • Added system.kanoa.item.getItemStateLink()
  • Added system.kanoa.item.linkItemStates()
  • Added system.kanoa.item.unlinkItemStates()
  • Added system.kanoa.item.checkItemState()
  • Added system.kanoa.item.checkItemStateClassPath()
  • Added system.kanoa.event.getCounterEvents() and deprecated system.kanoa.event.getCountEvents()
  • Added system.kanoa.event.getCounterEventTotals() and deprecated system.kanoa.event.getCountTotals()
  • Added system.kanoa.event.deleteCounterEvents() and system.kanoa.event.deleteCountEvents()
  • Added system.kanoa.shift.getPreviousShift()
  • Added system.kanoa.shift.getClosestAncestor()
  • Added system.kanoa.schedule.getShiftCalendarEvents()
  • Deprecated system.kanoa.shift.getClosestAncestorWithShifts()
  • Deprecated system.kanoa.shift.getAllEventsInRange()
  • Added system.kanoa.schedule.getCalendarEvents()
  • Added system.kanoa.schedule.adjustExistingEvents()
  • Updated system.kanoa.schedule.decodeScheduleBlock()
  • Deprecated system.kanoa.schedule.getAllEventsInRange()
  • Added system.kanoa.asset.getClosestAncestorAttribute()
  • Added system.kanoa.utilities.convertListToDict()
  • Added system.kanoa.utilities.convertDictListToDataset()
  • Added system.kanoa.date.getTimezones()
  • Added system.kanoa.date.getTimeZoneOffsetMins()
  • Added system.kanoa.date.getAssetTimeZoneInfo()
  • Deprecated system.kanoa.asset.adjustTimeForSite()
  • Deprecated system.kanoa.asset.getSiteTimezoneOffset()
  • Added system.kanoa.operators.enterBadge()
  • system.kanoa.attribute.getAttributeEvents() has been updated to add more handling of date parameter options.

Bug fixes

  • Assets don't switch back to Idle after their scheduled Production block is complete. This has been fixed.
  • Split bar position keeps resetting in Asset State configuration screen. This has been fixed.
  • Asset Overview screen doesn't display asset in the correct sort order. This has been fixed.
  • Selected asset not saved when switching between shift and Scheduling Operations screen. This has been fixed.
  • Navigation items get deleted even if ok is not selected in user confirm. This has been fixed.
  • Adding a production order fails when creating a new itemUnitName. This has been fixed.
  • Updated system.kanoa.lot.getLotQty() replacing temp table with an additional with statement to get rid of no result set found error.
  • Asset Import fails when the rate info for an itemClassPath was null. This has been fixed.
  • Added fix for endDate of null that caused countEditor to not pull counts correctly. spGetAssetProductionEventSummary and spGetAssetProductionEvents have been changed.
  • We now prevent deleting modes or editing modes when 'By Shift' is enabled as it doesn't show the correct start times for a mode.
  • assetOEE tags woQtyRemaining and outfeedRate were not updating. This has been fixed.
  • Setting a non-recurring shift event no longer prevents an asset from inheriting a parents shift schedule.