Here is the first tangible result of M3 Picking lists in Google Glass. This is a continuation of my previous posts in the series: Getting and processing an M3 picking list and Hello Google Glass from Infor Process Automation.
Goal
As a reminder, I’m developing a proof-of-concept to show rich picking lists from Infor M3 in Google Glass with item number, item description, quantity, stock location, image of the item from Infor Document Archive, and walking directions in a warehouse plan. Also, for interactivity, the picker will be able to tap Glass to confirm the picking. Also, the picker will be able to take a picture of a box at packing.
The result will be useful to showcase the integration capabilities of M3, it’s a first implementation of wearable computing for M3, and it sets a precedent for future Augmented Reality experiments with M3. And the advantages for a picker in a warehouse would be more efficiency and new capabilities. And for me it’s a way to keep my skills up-to-date, and it’s an outlet for my creativity. It’s a lot of software development work, and I’m progressing slowly but steadily on evenings and on week-ends. If you would like to participate please let me know.
Why it matters
According to Gartner, by 2016, wearables will emerge as a $10 billion industry [1].
According to Forbes, “Smart glasses with augmented reality (AR) and head-mounted cameras can increase the efficiency of technicians, engineers and other workers in field service, maintenance, healthcare and manufacturing roles” [2].
According to MarketsandMarkets, the Augmented Reality and Virtual Reality market is expected to grow and reach $1.06 billion by 2018 [3].
Basics of Google Glass
Google Glass is one of the first wearables for the mass market. It is a notification device on the face, an eyewear with all the capabilities of an Android device including camera, head-mounted display, touchpad, network connectivity, voice recognition, location and motion sensors.
It works by displaying a timeline of cards we can swipe back and forth to show past and present events.
To write applications for Google Glass we can use the Mirror API, the Glass Development Kit (GDK), or standard Android development. I will use the Mirror API for simplicity.
I will display an M3 picking list as a series of detailed cards on the timeline that pickers can swipe and interact with like a to-do list as they are progressing in their picking.
Card template
For the template of the timeline card, I will use SIMPLEEVENT from the Google Mirror API Playground per picking list line to easily identify the four pieces of information the picker will need to read per picking list line: item quantity, item number, item description, and stock location:
Bundling
I will use Bundling with bundleId and isBundleCover to group the cards together by picking list:
Picking list lines
I will get the picking list lines with the SQL of my previous post, and I will sort them in descending order because Glass will display them reversely last in, first out, thus they will appear naturally in-order to the user.
SELECT H6WHSL, H6ITNO, H6ITDS, H6ALQT FROM MVXJDTA.MHPICD WHERE H6CONO=<!CONO> AND H6DLIX=<!DLIX> AND H6PLSX=<!PLSX> ORDER BY H6WHSL DESC
HTML card
I will use the SIMPLEEVENT template’s HTML fragment and replace the sample values with item quantity ALQT, item number ITNO, item description ITDS, and stock location WHSL:
<article> <section> <div class="text-auto-size"> <p class="yellow"><!SQL_H6ALQT><sub><!SQL_H6ITNO></sub></p> <p><!SQL_H6ITDS></p> </div> </section> <footer> <div><!SQL_H6WHSL></div> </footer> </article>
JSON
I will embed the HTML fragment in the JSON payload for the Mirror API:
{ "html": html, "bundleId": DLIX }
Bundle cover
The bundle cover will be:
{ "text": "Picking list <!DLIX>", "bundleId": <!DLIX>, "isBundleCover": true }
Infor Process File
My process file in Infor Process Designer is illustrated in this GIF animation (you can open it in Gimp and see the layers in detail):
Problems
I had to solve the following two trivial problems:
- I had problems parsing new line characters in the MsgBuilder activity node with JavaScript in an Assign activity node. According to the ECMAScript Language Specification – ECMA-262 Edition 5.1 on String Literals the character for new line is simply \n (line feed <LF>). Then Samar explained to me that the MsgBuilder activity node in IPA uses both characters \r\n (carriage return <CR> and line feed <LF>).
- JSON is not implemented in IPA for JavaScript in the Assign activity node. So I had to manually add it to IPA. I used Douglas Crockford’s json2.js, and I appended it in the two files <IPDesigner>\IPD\pflow.js and <IPALandmark>\system\LPS\pflow.js.
I still have the following problem:
- The subscription I used in my previous post, M3:MHPICL:U, seems to occur too early in some of my tests, and that is a blocking problem because when my flow runs the SQL to get the picking list lines only gets the first line – which is the only line that exists in the database at that point in time – while the other lines haven’t yet been created in the database at that time and the flow misses them. I must find a solution to this problem. I haven’t been able to reproduce it.
Result
From my previous post, I had the following picking list:
H6WHSL | H6ITNO | H6ITDS | H6ALQT |
T0101 | TLSITEM01 | Item 01 | 11 |
T0102 | TLSITEM02 | Item 02 | 13 |
T0301 | TLSITEM03 | Item 03 | 17 |
T0302 | TLSITEM04 | Item 04 | 19 |
When I re-run the scenario, here are the resulting timeline cards in my Google Glass where black pixels are see-through pixels:
And here is a video capture of the result (I used Android screencast which captures at a slow frame rate):
And here is a picture of what it would look like to the user in Glass with see-through pixels:
Future work
Next, I will implement the following:
- Programmatically get the OAuth 2.0 token instead of copy/pasting it manually in the WebRun activity nodes.
- Show the item image from Infor Document Archive.
- Show walking directions on a warehouse plan.
- Tap to confirm the picking.
- Take a picture of the box at packing.
That’s it! Check out my previous posts on the project. Like this post. Tell me what you think in the comments section below. Share with your colleagues, customers, partners. Click the Follow button to subscribe to this blog. Be an author and publish your own ideas. And enjoy.
Hello, Thibaud!
I find your blog a very interesting read – thanks for the endless stream of cool ideas!
Regarding your bundling/grouping issue with the subscription on M3:PHPICL:U and the trigger being sent too early – I found a pretty simple way of solving this in EventAnalytics that might be of interest to you.
Each Session in Event Analytics can contain Facts. These Facts are accessible from all DRL files (rule files) you have under that Session – and they are kept even after a restart of Event Analytics. Fact data types can be defined within the DRL, so that basically gives us a simple storage engine we can use to temporarily store information.
Event Analytics also has a built in Timer that triggers every minute.
What I’ve tested is to use Facts and the Timer in combination in one DRL file (for another purpose, but it can be applied here).
Here’s the overview functionality in the DRL:
1. Define the datatype, in this case it would be for example GlassPickingList – with four fields CONO, DLIX, PLSX and LMTS
2. Subscribe to event M3:MHPICL:U
3.1. Rule “Listen for Picking List” utilizes normal rule behaviour to check for status of picking list, CONO, DIVI etc.
3.2. The Consequence of the rule will check if a GlassPickingList-fact for the CONO+DLIX+PLSX combination exists
– If it does NOT exist, create it, LMTS is timestamp from the database record
– If it DOES exist, update the LMTS to the new timestamp
3.3. Exit rule
4.1 Rule “Publish Picking List” listens to the Timer every minute and filters the GlassPickingList-facts with a LMTS older than now + X minutes.
4.2 The Consequence of the rule is to publish to a new event “BufferedPickingList” using the values from the Fact (CONO, DLIX, PLSX) as data for the event
4.3 After publish, delete the Fact record
5. Set your subscriber to listen to the BufferedPickingList event from publisher EventAnalytics
Upside is that you’ll only get one trigger per X minutes per combination of key values. This approach could apply to basically any event triggered from M3.
Downside is you’ll get up to a minute (or X minutes) delay, but for the purpose of printing a picking list, I doubt that would be an issue. I would say for most integrations or business processes this delay would be okay.
Hope this gives you some input on how to resolve your issue!
Thanks,
Janne Kindgren
LikeLike
Wow. That is a great information. I didn’t know how to use Facts and Timers. For my Glass proof-of-concept it will be good. Has this technique been tested/approved for production use? Does the buffer have known limit? Thank you.
LikeLike
The only limit I can think of would be the assigned heap size to EventAnalytics. It does store the Facts to disk, but I’m not sure if this is done while running or only as a part of graceful shutdown. My guess is that it’s storing to disk while running and keeping an index in memory. Considering the very limited amount of data, I don’t see a problem unless you start printing hundreds of thousands of picking lists at the same time (but then I assume you have other problems 🙂 ). The Fact would only store one record per unique value combination, in this case CONO/DLIX/PLSX.
The above logic has not been put in production yet, but I it will after the summer holidays. It’s been tested okay.
If you drop me an email to the address I’ve registered to this account, I’ll drop you some code you can play with.
LikeLike